5
5
6
6
import {
7
7
BuiltinNames ,
8
- BuiltinContext ,
9
- builtins ,
10
- function_builtins ,
8
+ BuiltinFunctionContext ,
9
+ BuiltinVariableContext ,
10
+ builtinFunctions ,
11
+ builtinVariables_onAccess ,
12
+ builtinVariables_onCompile ,
11
13
compileVisitGlobals ,
12
14
compileVisitMembers ,
13
15
compileRTTI
@@ -509,17 +511,6 @@ export class Compiler extends DiagnosticEmitter {
509
511
let startFunctionBody = this . currentBody ;
510
512
assert ( startFunctionBody . length == 0 ) ;
511
513
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
-
523
514
// compile entry file(s) while traversing reachable elements
524
515
let files = program . filesByName ;
525
516
// TODO: for (let file of files.values()) {
@@ -1174,13 +1165,13 @@ export class Compiler extends DiagnosticEmitter {
1174
1165
}
1175
1166
}
1176
1167
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 ) ) {
1179
1170
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
+ }
1184
1175
pendingElements . delete ( global ) ;
1185
1176
return true ;
1186
1177
}
@@ -6114,7 +6105,7 @@ export class Compiler extends DiagnosticEmitter {
6114
6105
) ;
6115
6106
}
6116
6107
let callee = expression . expression ;
6117
- let ctx = new BuiltinContext (
6108
+ let ctx = new BuiltinFunctionContext (
6118
6109
this ,
6119
6110
prototype ,
6120
6111
typeArguments ,
@@ -6126,26 +6117,17 @@ export class Compiler extends DiagnosticEmitter {
6126
6117
expression ,
6127
6118
false
6128
6119
) ;
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 ;
6146
6127
}
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 ) ;
6149
6131
}
6150
6132
6151
6133
/**
@@ -7361,6 +7343,9 @@ export class Compiler extends DiagnosticEmitter {
7361
7343
return module . unreachable ( ) ;
7362
7344
}
7363
7345
assert ( globalType != Type . void ) ;
7346
+ if ( global . hasDecorator ( DecoratorFlags . Builtin ) ) {
7347
+ return this . compileIdentifierExpressionBuiltin ( global , expression , contextualType ) ;
7348
+ }
7364
7349
if ( global . is ( CommonFlags . Inlined ) ) {
7365
7350
return this . compileInlineConstant ( global , contextualType , constraints ) ;
7366
7351
}
@@ -7435,6 +7420,23 @@ export class Compiler extends DiagnosticEmitter {
7435
7420
return module . unreachable ( ) ;
7436
7421
}
7437
7422
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
+
7438
7440
private compileInstanceOfExpression (
7439
7441
expression : InstanceOfExpression ,
7440
7442
contextualType : Type ,
0 commit comments