@@ -188,7 +188,8 @@ import {
188
188
TypeKind ,
189
189
TypeFlags ,
190
190
Signature ,
191
- typesToRefs
191
+ typesToRefs ,
192
+ SignatureFlags
192
193
} from "./types" ;
193
194
194
195
import {
@@ -2054,20 +2055,23 @@ export class Compiler extends DiagnosticEmitter {
2054
2055
2055
2056
// === Table ====================================================================================
2056
2057
2058
+ private registerFunctionInTable ( instance : Function ) : u32 {
2059
+ // Add to the function table
2060
+ let functionTable = this . functionTable ;
2061
+ let tableBase = this . options . tableBase ;
2062
+ if ( ! tableBase ) tableBase = 1 ; // leave first elem blank
2063
+ let index = tableBase + functionTable . length ;
2064
+ functionTable . push ( instance ) ;
2065
+ return index ;
2066
+ }
2067
+
2057
2068
/** Ensures that a runtime counterpart of the specified function exists and returns its address. */
2058
2069
ensureRuntimeFunction ( instance : Function ) : i64 {
2059
2070
assert ( instance . is ( CommonFlags . Compiled ) && ! instance . is ( CommonFlags . Stub ) ) ;
2060
2071
let program = this . program ;
2061
2072
let memorySegment = instance . memorySegment ;
2062
2073
if ( ! memorySegment ) {
2063
-
2064
- // Add to the function table
2065
- let functionTable = this . functionTable ;
2066
- let tableBase = this . options . tableBase ;
2067
- if ( ! tableBase ) tableBase = 1 ; // leave first elem blank
2068
- let index = tableBase + functionTable . length ;
2069
- functionTable . push ( instance ) ;
2070
-
2074
+ let index = this . registerFunctionInTable ( instance ) ;
2071
2075
// Create runtime function
2072
2076
let rtInstance = assert ( this . resolver . resolveClass ( program . functionPrototype , [ instance . type ] ) ) ;
2073
2077
let buf = rtInstance . createBuffer ( ) ;
@@ -6085,12 +6089,13 @@ export class Compiler extends DiagnosticEmitter {
6085
6089
let functionArg = this . compileExpression ( expression . expression , Type . auto ) ;
6086
6090
let signature = this . currentType . getSignature ( ) ;
6087
6091
if ( signature ) {
6092
+ const thisArg = signature . hasEnv ? functionArg : 0 ;
6088
6093
return this . compileCallIndirect (
6089
6094
signature ,
6090
6095
functionArg ,
6091
6096
expression . args ,
6092
6097
expression ,
6093
- 0 ,
6098
+ thisArg ,
6094
6099
contextualType == Type . void
6095
6100
) ;
6096
6101
}
@@ -7038,6 +7043,64 @@ export class Compiler extends DiagnosticEmitter {
7038
7043
return module . unreachable ( ) ;
7039
7044
}
7040
7045
7046
+ compileFirstClassFunction (
7047
+ expression : FunctionExpression
7048
+ // TODO(support contextualType)
7049
+ ) : ExpressionRef {
7050
+ // class AnonymousFunctionClass extends Function<T> {}
7051
+ let module = this . module ;
7052
+ let flow = this . currentFlow ;
7053
+ let sourceFunction = flow . sourceFunction ;
7054
+ let declaration = expression . declaration . clone ( ) ;
7055
+ let anonymousId = sourceFunction . nextAnonymousId ++ ;
7056
+ let contextualTypeArguments = cloneMap ( flow . contextualTypeArguments ) ;
7057
+
7058
+ let classPrototype = new ClassPrototype (
7059
+ `${ sourceFunction . internalName } |anonymous|${ anonymousId } ` ,
7060
+ sourceFunction ,
7061
+ Node . createClassDeclaration (
7062
+ Node . createIdentifierExpression (
7063
+ `${ sourceFunction . internalName } |anonymous|${ anonymousId } ` , declaration . range
7064
+ ) ,
7065
+ null ,
7066
+ CommonFlags . None ,
7067
+ null ,
7068
+ null ,
7069
+ null ,
7070
+ [ ] ,
7071
+ declaration . range
7072
+ ) ,
7073
+ DecoratorFlags . None
7074
+ ) ;
7075
+ let classInstance = this . resolver . resolveClass ( classPrototype , null , contextualTypeArguments , ReportMode . Report ) ;
7076
+ if ( ! classInstance ) return this . module . unreachable ( ) ;
7077
+
7078
+ declaration . flags |= CommonFlags . Instance ;
7079
+ let functionPrototype = new FunctionPrototype (
7080
+ `anonymous|${ anonymousId } ` ,
7081
+ classInstance ,
7082
+ declaration ,
7083
+ DecoratorFlags . None
7084
+ ) ;
7085
+
7086
+ let instance = this . resolver . resolveFirstClassFunction ( functionPrototype , null , contextualTypeArguments ) ;
7087
+ if ( ! instance ) return this . module . unreachable ( ) ;
7088
+ instance . flow . outer = flow ;
7089
+
7090
+ let worked = this . compileFunction ( instance ) ;
7091
+ this . currentType = instance . signature . type ;
7092
+ if ( ! worked ) return module . unreachable ( ) ;
7093
+
7094
+ let currentType = this . currentType ;
7095
+ if ( ! instance ) return module . unreachable ( ) ;
7096
+ let rtInstance = assert ( this . resolver . resolveClass ( this . program . functionPrototype , [ instance . type ] ) ) ;
7097
+ const functionIndexInTable = this . registerFunctionInTable ( instance ) ;
7098
+ let ctor = this . ensureConstructor ( rtInstance , expression ) ;
7099
+ let expr = this . makeCallDirect ( ctor , [ module . i32 ( 0 ) , module . i32 ( functionIndexInTable ) , module . usize ( 0 ) ] , expression , /* immediatelyDropped */ false ) ;
7100
+ this . currentType = currentType ;
7101
+ return expr ;
7102
+ }
7103
+
7041
7104
private compileFunctionExpression (
7042
7105
expression : FunctionExpression ,
7043
7106
contextualType : Type ,
@@ -8774,7 +8837,7 @@ export class Compiler extends DiagnosticEmitter {
8774
8837
classInstance . type ,
8775
8838
classInstance . type ,
8776
8839
baseCtor . signature . requiredParameters ,
8777
- baseCtor . signature . hasRest
8840
+ baseCtor . signature . hasRest ? SignatureFlags . Rest : SignatureFlags . None
8778
8841
) ,
8779
8842
contextualTypeArguments
8780
8843
) ;
0 commit comments