From 7bea7d185d4115346f2ecd4f7f4aff6d658eefe6 Mon Sep 17 00:00:00 2001 From: Nate Biggs Date: Wed, 18 Dec 2024 08:19:42 -0800 Subject: [PATCH] [dart2wasm] Add indirection for struct initialization. For dynamic modules we will "adjust" the class ID at runtime to ensure each module gets independent class ID spaces. This initial change simply provides the point where we will eventually add that logic. Change-Id: Iad9c38d9e3e842be2e77c48b1755ebe57d02d023 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/400923 Reviewed-by: Martin Kustermann Commit-Queue: Nate Biggs --- pkg/dart2wasm/lib/closures.dart | 4 ++-- pkg/dart2wasm/lib/code_generator.dart | 19 +++++++++++-------- pkg/dart2wasm/lib/constants.dart | 25 +++++++++---------------- pkg/dart2wasm/lib/sync_star.dart | 3 +-- pkg/dart2wasm/lib/types.dart | 3 +-- 5 files changed, 24 insertions(+), 30 deletions(-) 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) {