[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 <kustermann@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
This commit is contained in:
Nate Biggs
2024-12-18 08:19:42 -08:00
committed by Commit Queue
parent 8c1fa6d05b
commit 7bea7d185d
5 changed files with 24 additions and 30 deletions
+2 -2
View File
@@ -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
+11 -8
View File
@@ -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.
+9 -16
View File
@@ -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<ConstantInfo?>
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<ConstantInfo?>
(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<ConstantInfo?>
}
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<ConstantInfo?>
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<ConstantInfo?>
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<ConstantInfo?>
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<ConstantInfo?>
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<ConstantInfo?>
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);
+1 -2
View File
@@ -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);
+1 -2
View File
@@ -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) {