@@ -521,33 +521,24 @@ class DynamicModuleInfo {
521521
522522 void _initializeOverrideableReferences () {
523523 for (final builtin in BuiltinUpdatableFunctions .values) {
524- _createUpdateableFunction (
525- builtin.index, false , builtin._buildType (translator),
524+ _createUpdateableFunction (builtin.index, builtin._buildType (translator),
526525 buildMain: (f) => builtin._buildMain (f, translator),
527526 buildDynamic: (f) => builtin._buildDynamic (f, translator),
528527 name: '#r_${builtin .name }' );
529528 }
530529
531- for (final ( reference, useUncheckedEntry) in metadata.invokedReferences) {
530+ for (final reference in metadata.invokedReferences) {
532531 final selector = translator.dispatchTable.selectorForTarget (reference);
533- translator.functions.recordSelectorUse (selector, useUncheckedEntry);
534-
535- w.FunctionType signature;
536- void Function (w.FunctionBuilder ) buildMain;
537- void Function (w.FunctionBuilder ) buildDynamic;
532+ translator.functions.recordSelectorUse (selector, false );
538533
539534 final mainSelector = translator.dynamicMainModuleDispatchTable!
540535 .selectorForTarget (reference);
541- signature = _getGeneralizedSignature (mainSelector);
542- buildMain =
543- buildSelectorBranch (reference, useUncheckedEntry, mainSelector);
544- buildDynamic =
545- buildSelectorBranch (reference, useUncheckedEntry, mainSelector);
536+ final signature = _getGeneralizedSignature (mainSelector);
537+ final buildMain = buildSelectorBranch (reference, mainSelector);
538+ final buildDynamic = buildSelectorBranch (reference, mainSelector);
546539
547540 _createUpdateableFunction (
548- mainSelector.id + BuiltinUpdatableFunctions .values.length,
549- useUncheckedEntry,
550- signature,
541+ mainSelector.id + BuiltinUpdatableFunctions .values.length, signature,
551542 buildMain: buildMain,
552543 buildDynamic: buildDynamic,
553544 name: '#s${mainSelector .id }_${mainSelector .name }' );
@@ -582,16 +573,14 @@ class DynamicModuleInfo {
582573 b.drop ();
583574 }
584575
585- int _createUpdateableFunction (
586- int key, bool useUncheckedEntry, w.FunctionType type,
576+ int _createUpdateableFunction (int key, w.FunctionType type,
587577 {required void Function (w.FunctionBuilder function) buildMain,
588578 required void Function (w.FunctionBuilder function) buildDynamic,
589579 bool skipDynamic = false ,
590580 required String name}) {
591- final mapKey = ( key, useUncheckedEntry) ;
581+ final mapKey = key;
592582 final index = metadata.keyInvocationToIndex[mapKey] ?? =
593583 metadata.keyInvocationToIndex.length;
594-
595584 overrideableFunctions.putIfAbsent (index, () {
596585 if (! isDynamicModule) {
597586 final mainFunction = translator.mainModule.functions.define (type, name);
@@ -611,8 +600,8 @@ class DynamicModuleInfo {
611600 return index;
612601 }
613602
614- void _callClassIdBranch (int key, bool useUncheckedEntry,
615- w.InstructionsBuilder b, w.FunctionType signature,
603+ void _callClassIdBranch (
604+ int key, w.InstructionsBuilder b, w.FunctionType signature,
616605 {required void Function (w.FunctionBuilder b) buildMainMatch,
617606 required void Function (w.FunctionBuilder b) buildDynamicMatch,
618607 bool skipDynamic = false ,
@@ -622,8 +611,7 @@ class DynamicModuleInfo {
622611 final canSkipDynamicBranch = skipDynamic ||
623612 translator.classIdNumbering.maxDynamicModuleClassId ==
624613 translator.classIdNumbering.maxClassId;
625- final callIndex = _createUpdateableFunction (
626- key, useUncheckedEntry, signature,
614+ final callIndex = _createUpdateableFunction (key, signature,
627615 buildMain: buildMainMatch,
628616 buildDynamic: buildDynamicMatch,
629617 skipDynamic: canSkipDynamicBranch,
@@ -644,7 +632,7 @@ class DynamicModuleInfo {
644632 void callClassIdBranchBuiltIn (
645633 BuiltinUpdatableFunctions key, w.InstructionsBuilder b,
646634 {bool skipDynamic = false }) {
647- _callClassIdBranch (key.index, false , b, key._buildType (translator),
635+ _callClassIdBranch (key.index, b, key._buildType (translator),
648636 buildMainMatch: (f) => key._buildMain (f, translator),
649637 buildDynamicMatch: (f) => key._buildDynamic (f, translator),
650638 name: '#r_${key .name }' ,
@@ -658,6 +646,7 @@ class DynamicModuleInfo {
658646 // selector's signature may change between compilations.
659647 final generalizedSignature = translator.typesBuilder.defineFunction ([
660648 ...signature.inputs.map ((e) => const w.RefType .any (nullable: true )),
649+ w.NumType .i32,
661650 w.NumType .i32
662651 ], [
663652 ...signature.outputs.map ((e) => const w.RefType .any (nullable: true ))
@@ -666,15 +655,16 @@ class DynamicModuleInfo {
666655 }
667656
668657 void Function (w.FunctionBuilder ) buildSelectorBranch (
669- Reference target, bool useUncheckedEntry, SelectorInfo mainSelector) {
658+ Reference target, SelectorInfo mainSelector) {
670659 return (w.FunctionBuilder function) {
671660 final localSelector = translator.dispatchTable.selectorForTarget (target);
672661 final localSignature = localSelector.signature;
673662 final ib = function.body;
674663
675- final offset = localSelector.targets (unchecked: useUncheckedEntry).offset;
664+ final uncheckedOffset = localSelector.targets (unchecked: true ).offset;
665+ final checkedOffset = localSelector.targets (unchecked: false ).offset;
676666
677- if (offset == null ) {
667+ if (uncheckedOffset == null && checkedOffset == null ) {
678668 ib.unreachable ();
679669 ib.end ();
680670 return ;
@@ -745,12 +735,32 @@ class DynamicModuleInfo {
745735 ib, constant, localSignature.inputs[localsIndex]);
746736 }
747737
748- ib.local_get (ib.locals.last );
738+ ib.local_get (ib.locals[function.type.inputs.length - 2 ] );
749739 if (isDynamicModule) {
750740 translator.callReference (translator.scopeClassId.reference, ib);
751741 }
752- if (offset != 0 ) {
753- ib.i32_const (offset);
742+ if (checkedOffset == uncheckedOffset) {
743+ if (checkedOffset != 0 ) {
744+ ib.i32_const (checkedOffset! );
745+ ib.i32_add ();
746+ }
747+ } else if (checkedOffset != 0 || uncheckedOffset != 0 ) {
748+ // Check if the invocation is checked or unchecked and use the
749+ // appropriate offset.
750+ ib.local_get (ib.locals[function.type.inputs.length - 1 ]);
751+ ib.if_ (const [], const [w.NumType .i32]);
752+ if (uncheckedOffset != null ) {
753+ ib.i32_const (uncheckedOffset);
754+ } else {
755+ ib.unreachable ();
756+ }
757+ ib.else_ ();
758+ if (checkedOffset != null ) {
759+ ib.i32_const (checkedOffset);
760+ } else {
761+ ib.unreachable ();
762+ }
763+ ib.end ();
754764 ib.i32_add ();
755765 }
756766 final table = translator.dispatchTable.getWasmTable (ib.module);
@@ -764,7 +774,7 @@ class DynamicModuleInfo {
764774 void callOverrideableDispatch (
765775 w.InstructionsBuilder b, SelectorInfo selector, Reference interfaceTarget,
766776 {required bool useUncheckedEntry}) {
767- metadata.invokedReferences.add (( interfaceTarget, useUncheckedEntry) );
777+ metadata.invokedReferences.add (interfaceTarget);
768778
769779 final localSignature = selector.signature;
770780 // If any input is not a RefType (i.e. it's an unboxed value) then wrap it
@@ -788,6 +798,7 @@ class DynamicModuleInfo {
788798 final idLocal = b.addLocal (w.NumType .i32);
789799 b.struct_get (translator.topInfo.struct, FieldIndex .classId);
790800 b.local_tee (idLocal);
801+ b.i32_const (useUncheckedEntry ? 1 : 0 );
791802 b.local_get (idLocal);
792803
793804 final mainDispatchTable =
@@ -799,17 +810,13 @@ class DynamicModuleInfo {
799810 // For consistency, always use the main module selector ID when generating
800811 // the key.
801812 final key = mainModuleSelector.id + BuiltinUpdatableFunctions .values.length;
802- _callClassIdBranch (key, useUncheckedEntry, b, generalizedSignature,
813+ _callClassIdBranch (key, b, generalizedSignature,
803814 name: '#s${mainModuleSelector .id }_${mainModuleSelector .name }' ,
804- buildMainMatch: buildSelectorBranch (
805- interfaceTarget, useUncheckedEntry, mainModuleSelector),
806- buildDynamicMatch: buildSelectorBranch (
807- interfaceTarget, useUncheckedEntry, mainModuleSelector),
808- skipDynamic: translator.isDynamicModule &&
809- selector
810- .targets (unchecked: useUncheckedEntry)
811- .targetRanges
812- .isEmpty);
815+ buildMainMatch:
816+ buildSelectorBranch (interfaceTarget, mainModuleSelector),
817+ buildDynamicMatch:
818+ buildSelectorBranch (interfaceTarget, mainModuleSelector),
819+ skipDynamic: selector.targets (unchecked: false ).targetRanges.isEmpty);
813820 translator.convertType (
814821 b, generalizedSignature.outputs.single, localSignature.outputs.single);
815822 }
0 commit comments