diff --git a/pkg/dart2wasm/lib/closures.dart b/pkg/dart2wasm/lib/closures.dart index dc30f239edc..ecb5221fa5b 100644 --- a/pkg/dart2wasm/lib/closures.dart +++ b/pkg/dart2wasm/lib/closures.dart @@ -12,6 +12,7 @@ import 'package:vm/transformations/type_flow/utils.dart' show UnionFind; import 'package:wasm_builder/wasm_builder.dart' as w; import 'class_info.dart'; +import 'code_generator.dart'; import 'param_info.dart'; import 'translator.dart'; @@ -722,8 +723,7 @@ class ClosureLayouter extends RecursiveVisitor { w.Local typeParam(int i) => instantiationFunction.locals[1 + i]; // Header for the closure struct - b.i32_const(translator.closureInfo.classId); - b.i32_const(initialIdentityHash); + b.pushObjectHeaderFields(translator.closureInfo); // Context for the instantiated closure, containing the original closure and // the type arguments diff --git a/pkg/dart2wasm/lib/code_generator.dart b/pkg/dart2wasm/lib/code_generator.dart index bdea89f325f..38e5219354c 100644 --- a/pkg/dart2wasm/lib/code_generator.dart +++ b/pkg/dart2wasm/lib/code_generator.dart @@ -2335,8 +2335,7 @@ abstract class AstCodeGenerator ClassInfo info = translator.closureInfo; translator.functions.recordClassAllocation(info.classId); - b.i32_const(info.classId); - b.i32_const(initialIdentityHash); + b.pushObjectHeaderFields(info); pushContext(); translator.globals.readGlobal(b, closure.vtable); types.makeType(this, functionType); @@ -2941,8 +2940,7 @@ abstract class AstCodeGenerator translator.getRecordClassInfo(node.recordType); translator.functions.recordClassAllocation(recordClassInfo.classId); - b.i32_const(recordClassInfo.classId); - b.i32_const(initialIdentityHash); + b.pushObjectHeaderFields(recordClassInfo); for (Expression positional in node.positional) { translateExpression(positional, translator.topInfo.nullableType); } @@ -3256,8 +3254,7 @@ class TearOffCodeGenerator extends AstCodeGenerator { ClassInfo info = translator.closureInfo; translator.functions.recordClassAllocation(info.classId); - b.i32_const(info.classId); - b.i32_const(initialIdentityHash); + b.pushObjectHeaderFields(info); b.local_get(paramLocals[0]); // `this` as context translator.globals.readGlobal(b, closure.vtable); types.makeType(this, functionType); @@ -3731,8 +3728,7 @@ class ConstructorAllocatorCodeGenerator extends AstCodeGenerator { } // Set field values - b.i32_const(info.classId); - b.i32_const(initialIdentityHash); + b.pushObjectHeaderFields(info); for (w.Local local in orderedFieldLocals.reversed) { b.local_get(local); @@ -4595,6 +4591,13 @@ extension MacroAssembler on w.InstructionsBuilder { return target.signature.outputs; } + + /// Pushes fields common to all Dart objects (class id, id hash). + void pushObjectHeaderFields(ClassInfo classInfo) { + // TODO(natebiggs): Adjust class ID for dynamic module if appropriate. + i32_const(classInfo.classId); + i32_const(initialIdentityHash); + } } /// A call target that may be called with a direct call or may be inlined. diff --git a/pkg/dart2wasm/lib/constants.dart b/pkg/dart2wasm/lib/constants.dart index 81ed8c67090..776cba92954 100644 --- a/pkg/dart2wasm/lib/constants.dart +++ b/pkg/dart2wasm/lib/constants.dart @@ -12,6 +12,7 @@ import 'package:wasm_builder/wasm_builder.dart' as w; import 'class_info.dart'; import 'closures.dart'; +import 'code_generator.dart'; import 'param_info.dart'; import 'translator.dart'; import 'types.dart'; @@ -532,8 +533,7 @@ class ConstantCreator extends ConstantVisitor if (translator.options.jsCompatibility) { ClassInfo info = translator.classInfo[translator.jsStringClass]!; return createConstant(constant, info.nonNullableType, (b) { - b.i32_const(info.classId); - b.i32_const(initialIdentityHash); + b.pushObjectHeaderFields(info); translator.globals.readGlobal(b, translator.getInternalizedStringGlobal(b.module, constant.value)); b.struct_new(info.struct); @@ -551,8 +551,7 @@ class ConstantCreator extends ConstantVisitor (info.struct.fields[FieldIndex.stringArray].type as w.RefType) .heapType as w.ArrayType; - b.i32_const(info.classId); - b.i32_const(initialIdentityHash); + b.pushObjectHeaderFields(info); if (lazy) { // Initialize string contents from passive data segment. w.DataSegmentBuilder segment; @@ -631,8 +630,7 @@ class ConstantCreator extends ConstantVisitor } return createConstant(constant, type, lazy: lazy, (b) { - b.i32_const(info.classId); - b.i32_const(initialIdentityHash); + b.pushObjectHeaderFields(info); for (int i = baseFieldCount; i < fieldCount; i++) { Constant subConstant = subConstants[i]!; constants.instantiateConstant( @@ -740,8 +738,7 @@ class ConstantCreator extends ConstantVisitor w.ArrayType arrayType = translator.listArrayType; w.ValueType elementType = arrayType.elementType.type.unpacked; int length = constant.entries.length; - b.i32_const(info.classId); - b.i32_const(initialIdentityHash); + b.pushObjectHeaderFields(info); constants.instantiateConstant( b, typeArgConstant, constants.typeInfo.nullableType); b.i64_const(length); @@ -865,8 +862,7 @@ class ConstantCreator extends ConstantVisitor ClassInfo info = translator.closureInfo; translator.functions.recordClassAllocation(info.classId); - b.i32_const(info.classId); - b.i32_const(initialIdentityHash); + b.pushObjectHeaderFields(info); translator.globals.readGlobal(b, dummyStructGlobal); // Dummy context translator.globals.readGlobal(b, closure.vtable); constants.instantiateConstant( @@ -1026,8 +1022,7 @@ class ConstantCreator extends ConstantVisitor b.struct_new(instantiationOfTearOffRepresentation.vtableStruct); } - b.i32_const(info.classId); - b.i32_const(initialIdentityHash); + b.pushObjectHeaderFields(info); // Context is not used by the vtable functions, but it's needed for // closure equality checks to work (`_Closure._equals`). @@ -1059,8 +1054,7 @@ class ConstantCreator extends ConstantVisitor StringConstant nameConstant = StringConstant(constant.name); bool lazy = ensureConstant(nameConstant)?.isLazy ?? false; return createConstant(constant, info.nonNullableType, lazy: lazy, (b) { - b.i32_const(info.classId); - b.i32_const(initialIdentityHash); + b.pushObjectHeaderFields(info); constants.instantiateConstant(b, nameConstant, stringType); b.struct_new(info.struct); }); @@ -1082,8 +1076,7 @@ class ConstantCreator extends ConstantVisitor return createConstant(constant, recordClassInfo.nonNullableType, lazy: lazy, (b) { - b.i32_const(recordClassInfo.classId); - b.i32_const(initialIdentityHash); + b.pushObjectHeaderFields(recordClassInfo); for (Constant argument in arguments) { constants.instantiateConstant( b, argument, translator.topInfo.nullableType); diff --git a/pkg/dart2wasm/lib/sync_star.dart b/pkg/dart2wasm/lib/sync_star.dart index 4fcc2b2c249..1b84a2c0467 100644 --- a/pkg/dart2wasm/lib/sync_star.dart +++ b/pkg/dart2wasm/lib/sync_star.dart @@ -27,8 +27,7 @@ mixin SyncStarCodeGeneratorMixin on StateMachineEntryAstCodeGenerator { // function for this `sync*` function. DartType elementType = functionNode.emittedValueType!; translator.functions.recordClassAllocation(syncStarIterableInfo.classId); - b.i32_const(syncStarIterableInfo.classId); - b.i32_const(initialIdentityHash); + b.pushObjectHeaderFields(syncStarIterableInfo); types.makeType(this, elementType); if (context != null) { assert(!context.isEmpty); diff --git a/pkg/dart2wasm/lib/types.dart b/pkg/dart2wasm/lib/types.dart index 6ab597c2855..ada2336d76f 100644 --- a/pkg/dart2wasm/lib/types.dart +++ b/pkg/dart2wasm/lib/types.dart @@ -346,8 +346,7 @@ class Types { } translator.functions.recordClassAllocation(info.classId); - b.i32_const(info.classId); - b.i32_const(initialIdentityHash); + b.pushObjectHeaderFields(info); if (type is InterfaceType) { _makeInterfaceType(codeGen, type); } else if (type is FunctionType) {