55
66import {
77 BuiltinNames ,
8- BuiltinContext ,
9- builtins ,
10- function_builtins ,
8+ BuiltinFunctionContext ,
9+ BuiltinVariableContext ,
10+ builtinFunctions ,
11+ builtinVariables_onAccess ,
12+ builtinVariables_onCompile ,
1113 compileVisitGlobals ,
1214 compileVisitMembers ,
1315 compileRTTI
@@ -509,17 +511,6 @@ export class Compiler extends DiagnosticEmitter {
509511 let startFunctionBody = this . currentBody ;
510512 assert ( startFunctionBody . length == 0 ) ;
511513
512- // add mutable data, heap and rtti offset dummies
513- if ( options . isWasm64 ) {
514- module . addGlobal ( BuiltinNames . data_end , TypeRef . I64 , true , module . i64 ( 0 ) ) ;
515- module . addGlobal ( BuiltinNames . heap_base , TypeRef . I64 , true , module . i64 ( 0 ) ) ;
516- module . addGlobal ( BuiltinNames . rtti_base , TypeRef . I64 , true , module . i64 ( 0 ) ) ;
517- } else {
518- module . addGlobal ( BuiltinNames . data_end , TypeRef . I32 , true , module . i32 ( 0 ) ) ;
519- module . addGlobal ( BuiltinNames . heap_base , TypeRef . I32 , true , module . i32 ( 0 ) ) ;
520- module . addGlobal ( BuiltinNames . rtti_base , TypeRef . I32 , true , module . i32 ( 0 ) ) ;
521- }
522-
523514 // compile entry file(s) while traversing reachable elements
524515 let files = program . filesByName ;
525516 // TODO: for (let file of files.values()) {
@@ -1174,13 +1165,13 @@ export class Compiler extends DiagnosticEmitter {
11741165 }
11751166 }
11761167
1177- // Handle ambient builtins like '__heap_base' that need to be resolved but are added explicitly
1178- if ( global . is ( CommonFlags . Ambient ) && global . hasDecorator ( DecoratorFlags . Builtin ) ) {
1168+ // Handle builtins like '__heap_base' that need to be resolved but are added explicitly
1169+ if ( global . hasDecorator ( DecoratorFlags . Builtin ) ) {
11791170 let internalName = global . internalName ;
1180- if ( internalName == BuiltinNames . data_end ) this . runtimeFeatures |= RuntimeFeatures . Data ;
1181- else if ( internalName == BuiltinNames . stack_pointer ) this . runtimeFeatures |= RuntimeFeatures . Stack ;
1182- else if ( internalName == BuiltinNames . heap_base ) this . runtimeFeatures |= RuntimeFeatures . Heap ;
1183- else if ( internalName == BuiltinNames . rtti_base ) this . runtimeFeatures |= RuntimeFeatures . Rtti ;
1171+ if ( builtinVariables_onCompile . has ( internalName ) ) { // optional
1172+ let fn = assert ( builtinVariables_onCompile . get ( internalName ) ) ;
1173+ fn ( new BuiltinVariableContext ( this , global ) ) ;
1174+ }
11841175 pendingElements . delete ( global ) ;
11851176 return true ;
11861177 }
@@ -6114,7 +6105,7 @@ export class Compiler extends DiagnosticEmitter {
61146105 ) ;
61156106 }
61166107 let callee = expression . expression ;
6117- let ctx = new BuiltinContext (
6108+ let ctx = new BuiltinFunctionContext (
61186109 this ,
61196110 prototype ,
61206111 typeArguments ,
@@ -6126,26 +6117,17 @@ export class Compiler extends DiagnosticEmitter {
61266117 expression ,
61276118 false
61286119 ) ;
6129- // global builtins
6130- let internalName = prototype . internalName ;
6131- if ( builtins . has ( internalName ) ) {
6132- let fn = assert ( builtins . get ( internalName ) ) ;
6133- return fn ( ctx ) ;
6134- }
6135- // class builtins
6136- let parent = prototype . parent ;
6137- if ( parent . kind == ElementKind . Class ) {
6138- let classPrototype = ( < Class > parent ) . prototype ;
6139- if ( classPrototype == this . program . functionPrototype ) {
6140- let methodName = prototype . name ;
6141- if ( function_builtins . has ( methodName ) ) {
6142- let fn = assert ( function_builtins . get ( methodName ) ) ;
6143- return fn ( ctx ) ;
6144- }
6145- }
6120+ let internalName : string ;
6121+ if ( prototype . is ( CommonFlags . Instance ) ) {
6122+ // omit generic name components, e.g. in `Function<...>#call`
6123+ let parent = assert ( prototype . getBoundClassOrInterface ( ) ) ;
6124+ internalName = `${ parent . prototype . internalName } #${ prototype . name } ` ;
6125+ } else {
6126+ internalName = prototype . internalName ;
61466127 }
6147- assert ( false ) ;
6148- return this . module . unreachable ( ) ;
6128+ assert ( builtinFunctions . has ( internalName ) ) ; // checked earlier
6129+ let fn = assert ( builtinFunctions . get ( internalName ) ) ;
6130+ return fn ( ctx ) ;
61496131 }
61506132
61516133 /**
@@ -7361,6 +7343,9 @@ export class Compiler extends DiagnosticEmitter {
73617343 return module . unreachable ( ) ;
73627344 }
73637345 assert ( globalType != Type . void ) ;
7346+ if ( global . hasDecorator ( DecoratorFlags . Builtin ) ) {
7347+ return this . compileIdentifierExpressionBuiltin ( global , expression , contextualType ) ;
7348+ }
73647349 if ( global . is ( CommonFlags . Inlined ) ) {
73657350 return this . compileInlineConstant ( global , contextualType , constraints ) ;
73667351 }
@@ -7435,6 +7420,23 @@ export class Compiler extends DiagnosticEmitter {
74357420 return module . unreachable ( ) ;
74367421 }
74377422
7423+ private compileIdentifierExpressionBuiltin (
7424+ element : VariableLikeElement ,
7425+ expression : IdentifierExpression ,
7426+ contextualType : Type
7427+ ) : ExpressionRef {
7428+ if ( element . hasDecorator ( DecoratorFlags . Unsafe ) ) this . checkUnsafe ( expression , element . identifierNode ) ;
7429+ let internalName = element . internalName ;
7430+ assert ( builtinVariables_onAccess . has ( internalName ) ) ; // checked earlier
7431+ let fn = assert ( builtinVariables_onAccess . get ( internalName ) ) ;
7432+ return fn ( new BuiltinVariableContext (
7433+ this ,
7434+ element ,
7435+ contextualType ,
7436+ expression
7437+ ) ) ;
7438+ }
7439+
74387440 private compileInstanceOfExpression (
74397441 expression : InstanceOfExpression ,
74407442 contextualType : Type ,
0 commit comments