[dart2wasm] Reduce RTT related wasm function

In essentials main module this removes 95k from code section
and adds 350k to data section. Uncompressed it increases size
by 3%. But because the data section addition compresses really
well, we see overall size reduction by -0.9%. We'll also see
faster startup, since we avoid the runtime to compile the 100kb
wasm function & execute it - instead just do a memcpy of the
data section.

In large apps the `_ModuleRtt.*` tables are too large to fit into
the global section, so they end up being lazily initialized.

For a large app we have a `_ModuleRtt.typeRowDisplacementSubstTable`
being 100 kb large wasm function.

The reason is that it initializes a `WasmArray<WasmArray<Type>>` which
is sparsely populated and nearby entries are often not the same,
requiring emitting 4 wasm instructions for every entry we fill.

Now instead of having two tables with the same layout where we use
the first to determine if two classes are related and the second
to give us the substitution, we store it in 3 tables:

* one that determins whether two classes are related
* one that stores the index of the substitution
* one that stores all unique substitutions

This shrinks the `WasmArray<WasmArray<_Type>>` table to be much
smaller (as it now holds only unique entries) and have a new
`WasmArray<WasmI16>` array which compresses really well and
who's data lives in the data segment.

Change-Id: If60af763b9739fd4e515e730a8e7be0db98beefd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/473281
Reviewed-by: Slava Egorov <vegorov@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
This commit is contained in:
Martin Kustermann
2026-01-16 03:48:22 -08:00
committed by Commit Queue
parent c6ecb567ad
commit 7022754207
26 changed files with 242 additions and 194 deletions
+28 -13
View File
@@ -164,7 +164,7 @@ typedef ConstantCodeGeneratorLazy = bool Function(
class Constants {
final Translator translator;
final Map<Constant, ConstantInfo> constantInfo = {};
w.DataSegmentBuilder? int32Segment;
w.DataSegmentBuilder? byteSegment;
late final ClassInfo typeInfo = translator.classInfo[translator.typeClass]!;
late final _constantAccessor = _ConstantAccessor(translator);
@@ -888,25 +888,40 @@ class ConstantCreator extends ConstantVisitor<ConstantInfo?>
// This can be a little bit larger than individual array stores, but the
// data section will compress better, so for app.wasm.gz it'a a win and
// will cause much faster validation & faster initialization.
if (arrayType.elementType.type == w.NumType.i32) {
final fieldType = arrayType.elementType.type;
final isI32 = fieldType == w.NumType.i32;
final isI16 = fieldType == w.PackedType.i16;
if (isI32 || isI16) {
// Initialize array contents from passive data segment.
final w.DataSegmentBuilder segment =
constants.int32Segment ??= b.moduleBuilder.dataSegments.define();
constants.byteSegment ??= b.moduleBuilder.dataSegments.define();
final field = translator.wasmI32Value.fieldReference;
final list = Uint32List(elements.length);
for (int i = 0; i < list.length; ++i) {
// The constant is a `const WasmI32 {WasmI32._value: <XXX>}`
final constant = elements[i] as InstanceConstant;
assert(constant.classNode == translator.wasmI32Class);
list[i] = (constant.fieldValues[field] as IntConstant).value;
Uint8List bytes;
if (isI16) {
final list = Uint16List(elements.length);
for (int i = 0; i < list.length; ++i) {
// The constant is a `const WasmI32 {WasmI32._value: <XXX>}`
final constant = elements[i] as InstanceConstant;
assert(constant.classNode == translator.wasmI32Class);
list[i] = (constant.fieldValues[field] as IntConstant).value;
}
bytes = list.buffer.asUint8List();
} else {
assert(isI32);
final list = Uint32List(elements.length);
for (int i = 0; i < list.length; ++i) {
// The constant is a `const WasmI32 {WasmI32._value: <XXX>}`
final constant = elements[i] as InstanceConstant;
assert(constant.classNode == translator.wasmI32Class);
list[i] = (constant.fieldValues[field] as IntConstant).value;
}
bytes = list.buffer.asUint8List();
}
final offset = segment.length;
segment.append(list.buffer.asUint8List());
b.i32_const(offset);
b.i32_const(segment.length);
b.i32_const(elements.length);
b.array_new_data(arrayType, segment);
segment.append(bytes);
return;
}
+6 -1
View File
@@ -127,8 +127,10 @@ mixin KernelNodes {
index.getField("dart:core", "_ModuleRtt", "typeRowDisplacementOffsets");
late final Field moduleRttDisplacementTable =
index.getField("dart:core", "_ModuleRtt", "typeRowDisplacementTable");
late final Field moduleRttSubstTable = index.getField(
late final Field moduleRttDisplacementSubstTable = index.getField(
"dart:core", "_ModuleRtt", "typeRowDisplacementSubstTable");
late final Field moduleRttSubstTable =
index.getField("dart:core", "_ModuleRtt", "canonicalSubstitutionTable");
late final Field moduleRttTypeNames =
index.getField("dart:core", "_ModuleRtt", "typeNames");
late final Procedure registerModuleRtt =
@@ -438,6 +440,8 @@ mixin KernelNodes {
index.getTopLevelField('dart:_internal', 'i8ConstImmutableArray');
late final Field i32ConstArrayCache =
index.getTopLevelField('dart:_internal', 'i32ConstArray');
late final Field i16ConstArrayCache =
index.getTopLevelField('dart:_internal', 'i16ConstArray');
late final Field i64ConstImmutableArrayCache =
index.getTopLevelField('dart:_internal', 'i64ConstImmutableArray');
late final Field boxedIntImmutableArrayCache =
@@ -468,6 +472,7 @@ mixin KernelNodes {
_makeElementType(namedParameterClass): namedParameterConstArrayCache,
_makeElementType(coreTypes.stringClass): stringConstArrayCache,
_makeElementType(wasmI32Class): i32ConstArrayCache,
_makeElementType(wasmI16Class): i16ConstArrayCache,
_makeElementType(wasmArrayClass,
typeArguments: [_makeElementType(typeClass)]): typeArrayConstArrayCache,
};
+14 -7
View File
@@ -1249,6 +1249,8 @@ class RuntimeTypeInformation {
InterfaceType(translator.typeClass, Nullability.nonNullable);
final arrayOfType = InterfaceType(
translator.wasmArrayClass, Nullability.nonNullable, [typeType]);
final wasmI16 =
InterfaceType(translator.wasmI16Class, Nullability.nonNullable);
final wasmI32 =
InterfaceType(translator.wasmI32Class, Nullability.nonNullable);
@@ -1260,17 +1262,21 @@ class RuntimeTypeInformation {
rows.sort((Row a, Row b) => -weight(a).compareTo(weight(b)));
final table = buildRowDisplacementTable(rows, firstAvailable: 1);
const invalidClassId = 0;
final typeRowDisplacementTable = translator.constants.makeArrayOf(wasmI32, [
for (final entry in table)
translator.constants.makeWasmI32(entry == null
? 0
: (entry.$2 == noSubstitutionIndex ? -entry.$1 : entry.$1)),
translator.constants
.makeWasmI32(entry == null ? invalidClassId : entry.$1),
]);
final typeRowDisplacementSubstTable =
translator.constants.makeArrayOf(arrayOfType, [
translator.constants.makeArrayOf(wasmI16, [
for (final entry in table)
_substitutionTableByIndex[
entry == null ? noSubstitutionIndex : entry.$2],
translator.constants
.makeWasmI32(entry == null ? noSubstitutionIndex : entry.$2),
]);
final canonicalSubstitutionTable =
translator.constants.makeArrayOf(arrayOfType, [
for (final sustitution in _substitutionTableByIndex) sustitution,
]);
final typeRowDisplacementOffsets =
@@ -1288,8 +1294,9 @@ class RuntimeTypeInformation {
translator.moduleRttOffsets.fieldReference: typeRowDisplacementOffsets,
translator.moduleRttDisplacementTable.fieldReference:
typeRowDisplacementTable,
translator.moduleRttSubstTable.fieldReference:
translator.moduleRttDisplacementSubstTable.fieldReference:
typeRowDisplacementSubstTable,
translator.moduleRttSubstTable.fieldReference: canonicalSubstitutionTable,
translator.moduleRttTypeNames.fieldReference: typeNames,
});
}
@@ -19,7 +19,7 @@
(result (ref $MyConstClass))))
(table $static0-0 (export "static0-0") 2 (ref null $type0))
(table $static1-0 (export "static1-0") 1 (ref null $type2))
(global $"C383 \"bad\"" (ref $JSStringImpl) <...>)
(global $"C384 \"bad\"" (ref $JSStringImpl) <...>)
(func $"mainImpl <noInline>" (param $var0 i32)
(local $var1 (ref $MyConstClass))
i64.const 0
@@ -35,7 +35,7 @@
ref.eq
i32.eqz
if
global.get $"C383 \"bad\""
global.get $"C384 \"bad\""
call $Error._throwWithCurrentStackTrace
unreachable
end
@@ -16,7 +16,7 @@
(result (ref $MyConstClass))))
(global $.h0-nonshared-const (import "" "h0-nonshared-const") (ref extern))
(table $module0.static1-0 (import "module0" "static1-0") 1 (ref null $type0))
(global $"C505 MyConstClass" (ref $MyConstClass)
(global $"C506 MyConstClass" (ref $MyConstClass)
(i32.const 120)
(i32.const 0)
(i32.const 4)
@@ -27,7 +27,7 @@
(func $"modH0Use <noInline>" (param $var0 i32) (result (ref $MyConstClass))
local.get $var0
if (result (ref $MyConstClass))
global.get $"C505 MyConstClass"
global.get $"C506 MyConstClass"
else
i32.const 0
call_indirect $module0.static1-0 (result (ref $MyConstClass))
@@ -13,7 +13,7 @@
(field $field0 i32)
(field $field1 (mut i32)))))
(global $.shared-const (import "" "shared-const") (ref extern))
(global $"C503 MyConstClass" (ref $MyConstClass)
(global $"C504 MyConstClass" (ref $MyConstClass)
(i32.const 120)
(i32.const 0)
(i32.const 4)
@@ -16,7 +16,7 @@
(result (ref $MyConstClass))))
(global $.h1-nonshared-const (import "" "h1-nonshared-const") (ref extern))
(table $module0.static1-0 (import "module0" "static1-0") 1 (ref null $type0))
(global $"C501 MyConstClass" (ref $MyConstClass)
(global $"C502 MyConstClass" (ref $MyConstClass)
(i32.const 120)
(i32.const 0)
(i32.const 4)
@@ -27,7 +27,7 @@
(func $"modH1Use <noInline>" (param $var0 i32) (result (ref $MyConstClass))
local.get $var0
if (result (ref $MyConstClass))
global.get $"C501 MyConstClass"
global.get $"C502 MyConstClass"
else
i32.const 0
call_indirect $module0.static1-0 (result (ref $MyConstClass))
@@ -5,7 +5,7 @@
(type $_InterfaceType <...>)
(type $type0 <...>)
(table $static0-0 (export "static0-0") 1 (ref null $type0))
(global $"C419 _InterfaceType" (ref $_InterfaceType) <...>)
(global $"C420 _InterfaceType" (ref $_InterfaceType) <...>)
(func $_loaded implicit getter (result (ref $_DefaultSet&_HashFieldBase&SetMixin)) <...>)
(func $"useFoo <noInline>"
call $"useFooAsType <noInline>"
@@ -26,7 +26,7 @@
drop
)
(func $"useFooAsType <noInline>"
global.get $"C419 _InterfaceType"
global.get $"C420 _InterfaceType"
call $print
drop
)
@@ -7,7 +7,7 @@
(type $JSStringImpl <...>)
(type $Object <...>)
(global $".Foo called " (import "" "Foo called ") (ref extern))
(global $"C467 \"Foo called \"" (ref $JSStringImpl)
(global $"C468 \"Foo called \"" (ref $JSStringImpl)
(i32.const 4)
(i32.const 0)
(global.get $".Foo called ")
@@ -15,30 +15,30 @@
(type $_TopType <...>)
(func $print (import "module0" "func3") (param (ref null $#Top)) (result (ref null $#Top)))
(global $"C1 WasmArray<_Type>[0]" (import "module0" "global1") (ref $Array<_Type>))
(global $"C319 WasmArray<_NamedParameter>[0]" (import "module0" "global4") (ref $Array<_NamedParameter>))
(global $"C344 _TopType" (import "module0" "global2") (ref $_TopType))
(global $"C63 WasmArray<_Type>[1]" (import "module0" "global3") (ref $Array<_Type>))
(global $"C320 WasmArray<_NamedParameter>[0]" (import "module0" "global4") (ref $Array<_NamedParameter>))
(global $"C345 _TopType" (import "module0" "global2") (ref $_TopType))
(global $"C64 WasmArray<_Type>[1]" (import "module0" "global3") (ref $Array<_Type>))
(global $.globalH0Foo (import "" "globalH0Foo") (ref extern))
(table $module0.constant-table0 (import "module0" "constant-table0") 1 (ref null $_FunctionType))
(global $"C478 globalH0Foo tear-off" (mut (ref null $#Closure-0-1))
(global $"C479 globalH0Foo tear-off" (mut (ref null $#Closure-0-1))
(ref.null none))
(global $"C479 H0" (mut (ref null $H0))
(global $"C480 H0" (mut (ref null $H0))
(ref.null none))
(global $"C480 \"globalH0Foo\"" (ref $JSStringImpl)
(global $"C481 \"globalH0Foo\"" (ref $JSStringImpl)
(i32.const 4)
(i32.const 0)
(global.get $.globalH0Foo)
(struct.new $JSStringImpl))
(global $global0 (ref $#DummyStruct) <...>)
(global $global2 (ref $#Vtable-0-1) <...>)
(func $"C479 H0 (lazy initializer)}" (result (ref $H0))
(func $"C480 H0 (lazy initializer)}" (result (ref $H0))
(local $var0 (ref $_FunctionType))
(local $var1 (ref $#Closure-0-1))
(local $var2 (ref $H0))
i32.const 118
i32.const 0
block $label0 (result (ref $#Closure-0-1))
global.get $"C478 globalH0Foo tear-off"
global.get $"C479 globalH0Foo tear-off"
br_on_non_null $label0
i32.const 38
i32.const 0
@@ -55,10 +55,10 @@
i64.const 0
global.get $"C1 WasmArray<_Type>[0]"
global.get $"C1 WasmArray<_Type>[0]"
global.get $"C344 _TopType"
global.get $"C63 WasmArray<_Type>[1]"
global.get $"C345 _TopType"
global.get $"C64 WasmArray<_Type>[1]"
i64.const 1
global.get $"C319 WasmArray<_NamedParameter>[0]"
global.get $"C320 WasmArray<_NamedParameter>[0]"
struct.new $_FunctionType
local.tee $var0
table.set $module0.constant-table0
@@ -66,20 +66,20 @@
end $label1
struct.new $#Closure-0-1
local.tee $var1
global.set $"C478 globalH0Foo tear-off"
global.set $"C479 globalH0Foo tear-off"
local.get $var1
end $label0
struct.new $H0
local.tee $var2
global.set $"C479 H0"
global.set $"C480 H0"
local.get $var2
)
(func $"globalH0Foo tear-off trampoline" (param $var0 (ref struct)) (param $var1 (ref null $#Top)) (result (ref null $#Top))
global.get $"C480 \"globalH0Foo\""
global.get $"C481 \"globalH0Foo\""
call $print
)
(func $globalH0Foo (param $var0 i64) (result (ref null $#Top))
global.get $"C480 \"globalH0Foo\""
global.get $"C481 \"globalH0Foo\""
call $print
)
)
@@ -26,28 +26,28 @@
(global $"C1 WasmArray<_Type>[0]" (import "module0" "global1") (ref $Array<_Type>))
(global $"C21 \")\"" (import "module0" "global0") (ref $JSStringImpl))
(global $"C28 _InterfaceType" (import "module0" "global7") (ref $_InterfaceType))
(global $"C319 WasmArray<_NamedParameter>[0]" (import "module0" "global4") (ref $Array<_NamedParameter>))
(global $"C344 _TopType" (import "module0" "global2") (ref $_TopType))
(global $"C63 WasmArray<_Type>[1]" (import "module0" "global3") (ref $Array<_Type>))
(global $"C320 WasmArray<_NamedParameter>[0]" (import "module0" "global4") (ref $Array<_NamedParameter>))
(global $"C345 _TopType" (import "module0" "global2") (ref $_TopType))
(global $"C64 WasmArray<_Type>[1]" (import "module0" "global3") (ref $Array<_Type>))
(global $.globalH1Bar< (import "" "globalH1Bar<") (ref extern))
(table $module0.constant-table0 (import "module0" "constant-table0") 1 (ref null $_FunctionType))
(global $"C472 _FunctionType" (ref $_FunctionType) <...>)
(global $"C473 globalH1Foo tear-off" (mut (ref null $#Closure-1-1))
(global $"C473 _FunctionType" (ref $_FunctionType) <...>)
(global $"C474 globalH1Foo tear-off" (mut (ref null $#Closure-1-1))
(ref.null none))
(global $"C474 InstantiationConstant(globalH1Foo<int>)" (mut (ref null $#Closure-0-1))
(global $"C475 InstantiationConstant(globalH1Foo<int>)" (mut (ref null $#Closure-0-1))
(ref.null none))
(global $"C475 H1" (mut (ref null $H1))
(global $"C476 H1" (mut (ref null $H1))
(ref.null none))
(global $"C476 \"globalH1Bar<\"" (ref $JSStringImpl)
(global $"C477 \"globalH1Bar<\"" (ref $JSStringImpl)
(i32.const 4)
(i32.const 0)
(global.get $.globalH1Bar<)
(struct.new $JSStringImpl))
(global $"C477 \">(\"" (ref $JSStringImpl) <...>)
(global $"C478 \">(\"" (ref $JSStringImpl) <...>)
(global $global0 (ref $#DummyStruct) <...>)
(global $global2 (ref $#Vtable-1-1) <...>)
(func $#dummy function (ref struct) -> (ref null #Top) (param $var0 (ref struct)) (result (ref null $#Top)) <...>)
(func $"C475 H1 (lazy initializer)}" (result (ref $H1))
(func $"C476 H1 (lazy initializer)}" (result (ref $H1))
(local $var0 (ref $#Closure-1-1))
(local $var1 (ref $_FunctionType))
(local $var2 (ref $#Closure-0-1))
@@ -55,21 +55,21 @@
i32.const 119
i32.const 0
block $label0 (result (ref $#Closure-0-1))
global.get $"C474 InstantiationConstant(globalH1Foo<int>)"
global.get $"C475 InstantiationConstant(globalH1Foo<int>)"
br_on_non_null $label0
i32.const 38
i32.const 0
block $label1 (result (ref $#Closure-1-1))
global.get $"C473 globalH1Foo tear-off"
global.get $"C474 globalH1Foo tear-off"
br_on_non_null $label1
i32.const 38
i32.const 0
global.get $global0
global.get $global2
global.get $"C472 _FunctionType"
global.get $"C473 _FunctionType"
struct.new $#Closure-1-1
local.tee $var0
global.set $"C473 globalH1Foo tear-off"
global.set $"C474 globalH1Foo tear-off"
local.get $var0
end $label1
global.get $"C28 _InterfaceType"
@@ -88,10 +88,10 @@
i64.const 0
global.get $"C1 WasmArray<_Type>[0]"
global.get $"C1 WasmArray<_Type>[0]"
global.get $"C344 _TopType"
global.get $"C63 WasmArray<_Type>[1]"
global.get $"C345 _TopType"
global.get $"C64 WasmArray<_Type>[1]"
i64.const 1
global.get $"C319 WasmArray<_NamedParameter>[0]"
global.get $"C320 WasmArray<_NamedParameter>[0]"
struct.new $_FunctionType
local.tee $var1
table.set $module0.constant-table0
@@ -99,18 +99,18 @@
end $label2
struct.new $#Closure-0-1
local.tee $var2
global.set $"C474 InstantiationConstant(globalH1Foo<int>)"
global.set $"C475 InstantiationConstant(globalH1Foo<int>)"
local.get $var2
end $label0
struct.new $H1
local.tee $var3
global.set $"C475 H1"
global.set $"C476 H1"
local.get $var3
)
(func $"globalH1Foo tear-off trampoline" (param $var0 (ref struct)) (param $var1 (ref $_Type)) (param $var2 (ref null $#Top)) (result (ref null $#Top))
global.get $"C476 \"globalH1Bar<\""
global.get $"C477 \"globalH1Bar<\""
local.get $var1
global.get $"C477 \">(\""
global.get $"C478 \">(\""
local.get $var2
global.get $"C21 \")\""
array.new_fixed $Array<Object?> 5
@@ -121,16 +121,16 @@
(func $"modH1UseH1 <noInline>" (result (ref null $#Top))
(local $var0 (ref $#Closure-0-1))
block $label0 (result (ref $H1))
global.get $"C475 H1"
global.get $"C476 H1"
br_on_non_null $label0
call $"C475 H1 (lazy initializer)}"
call $"C476 H1 (lazy initializer)}"
end $label0
call $print
drop
block $label1 (result (ref $H1))
global.get $"C475 H1"
global.get $"C476 H1"
br_on_non_null $label1
call $"C475 H1 (lazy initializer)}"
call $"C476 H1 (lazy initializer)}"
end $label1
struct.get $H1 $fun
local.tee $var0
@@ -7,17 +7,17 @@
(global $".Foo1.doitDispatch(" (import "" "Foo1.doitDispatch(") (ref extern))
(global $".FooBase(" (import "" "FooBase(") (ref extern))
(table $static0-0 (export "static0-0") 1 (ref null $type0))
(global $"C385 \"FooBase(\"" (ref $JSStringImpl)
(global $"C386 \"FooBase(\"" (ref $JSStringImpl)
(i32.const 4)
(i32.const 0)
(global.get $".FooBase(")
(struct.new $JSStringImpl))
(global $"C386 \"Foo1.doitDispatch(\"" (ref $JSStringImpl)
(global $"C387 \"Foo1.doitDispatch(\"" (ref $JSStringImpl)
(i32.const 4)
(i32.const 0)
(global.get $".Foo1.doitDispatch(")
(struct.new $JSStringImpl))
(global $"C387 \"Foo0.doitDispatch(\"" (ref $JSStringImpl)
(global $"C388 \"Foo0.doitDispatch(\"" (ref $JSStringImpl)
(i32.const 4)
(i32.const 0)
(global.get $".Foo0.doitDispatch(")
@@ -46,7 +46,7 @@
)
(func $runtimeTrue implicit getter (result i32) <...>)
(func $Foo0.doitDispatch (param $var0 (ref $Object)) (param $var1 (ref null $#Top)) (result (ref null $#Top))
global.get $"C387 \"Foo0.doitDispatch(\""
global.get $"C388 \"Foo0.doitDispatch(\""
local.get $var1
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
@@ -58,7 +58,7 @@
)
(func $Foo1 (result (ref $Object)) <...>)
(func $Foo1.doitDispatch (export "func1") (param $var0 (ref $Object)) (param $var1 (ref null $#Top)) (result (ref null $#Top))
global.get $"C386 \"Foo1.doitDispatch(\""
global.get $"C387 \"Foo1.doitDispatch(\""
local.get $var1
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
@@ -69,7 +69,7 @@
ref.null none
)
(func $FooBase.doitDispatch (param $var0 (ref null $#Top))
global.get $"C385 \"FooBase(\""
global.get $"C386 \"FooBase(\""
local.get $var0
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
@@ -8,14 +8,14 @@
(func $JSStringImpl._interpolate3 (import "module0" "func2") (param (ref null $#Top) (ref null $#Top) (ref null $#Top)) (result (ref $JSStringImpl)))
(func $print (import "module0" "func3") (param (ref null $#Top)) (result (ref null $#Top)))
(global $".Foo1.doitDevirt(" (import "" "Foo1.doitDevirt(") (ref extern))
(global $"C317 1" (import "module0" "global1") (ref $BoxedInt))
(global $"C346 2" (import "module0" "global3") (ref $BoxedInt))
(global $"C385 \"FooBase(\"" (import "module0" "global5") (ref $JSStringImpl))
(global $"C318 1" (import "module0" "global1") (ref $BoxedInt))
(global $"C347 2" (import "module0" "global3") (ref $BoxedInt))
(global $"C386 \"FooBase(\"" (import "module0" "global5") (ref $JSStringImpl))
(global $"C8 \")\"" (import "module0" "global4") (ref $JSStringImpl))
(global $baseObj (import "module0" "global0") (ref null $Object))
(global $foo1Obj (import "module0" "global2") (ref null $Object))
(table $module0.dispatch0 (import "module0" "dispatch0") 773 funcref)
(global $"C504 \"Foo1.doitDevirt(\"" (ref $JSStringImpl)
(global $"C505 \"Foo1.doitDevirt(\"" (ref $JSStringImpl)
(i32.const 4)
(i32.const 0)
(global.get $".Foo1.doitDevirt(")
@@ -29,7 +29,7 @@
br $label0
end $label1
local.tee $var0
global.get $"C317 1"
global.get $"C318 1"
local.get $var0
struct.get $Object $field0
i32.const 444
@@ -41,7 +41,7 @@
br_on_non_null $label2
br $label0
end $label2
global.get $"C346 2"
global.get $"C347 2"
call $Foo1.doitDispatch
drop
block $label3 (result (ref $Object))
@@ -63,14 +63,14 @@
unreachable
)
(func $Foo1.doitDevirt (param $var0 (ref $Object))
global.get $"C504 \"Foo1.doitDevirt(\""
global.get $"C317 1"
global.get $"C505 \"Foo1.doitDevirt(\""
global.get $"C318 1"
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
call $print
drop
global.get $"C385 \"FooBase(\""
global.get $"C317 1"
global.get $"C386 \"FooBase(\""
global.get $"C318 1"
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
call $print
@@ -14,29 +14,29 @@
(table $static2-0 (export "static2-0") 4 (ref null $type4))
(table $static3-0 (export "static3-0") 4 (ref null $type6))
(global $"C12 0" (ref $BoxedInt) <...>)
(global $"C392 \"FooConstBase(\"" (ref $JSStringImpl)
(global $"C393 \"FooConstBase(\"" (ref $JSStringImpl)
(i32.const 4)
(i32.const 0)
(global.get $".FooConstBase(")
(struct.new $JSStringImpl))
(global $"C393 FooConst0" (ref $Object)
(global $"C394 FooConst0" (ref $Object)
(i32.const 120)
(i32.const 0)
(struct.new $Object))
(global $"C394 \"FooConst0(\"" (ref $JSStringImpl)
(global $"C395 \"FooConst0(\"" (ref $JSStringImpl)
(i32.const 4)
(i32.const 0)
(global.get $".FooConst0(")
(struct.new $JSStringImpl))
(global $"C510 \"foo0Code(\"" (ref $JSStringImpl) <...>)
(global $"C511 \"foo0Code(\"" (ref $JSStringImpl) <...>)
(global $"C8 \")\"" (ref $JSStringImpl) <...>)
(global $fooGlobal0 (mut (ref null $#Top))
(ref.null none))
(func $"foo0Code <noInline>" (export "func12") (param $var0 (ref null $#Top)) (result (ref null $#Top))
global.get $"C393 FooConst0"
global.get $"C394 FooConst0"
call $print
drop
global.get $"C510 \"foo0Code(\""
global.get $"C511 \"foo0Code(\""
local.get $var0
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
@@ -47,7 +47,7 @@
ref.null none
)
(func $FooConst0.doit (param $var0 (ref $Object)) (param $var1 (ref null $#Top)) (result (ref null $#Top))
global.get $"C394 \"FooConst0(\""
global.get $"C395 \"FooConst0(\""
local.get $var1
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
@@ -60,7 +60,7 @@
ref.null none
)
(func $FooConstBase.doit (export "func14") (param $var0 (ref $Object)) (param $var1 (ref null $#Top)) (result (ref null $#Top))
global.get $"C392 \"FooConstBase(\""
global.get $"C393 \"FooConstBase(\""
local.get $var1
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
@@ -18,25 +18,25 @@
(func $JSStringImpl._interpolate3 (import "module0" "func10") (param (ref null $#Top) (ref null $#Top) (ref null $#Top)) (result (ref $JSStringImpl)))
(func $print (import "module0" "func9") (param (ref null $#Top)) (result (ref null $#Top)))
(global $".FooConst5(" (import "" "FooConst5(") (ref extern))
(global $"C315 \"[]\"" (import "module0" "global6") (ref $JSStringImpl))
(global $"C391 5" (import "module0" "global5") (ref $BoxedInt))
(global $"C393 FooConst0" (import "module0" "global7") (ref $Object))
(global $"C316 \"[]\"" (import "module0" "global6") (ref $JSStringImpl))
(global $"C392 5" (import "module0" "global5") (ref $BoxedInt))
(global $"C394 FooConst0" (import "module0" "global7") (ref $Object))
(global $"C8 \")\"" (import "module0" "global4") (ref $JSStringImpl))
(table $module0.dispatch0 (import "module0" "dispatch0") 789 funcref)
(table $module0.static1-0 (import "module0" "static1-0") 4 (ref null $type2))
(table $module0.static2-0 (import "module0" "static2-0") 4 (ref null $type0))
(table $module0.static3-0 (import "module0" "static3-0") 4 (ref null $type4))
(global $"C512 FooConst5" (ref $Object)
(global $"C513 FooConst5" (ref $Object)
(i32.const 125)
(i32.const 0)
(struct.new $Object))
(global $"C513 \"foo5Code(\"" (ref $JSStringImpl) <...>)
(global $"C514 \"FooConst5(\"" (ref $JSStringImpl)
(global $"C514 \"foo5Code(\"" (ref $JSStringImpl) <...>)
(global $"C515 \"FooConst5(\"" (ref $JSStringImpl)
(i32.const 4)
(i32.const 0)
(global.get $".FooConst5(")
(struct.new $JSStringImpl))
(global $"C515 _InterfaceType" (ref $_InterfaceType) <...>)
(global $"C516 _InterfaceType" (ref $_InterfaceType) <...>)
(global $allFooConstants (mut (ref null $WasmListBase))
(ref.null none))
(global $fooGlobal5 (mut (ref null $#Top))
@@ -46,16 +46,16 @@
(local $var1 (ref $WasmListBase))
(local $var2 (ref $Object))
(local $var3 i64)
global.get $"C512 FooConst5"
global.get $"C513 FooConst5"
call $print
drop
global.get $"C513 \"foo5Code(\""
global.get $"C514 \"foo5Code(\""
local.get $var0
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
call $print
drop
global.get $"C391 5"
global.get $"C392 5"
global.set $fooGlobal5
call $"fooGlobal0 implicit getter"
call $"foo0Code <noInline>"
@@ -83,8 +83,8 @@
block $label0 (result (ref $WasmListBase))
global.get $allFooConstants
br_on_non_null $label0
global.get $"C515 _InterfaceType"
global.get $"C393 FooConst0"
global.get $"C516 _InterfaceType"
global.get $"C394 FooConst0"
i32.const 0
call_indirect $module0.static3-0 (result (ref $Object))
i32.const 1
@@ -93,7 +93,7 @@
call_indirect $module0.static3-0 (result (ref $Object))
i32.const 3
call_indirect $module0.static3-0 (result (ref $Object))
global.get $"C512 FooConst5"
global.get $"C513 FooConst5"
array.new_fixed $Array<Object?> 6
call $GrowableList._withData
global.set $allFooConstants
@@ -107,7 +107,7 @@
if
i64.const 0
local.get $var3
global.get $"C315 \"[]\""
global.get $"C316 \"[]\""
call $"_throwIndexError <noInline>"
unreachable
end
@@ -127,7 +127,7 @@
)
(func $fooGlobal5 implicit getter (result (ref $#Top)) <...>)
(func $FooConst5.doit (param $var0 (ref $Object)) (param $var1 (ref null $#Top)) (result (ref null $#Top))
global.get $"C514 \"FooConst5(\""
global.get $"C515 \"FooConst5(\""
local.get $var1
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
@@ -7,36 +7,36 @@
(func $JSStringImpl._interpolate3 (import "module0" "func10") (param (ref null $#Top) (ref null $#Top) (ref null $#Top)) (result (ref $JSStringImpl)))
(func $print (import "module0" "func9") (param (ref null $#Top)) (result (ref null $#Top)))
(global $".FooConst1(" (import "" "FooConst1(") (ref extern))
(global $"C321 1" (import "module0" "global8") (ref $BoxedInt))
(global $"C322 1" (import "module0" "global8") (ref $BoxedInt))
(global $"C8 \")\"" (import "module0" "global4") (ref $JSStringImpl))
(global $"C516 FooConst1" (ref $Object)
(global $"C517 FooConst1" (ref $Object)
(i32.const 121)
(i32.const 0)
(struct.new $Object))
(global $"C523 \"FooConst1(\"" (ref $JSStringImpl)
(global $"C524 \"FooConst1(\"" (ref $JSStringImpl)
(i32.const 4)
(i32.const 0)
(global.get $".FooConst1(")
(struct.new $JSStringImpl))
(global $"C531 \"foo1Code(\"" (ref $JSStringImpl) <...>)
(global $"C532 \"foo1Code(\"" (ref $JSStringImpl) <...>)
(global $fooGlobal1 (mut (ref null $#Top))
(ref.null none))
(func $"foo1Code <noInline>" (param $var0 (ref null $#Top)) (result (ref null $#Top))
global.get $"C516 FooConst1"
global.get $"C517 FooConst1"
call $print
drop
global.get $"C531 \"foo1Code(\""
global.get $"C532 \"foo1Code(\""
local.get $var0
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
call $print
drop
global.get $"C321 1"
global.get $"C322 1"
global.set $fooGlobal1
ref.null none
)
(func $FooConst1.doit (param $var0 (ref $Object)) (param $var1 (ref null $#Top)) (result (ref null $#Top))
global.get $"C523 \"FooConst1(\""
global.get $"C524 \"FooConst1(\""
local.get $var1
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
@@ -7,36 +7,36 @@
(func $JSStringImpl._interpolate3 (import "module0" "func10") (param (ref null $#Top) (ref null $#Top) (ref null $#Top)) (result (ref $JSStringImpl)))
(func $print (import "module0" "func9") (param (ref null $#Top)) (result (ref null $#Top)))
(global $".FooConst2(" (import "" "FooConst2(") (ref extern))
(global $"C350 2" (import "module0" "global12") (ref $BoxedInt))
(global $"C351 2" (import "module0" "global12") (ref $BoxedInt))
(global $"C8 \")\"" (import "module0" "global4") (ref $JSStringImpl))
(global $"C517 FooConst2" (ref $Object)
(global $"C518 FooConst2" (ref $Object)
(i32.const 122)
(i32.const 0)
(struct.new $Object))
(global $"C522 \"FooConst2(\"" (ref $JSStringImpl)
(global $"C523 \"FooConst2(\"" (ref $JSStringImpl)
(i32.const 4)
(i32.const 0)
(global.get $".FooConst2(")
(struct.new $JSStringImpl))
(global $"C530 \"foo2Code(\"" (ref $JSStringImpl) <...>)
(global $"C531 \"foo2Code(\"" (ref $JSStringImpl) <...>)
(global $fooGlobal2 (mut (ref null $#Top))
(ref.null none))
(func $"foo2Code <noInline>" (param $var0 (ref null $#Top)) (result (ref null $#Top))
global.get $"C517 FooConst2"
global.get $"C518 FooConst2"
call $print
drop
global.get $"C530 \"foo2Code(\""
global.get $"C531 \"foo2Code(\""
local.get $var0
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
call $print
drop
global.get $"C350 2"
global.get $"C351 2"
global.set $fooGlobal2
ref.null none
)
(func $FooConst2.doit (param $var0 (ref $Object)) (param $var1 (ref null $#Top)) (result (ref null $#Top))
global.get $"C522 \"FooConst2(\""
global.get $"C523 \"FooConst2(\""
local.get $var1
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
@@ -7,36 +7,36 @@
(func $JSStringImpl._interpolate3 (import "module0" "func10") (param (ref null $#Top) (ref null $#Top) (ref null $#Top)) (result (ref $JSStringImpl)))
(func $print (import "module0" "func9") (param (ref null $#Top)) (result (ref null $#Top)))
(global $".FooConst3(" (import "" "FooConst3(") (ref extern))
(global $"C429 3" (import "module0" "global11") (ref $BoxedInt))
(global $"C430 3" (import "module0" "global11") (ref $BoxedInt))
(global $"C8 \")\"" (import "module0" "global4") (ref $JSStringImpl))
(global $"C518 FooConst3" (ref $Object)
(global $"C519 FooConst3" (ref $Object)
(i32.const 123)
(i32.const 0)
(struct.new $Object))
(global $"C521 \"FooConst3(\"" (ref $JSStringImpl)
(global $"C522 \"FooConst3(\"" (ref $JSStringImpl)
(i32.const 4)
(i32.const 0)
(global.get $".FooConst3(")
(struct.new $JSStringImpl))
(global $"C529 \"foo3Code(\"" (ref $JSStringImpl) <...>)
(global $"C530 \"foo3Code(\"" (ref $JSStringImpl) <...>)
(global $fooGlobal3 (mut (ref null $#Top))
(ref.null none))
(func $"foo3Code <noInline>" (param $var0 (ref null $#Top)) (result (ref null $#Top))
global.get $"C518 FooConst3"
global.get $"C519 FooConst3"
call $print
drop
global.get $"C529 \"foo3Code(\""
global.get $"C530 \"foo3Code(\""
local.get $var0
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
call $print
drop
global.get $"C429 3"
global.get $"C430 3"
global.set $fooGlobal3
ref.null none
)
(func $FooConst3.doit (param $var0 (ref $Object)) (param $var1 (ref null $#Top)) (result (ref null $#Top))
global.get $"C521 \"FooConst3(\""
global.get $"C522 \"FooConst3(\""
local.get $var1
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
@@ -7,36 +7,36 @@
(func $JSStringImpl._interpolate3 (import "module0" "func10") (param (ref null $#Top) (ref null $#Top) (ref null $#Top)) (result (ref $JSStringImpl)))
(func $print (import "module0" "func9") (param (ref null $#Top)) (result (ref null $#Top)))
(global $".FooConst4(" (import "" "FooConst4(") (ref extern))
(global $"C369 4" (import "module0" "global10") (ref $BoxedInt))
(global $"C370 4" (import "module0" "global10") (ref $BoxedInt))
(global $"C8 \")\"" (import "module0" "global4") (ref $JSStringImpl))
(global $"C519 FooConst4" (ref $Object)
(global $"C520 FooConst4" (ref $Object)
(i32.const 124)
(i32.const 0)
(struct.new $Object))
(global $"C520 \"FooConst4(\"" (ref $JSStringImpl)
(global $"C521 \"FooConst4(\"" (ref $JSStringImpl)
(i32.const 4)
(i32.const 0)
(global.get $".FooConst4(")
(struct.new $JSStringImpl))
(global $"C528 \"foo4Code(\"" (ref $JSStringImpl) <...>)
(global $"C529 \"foo4Code(\"" (ref $JSStringImpl) <...>)
(global $fooGlobal4 (mut (ref null $#Top))
(ref.null none))
(func $"foo4Code <noInline>" (param $var0 (ref null $#Top)) (result (ref null $#Top))
global.get $"C519 FooConst4"
global.get $"C520 FooConst4"
call $print
drop
global.get $"C528 \"foo4Code(\""
global.get $"C529 \"foo4Code(\""
local.get $var0
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
call $print
drop
global.get $"C369 4"
global.get $"C370 4"
global.set $fooGlobal4
ref.null none
)
(func $FooConst4.doit (param $var0 (ref $Object)) (param $var1 (ref null $#Top)) (result (ref null $#Top))
global.get $"C520 \"FooConst4(\""
global.get $"C521 \"FooConst4(\""
local.get $var1
global.get $"C8 \")\""
call $JSStringImpl._interpolate3
+8 -8
View File
@@ -20,9 +20,9 @@
(type $type2 <...>)
(global $"C1 WasmArray<_Type>[0]" (ref $Array<_Type>) <...>)
(global $"C28 _InterfaceType" (ref $_InterfaceType) <...>)
(global $"C316 WasmArray<_NamedParameter>[0]" (ref $Array<_NamedParameter>) <...>)
(global $"C342 _TopType" (ref $_TopType) <...>)
(global $"C346 foo tear-off" (ref $#Closure-0-2)
(global $"C317 WasmArray<_NamedParameter>[0]" (ref $Array<_NamedParameter>) <...>)
(global $"C343 _TopType" (ref $_TopType) <...>)
(global $"C347 foo tear-off" (ref $#Closure-0-2)
(i32.const 56)
(i32.const 0)
(global.get $global0)
@@ -34,7 +34,7 @@
(i32.const 0)
(global.get $"C1 WasmArray<_Type>[0]")
(global.get $"C1 WasmArray<_Type>[0]")
(global.get $"C342 _TopType")
(global.get $"C343 _TopType")
(global.get $"C28 _InterfaceType")
(i32.const 10)
(i32.const 0)
@@ -44,10 +44,10 @@
(struct.new $_InterfaceType)
(array.new_fixed $Array<_Type> 2)
(i64.const 1)
(global.get $"C316 WasmArray<_NamedParameter>[0]")
(global.get $"C317 WasmArray<_NamedParameter>[0]")
(struct.new $_FunctionType)
(struct.new $#Closure-0-2))
(global $"C350 bar tear-off" (ref $#Closure-0-2)
(global $"C351 bar tear-off" (ref $#Closure-0-2)
(i32.const 56)
(i32.const 0)
(global.get $global0)
@@ -59,7 +59,7 @@
(i32.const 0)
(global.get $"C1 WasmArray<_Type>[0]")
(global.get $"C1 WasmArray<_Type>[0]")
(global.get $"C342 _TopType")
(global.get $"C343 _TopType")
(global.get $"C28 _InterfaceType")
(i32.const 10)
(i32.const 0)
@@ -69,7 +69,7 @@
(struct.new $_InterfaceType)
(array.new_fixed $Array<_Type> 2)
(i64.const 1)
(global.get $"C316 WasmArray<_NamedParameter>[0]")
(global.get $"C317 WasmArray<_NamedParameter>[0]")
(struct.new $_FunctionType)
(struct.new $#Closure-0-2))
(global $global0 (ref $#DummyStruct) <...>)
@@ -20,9 +20,9 @@
(type $type2 <...>)
(global $"C1 WasmArray<_Type>[0]" (ref $Array<_Type>) <...>)
(global $"C28 _InterfaceType" (ref $_InterfaceType) <...>)
(global $"C316 WasmArray<_NamedParameter>[0]" (ref $Array<_NamedParameter>) <...>)
(global $"C342 _TopType" (ref $_TopType) <...>)
(global $"C346 foo tear-off" (ref $#Closure-0-2)
(global $"C317 WasmArray<_NamedParameter>[0]" (ref $Array<_NamedParameter>) <...>)
(global $"C343 _TopType" (ref $_TopType) <...>)
(global $"C347 foo tear-off" (ref $#Closure-0-2)
(i32.const 56)
(i32.const 0)
(global.get $global0)
@@ -34,7 +34,7 @@
(i32.const 0)
(global.get $"C1 WasmArray<_Type>[0]")
(global.get $"C1 WasmArray<_Type>[0]")
(global.get $"C342 _TopType")
(global.get $"C343 _TopType")
(global.get $"C28 _InterfaceType")
(i32.const 10)
(i32.const 0)
@@ -44,10 +44,10 @@
(struct.new $_InterfaceType)
(array.new_fixed $Array<_Type> 2)
(i64.const 1)
(global.get $"C316 WasmArray<_NamedParameter>[0]")
(global.get $"C317 WasmArray<_NamedParameter>[0]")
(struct.new $_FunctionType)
(struct.new $#Closure-0-2))
(global $"C351 bar tear-off" (ref $#Closure-0-2)
(global $"C352 bar tear-off" (ref $#Closure-0-2)
(i32.const 56)
(i32.const 0)
(global.get $global0)
@@ -59,7 +59,7 @@
(i32.const 0)
(global.get $"C1 WasmArray<_Type>[0]")
(global.get $"C1 WasmArray<_Type>[0]")
(global.get $"C342 _TopType")
(global.get $"C343 _TopType")
(global.get $"C28 _InterfaceType")
(i32.const 10)
(i32.const 0)
@@ -69,7 +69,7 @@
(struct.new $_InterfaceType)
(array.new_fixed $Array<_Type> 2)
(i64.const 1)
(global.get $"C316 WasmArray<_NamedParameter>[0]")
(global.get $"C317 WasmArray<_NamedParameter>[0]")
(struct.new $_FunctionType)
(struct.new $#Closure-0-2))
(global $global0 (ref $#DummyStruct) <...>)
@@ -24,9 +24,9 @@
(type $type2 <...>)
(global $"C1 WasmArray<_Type>[0]" (ref $Array<_Type>) <...>)
(global $"C28 _InterfaceType" (ref $_InterfaceType) <...>)
(global $"C316 WasmArray<_NamedParameter>[0]" (ref $Array<_NamedParameter>) <...>)
(global $"C342 _TopType" (ref $_TopType) <...>)
(global $"C346 foo tear-off" (ref $#Closure-0-2)
(global $"C317 WasmArray<_NamedParameter>[0]" (ref $Array<_NamedParameter>) <...>)
(global $"C343 _TopType" (ref $_TopType) <...>)
(global $"C347 foo tear-off" (ref $#Closure-0-2)
(i32.const 56)
(i32.const 0)
(global.get $global0)
@@ -38,7 +38,7 @@
(i32.const 0)
(global.get $"C1 WasmArray<_Type>[0]")
(global.get $"C1 WasmArray<_Type>[0]")
(global.get $"C342 _TopType")
(global.get $"C343 _TopType")
(global.get $"C28 _InterfaceType")
(i32.const 10)
(i32.const 0)
@@ -48,11 +48,11 @@
(struct.new $_InterfaceType)
(array.new_fixed $Array<_Type> 2)
(i64.const 1)
(global.get $"C316 WasmArray<_NamedParameter>[0]")
(global.get $"C317 WasmArray<_NamedParameter>[0]")
(struct.new $_FunctionType)
(struct.new $#Closure-0-2))
(global $"C348 _InterfaceType" (ref $_InterfaceType) <...>)
(global $"C351 bar tear-off" (ref $#Closure-0-2)
(global $"C349 _InterfaceType" (ref $_InterfaceType) <...>)
(global $"C352 bar tear-off" (ref $#Closure-0-2)
(i32.const 56)
(i32.const 0)
(global.get $global0)
@@ -64,12 +64,12 @@
(i32.const 0)
(global.get $"C1 WasmArray<_Type>[0]")
(global.get $"C1 WasmArray<_Type>[0]")
(global.get $"C342 _TopType")
(global.get $"C343 _TopType")
(global.get $"C28 _InterfaceType")
(global.get $"C348 _InterfaceType")
(global.get $"C349 _InterfaceType")
(array.new_fixed $Array<_Type> 2)
(i64.const 1)
(global.get $"C316 WasmArray<_NamedParameter>[0]")
(global.get $"C317 WasmArray<_NamedParameter>[0]")
(struct.new $_FunctionType)
(struct.new $#Closure-0-2))
(global $global0 (ref $#DummyStruct) <...>)
+2 -2
View File
@@ -5,12 +5,12 @@
(field $field0 i32)
(field $_ref externref))))
(global $".hello world" (import "" "hello world") (ref extern))
(global $"C340 \"hello world\"" (ref $JSStringImpl)
(global $"C341 \"hello world\"" (ref $JSStringImpl)
(i32.const 4)
(global.get $".hello world")
(struct.new $JSStringImpl))
(func $"main <noInline>"
global.get $"C340 \"hello world\""
global.get $"C341 \"hello world\""
call $print
)
(func $print (param $var0 (ref $#Top)) <...>)
@@ -10,7 +10,7 @@
(field $field1 (mut i32)))))
(func $print (import "module0" "func0") (param (ref null $#Top)) (result (ref null $#Top)))
(global $".hello world" (import "" "hello world") (ref extern))
(global $"C465 \"hello world\"" (ref $JSStringImpl)
(global $"C466 \"hello world\"" (ref $JSStringImpl)
(i32.const 4)
(i32.const 0)
(global.get $".hello world")
@@ -20,7 +20,7 @@
ref.null none
)
(func $"mainFoo <noInline>"
global.get $"C465 \"hello world\""
global.get $"C466 \"hello world\""
call $print
drop
)
@@ -113,6 +113,8 @@ final nameParameterConstArray = WasmArrayConstCache();
@pragma('dyn-module:callable')
final i8ConstImmutableArray = WasmArrayConstCache();
@pragma('dyn-module:callable')
final i16ConstArray = WasmArrayConstCache();
@pragma('dyn-module:callable')
final i32ConstArray = WasmArrayConstCache();
@pragma('dyn-module:callable')
final i64ConstImmutableArray = WasmArrayConstCache();
+41 -22
View File
@@ -661,7 +661,7 @@ class _RecordType extends _Type {
identical(names, other.names);
}
/// The non-negative index into [_ModuleRtt.typeRowDisplacementSubstTable] that
/// The non-negative index into [_ModuleRtt.canonicalSubstitutionTable] that
/// represents that no substitution is needed.
external WasmI32 get _noSubstitutionIndex;
@@ -697,12 +697,15 @@ class _ModuleRtt {
///
/// Used via
/// ```
/// baseOffset = _typeRowDisplacementOffsets[Base.classId]`
/// baseOffset = typeRowDisplacementOffsets[Base.classId]`
/// index = baseOffset + Sub.classId
/// value = _typeRowDisplacementTable[index]
/// value = typeRowDisplacementTable[index]
/// if (value == Base.classId) {
/// // => Sub.classId is a subclass of Base.classId
/// // => Can use `index` into `typeRowDisplacementSubstTable[index]`
/// // => Can find how to translate Sub's type parameters to Base's type
/// // parameters via substitution:
/// substIndex = typeRowDisplacementSubstTable[index];
/// substitution = canonicalSubstitutionTable[substIndex]
/// }
///```
///
@@ -711,17 +714,23 @@ class _ModuleRtt {
/// are ignored for all other compilations.
final WasmArray<WasmI32> typeRowDisplacementTable;
/// Holds the canonical type argument substitution index for matching table
/// entries (see above).
/// Same entries and indexing scheme as [typeRowDisplacementTable] but stores
/// the index into [canonicalSubstitutionTable].
///
/// If `index` matches in [typeRowDisplacementTable] then the same index can be
/// used in this array to find the type argument substitution array for
/// translating type arguments from a base class to a direct/indirect class.
/// We use WasmI16 as we don't expect there to be more than 64k type
/// substitutions.
final WasmArray<WasmI16> typeRowDisplacementSubstTable;
/// Holds the canonical type argument substitutions.
///
/// Takes two class IDs of classes to be queried. For dynamic modules this will
/// allow the compiler to scope the query to a specific module. The class IDs
/// are ignored for all other compilations.
final WasmArray<WasmArray<_Type>> typeRowDisplacementSubstTable;
/// The entries can be used to translate type arguments from a subclass to the
/// type arguments of a super class.
///
/// This array is indexed by values stores in the
/// [typeRowDisplacementSubstTable].
///
/// (See [typeRowDisplacementTable] above for more information).
final WasmArray<WasmArray<_Type>> canonicalSubstitutionTable;
/// The names of all classes (indexed by class id) or null (if `--minify` was
/// used)
@@ -732,6 +741,7 @@ class _ModuleRtt {
this.typeRowDisplacementOffsets,
this.typeRowDisplacementTable,
this.typeRowDisplacementSubstTable,
this.canonicalSubstitutionTable,
this.typeNames,
);
}
@@ -1023,7 +1033,7 @@ abstract class _TypeUniverse {
substitutionIndex,
// Since these are already proved to be subclasses, sId and tId are in the
// same module or sId's module contains info for both.
_moduleRttForClassId(sId).typeRowDisplacementSubstTable,
_moduleRttForClassId(sId).canonicalSubstitutionTable,
);
}
@@ -1051,7 +1061,7 @@ abstract class _TypeUniverse {
substitutionIndex,
// Since these are already proved to be subclasses, sId and tId are in the
// same module or sId's module contains info for both.
_moduleRttForClassId(sId).typeRowDisplacementSubstTable,
_moduleRttForClassId(sId).canonicalSubstitutionTable,
);
}
@@ -1076,7 +1086,7 @@ abstract class _TypeUniverse {
substitutionIndex,
// Since these are already proved to be subclasses, sId and tId are in the
// same module or sId's module contains info for both.
_moduleRttForClassId(sId).typeRowDisplacementSubstTable,
_moduleRttForClassId(sId).canonicalSubstitutionTable,
);
}
@@ -1105,7 +1115,7 @@ abstract class _TypeUniverse {
substitutionIndex,
// Since these are already proved to be subclasses, sId and tId are in the
// same module or sId's module contains info for both.
_moduleRttForClassId(sId).typeRowDisplacementSubstTable,
_moduleRttForClassId(sId).canonicalSubstitutionTable,
);
}
@@ -1195,12 +1205,17 @@ abstract class _TypeUniverse {
return true;
}
/// Checks that [sId] is direct/indirect subclass of [tId] and obtains
/// Checks whether [sId] is direct/indirect subclass of [tId] and obtains
/// substitution array index to translate [sId]s type arguments to [tId]s
/// type arguments.
///
/// Returns `null` if [sId] does not have [tId] in its transitive
/// extends/implements chain or
/// Returns
/// * -1 if the [sId] is not a subtype of [tId]
/// * [_noSubstitutionIndex] if the classes are related but no type
/// arguments have to be translated (either classes are not generic or
/// their type arguments are identical and don't have to be translated)
/// * otherwise returns an index that can be used to index
/// [_ModuleRtt.canonicalSubstitutionTable]
@pragma('wasm:prefer-inline')
static WasmI32 _checkSubclassRelationship(WasmI32 sId, WasmI32 tId) {
// Caller should ensure that the target cannot be a top type (which is
@@ -1229,8 +1244,12 @@ abstract class _TypeUniverse {
final WasmI32 index = offset[tId.toIntSigned()] + sId;
if (index.geU(table.length.toWasmI32())) return (-1).toWasmI32();
final value = table[index.toIntSigned()];
if (value == tId) return index;
if (value == -tId) return _noSubstitutionIndex;
if (value == tId) {
// Match: The [sId] is a subtype of [tId].
return rtt.typeRowDisplacementSubstTable
.readUnsigned(index.toIntSigned())
.toWasmI32();
}
return (-1).toWasmI32();
}