diff --git a/pkg/dart2wasm/lib/async.dart b/pkg/dart2wasm/lib/async.dart index c556e223175..dc84f472ce5 100644 --- a/pkg/dart2wasm/lib/async.dart +++ b/pkg/dart2wasm/lib/async.dart @@ -55,9 +55,9 @@ mixin AsyncCodeGeneratorMixin on StateMachineEntryAstCodeGenerator { // here. b.local_get(asyncStateLocal); - b.ref_null(translator.topInfo.struct); // await value - b.ref_null(translator.topInfo.struct); // error value - b.ref_null(translator.stackTraceInfo.repr.struct); // stack trace + b.ref_null(translator.topType.heapType); // await value + b.ref_null(translator.topType.heapType); // error value + b.ref_null(translator.stackTraceType.heapType); // stack trace translator.callFunction(resumeFun, b); b.drop(); // drop null @@ -79,15 +79,14 @@ mixin AsyncCodeGeneratorMixin on StateMachineEntryAstCodeGenerator { b.module.functions.define( translator.typesBuilder.defineFunction([ asyncSuspendStateInfo.nonNullableType, // _AsyncSuspendState - translator.topInfo.nullableType, // Object?, await value - translator.topInfo.nullableType, // Object?, error value - translator.stackTraceInfo.repr - .nullableType // StackTrace?, error stack trace + translator.topType, // Object?, await value + translator.topType, // Object?, error value + translator.stackTraceTypeNullable // StackTrace?, error stack trace ], [ // Inner function does not return a value, but it's Dart type is // `void Function(...)` and all Dart functions return a value, so we // add a return type. - translator.topInfo.nullableType + translator.topType ]), "${function.functionName} inner"); } @@ -254,17 +253,15 @@ class AsyncStateMachineCodeGenerator extends StateMachineCodeGenerator { // Final state: return. emitTargetLabel(targets.last); b.local_get(_suspendStateLocal); - b.ref_null(translator.topInfo.struct); + b.ref_null(translator.topType.heapType); call(translator.getFunctionEntry( translator.asyncSuspendStateComplete.reference, uncheckedEntry: true)); b.return_(); b.end(); // masterLoop - final stackTraceLocal = - addLocal(translator.stackTraceInfo.repr.nonNullableType); - - final exceptionLocal = addLocal(translator.topInfo.nonNullableType); + final stackTraceLocal = addLocal(translator.stackTraceType); + final exceptionLocal = addLocal(translator.topTypeNonNullable); void callCompleteError() { b.local_get(_suspendStateLocal); diff --git a/pkg/dart2wasm/lib/class_info.dart b/pkg/dart2wasm/lib/class_info.dart index f5ab167f0ab..cc76db6b529 100644 --- a/pkg/dart2wasm/lib/class_info.dart +++ b/pkg/dart2wasm/lib/class_info.dart @@ -183,11 +183,11 @@ class ClassInfo { /// the superclass. final Map typeParameterMatch; - /// The class whose struct is used as the type for variables of this type. - /// This is a type which is a superclass of all subtypes of this type. - ClassInfo get repr => _repr!; + /// The wasm type used to represent values of a dart interface type of this + /// class. + w.RefType get repr => _repr!; - ClassInfo? _repr; + w.RefType? _repr; /// Nullabe Wasm ref type for this class. final w.RefType nullableType; @@ -478,7 +478,7 @@ class ClassInfoCollector { } for (Field field in info.cls!.fields) { - info._addField(w.FieldType(topInfo.nullableType), + info._addField(w.FieldType(translator.topType), fieldName: field.name.text); } } @@ -548,7 +548,7 @@ class ClassInfoCollector { // class maps to topInfo because boxed values are a subtype of Object in // Dart but not of the object struct. representation = cls == translator.coreTypes.objectClass - ? translator.topInfo + ? topInfo : translator.objectInfo; } else { void addRanges(List ranges) { @@ -581,7 +581,13 @@ class ClassInfoCollector { } } final info = translator.classInfo[cls]!; - info._repr = representation ?? info; + representation ??= info; + + if (representation == topInfo) { + info._repr = translator.topTypeNonNullable; + } else { + info._repr = representation!.nonNullableType; + } } // Now that the representation types for all classes have been computed, diff --git a/pkg/dart2wasm/lib/closures.dart b/pkg/dart2wasm/lib/closures.dart index 89221c35728..3700a53f2aa 100644 --- a/pkg/dart2wasm/lib/closures.dart +++ b/pkg/dart2wasm/lib/closures.dart @@ -356,7 +356,7 @@ class ClosureLayouter extends RecursiveVisitor { superType: superType); } - w.ValueType get topType => translator.topInfo.nullableType; + w.ValueType get topType => translator.topType; ClosureLayouter(this.translator) : procedureAttributeMetadata = diff --git a/pkg/dart2wasm/lib/code_generator.dart b/pkg/dart2wasm/lib/code_generator.dart index 9625b3c7ee6..86b1cc38e10 100644 --- a/pkg/dart2wasm/lib/code_generator.dart +++ b/pkg/dart2wasm/lib/code_generator.dart @@ -303,8 +303,8 @@ abstract class AstCodeGenerator if (translator.needToCheckParameter(variable, uncheckedEntry: canSafelyOmitImplicitChecks)) { final boxedType = variable.type.isPotentiallyNullable - ? translator.topInfo.nullableType - : translator.topInfo.nonNullableType; + ? translator.topType + : translator.topTypeNonNullable; w.Local operand = local; if (!operand.type.isSubtypeOf(boxedType)) { final boxedOperand = addLocal(boxedType); @@ -862,14 +862,12 @@ abstract class AstCodeGenerator Expression? message = node.message; if (message != null) { - translateExpression(message, translator.topInfo.nullableType); + translateExpression(message, translator.topType); } else { b.ref_null(w.HeapType.none); } final Location? location = node.location; - final stringClass = translator.jsStringClass; - final w.RefType stringRefType = - translator.classInfo[stringClass]!.nullableType; + final w.RefType stringRefType = translator.stringTypeNullable; if (location != null) { translator.constants.instantiateConstant( b, @@ -915,9 +913,8 @@ abstract class AstCodeGenerator // It is not valid Dart to have a try without a catch. assert(node.catches.isNotEmpty); - final w.RefType exceptionType = translator.topInfo.nonNullableType; - final w.RefType stackTraceType = - translator.stackTraceInfo.repr.nonNullableType; + final w.RefType exceptionType = translator.topTypeNonNullable; + final w.RefType stackTraceType = translator.stackTraceType; final w.Label wrapperBlock = b.block(); @@ -1421,7 +1418,7 @@ abstract class AstCodeGenerator final dynamicTypeGuard = switchInfo.dynamicTypeGuard; if (dynamicTypeGuard != null) { - final success = b.block(const [], [translator.topInfo.nonNullableType]); + final success = b.block(const [], [translator.topTypeNonNullable]); dynamicTypeGuard(switchValueNonNullableLocal, success); b.br(switchLabels[defaultCase] ?? doneLabel); b.end(); @@ -1663,7 +1660,7 @@ abstract class AstCodeGenerator _virtualCall(node, target, _VirtualCallKind.Call, (signature) { done = b.block(const [], signature.outputs); final w.Label nullReceiver = b.block(); - translateExpression(node.receiver, translator.topInfo.nullableType); + translateExpression(node.receiver, translator.topType); b.br_on_null(nullReceiver); }, (w.FunctionType signature, ParameterInfo paramInfo) { _visitArguments(node.arguments, signature, paramInfo, 1); @@ -1690,7 +1687,7 @@ abstract class AstCodeGenerator final paramInfo = translator.paramInfoForDirectCall(target); // Object? receiver - b.ref_null(translator.topInfo.struct); + b.ref_null(translator.topType.heapType); // Invocation invocation _visitArguments(node.arguments, signature, paramInfo, 1); call(translator.noSuchMethodErrorThrowWithInvocation.reference); @@ -1750,8 +1747,8 @@ abstract class AstCodeGenerator .getDynamicInvocationForwarder(memberName); // Evaluate receiver - translateExpression(receiver, translator.topInfo.nullableType); - final nullableReceiverLocal = addLocal(translator.topInfo.nullableType); + translateExpression(receiver, translator.topType); + final nullableReceiverLocal = addLocal(translator.topType); b.local_set(nullableReceiverLocal); // Evaluate type arguments. @@ -1776,8 +1773,8 @@ abstract class AstCodeGenerator // each argument to allow adding values to the list in expected order. final List> namedArgumentLocals = []; for (final namedArgument in namedArguments) { - translateExpression(namedArgument.value, translator.topInfo.nullableType); - final argumentLocal = addLocal(translator.topInfo.nullableType); + translateExpression(namedArgument.value, translator.topType); + final argumentLocal = addLocal(translator.topType); b.local_set(argumentLocal); namedArgumentLocals.add(MapEntry(namedArgument.name, argumentLocal)); } @@ -1800,7 +1797,7 @@ abstract class AstCodeGenerator })); b.local_set(namedArgsLocal); - final nullBlock = b.block([], [translator.topInfo.nonNullableType]); + final nullBlock = b.block([], [translator.topTypeNonNullable]); b.local_get(nullableReceiverLocal); b.br_on_non_null(nullBlock); // Throw `NoSuchMethodError`. Normally this needs to happen via instance @@ -1819,7 +1816,7 @@ abstract class AstCodeGenerator b.local_get(namedArgsLocal); translator.callFunction(forwarder.function, b); - return translator.topInfo.nullableType; + return translator.topType; } @override @@ -1833,8 +1830,7 @@ abstract class AstCodeGenerator // If leftType is not a Dart type (or builtin value type) then use // reference equality (e.g. the vtable type is not a subtype of // topType). - (leftType is w.RefType && - !leftType.isSubtypeOf(translator.topInfo.nullableType))) { + (leftType is w.RefType && !leftType.isSubtypeOf(translator.topType))) { // Plain reference comparison translateExpression(node.left, w.RefType.eq(nullable: true)); translateExpression(node.right, w.RefType.eq(nullable: true)); @@ -1843,9 +1839,8 @@ abstract class AstCodeGenerator // Check operands for null, then call implementation bool leftNullable = dartTypeOf(node.left).isPotentiallyNullable; bool rightNullable = dartTypeOf(node.right).isPotentiallyNullable; - w.RefType leftType = translator.topInfo.typeWithNullability(leftNullable); - w.RefType rightType = - translator.topInfo.typeWithNullability(rightNullable); + w.RefType leftType = translator.topType.withNullability(leftNullable); + w.RefType rightType = translator.topType.withNullability(rightNullable); w.Local leftLocal = addLocal(leftType); w.Local rightLocal = addLocal(rightType); w.Label? operandNull; @@ -1980,7 +1975,7 @@ abstract class AstCodeGenerator assert(!receiverVar.type.nullable); b.local_tee(receiverVar); if (callPolymorphicDispatcher) { - b.struct_get(translator.topInfo.struct, FieldIndex.classId); + b.loadClassId(translator, receiverVar.type); b.local_get(receiverVar); } pushArguments(signature, selector.paramInfo); @@ -2127,7 +2122,7 @@ abstract class AstCodeGenerator _virtualCall(node, target, _VirtualCallKind.Get, (signature) { doneLabel = b.block(const [], signature.outputs); w.Label nullLabel = b.block(); - translateExpression(node.receiver, translator.topInfo.nullableType); + translateExpression(node.receiver, translator.topType); b.br_on_null(nullLabel); }, (_, __) {}, useUncheckedEntry: false); b.br(doneLabel); @@ -2176,11 +2171,11 @@ abstract class AstCodeGenerator .getDynamicGetForwarder(memberName); // Evaluate receiver - translateExpression(receiver, translator.topInfo.nullableType); - final nullableReceiverLocal = addLocal(translator.topInfo.nullableType); + translateExpression(receiver, translator.topType); + final nullableReceiverLocal = addLocal(translator.topType); b.local_set(nullableReceiverLocal); - final nullBlock = b.block([], [translator.topInfo.nonNullableType]); + final nullBlock = b.block([], [translator.topTypeNonNullable]); b.local_get(nullableReceiverLocal); b.br_on_non_null(nullBlock); // Throw `NoSuchMethodError`. Normally this needs to happen via instance @@ -2196,7 +2191,7 @@ abstract class AstCodeGenerator // Call get forwarder translator.callFunction(forwarder.function, b); - return translator.topInfo.nullableType; + return translator.topType; } @override @@ -2209,16 +2204,16 @@ abstract class AstCodeGenerator .getDynamicSetForwarder(memberName); // Evaluate receiver - translateExpression(receiver, translator.topInfo.nullableType); - final nullableReceiverLocal = addLocal(translator.topInfo.nullableType); + translateExpression(receiver, translator.topType); + final nullableReceiverLocal = addLocal(translator.topType); b.local_set(nullableReceiverLocal); // Evaluate positional arg - translateExpression(value, translator.topInfo.nullableType); - final positionalArgLocal = addLocal(translator.topInfo.nullableType); + translateExpression(value, translator.topType); + final positionalArgLocal = addLocal(translator.topType); b.local_set(positionalArgLocal); - final nullBlock = b.block([], [translator.topInfo.nonNullableType]); + final nullBlock = b.block([], [translator.topTypeNonNullable]); b.local_get(nullableReceiverLocal); b.br_on_non_null(nullBlock); // Throw `NoSuchMethodError`. Normally this needs to happen via instance @@ -2235,7 +2230,7 @@ abstract class AstCodeGenerator b.local_get(positionalArgLocal); translator.callFunction(forwarder.function, b); - return translator.topInfo.nullableType; + return translator.topType; } w.ValueType _directGet(Member target, Expression receiver) { @@ -2268,10 +2263,9 @@ abstract class AstCodeGenerator _virtualCall(node, target, _VirtualCallKind.Get, (signature) { doneLabel = b.block(const [], signature.outputs); w.Label nullLabel = b.block(); - translateExpression(node.receiver, translator.topInfo.nullableType); + translateExpression(node.receiver, translator.topType); b.br_on_null(nullLabel); - translator.convertType( - b, translator.topInfo.nullableType, signature.inputs[0]); + translator.convertType(b, translator.topType, signature.inputs[0]); }, (_, __) {}, useUncheckedEntry: false); b.br(doneLabel); b.end(); // nullLabel @@ -2470,7 +2464,7 @@ abstract class AstCodeGenerator // This is a dynamic function call with a signature that matches no // functions in the program. b.unreachable(); - return translator.topInfo.nullableType; + return translator.topType; } final SingleClosureTarget? directClosureCall = @@ -2533,7 +2527,7 @@ abstract class AstCodeGenerator // Positional arguments for (Expression arg in node.arguments.positional) { - translateExpression(arg, translator.topInfo.nullableType); + translateExpression(arg, translator.topType); } // Named arguments @@ -2541,7 +2535,7 @@ abstract class AstCodeGenerator node.arguments.named.map((a) => a.name).toList()..sort(); final Map namedLocals = {}; for (final namedArg in node.arguments.named) { - final w.Local namedLocal = addLocal(translator.topInfo.nullableType); + final w.Local namedLocal = addLocal(translator.topType); namedLocals[namedArg.name] = namedLocal; translateExpression(namedArg.value, namedLocal.type); b.local_set(namedLocal); @@ -2561,7 +2555,7 @@ abstract class AstCodeGenerator b.struct_get(representation.vtableStruct, vtableFieldIndex); b.call_ref(functionType); - return translator.topInfo.nullableType; + return translator.topType; } @override @@ -2771,7 +2765,7 @@ abstract class AstCodeGenerator // Front-end wraps the argument with `as Object` when necessary, so we can // assume non-nullable here. assert(!dartTypeOf(node.expression).isPotentiallyNullable); - translateExpression(node.expression, translator.topInfo.nonNullableType); + translateExpression(node.expression, translator.topTypeNonNullable); call(translator.errorThrowWithCurrentStackTrace.reference); b.unreachable(); return expectedType; @@ -2955,8 +2949,8 @@ abstract class AstCodeGenerator w.ValueType visitIsExpression(IsExpression node, w.ValueType expectedType) { final operandType = dartTypeOf(node.operand); final boxedOperandType = operandType.isPotentiallyNullable - ? translator.topInfo.nullableType - : translator.topInfo.nonNullableType; + ? translator.topType + : translator.topTypeNonNullable; translateExpression(node.operand, boxedOperandType); types.emitIsTest(this, node.type, operandType, node.location); return w.NumType.i32; @@ -2974,8 +2968,8 @@ abstract class AstCodeGenerator final operandType = dartTypeOf(node.operand); final boxedOperandType = operandType.isPotentiallyNullable - ? translator.topInfo.nullableType - : translator.topInfo.nonNullableType; + ? translator.topType + : translator.topTypeNonNullable; translateExpression(node.operand, boxedOperandType); return types.emitAsCheck(this, node.isCovarianceCheck, node.type, operandType, boxedOperandType, node.location); @@ -3030,10 +3024,10 @@ abstract class AstCodeGenerator b.pushObjectHeaderFields(translator, recordClassInfo); for (Expression positional in node.positional) { - translateExpression(positional, translator.topInfo.nullableType); + translateExpression(positional, translator.topType); } for (NamedExpression named in node.named) { - translateExpression(named.value, translator.topInfo.nullableType); + translateExpression(named.value, translator.topType); } b.struct_new(recordClassInfo.struct); @@ -3047,12 +3041,12 @@ abstract class AstCodeGenerator final ClassInfo recordClassInfo = translator.getRecordClassInfo(node.receiverType); - translateExpression(node.receiver, translator.topInfo.nonNullableType); + translateExpression(node.receiver, translator.topTypeNonNullable); b.ref_cast(w.RefType(recordClassInfo.struct, nullable: false)); b.struct_get( recordClassInfo.struct, recordShape.getPositionalIndex(node.index)); - return translator.topInfo.nullableType; + return translator.topType; } @override @@ -3061,11 +3055,11 @@ abstract class AstCodeGenerator final ClassInfo recordClassInfo = translator.getRecordClassInfo(node.receiverType); - translateExpression(node.receiver, translator.topInfo.nonNullableType); + translateExpression(node.receiver, translator.topTypeNonNullable); b.ref_cast(w.RefType(recordClassInfo.struct, nullable: false)); b.struct_get(recordClassInfo.struct, recordShape.getNameIndex(node.name)); - return translator.topInfo.nullableType; + return translator.topType; } @override @@ -3115,8 +3109,7 @@ abstract class AstCodeGenerator DartType bound, ) { b.local_get(typeLocal); - final boundLocal = - b.addLocal(translator.classInfo[translator.typeClass]!.nonNullableType); + final boundLocal = b.addLocal(translator.runtimeTypeType); types.makeType(this, bound); b.local_tee(boundLocal); call(translator.isTypeSubtype.reference); @@ -3550,8 +3543,7 @@ class TypeCheckerCodeGenerator extends AstCodeGenerator { b.local_get(positionalArgsLocal); b.i32_const(positionalParamIdx); b.array_get(translator.nullableObjectArrayType); - _generateArgumentTypeCheck( - param.name!, translator.topInfo.nullableType, param.type); + _generateArgumentTypeCheck(param.name!, translator.topType, param.type); } // Check named argument types @@ -3577,8 +3569,7 @@ class TypeCheckerCodeGenerator extends AstCodeGenerator { b.local_get(namedArgsLocal); b.i32_const(mapNamedParameterToArrayIndex(param.name!)); b.array_get(translator.nullableObjectArrayType); - _generateArgumentTypeCheck( - param.name!, translator.topInfo.nullableType, param.type); + _generateArgumentTypeCheck(param.name!, translator.topType, param.type); } } @@ -3602,7 +3593,7 @@ class TypeCheckerCodeGenerator extends AstCodeGenerator { b.i32_const(listIdx); b.array_get(translator.nullableObjectArrayType); translator.convertType( - b, translator.topInfo.nullableType, memberWasmInputs[wasmInputIdx]); + b, translator.topType, memberWasmInputs[wasmInputIdx]); } for (int positionalParamIdx = 0; @@ -3624,7 +3615,7 @@ class TypeCheckerCodeGenerator extends AstCodeGenerator { translator.convertType( b, translator.outputOrVoid(memberWasmFunctionType.outputs), - translator.topInfo.nullableType); + translator.topType); b.return_(); b.end(); @@ -4191,12 +4182,12 @@ class ImplicitFieldAccessorCodeGenerator extends AstCodeGenerator { // Implicit getter or setter w.StructType struct = translator.classInfo[field.enclosingClass!]!.struct; + w.RefType structType = w.RefType.def(struct, nullable: false); int fieldIndex = translator.fieldIndex[field]!; w.ValueType fieldType = struct.fields[fieldIndex].type.unpacked; void getThis() { w.Local thisLocal = paramLocals[0]; - w.RefType structType = w.RefType.def(struct, nullable: false); b.local_get(thisLocal); translator.convertType(b, thisLocal.type, structType); } @@ -4215,8 +4206,8 @@ class ImplicitFieldAccessorCodeGenerator extends AstCodeGenerator { translator.needToCheckImplicitSetterValue(field, uncheckedEntry: useUncheckedEntry)) { final boxedType = field.type.isPotentiallyNullable - ? translator.topInfo.nullableType - : translator.topInfo.nonNullableType; + ? translator.topType + : translator.topTypeNonNullable; w.Local operand = valueLocal; if (!operand.type.isSubtypeOf(boxedType)) { final boxedOperand = addLocal(boxedType); @@ -4377,10 +4368,8 @@ class SwitchInfo { compare = (switchExprLocal, pushCaseExpr) => throw "Comparison in default-only switch"; } else if (canInvokeTypeEquality()) { - nonNullableType = translator - .classInfo[translator.coreTypes.typeClass]!.repr.nonNullableType; - nullableType = translator - .classInfo[translator.coreTypes.typeClass]!.repr.nullableType; + nonNullableType = translator.runtimeTypeType; + nullableType = translator.runtimeTypeTypeNullable; compare = (switchExprLocal, pushCaseExpr) { // Virtual call to `Object.==`. codeGen._virtualCall( @@ -4393,8 +4382,8 @@ class SwitchInfo { }; } else if (switchExprType is DynamicType) { // Object equality switch - nonNullableType = translator.topInfo.nonNullableType; - nullableType = translator.topInfo.nullableType; + nonNullableType = translator.topTypeNonNullable; + nullableType = translator.topType; // Per spec, compare with ` == `. final Member equalsMember; @@ -4459,10 +4448,8 @@ class SwitchInfo { }; } else if (check()) { // String switch - nonNullableType = translator - .classInfo[translator.coreTypes.stringClass]!.repr.nonNullableType; - nullableType = translator - .classInfo[translator.coreTypes.stringClass]!.repr.nullableType; + nonNullableType = translator.stringType; + nullableType = translator.stringTypeNullable; compare = (switchExprLocal, pushCaseExpr) { codeGen.b.local_get(switchExprLocal); pushCaseExpr(); @@ -4470,8 +4457,8 @@ class SwitchInfo { }; } else { // Object identity switch - nonNullableType = translator.topInfo.nonNullableType; - nullableType = translator.topInfo.nullableType; + nonNullableType = translator.topTypeNonNullable; + nullableType = translator.topType; compare = (switchExprLocal, pushCaseExpr) { codeGen.b.local_get(switchExprLocal); pushCaseExpr(); @@ -4801,7 +4788,7 @@ extension MacroAssembler on w.InstructionsBuilder { nullable: false)); struct_get(translator.closureLayouter.closureBaseStruct, FieldIndex.closureContext); - ref_test(translator.topInfo.nonNullableType); + ref_test(translator.topTypeNonNullable); } /// `[ref _Closure] -> [ref #Top]` @@ -4812,7 +4799,7 @@ extension MacroAssembler on w.InstructionsBuilder { nullable: false)); struct_get(translator.closureLayouter.closureBaseStruct, FieldIndex.closureContext); - ref_cast(translator.topInfo.nonNullableType); + ref_cast(translator.topTypeNonNullable); } /// `[ref _Closure] -> [ref Any] @@ -4952,6 +4939,13 @@ extension MacroAssembler on w.InstructionsBuilder { translator.callReference(translator.globalizeClassId.reference, this); } } + + void loadClassId(Translator translator, w.ValueType receiverType) { + assert(!receiverType.nullable); + assert(receiverType.isSubtypeOf(translator.topTypeNonNullable)); + struct_get( + translator.classInfoCollector.topInfo.struct, FieldIndex.classId); + } } /// 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 08add9f8072..881eafaef19 100644 --- a/pkg/dart2wasm/lib/constants.dart +++ b/pkg/dart2wasm/lib/constants.dart @@ -1175,8 +1175,7 @@ class ConstantCreator extends ConstantVisitor ConstantInfo? visitSymbolConstant(SymbolConstant constant) { ClassInfo info = translator.classInfo[translator.symbolClass]!; translator.functions.recordClassAllocation(info.classId); - w.RefType stringType = translator - .classInfo[translator.coreTypes.stringClass]!.repr.nonNullableType; + w.RefType stringType = translator.stringType; final String symbolStringValue = constants.minifySymbol(constant.name); StringConstant nameConstant = StringConstant(symbolStringValue); bool lazy = ensureConstant(nameConstant)?.isLazy ?? false; @@ -1205,8 +1204,7 @@ class ConstantCreator extends ConstantVisitor (b) { b.pushObjectHeaderFields(translator, recordClassInfo); for (Constant argument in arguments) { - constants.instantiateConstant( - b, argument, translator.topInfo.nullableType); + constants.instantiateConstant(b, argument, translator.topType); } b.struct_new(recordClassInfo.struct); }); diff --git a/pkg/dart2wasm/lib/dispatch_table.dart b/pkg/dart2wasm/lib/dispatch_table.dart index b0a7e503869..f7dc07e07a1 100644 --- a/pkg/dart2wasm/lib/dispatch_table.dart +++ b/pkg/dart2wasm/lib/dispatch_table.dart @@ -203,7 +203,7 @@ class SelectorInfo { } assert(returns.length <= outputSets.length); inputSets[0].add(isDynamicSubmoduleOverridable - ? translator.topInfo.nonNullableType + ? translator.topTypeNonNullable : translator.translateType(receiver)); for (int i = 0; i < positional.length; i++) { DartType type = positional[i]; @@ -223,7 +223,7 @@ class SelectorInfo { DartType type = returns[i]; outputSets[i].add(translator.translateReturnType(type)); } else { - outputSets[i].add(translator.topInfo.nullableType); + outputSets[i].add(translator.topType); } } } @@ -253,9 +253,7 @@ class SelectorInfo { // create a dummy signature with top types. Receivers specifically should // be non-nullable since we must be invoking a selector on some object. assert(!isReceiver || isDynamicSubmoduleOverridable); - return isReceiver - ? translator.topInfo.nonNullableType - : translator.topInfo.nullableType; + return isReceiver ? translator.topTypeNonNullable : translator.topType; } if (!ensureBoxed && types.length == 1 && types.single.isPrimitive) { // Unboxed primitive. diff --git a/pkg/dart2wasm/lib/dynamic_forwarders.dart b/pkg/dart2wasm/lib/dynamic_forwarders.dart index 91162ff9e12..6f31451604d 100644 --- a/pkg/dart2wasm/lib/dynamic_forwarders.dart +++ b/pkg/dart2wasm/lib/dynamic_forwarders.dart @@ -136,7 +136,7 @@ class _DynamicForwarderCodeGenerator extends CodeGenerator { final b = function.body; b.local_get(receiverLocal); - b.struct_get(translator.topInfo.struct, FieldIndex.classId); + b.loadClassId(translator, receiverLocal.type); b.classIdSearch(ranges, outputs, (Reference target) { final targetMember = target.asMember; final Reference targetReference; @@ -184,7 +184,7 @@ class _DynamicForwarderCodeGenerator extends CodeGenerator { final b = function.body; b.local_get(receiverLocal); - b.struct_get(translator.topInfo.struct, FieldIndex.classId); + b.loadClassId(translator, receiverLocal.type); b.classIdSearch(ranges, [positionalArgLocal.type], (Reference target) { final Member targetMember = target.asMember; b.local_get(receiverLocal); @@ -237,7 +237,7 @@ class _DynamicForwarderCodeGenerator extends CodeGenerator { final targetMemberParamInfo = translator.paramInfoForDirectCall(target); b.local_get(receiverLocal); - b.struct_get(translator.topInfo.struct, FieldIndex.classId); + b.loadClassId(translator, receiverLocal.type); b.local_set(classIdLocal); final classIdNoMatch = b.block(); @@ -350,7 +350,7 @@ class _DynamicForwarderCodeGenerator extends CodeGenerator { b.local_get(adjustedPositionalArgsLocal); b.i32_const(optionalParamIdx); translator.constants - .instantiateConstant(b, param, translator.topInfo.nullableType); + .instantiateConstant(b, param, translator.topType); b.array_set(translator.nullableObjectArrayType); b.end(); } @@ -458,13 +458,13 @@ class _DynamicForwarderCodeGenerator extends CodeGenerator { translator.constants.instantiateConstant( b, (functionNodeDefaultValue as ConstantExpression).constant, - translator.topInfo.nullableType); + translator.topType); } else { // Not used by the member translator.constants.instantiateConstant( b, paramInfoDefaultValue!, - translator.topInfo.nullableType, + translator.topType, ); } b.array_set(translator.nullableObjectArrayType); @@ -503,7 +503,7 @@ class _DynamicForwarderCodeGenerator extends CodeGenerator { } } - final getterValueLocal = b.addLocal(translator.topInfo.nullableType); + final getterValueLocal = b.addLocal(translator.topType); void handleGetterSelector(SelectorInfo selector) { for (final (:range, :target) in selector.targets(unchecked: false).targetRanges) { @@ -516,7 +516,7 @@ class _DynamicForwarderCodeGenerator extends CodeGenerator { } b.local_get(receiverLocal); - b.struct_get(translator.topInfo.struct, FieldIndex.classId); + b.loadClassId(translator, receiverLocal.type); b.i32_const(classId); b.i32_eq(); b.if_(); @@ -539,8 +539,8 @@ class _DynamicForwarderCodeGenerator extends CodeGenerator { translator.convertType( b, receiverLocal.type, targetFunction.type.inputs.first); translator.callFunction(targetFunction, b); - translator.convertType(b, targetFunction.type.outputs.single, - translator.topInfo.nullableType); + translator.convertType( + b, targetFunction.type.outputs.single, translator.topType); b.local_tee(getterValueLocal); // Throw `NoSuchMethodError` if the value is null @@ -550,7 +550,7 @@ class _DynamicForwarderCodeGenerator extends CodeGenerator { b.local_tee(receiverLocal); // Invoke "call" if the value is not a closure - b.struct_get(translator.topInfo.struct, FieldIndex.classId); + b.loadClassId(translator, receiverLocal.type); b.i32_const( (translator.closureInfo.classId as AbsoluteClassId).value); b.i32_ne(); @@ -799,7 +799,7 @@ void generateNoSuchMethodCall( pushReceiver(); if (callPolymorphicDispatcher) { - b.struct_get(translator.topInfo.struct, FieldIndex.classId); + b.loadClassId(translator, translator.topTypeNonNullable); pushReceiver(); } pushInvocationObject(); diff --git a/pkg/dart2wasm/lib/dynamic_modules.dart b/pkg/dart2wasm/lib/dynamic_modules.dart index 67ab4047be5..fed50ea424c 100644 --- a/pkg/dart2wasm/lib/dynamic_modules.dart +++ b/pkg/dart2wasm/lib/dynamic_modules.dart @@ -894,7 +894,7 @@ class DynamicModuleInfo { // If any input is not a RefType (i.e. it's an unboxed value) then wrap it // so the updated signature works. if (localSignature.inputs.any((i) => i is! w.RefType)) { - final receiverLocal = b.addLocal(translator.topInfo.nullableType); + final receiverLocal = b.addLocal(translator.topTypeNonNullable); b.local_set(receiverLocal); final locals = []; for (final input in localSignature.inputs.reversed) { @@ -910,7 +910,7 @@ class DynamicModuleInfo { } final idLocal = b.addLocal(w.NumType.i32); - b.struct_get(translator.topInfo.struct, FieldIndex.classId); + b.loadClassId(translator, translator.topTypeNonNullable); b.local_tee(idLocal); b.i32_const(useUncheckedEntry ? 1 : 0); b.local_get(idLocal); @@ -967,8 +967,8 @@ class ConstantCanonicalizer extends ConstantVisitor { ConstantCanonicalizer(this.translator, this.b, this.valueLocal); late final _checkerType = translator.typesBuilder.defineFunction([ - translator.topInfo.nonNullableType, - translator.topInfo.nonNullableType, + translator.topTypeNonNullable, + translator.topTypeNonNullable, ], const [ w.NumType.i32 ]); @@ -1188,7 +1188,6 @@ class ConstantCanonicalizer extends ConstantVisitor { /// values are already canonicalized. void _defaultChecker(w.InstructionsBuilder b, ClassInfo classInfo, {Set? fieldsToInclude}) { - classInfo = classInfo.repr; final structType = classInfo.struct; final structRefType = classInfo.nonNullableType; final castedLocal1 = b.addLocal(structRefType); diff --git a/pkg/dart2wasm/lib/intrinsics.dart b/pkg/dart2wasm/lib/intrinsics.dart index 38c17662e2e..18d0a46ec31 100644 --- a/pkg/dart2wasm/lib/intrinsics.dart +++ b/pkg/dart2wasm/lib/intrinsics.dart @@ -416,7 +416,7 @@ class Intrinsifier { if (cls == translator.wasmAnyRefClass) { if (name == "isObject") { codeGen.translateExpression(receiver, w.RefType.any(nullable: false)); - b.ref_test(translator.topInfo.nonNullableType); + b.ref_test(translator.topTypeNonNullable); return w.NumType.i32; } else if (name == "isI31") { codeGen.translateExpression(receiver, w.RefType.any(nullable: false)); @@ -475,14 +475,14 @@ class Intrinsifier { // WasmAnyRef.toObject if (cls == translator.wasmAnyRefClass && name == "toObject") { - w.Label succeed = b.block(const [], [translator.topInfo.nonNullableType]); + w.Label succeed = b.block(const [], [translator.topTypeNonNullable]); codeGen.translateExpression( receiver, const w.RefType.any(nullable: false)); b.br_on_cast(succeed, const w.RefType.any(nullable: false), - translator.topInfo.nonNullableType); + translator.topTypeNonNullable); codeGen.throwWasmRefError("a Dart object"); b.end(); // succeed - return translator.topInfo.nonNullableType; + return translator.topTypeNonNullable; } // Wasm(I32|I64|F32|F64) conversions @@ -1203,14 +1203,13 @@ class Intrinsifier { // Ensure we compile the target function & export it. translator.functions.getFunction(target.reference); - final topType = translator.topInfo.nullableType; + final topType = translator.topType; codeGen.translateExpression(NullLiteral(), topType); return topType; case StaticIntrinsic.getID: - ClassInfo info = translator.topInfo; - codeGen.translateExpression( - node.arguments.positional.single, info.nonNullableType); - b.struct_get(info.struct, FieldIndex.classId); + final type = translator.topTypeNonNullable; + codeGen.translateExpression(node.arguments.positional.single, type); + b.loadClassId(translator, type); return w.NumType.i32; // dart:ffi static functions @@ -1504,8 +1503,8 @@ class Intrinsifier { translator.classIdNumbering.getConcreteSubclassRanges(baseClass); final object = node.arguments.positional.single; - codeGen.translateExpression(object, w.RefType.any(nullable: false)); - b.struct_get(translator.topInfo.struct, FieldIndex.classId); + codeGen.translateExpression(object, translator.topTypeNonNullable); + b.loadClassId(translator, translator.topTypeNonNullable); b.emitClassIdRangeCheck(ranges); return w.NumType.i32; @@ -1679,11 +1678,11 @@ class Intrinsifier { // If either is `null`, or their class IDs are different, return false. b.local_get(first); b.br_on_null(fail); - b.struct_get(translator.topInfo.struct, FieldIndex.classId); + b.loadClassId(translator, translator.topTypeNonNullable); b.local_tee(cid); b.local_get(second); b.br_on_null(fail); - b.struct_get(translator.topInfo.struct, FieldIndex.classId); + b.loadClassId(translator, translator.topTypeNonNullable); b.i32_ne(); b.br_if(fail); @@ -1737,8 +1736,7 @@ class Intrinsifier { case MemberIntrinsic.identityHashCode: final w.Local arg = paramLocals[0]; - final w.Local nonNullArg = - b.addLocal(translator.topInfo.nonNullableType); + final w.Local nonNullArg = b.addLocal(translator.topTypeNonNullable); final List classIds = translator.valueClasses.keys .map((cls) => (translator.classInfo[cls]!.classId as AbsoluteClassId).value) @@ -1747,7 +1745,7 @@ class Intrinsifier { // If the argument is `null`, return the hash code of `null`. final w.Label notNull = - b.block(const [], [translator.topInfo.nonNullableType]); + b.block(const [], [translator.topTypeNonNullable]); b.local_get(arg); b.br_on_non_null(notNull); b.i64_const(null.hashCode); @@ -1760,7 +1758,7 @@ class Intrinsifier { final List labels = List.generate(classIds.length, (_) => b.block()); b.local_get(nonNullArg); - b.struct_get(translator.topInfo.struct, FieldIndex.classId); + b.loadClassId(translator, translator.topTypeNonNullable); int labelIndex = 0; final List targets = List.generate(classIds.last + 1, (id) { return id == classIds[labelIndex] diff --git a/pkg/dart2wasm/lib/state_machine.dart b/pkg/dart2wasm/lib/state_machine.dart index 39202debfa5..01bec9ed3fb 100644 --- a/pkg/dart2wasm/lib/state_machine.dart +++ b/pkg/dart2wasm/lib/state_machine.dart @@ -316,17 +316,14 @@ class ExceptionHandlerStack { int nextHandlerIdx = _handlers.length - 1; final b = codeGen.b; for (final int nCoveredHandlers in _tryBlockNumHandlers.reversed) { - final stackTraceLocal = - b.addLocal(codeGen.translator.stackTraceInfo.repr.nonNullableType); + final stackTraceLocal = b.addLocal(codeGen.translator.stackTraceType); - final exceptionLocal = - b.addLocal(codeGen.translator.topInfo.nonNullableType); + final exceptionLocal = b.addLocal(codeGen.translator.topTypeNonNullable); - final previousException = - b.addLocal(codeGen.translator.topInfo.nullableType); + final previousException = b.addLocal(codeGen.translator.topType); final previousStackTrace = - b.addLocal(codeGen.translator.stackTraceInfo.repr.nullableType); + b.addLocal(codeGen.translator.stackTraceTypeNullable); _previousCatchLocals.add((previousException, previousStackTrace)); @@ -1049,7 +1046,7 @@ abstract class StateMachineCodeGenerator extends AstCodeGenerator { setVariable(catch_.exception!, () { getSuspendStateCurrentException(); // Type test already passed, convert the exception. - translator.convertType(b, translator.topInfo.nullableType, + translator.convertType(b, translator.topType, translator.translateType(catch_.exception!.type)); }); setVariable(catch_.stackTrace!, () => getSuspendStateCurrentStackTrace()); @@ -1194,21 +1191,21 @@ abstract class StateMachineCodeGenerator extends AstCodeGenerator { if (firstFinalizer == null) { emitReturn(() { if (value == null) { - b.ref_null(translator.topInfo.struct); + b.ref_null(translator.topType.heapType); } else { - translateExpression(value, translator.topInfo.nullableType); + translateExpression(value, translator.topType); } }); return; } if (value == null) { - b.ref_null(translator.topInfo.struct); + b.ref_null(translator.topType.heapType); } else { - translateExpression(value, translator.topInfo.nullableType); + translateExpression(value, translator.topType); } - final returnValueLocal = addLocal(translator.topInfo.nullableType); + final returnValueLocal = addLocal(translator.topType); b.local_set(returnValueLocal); // Set return value for the last finalizer to return. @@ -1230,12 +1227,11 @@ abstract class StateMachineCodeGenerator extends AstCodeGenerator { @override w.ValueType visitThrow(Throw node, w.ValueType expectedType) { - final exceptionLocal = addLocal(translator.topInfo.nonNullableType); - translateExpression(node.expression, translator.topInfo.nonNullableType); + final exceptionLocal = addLocal(translator.topTypeNonNullable); + translateExpression(node.expression, translator.topTypeNonNullable); b.local_set(exceptionLocal); - final stackTraceLocal = - addLocal(translator.stackTraceInfo.repr.nonNullableType); + final stackTraceLocal = addLocal(translator.stackTraceType); call(translator.stackTraceCurrent.reference); b.local_set(stackTraceLocal); @@ -1320,6 +1316,6 @@ abstract class StateMachineCodeGenerator extends AstCodeGenerator { /// Same as [_getVariable], but boxes the value if it's not already boxed. void _getVariableBoxed(VariableDeclaration variable) { final varType = _getVariable(variable); - translator.convertType(b, varType, translator.topInfo.nullableType); + translator.convertType(b, varType, translator.topType); } } diff --git a/pkg/dart2wasm/lib/sync_star.dart b/pkg/dart2wasm/lib/sync_star.dart index d5793929efd..05f62568c50 100644 --- a/pkg/dart2wasm/lib/sync_star.dart +++ b/pkg/dart2wasm/lib/sync_star.dart @@ -50,9 +50,8 @@ mixin SyncStarCodeGeneratorMixin on StateMachineEntryAstCodeGenerator { translator.moduleForReference(enclosingMember.reference).functions.define( translator.typesBuilder.defineFunction([ suspendStateInfo.nonNullableType, // _SuspendState - translator.topInfo.nullableType, // Object?, error value - translator.stackTraceInfo.repr - .nullableType // StackTrace?, error stack trace + translator.topType, // Object?, error value + translator.stackTraceTypeNullable // StackTrace?, error stack trace ], const [ // bool for whether the generator has more to do w.NumType.i32 @@ -235,7 +234,7 @@ class SyncStarStateMachineCodeGenerator extends StateMachineCodeGenerator { // `_yieldStarIterable` for `yield*`. b.local_get(_suspendStateLocal); b.struct_get(suspendStateInfo.struct, FieldIndex.suspendStateIterator); - translateExpression(node.expression, translator.topInfo.nullableType); + translateExpression(node.expression, translator.topType); if (node.isYieldStar) { b.ref_cast(translator.objectInfo.nonNullableType); b.struct_set(syncStarIteratorInfo.struct, diff --git a/pkg/dart2wasm/lib/tags.dart b/pkg/dart2wasm/lib/tags.dart index d7b189d45c4..84d99e529e2 100644 --- a/pkg/dart2wasm/lib/tags.dart +++ b/pkg/dart2wasm/lib/tags.dart @@ -25,10 +25,8 @@ class ExceptionTag { /// [stackTraceInfo.nonNullableType] to hold a stack trace. This single /// exception tag is used to throw and catch all Dart exceptions. w.Tag _defineExceptionTag() { - final w.FunctionType tagType = translator.typesBuilder.defineFunction([ - translator.topInfo.nonNullableType, - translator.stackTraceInfo.repr.nonNullableType - ], const []); + final w.FunctionType tagType = translator.typesBuilder.defineFunction( + [translator.topTypeNonNullable, translator.stackTraceType], const []); return translator.mainModule.tags.define(tagType); } } diff --git a/pkg/dart2wasm/lib/translator.dart b/pkg/dart2wasm/lib/translator.dart index 4bc002201c3..fdc8ab80a75 100644 --- a/pkg/dart2wasm/lib/translator.dart +++ b/pkg/dart2wasm/lib/translator.dart @@ -228,7 +228,6 @@ class Translator with KernelNodes { closureImplementations = {}; // Some convenience accessors for commonly used values. - late final ClassInfo topInfo = classes[0]; late final ClassInfo objectInfo = classInfo[coreTypes.objectClass]!; late final ClassInfo closureInfo = classInfo[closureClass]!; late final ClassInfo stackTraceInfo = classInfo[stackTraceClass]!; @@ -254,6 +253,37 @@ class Translator with KernelNodes { late final boxedDoubleType = boxedDoubleClass.getThisType(coreTypes, Nullability.nonNullable); + // The wasm type used to hold values of Dart top types + // (e.g. `Object?`, `dynamic`) + late final w.RefType topType = classes[0].nullableType; + + // The wasm type used to hold values of Dart top types excluding null + // (e.g. `Object`) + late final w.RefType topTypeNonNullable = topType.withNullability(false); + + // The wasm type used to hold values of `StackTrace` + late final w.RefType stackTraceType = + translateType(coreTypes.stackTraceNonNullableRawType) as w.RefType; + + // The wasm type used to hold values of `StackTrace?` + late final w.RefType stackTraceTypeNullable = + stackTraceType.withNullability(true); + + // The wasm type used to hold values of `Type` + late final w.RefType runtimeTypeType = + translateType(coreTypes.typeNonNullableRawType) as w.RefType; + + // The wasm type used to hold values of `Type?` + late final w.RefType runtimeTypeTypeNullable = + runtimeTypeType.withNullability(true); + + // The wasm type used to hold values of `String` + late final w.RefType stringType = + translateType(coreTypes.stringNonNullableRawType) as w.RefType; + + // The wasm type used to hold values of `String?` + late final w.RefType stringTypeNullable = stringType.withNullability(true); + final Map _partialInstantiators = {}; PartialInstantiator getPartialInstantiatorForModule(w.ModuleBuilder module) { return _partialInstantiators[module] ??= PartialInstantiator(this, module); @@ -340,14 +370,14 @@ class Translator with KernelNodes { // Named arguments, represented as array of symbol and object pairs nullableObjectArrayTypeRef, ], [ - topInfo.nullableType + topType, ]); /// Type of a dynamic invocation forwarder function. late final w.FunctionType dynamicInvocationForwarderFunctionType = typesBuilder.defineFunction([ // Receiver - topInfo.nonNullableType, + topTypeNonNullable, // Type arguments typeArrayTypeRef, @@ -358,28 +388,28 @@ class Translator with KernelNodes { // Named arguments, represented as array of symbol and object pairs nullableObjectArrayTypeRef, ], [ - topInfo.nullableType + topType, ]); /// Type of a dynamic get forwarder function. late final w.FunctionType dynamicGetForwarderFunctionType = typesBuilder.defineFunction([ // Receiver - topInfo.nonNullableType, + topTypeNonNullable, ], [ - topInfo.nullableType + topType, ]); /// Type of a dynamic set forwarder function. late final w.FunctionType dynamicSetForwarderFunctionType = typesBuilder.defineFunction([ // Receiver - topInfo.nonNullableType, + topTypeNonNullable, // Positional argument - topInfo.nullableType, + topType, ], [ - topInfo.nullableType + topType, ]); // Module predicates and helpers @@ -604,13 +634,14 @@ class Translator with KernelNodes { dynamicModuleInfo!.callOverridableDispatch(b, selector, interfaceTarget!, useUncheckedEntry: useUncheckedEntry); } else { - b.struct_get(topInfo.struct, FieldIndex.classId); final offset = selector.targets(unchecked: useUncheckedEntry).offset; if (offset == null) { b.unreachable(); return; } + final receiverType = selector.signature.inputs.first; + b.loadClassId(this, receiverType); if (offset != 0) { b.i32_const(offset); b.i32_add(); @@ -804,10 +835,10 @@ class Translator with KernelNodes { } // Regular class. - return classInfo[cls]!.repr.typeWithNullability(nullable); + return classInfo[cls]!.repr.withNullability(nullable); } if (type is DynamicType || type is VoidType) { - return topInfo.nullableType; + return topType; } if (type is NullType) { return const w.RefType.none(nullable: true); @@ -836,7 +867,7 @@ class Translator with KernelNodes { return translateStorageType(type.left); } if (type is FutureOrType) { - return topInfo.typeWithNullability(nullable); + return topType.withNullability(nullable); } if (type is FunctionType) { if (dynamicModuleSupportEnabled) { @@ -1406,10 +1437,7 @@ class Translator with KernelNodes { // Otherwise we use [boxClass] to represent `this`. cls = boxClass; } - final representationClassInfo = classInfo[cls]!.repr; - return nullable - ? representationClassInfo.nullableType - : representationClassInfo.nonNullableType; + return classInfo[cls]!.repr.withNullability(nullable); } /// Get the Wasm table declared by [field], or `null` if [field] is not a @@ -2074,8 +2102,7 @@ class _ClosureDynamicEntryGenerator implements CodeGenerator { b.local_get(typeArgsListLocal); b.i32_const(typeIdx); b.array_get(translator.typeArrayType); - translator.convertType( - b, translator.topInfo.nullableType, targetInputs[inputIdx]); + translator.convertType(b, translator.topType, targetInputs[inputIdx]); inputIdx += 1; } @@ -2092,17 +2119,16 @@ class _ClosureDynamicEntryGenerator implements CodeGenerator { b.local_get(posArgsListLocal); b.array_len(); b.i32_lt_u(); - b.if_([], [translator.topInfo.nullableType]); + b.if_([], [translator.topType]); b.local_get(posArgsListLocal); b.i32_const(posIdx); b.array_get(translator.nullableObjectArrayType); b.else_(); translator.constants.instantiateConstant( - b, paramInfo.positional[posIdx]!, translator.topInfo.nullableType); + b, paramInfo.positional[posIdx]!, translator.topType); b.end(); } - translator.convertType( - b, translator.topInfo.nullableType, targetInputs[inputIdx]); + translator.convertType(b, translator.topType, targetInputs[inputIdx]); inputIdx += 1; } @@ -2149,19 +2175,19 @@ class _ClosureDynamicEntryGenerator implements CodeGenerator { // Parameter may not be passed. b.local_get(namedArgValueIndexLocal); b.ref_is_null(); - b.if_([], [translator.topInfo.nullableType]); + b.if_([], [translator.topType]); if (functionNodeDefaultValue != null) { // Used by the member, has a default value translator.constants.instantiateConstant( b, (functionNodeDefaultValue as ConstantExpression).constant, - translator.topInfo.nullableType); + translator.topType); } else { // Not used by the member translator.constants.instantiateConstant( b, paramInfoDefaultValue!, - translator.topInfo.nullableType, + translator.topType, ); } b.else_(); // value index not null @@ -2171,8 +2197,7 @@ class _ClosureDynamicEntryGenerator implements CodeGenerator { b.i32_wrap_i64(); b.array_get(translator.nullableObjectArrayType); b.end(); - translator.convertType( - b, translator.topInfo.nullableType, targetInputs[inputIdx]); + translator.convertType(b, translator.topType, targetInputs[inputIdx]); } inputIdx += 1; } diff --git a/pkg/dart2wasm/lib/types.dart b/pkg/dart2wasm/lib/types.dart index 45f6e17ebda..404163a81bb 100644 --- a/pkg/dart2wasm/lib/types.dart +++ b/pkg/dart2wasm/lib/types.dart @@ -400,7 +400,7 @@ class Types { b.comment("type check against $testedAgainstType"); w.Local? operandTemp; if (translator.options.verifyTypeChecks) { - operandTemp = b.addLocal(translator.topInfo.nullableType); + operandTemp = b.addLocal(translator.topType); b.local_tee(operandTemp); } final checkOnlyNullAssignability = @@ -658,8 +658,8 @@ class IsCheckers extends _TypeCheckers { return cache.putIfAbsent(testedAgainstType, () { final typeType = translator.translateType(translator.typeType); final argumentType = operandIsNullable - ? translator.topInfo.nullableType - : translator.topInfo.nonNullableType; + ? translator.topType + : translator.topTypeNonNullable; final signature = w.FunctionType( [argumentType, for (int i = 0; i < argumentCount; ++i) typeType], [w.NumType.i32]); @@ -701,8 +701,8 @@ class AsCheckers extends _TypeCheckers { return cache.putIfAbsent(testedAgainstType, () { final returnType = translator.translateType(testedAgainstType); final argumentType = operandIsNullable - ? translator.topInfo.nullableType - : translator.topInfo.nonNullableType; + ? translator.topType + : translator.topTypeNonNullable; final typeType = translator.translateType(translator.typeType); final signature = w.FunctionType( [argumentType, for (int i = 0; i < argumentCount; ++i) typeType], @@ -812,7 +812,7 @@ class IsCheckerCodeGenerator implements CodeGenerator { w.Label nullLabel = b.block(const [], const []); b.local_get(operand); b.br_on_null(nullLabel); - final nonNullableOperand = b.addLocal(translator.topInfo.nonNullableType); + final nonNullableOperand = b.addLocal(translator.topTypeNonNullable); b.local_get(operand); b.ref_cast(nonNullableOperand.type as w.RefType); b.local_set(nonNullableOperand); @@ -885,7 +885,7 @@ class IsCheckerCodeGenerator implements CodeGenerator { final ranges = translator.classIdNumbering .getConcreteClassIdRangeForClass(interfaceClass); b.local_get(operand); - b.struct_get(translator.topInfo.struct, FieldIndex.classId); + b.loadClassId(translator, operand.type); if (translator.isDynamicSubmodule) { // Only types that are not dynamic module extendable can get here. final classIdLocal = b.addLocal(w.NumType.i32); @@ -1054,7 +1054,7 @@ class AsCheckerCodeGenerator implements CodeGenerator { } b.unreachable(); - b.end(); + b.end(); // asCheckBlock b.local_get(b.locals[0]); translator.convertType(b, signature.inputs.first, signature.outputs.single); diff --git a/sdk/lib/_internal/wasm/lib/class_id.dart b/sdk/lib/_internal/wasm/lib/class_id.dart index d29b8205e94..7ecfdd9d51f 100644 --- a/sdk/lib/_internal/wasm/lib/class_id.dart +++ b/sdk/lib/_internal/wasm/lib/class_id.dart @@ -7,7 +7,7 @@ part of "internal_patch.dart"; @pragma("wasm:entry-point") class ClassID { @pragma("wasm:intrinsic") - external static WasmI32 getID(Object? value); + external static WasmI32 getID(Object value); @pragma("wasm:class-id", "dart.typed_data#_ExternalUint8Array") external static WasmI32 get cidExternalUint8Array;