@@ -307,6 +307,8 @@ export class Compiler extends DiagnosticEmitter {
307
307
runtimeFeatures : RuntimeFeatures = RuntimeFeatures . NONE ;
308
308
/** Expressions known to have skipped an autorelease. Usually function returns. */
309
309
skippedAutoreleases : Set < ExpressionRef > = new Set ( ) ;
310
+ /** Classes that implement an interface */
311
+ implementers : Class [ ] = [ ] ;
310
312
311
313
/** Compiles a {@link Program} to a {@link Module} using the specified options. */
312
314
static compile ( program : Program , options : Options | null = null ) : Module {
@@ -447,6 +449,10 @@ export class Compiler extends DiagnosticEmitter {
447
449
// import memory if requested (default memory is named '0' by Binaryen)
448
450
if ( options . importMemory ) module . addMemoryImport ( "0" , "env" , "memory" , isSharedMemory ) ;
449
451
452
+ // set up virtual table
453
+ this . compileVirtualTable ( ) ;
454
+
455
+
450
456
// set up function table
451
457
var functionTable = this . functionTable ;
452
458
module . setFunctionTable ( functionTable . length , 0xffffffff , functionTable ) ;
@@ -459,6 +465,7 @@ export class Compiler extends DiagnosticEmitter {
459
465
for ( let file of this . program . filesByName . values ( ) ) {
460
466
if ( file . source . sourceKind == SourceKind . USER_ENTRY ) this . ensureModuleExports ( file ) ;
461
467
}
468
+ console . log ( functionTable . join ( ",\n" ) ) ;
462
469
return module ;
463
470
}
464
471
@@ -1305,7 +1312,58 @@ export class Compiler extends DiagnosticEmitter {
1305
1312
typesToNativeTypes ( instance . additionalLocals ) ,
1306
1313
flatten ( module , stmts , instance . signature . returnType . toNativeType ( ) )
1307
1314
) ;
1315
+ // Virtual Methods
1316
+ } else if ( instance . is ( CommonFlags . VIRTUAL ) ) {
1317
+ let func : Function = instance ;
1318
+ let signature = func . signature ;
1319
+ let typeRef = this . ensureFunctionType (
1320
+ signature . parameterTypes ,
1321
+ signature . returnType ,
1322
+ signature . thisType
1323
+ ) ;
1324
+ let loadMethodID = module . i32 ( signature . id ) ;
1325
+ // let target = this.compiler.program.instancesByName("virtual");
1326
+ let loadClass = module . load (
1327
+ 4 ,
1328
+ false ,
1329
+ module . binary (
1330
+ BinaryOp . SubI32 ,
1331
+ module . local_get ( 0 , NativeType . I32 ) ,
1332
+ module . i32 ( 8 )
1333
+ ) ,
1334
+ NativeType . I32
1335
+ ) ;
1336
+ let callVirtual = module . call (
1337
+ "~lib/virtual" ,
1338
+ [ loadMethodID , loadClass ] ,
1339
+ NativeType . I32
1340
+ ) ;
1341
+ // module.removeFunction(member.internalName);
1308
1342
1343
+ let callIndirect = module . call_indirect (
1344
+ callVirtual ,
1345
+ func . localsByIndex . map < number > ( local =>
1346
+ module . local_get ( local . index , local . type . toNativeType ( ) )
1347
+ ) ,
1348
+
1349
+ Signature . makeSignatureString (
1350
+ func . signature . parameterTypes ,
1351
+ func . signature . returnType ,
1352
+ func . signature . thisType
1353
+ )
1354
+ ) ;
1355
+
1356
+ let body = module . block (
1357
+ null ,
1358
+ [ callIndirect ] ,
1359
+ func . signature . returnType . toNativeType ( )
1360
+ ) ;
1361
+
1362
+ funcRef = module . addFunction ( instance . internalName ,
1363
+ typeRef ,
1364
+ null ,
1365
+ body
1366
+ ) ;
1309
1367
// imported function
1310
1368
} else {
1311
1369
if ( ! instance . is ( CommonFlags . AMBIENT ) ) {
@@ -1314,18 +1372,21 @@ export class Compiler extends DiagnosticEmitter {
1314
1372
instance . identifierNode . range
1315
1373
) ;
1316
1374
}
1317
-
1375
+
1318
1376
instance . set ( CommonFlags . MODULE_IMPORT ) ;
1319
1377
mangleImportName ( instance , instance . declaration ) ; // TODO: check for duplicates
1320
-
1378
+
1321
1379
// create the import
1322
1380
module . addFunctionImport (
1323
1381
instance . internalName ,
1324
1382
mangleImportName_moduleName ,
1325
1383
mangleImportName_elementName ,
1326
1384
typeRef
1327
- ) ;
1328
- funcRef = module . getFunction ( instance . internalName ) ;
1385
+ ) ;
1386
+ }
1387
+ funcRef = module . getFunction ( instance . internalName ) ;
1388
+ if ( instance . prototype . isBound && ( < Class > instance . parent ) . prototype . implementsNodes ) {
1389
+ this . ensureFunctionTableEntry ( instance ) ;
1329
1390
}
1330
1391
1331
1392
instance . finalize ( module , funcRef ) ;
@@ -1436,6 +1497,9 @@ export class Compiler extends DiagnosticEmitter {
1436
1497
}
1437
1498
}
1438
1499
}
1500
+ if ( instance . prototype . implementsNodes ) {
1501
+ this . implementers . push ( instance ) ;
1502
+ }
1439
1503
return true ;
1440
1504
}
1441
1505
@@ -1445,11 +1509,11 @@ export class Compiler extends DiagnosticEmitter {
1445
1509
contextualTypeArguments : Map < string , Type > | null = null ,
1446
1510
alternativeReportNode : Node | null = null
1447
1511
) : void {
1448
- // TODO
1449
- this . error (
1450
- DiagnosticCode . Operation_not_supported ,
1451
- declaration . range
1452
- ) ;
1512
+ // TODO Compile functions to use
1513
+ // this.error(
1514
+ // DiagnosticCode.Operation_not_supported,
1515
+ // declaration.range
1516
+ // );
1453
1517
}
1454
1518
1455
1519
// === Memory ===================================================================================
@@ -6196,6 +6260,11 @@ export class Compiler extends DiagnosticEmitter {
6196
6260
}
6197
6261
var parameterTypes = signature . parameterTypes ;
6198
6262
for ( let i = 0 ; i < numArguments ; ++ i , ++ index ) {
6263
+ if ( parameterTypes [ i ] . is ( TypeFlags . REFERENCE ) ) {
6264
+
6265
+ }
6266
+ let arg_type = this . resolver . resolveExpression ( argumentExpressions [ i ] , this . currentFlow ) ;
6267
+
6199
6268
operands [ index ] = this . compileExpression ( argumentExpressions [ i ] , parameterTypes [ i ] ,
6200
6269
Constraints . CONV_IMPLICIT
6201
6270
) ;
@@ -9117,6 +9186,35 @@ export class Compiler extends DiagnosticEmitter {
9117
9186
return module . block ( label , conditions , NativeType . I32 ) ;
9118
9187
}
9119
9188
9189
+ compileVirtualTable ( ) : void {
9190
+ const interfaces = this . program . interfaces ;
9191
+ const implementers : ClassPrototype [ ] = this . program . queuedImplements ;
9192
+ const program : Program = this . program ;
9193
+ const getFunc = ( funcP : FunctionPrototype ) : Function => {
9194
+ if ( ! program . instancesByName . has ( funcP . internalName ) ) {
9195
+ this . compileElement ( funcP ) ;
9196
+ }
9197
+ return < Function > program . instancesByName . get ( funcP . internalName ) ! ;
9198
+ } ;
9199
+ const methods : Function [ ] = [ ] ;
9200
+ debugger ;
9201
+ // for (const _class of implementers) {
9202
+ // methods.concat(_class.instanceMethods.map(getFunc)
9203
+ // .filter(func => {
9204
+ // return interfaces.some(_interface => {
9205
+ // return _interface.prototype.instanceMethods.map(getFunc)
9206
+ // .some(ifunc => func.signature.id == ifunc.signature.id )
9207
+ // })
9208
+ // }))
9209
+ // }
9210
+ const relooper = this . module . createRelooper ( ) ;
9211
+ var typeRef = this . ensureFunctionType ( [ Type . u32 , Type . u32 ] , Type . u32 , null ) ;
9212
+
9213
+
9214
+ // let body = this.module.
9215
+ // this.module.addFunction("~lib/_virtual", typeRef, null, );
9216
+
9217
+ }
9120
9218
}
9121
9219
9122
9220
// helpers
@@ -9197,3 +9295,4 @@ export function flatten(module: Module, stmts: ExpressionRef[], type: NativeType
9197
9295
: type
9198
9296
) ;
9199
9297
}
9298
+
0 commit comments