@@ -188,7 +188,8 @@ import {
188188 TypeKind ,
189189 TypeFlags ,
190190 Signature ,
191- typesToRefs
191+ typesToRefs ,
192+ SignatureFlags
192193} from "./types" ;
193194
194195import {
@@ -2054,20 +2055,23 @@ export class Compiler extends DiagnosticEmitter {
20542055
20552056 // === Table ====================================================================================
20562057
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+
20572068 /** Ensures that a runtime counterpart of the specified function exists and returns its address. */
20582069 ensureRuntimeFunction ( instance : Function ) : i64 {
20592070 assert ( instance . is ( CommonFlags . Compiled ) && ! instance . is ( CommonFlags . Stub ) ) ;
20602071 let program = this . program ;
20612072 let memorySegment = instance . memorySegment ;
20622073 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 ) ;
20712075 // Create runtime function
20722076 let rtInstance = assert ( this . resolver . resolveClass ( program . functionPrototype , [ instance . type ] ) ) ;
20732077 let buf = rtInstance . createBuffer ( ) ;
@@ -6082,12 +6086,13 @@ export class Compiler extends DiagnosticEmitter {
60826086 let functionArg = this . compileExpression ( expression . expression , Type . auto ) ;
60836087 let signature = this . currentType . getSignature ( ) ;
60846088 if ( signature ) {
6089+ const thisArg = signature . hasEnv ? functionArg : 0 ;
60856090 return this . compileCallIndirect (
60866091 signature ,
60876092 functionArg ,
60886093 expression . args ,
60896094 expression ,
6090- 0 ,
6095+ thisArg ,
60916096 contextualType == Type . void
60926097 ) ;
60936098 }
@@ -7035,6 +7040,65 @@ export class Compiler extends DiagnosticEmitter {
70357040 return module . unreachable ( ) ;
70367041 }
70377042
7043+ compileFirstClassFunction (
7044+ expression : FunctionExpression
7045+ // TODO(support contextualType)
7046+ ) : ExpressionRef {
7047+ // class AnonymousFunctionClass extends Function<T> {}
7048+ let module = this . module ;
7049+ let flow = this . currentFlow ;
7050+ let sourceFunction = flow . sourceFunction ;
7051+ let declaration = expression . declaration . clone ( ) ;
7052+ let anonymousId = sourceFunction . nextAnonymousId ++ ;
7053+ let contextualTypeArguments = cloneMap ( flow . contextualTypeArguments ) ;
7054+
7055+ let classPrototype = new ClassPrototype (
7056+ `${ sourceFunction . internalName } |anonymous|${ anonymousId } ` ,
7057+ sourceFunction ,
7058+ Node . createClassDeclaration (
7059+ Node . createIdentifierExpression (
7060+ `${ sourceFunction . internalName } |anonymous|${ anonymousId } ` , declaration . range
7061+ ) ,
7062+ null ,
7063+ CommonFlags . None ,
7064+ null ,
7065+ null ,
7066+ null ,
7067+ [ ] ,
7068+ declaration . range
7069+ ) ,
7070+ DecoratorFlags . None
7071+ ) ;
7072+ let classInstance = this . resolver . resolveClass ( classPrototype , null , contextualTypeArguments , ReportMode . Report ) ;
7073+ if ( ! classInstance ) return this . module . unreachable ( ) ;
7074+
7075+ declaration . flags |= CommonFlags . Instance ;
7076+ let functionPrototype = new FunctionPrototype (
7077+ `anonymous|${ anonymousId } ` ,
7078+ classInstance ,
7079+ declaration ,
7080+ DecoratorFlags . None
7081+ ) ;
7082+
7083+ let instance = this . resolver . resolveFunction ( functionPrototype , null , contextualTypeArguments ) ;
7084+ if ( ! instance ) return this . module . unreachable ( ) ;
7085+ instance . signature . setEnv ( ) ;
7086+ instance . flow . outer = flow ;
7087+
7088+ let worked = this . compileFunction ( instance ) ;
7089+ this . currentType = instance . signature . type ;
7090+ if ( ! worked ) return module . unreachable ( ) ;
7091+
7092+ let currentType = this . currentType ;
7093+ if ( ! instance ) return module . unreachable ( ) ;
7094+ let rtInstance = assert ( this . resolver . resolveClass ( this . program . functionPrototype , [ instance . type ] ) ) ;
7095+ const functionIndexInTable = this . registerFunctionInTable ( instance ) ;
7096+ let ctor = this . ensureConstructor ( rtInstance , expression ) ;
7097+ let expr = this . makeCallDirect ( ctor , [ module . i32 ( 0 ) , module . i32 ( functionIndexInTable ) , module . usize ( 0 ) ] , expression , /* immediatelyDropped */ false ) ;
7098+ this . currentType = currentType ;
7099+ return expr ;
7100+ }
7101+
70387102 private compileFunctionExpression (
70397103 expression : FunctionExpression ,
70407104 contextualType : Type ,
@@ -8771,7 +8835,7 @@ export class Compiler extends DiagnosticEmitter {
87718835 classInstance . type ,
87728836 classInstance . type ,
87738837 baseCtor . signature . requiredParameters ,
8774- baseCtor . signature . hasRest
8838+ baseCtor . signature . hasRest ? SignatureFlags . Rest : SignatureFlags . None
87758839 ) ,
87768840 contextualTypeArguments
87778841 ) ;
0 commit comments