diff --git a/pkg/dart2wasm/lib/closures.dart b/pkg/dart2wasm/lib/closures.dart index 039ede5af40..499a98c3c78 100644 --- a/pkg/dart2wasm/lib/closures.dart +++ b/pkg/dart2wasm/lib/closures.dart @@ -664,7 +664,7 @@ class ClosureLayouter extends RecursiveVisitor { b.local_get(preciseClosure); b.struct_get(genericClosureStruct, FieldIndex.closureRuntimeType); - // Put type arguments into a `WasmObjectArray<_Type>`. + // Put type arguments into a `WasmArray<_Type>`. for (int i = 0; i < typeCount; i++) { b.local_get(typeParam(i)); } diff --git a/pkg/dart2wasm/lib/constants.dart b/pkg/dart2wasm/lib/constants.dart index de6f34a3681..cd06d965c26 100644 --- a/pkg/dart2wasm/lib/constants.dart +++ b/pkg/dart2wasm/lib/constants.dart @@ -62,7 +62,7 @@ class Constants { ListConstant makeTypeList(Iterable types) => ListConstant( translator.typeType, types.map((t) => TypeLiteralConstant(t)).toList()); - /// Makes a `WasmObjectArray<_Type>` [InstanceConstant]. + /// Makes a `WasmArray<_Type>` [InstanceConstant]. InstanceConstant makeTypeArray(Iterable types) => makeArrayOf( translator.typeType, types.map((t) => TypeLiteralConstant(t)).toList()); @@ -77,29 +77,19 @@ class Constants { BoolConstant(n.isRequired), }); - /// Creates a `WasmObjectArray<_NamedParameter>` to be used as field of + /// Creates a `WasmArray<_NamedParameter>` to be used as field of /// `_FunctionType`. InstanceConstant makeNamedParametersArray(FunctionType type) => makeArrayOf( translator.namedParameterType, [for (final n in type.namedParameters) makeNamedParameterConstant(n)]); - /// Creates a `WasmObjectArray` with the given [Constant]s + /// Creates a `WasmArray` with the given [Constant]s InstanceConstant makeArrayOf( InterfaceType elementType, List entries) => - InstanceConstant(translator.wasmObjectArrayClass.reference, [ + InstanceConstant(translator.wasmArrayClass.reference, [ elementType, ], { - translator.wasmObjectArrayValueField.fieldReference: - ListConstant(elementType, entries), - }); - - /// Creates a `WasmIntArray` with the given [Constant]s - InstanceConstant makeIntArrayOf( - InterfaceType elementType, List entries) => - InstanceConstant(translator.wasmIntArrayClass.reference, [ - elementType, - ], { - translator.wasmIntArrayValueField.fieldReference: + translator.wasmArrayValueField.fieldReference: ListConstant(elementType, entries), }); @@ -393,10 +383,7 @@ class ConstantCreator extends ConstantVisitor @override ConstantInfo? visitInstanceConstant(InstanceConstant constant) { Class cls = constant.classNode; - if (cls == translator.wasmObjectArrayClass) { - return _makeWasmArrayLiteral(constant); - } - if (cls == translator.wasmIntArrayClass) { + if (cls == translator.wasmArrayClass) { return _makeWasmArrayLiteral(constant); } diff --git a/pkg/dart2wasm/lib/intrinsics.dart b/pkg/dart2wasm/lib/intrinsics.dart index 33448d56775..6baa2f5aa12 100644 --- a/pkg/dart2wasm/lib/intrinsics.dart +++ b/pkg/dart2wasm/lib/intrinsics.dart @@ -224,125 +224,9 @@ class Intrinsifier { return translator.topInfo.nonNullableType; } - // WasmIntArray.(readSigned|readUnsigned|write) - // WasmFloatArray.(read|write) - // WasmObjectArray.(read|write) - if (cls.superclass == translator.wasmArrayRefClass) { - DartType elementType = - (receiverType as InterfaceType).typeArguments.single; - w.ArrayType arrayType = translator.arrayTypeForDartType(elementType); - w.StorageType wasmType = arrayType.elementType.type; - bool innerExtend = - wasmType == w.PackedType.i8 || wasmType == w.PackedType.i16; - bool outerExtend = - wasmType.unpacked == w.NumType.i32 || wasmType == w.NumType.f32; - switch (name) { - case 'read': - case 'readSigned': - case 'readUnsigned': - bool unsigned = name == 'readUnsigned'; - Expression array = receiver; - Expression index = node.arguments.positional.single; - codeGen.wrap(array, w.RefType.def(arrayType, nullable: false)); - codeGen.wrap(index, w.NumType.i64); - b.i32_wrap_i64(); - if (innerExtend) { - if (unsigned) { - b.array_get_u(arrayType); - } else { - b.array_get_s(arrayType); - } - } else { - b.array_get(arrayType); - } - if (outerExtend) { - if (wasmType == w.NumType.f32) { - b.f64_promote_f32(); - return w.NumType.f64; - } else { - if (unsigned) { - b.i64_extend_i32_u(); - } else { - b.i64_extend_i32_s(); - } - return w.NumType.i64; - } - } - return wasmType.unpacked; - case 'write': - Expression array = receiver; - Expression index = node.arguments.positional[0]; - Expression value = node.arguments.positional[1]; - codeGen.wrap(array, w.RefType.def(arrayType, nullable: false)); - codeGen.wrap(index, w.NumType.i64); - b.i32_wrap_i64(); - codeGen.wrap(value, typeOfExp(value)); - if (outerExtend) { - if (wasmType == w.NumType.f32) { - b.f32_demote_f64(); - } else { - b.i32_wrap_i64(); - } - } - b.array_set(arrayType); - return codeGen.voidMarker; - } - } - - // WasmIntArray.copy - // WasmFloatArray.copy - // WasmObjectArray.copy - if (cls.superclass == translator.wasmArrayRefClass && name == 'copy') { - final DartType elementType = - (receiverType as InterfaceType).typeArguments.single; - final w.ArrayType arrayType = - translator.arrayTypeForDartType(elementType); - - final Expression destArray = receiver; - final Expression destOffset = node.arguments.positional[0]; - final Expression sourceArray = node.arguments.positional[1]; - final Expression sourceOffset = node.arguments.positional[2]; - final Expression size = node.arguments.positional[3]; - - codeGen.wrap(destArray, w.RefType.def(arrayType, nullable: false)); - codeGen.wrap(destOffset, w.NumType.i64); - b.i32_wrap_i64(); - codeGen.wrap(sourceArray, w.RefType.def(arrayType, nullable: false)); - codeGen.wrap(sourceOffset, w.NumType.i64); - b.i32_wrap_i64(); - codeGen.wrap(size, w.NumType.i64); - b.i32_wrap_i64(); - b.array_copy(arrayType, arrayType); - return codeGen.voidMarker; - } - - // WasmIntArray.fill - // WasmFloatArray.fill - // WasmObjectArray.fill - if (cls.superclass == translator.wasmArrayRefClass && name == 'fill') { - final DartType elementType = - (receiverType as InterfaceType).typeArguments.single; - final w.ArrayType arrayType = - translator.arrayTypeForDartType(elementType); - - final Expression array = receiver; - final Expression offset = node.arguments.positional[0]; - final Expression value = node.arguments.positional[1]; - final Expression size = node.arguments.positional[2]; - - codeGen.wrap(array, w.RefType.def(arrayType, nullable: false)); - codeGen.wrap(offset, w.NumType.i64); - b.i32_wrap_i64(); - codeGen.wrap(value, translator.translateType(elementType)); - codeGen.wrap(size, w.NumType.i64); - b.i32_wrap_i64(); - b.array_fill(arrayType); - return codeGen.voidMarker; - } - // Wasm(I32|I64|F32|F64) conversions - if (cls.superclass?.superclass == translator.wasmTypesBaseClass) { - w.StorageType receiverType = translator.builtinTypes[cls]!; + if (cls.superclass == translator.wasmTypesBaseClass) { + w.StorageType? receiverType = translator.builtinTypes[cls]; switch (receiverType) { case w.NumType.i32: codeGen.wrap(receiver, w.NumType.i32); @@ -572,7 +456,152 @@ class Intrinsifier { /// intrinsic. w.ValueType? generateStaticIntrinsic(StaticInvocation node) { String name = node.name.text; - Class? cls = node.target.enclosingClass; + final Procedure target = node.target; + final Library library = target.enclosingLibrary; + Class? cls = target.enclosingClass; + + if (target.isExtensionMember && library == translator.wasmLibrary) { + final (ext, extDescriptor) = translator.extensionOfMember(target); + final memberName = extDescriptor.name.text; + + // extension WasmArrayExt on WasmArray + if (ext.name == 'WasmArrayExt') { + final dartWasmArrayType = dartTypeOf(node.arguments.positional.first); + final dartElementType = + (dartWasmArrayType as InterfaceType).typeArguments.single; + w.ArrayType arrayType = + translator.arrayTypeForDartType(dartElementType); + w.StorageType wasmType = arrayType.elementType.type; + + switch (memberName) { + case '[]': + final array = node.arguments.positional[0]; + final index = node.arguments.positional[1]; + codeGen.wrap(array, w.RefType.def(arrayType, nullable: false)); + codeGen.wrap(index, w.NumType.i64); + b.i32_wrap_i64(); + if (wasmType is w.PackedType) { + b.array_get_u(arrayType); + } else { + b.array_get(arrayType); + } + return wasmType.unpacked; + case '[]=': + final array = node.arguments.positional[0]; + final index = node.arguments.positional[1]; + final value = node.arguments.positional[2]; + codeGen.wrap(array, w.RefType.def(arrayType, nullable: false)); + codeGen.wrap(index, w.NumType.i64); + b.i32_wrap_i64(); + codeGen.wrap(value, typeOfExp(value)); + b.array_set(arrayType); + return codeGen.voidMarker; + case 'copy': + final destArray = node.arguments.positional[0]; + final destOffset = node.arguments.positional[1]; + final sourceArray = node.arguments.positional[2]; + final sourceOffset = node.arguments.positional[3]; + final size = node.arguments.positional[4]; + + codeGen.wrap(destArray, w.RefType.def(arrayType, nullable: false)); + codeGen.wrap(destOffset, w.NumType.i64); + b.i32_wrap_i64(); + codeGen.wrap( + sourceArray, w.RefType.def(arrayType, nullable: false)); + codeGen.wrap(sourceOffset, w.NumType.i64); + b.i32_wrap_i64(); + codeGen.wrap(size, w.NumType.i64); + b.i32_wrap_i64(); + b.array_copy(arrayType, arrayType); + return codeGen.voidMarker; + case 'fill': + final array = node.arguments.positional[0]; + final offset = node.arguments.positional[1]; + final value = node.arguments.positional[2]; + final size = node.arguments.positional[3]; + + codeGen.wrap(array, w.RefType.def(arrayType, nullable: false)); + codeGen.wrap(offset, w.NumType.i64); + b.i32_wrap_i64(); + codeGen.wrap(value, translator.translateType(dartElementType)); + codeGen.wrap(size, w.NumType.i64); + b.i32_wrap_i64(); + b.array_fill(arrayType); + return codeGen.voidMarker; + default: + throw 'unknown'; + } + } + + // extension (I8|I16|I32|I64|F32|F64)ArrayExt on WasmArray<...> + if (ext.name.endsWith('ArrayExt')) { + final dartWasmArrayType = dartTypeOf(node.arguments.positional.first); + final dartElementType = + (dartWasmArrayType as InterfaceType).typeArguments.single; + w.ArrayType arrayType = + translator.arrayTypeForDartType(dartElementType); + w.StorageType wasmType = arrayType.elementType.type; + + final innerExtend = + wasmType == w.PackedType.i8 || wasmType == w.PackedType.i16; + final outerExtend = + wasmType.unpacked == w.NumType.i32 || wasmType == w.NumType.f32; + + // WasmArray.(readSigned|readUnsigned|write) + // WasmArray.(read|write) + switch (memberName) { + case 'read': + case 'readSigned': + case 'readUnsigned': + final unsigned = memberName == 'readUnsigned'; + final array = node.arguments.positional[0]; + final index = node.arguments.positional[1]; + codeGen.wrap(array, w.RefType.def(arrayType, nullable: false)); + codeGen.wrap(index, w.NumType.i64); + b.i32_wrap_i64(); + if (innerExtend) { + if (unsigned) { + b.array_get_u(arrayType); + } else { + b.array_get_s(arrayType); + } + } else { + b.array_get(arrayType); + } + if (outerExtend) { + if (wasmType == w.NumType.f32) { + b.f64_promote_f32(); + return w.NumType.f64; + } else { + if (unsigned) { + b.i64_extend_i32_u(); + } else { + b.i64_extend_i32_s(); + } + return w.NumType.i64; + } + } + return wasmType.unpacked; + case 'write': + final array = node.arguments.positional[0]; + final index = node.arguments.positional[1]; + final value = node.arguments.positional[2]; + codeGen.wrap(array, w.RefType.def(arrayType, nullable: false)); + codeGen.wrap(index, w.NumType.i64); + b.i32_wrap_i64(); + codeGen.wrap(value, typeOfExp(value)); + if (outerExtend) { + if (wasmType == w.NumType.f32) { + b.f32_demote_f64(); + } else { + b.i32_wrap_i64(); + } + } + b.array_set(arrayType); + return codeGen.voidMarker; + } + } + } // dart:core static functions if (node.target.enclosingLibrary == translator.coreTypes.coreLibrary) { @@ -817,18 +846,24 @@ class Intrinsifier { } if (cls != null && translator.isWasmType(cls)) { - // Wasm(Int|Float|Object)Array constructors - if (cls.superclass == translator.wasmArrayRefClass) { - Expression length = node.arguments.positional[0]; + // WasmArray constructors + if (cls == translator.wasmArrayClass) { + final dartElementType = node.arguments.types.single; w.ArrayType arrayType = - translator.arrayTypeForDartType(node.arguments.types.single); + translator.arrayTypeForDartType(dartElementType); + final elementType = arrayType.elementType.type; + final isDefaultable = elementType is! w.RefType || elementType.nullable; + if (!isDefaultable && node.arguments.positional.length == 1) { + throw 'The element type $dartElementType does not have a default value' + '- please use WasmArray<$dartElementType>.filled() instead.'; + } + + Expression length = node.arguments.positional[0]; codeGen.wrap(length, w.NumType.i64); b.i32_wrap_i64(); if (node.arguments.positional.length < 2) { - // WasmIntArray or WasmFloatArray b.array_new_default(arrayType); } else { - // WasmObjectArray Expression initialValue = node.arguments.positional[1]; if (initialValue is NullLiteral || initialValue is ConstantExpression && @@ -994,11 +1029,9 @@ class Intrinsifier { w.ValueType? generateConstructorIntrinsic(ConstructorInvocation node) { String name = node.name.text; - // WasmObjectArray.literal & WasmIntArray.literal + // WasmArray.literal final klass = node.target.enclosingClass; - if ((klass == translator.wasmObjectArrayClass || - klass == translator.wasmIntArrayClass) && - name == "literal") { + if (klass == translator.wasmArrayClass && name == "literal") { w.ArrayType arrayType = translator.arrayTypeForDartType(node.arguments.types.single); w.ValueType elementType = arrayType.elementType.type.unpacked; @@ -1010,7 +1043,7 @@ class Intrinsifier { .entries .map(ConstantExpression.new) .toList() - : throw "WasmObjectArray.literal argument is not a list literal" + : throw "WasmArray.literal argument is not a list literal" " at ${value.location}"; for (Expression element in elements) { codeGen.wrap(element, elementType); diff --git a/pkg/dart2wasm/lib/kernel_nodes.dart b/pkg/dart2wasm/lib/kernel_nodes.dart index 242d7e9c476..a69aa024ced 100644 --- a/pkg/dart2wasm/lib/kernel_nodes.dart +++ b/pkg/dart2wasm/lib/kernel_nodes.dart @@ -127,6 +127,7 @@ mixin KernelNodes { late final Class ffiPointerClass = index.getClass("dart:ffi", "Pointer"); // dart:_wasm classes + late final Library wasmLibrary = index.getLibrary("dart:_wasm"); late final Class wasmTypesBaseClass = index.getClass("dart:_wasm", "_WasmBase"); late final wasmI8Class = index.getClass("dart:_wasm", "WasmI8"); @@ -149,14 +150,9 @@ mixin KernelNodes { index.getClass("dart:_wasm", "WasmFunction"); late final Class wasmVoidClass = index.getClass("dart:_wasm", "WasmVoid"); late final Class wasmTableClass = index.getClass("dart:_wasm", "WasmTable"); - late final Class wasmObjectArrayClass = - index.getClass("dart:_wasm", "WasmObjectArray"); - late final Field wasmObjectArrayValueField = - index.getField("dart:_wasm", "WasmObjectArray", "_value"); - late final Class wasmIntArrayClass = - index.getClass("dart:_wasm", "WasmIntArray"); - late final Field wasmIntArrayValueField = - index.getField("dart:_wasm", "WasmIntArray", "_value"); + late final Class wasmArrayClass = index.getClass("dart:_wasm", "WasmArray"); + late final Field wasmArrayValueField = + index.getField("dart:_wasm", "WasmArray", "_value"); // dart:_internal procedures late final Procedure loadLibrary = @@ -294,4 +290,23 @@ mixin KernelNodes { // Debugging late final Procedure printToConsole = index.getTopLevelProcedure("dart:_internal", "printToConsole"); + + late final Map + _extensionCache = {}; + + (Extension, ExtensionMemberDescriptor) extensionOfMember(Member member) { + return _extensionCache.putIfAbsent(member, () { + assert(member.isExtensionMember); + + final memberRef = member.reference; + for (final ext in member.enclosingLibrary.extensions) { + for (final descriptor in ext.memberDescriptors) { + if (memberRef == descriptor.memberReference) { + return (ext, descriptor); + } + } + } + throw 'Did not find extension for $member'; + }); + } } diff --git a/pkg/dart2wasm/lib/transformers.dart b/pkg/dart2wasm/lib/transformers.dart index d219a092857..48baeac72b9 100644 --- a/pkg/dart2wasm/lib/transformers.dart +++ b/pkg/dart2wasm/lib/transformers.dart @@ -33,7 +33,7 @@ class _WasmTransformer extends Transformer { final Library _coreLibrary; final InterfaceType _nonNullableTypeType; final Class _wasmBaseClass; - final Class _wasmObjectArrayClass; + final Class _wasmArrayClass; final List<_AsyncStarFrame> _asyncStarFrames = []; bool _enclosingIsAsyncStar = false; late final controllerNullableObjectType = InterfaceType( @@ -59,8 +59,7 @@ class _WasmTransformer extends Transformer { .getClass('dart:core', '_Type') .getThisType(coreTypes, Nullability.nonNullable), _wasmBaseClass = coreTypes.index.getClass('dart:_wasm', '_WasmBase'), - _wasmObjectArrayClass = - coreTypes.index.getClass('dart:_wasm', 'WasmObjectArray'), + _wasmArrayClass = coreTypes.index.getClass('dart:_wasm', 'WasmArray'), _coreLibrary = coreTypes.index.getLibrary('dart:core'), _listFactorySpecializer = ListFactorySpecializer(coreTypes); @@ -125,8 +124,8 @@ class _WasmTransformer extends Transformer { ProcedureKind.Getter, FunctionNode( null, - returnType: InterfaceType(_wasmObjectArrayClass, - Nullability.nonNullable, [_nonNullableTypeType]), + returnType: InterfaceType(_wasmArrayClass, Nullability.nonNullable, + [_nonNullableTypeType]), ), isExternal: true, isSynthetic: true, diff --git a/pkg/dart2wasm/lib/translator.dart b/pkg/dart2wasm/lib/translator.dart index 2dc2ad429e1..d73dc8dd888 100644 --- a/pkg/dart2wasm/lib/translator.dart +++ b/pkg/dart2wasm/lib/translator.dart @@ -481,7 +481,13 @@ class Translator with KernelNodes { w.ValueType translateType(DartType type) { w.StorageType wasmType = translateStorageType(type); if (wasmType is w.ValueType) return wasmType; - throw "Packed types are only allowed in arrays and fields"; + + // We represent the packed i8/i16 types as zero-extended i32 type. + // Dart code can currently only obtain them via loading from packed arrays + // and only use them for storing into packed arrays (there are no + // conversion or other operations on WasmI8/WasmI16). + if (wasmType is w.PackedType) return w.NumType.i32; + throw "Cannot translate $type to wasm type."; } bool _hasSuperclass(Class cls, Class superclass) { diff --git a/pkg/dart2wasm/lib/types.dart b/pkg/dart2wasm/lib/types.dart index d34fc684268..b27c8dda0ea 100644 --- a/pkg/dart2wasm/lib/types.dart +++ b/pkg/dart2wasm/lib/types.dart @@ -60,15 +60,15 @@ class Types { late final w.ValueType typeListExpectedType = translator.classInfo[translator.listBaseClass]!.nonNullableType; - /// Wasm array type of `WasmObjectArray<_Type>` + /// Wasm array type of `WasmArray<_Type>` late final w.ArrayType typeArrayArrayType = translator.arrayTypeForDartType(typeType); - /// Wasm value type of `WasmObjectArray<_Type>` + /// Wasm value type of `WasmArray<_Type>` late final w.ValueType typeArrayExpectedType = w.RefType.def(typeArrayArrayType, nullable: false); - /// Wasm value type of `WasmObjectArray<_NamedParameter>` + /// Wasm value type of `WasmArray<_NamedParameter>` late final w.ValueType namedParametersExpectedType = classAndFieldToType( translator.functionTypeClass, FieldIndex.functionTypeNamedParameters); @@ -229,19 +229,17 @@ class Types { final supersOfClasses = []; for (List supers in typeRulesSupers) { - supersOfClasses.add(translator.constants.makeIntArrayOf( + supersOfClasses.add(translator.constants.makeArrayOf( wasmI32Type, [for (final cid in supers) IntConstant(cid)])); } final arrayOfWasmI32Type = InterfaceType( - translator.wasmIntArrayClass, Nullability.nonNullable, [wasmI32Type]); + translator.wasmArrayClass, Nullability.nonNullable, [wasmI32Type]); final typeRuleSupers = translator.constants.makeArrayOf(arrayOfWasmI32Type, supersOfClasses); - final arrayOfArrayOfWasmI32Type = InterfaceType( - translator.wasmObjectArrayClass, - Nullability.nonNullable, - [arrayOfWasmI32Type]); + final arrayOfArrayOfWasmI32Type = InterfaceType(translator.wasmArrayClass, + Nullability.nonNullable, [arrayOfWasmI32Type]); final typeRulesSupersType = translator.translateStorageType(arrayOfArrayOfWasmI32Type).unpacked; @@ -257,13 +255,11 @@ class Types { final typeType = InterfaceType(translator.typeClass, Nullability.nonNullable); final arrayOfType = InterfaceType( - translator.wasmObjectArrayClass, Nullability.nonNullable, [typeType]); - final arrayOfArrayOfType = InterfaceType(translator.wasmObjectArrayClass, - Nullability.nonNullable, [arrayOfType]); - final arrayOfArrayOfArrayOfType = InterfaceType( - translator.wasmObjectArrayClass, - Nullability.nonNullable, - [arrayOfArrayOfType]); + translator.wasmArrayClass, Nullability.nonNullable, [typeType]); + final arrayOfArrayOfType = InterfaceType( + translator.wasmArrayClass, Nullability.nonNullable, [arrayOfType]); + final arrayOfArrayOfArrayOfType = InterfaceType(translator.wasmArrayClass, + Nullability.nonNullable, [arrayOfArrayOfType]); final substitutionsConstantL0 = []; for (List> substitutionsL1 in typeRulesSubstitutions) { @@ -292,7 +288,7 @@ class Types { final stringType = translator.coreTypes.stringRawType(Nullability.nonNullable); final arrayOfStringType = InterfaceType( - translator.wasmObjectArrayClass, Nullability.nonNullable, [stringType]); + translator.wasmArrayClass, Nullability.nonNullable, [stringType]); final arrayOfStrings = translator.constants.makeArrayOf( stringType, [for (final name in typeNames) StringConstant(name)]); @@ -433,7 +429,7 @@ class Types { } } - /// Allocates a `WasmObjectArray<_Type>` from [types] and pushes it to the + /// Allocates a `WasmArray<_Type>` from [types] and pushes it to the /// stack. void _makeTypeArray(CodeGenerator codeGen, Iterable types) { if (types.every(_isTypeConstant)) { @@ -520,22 +516,22 @@ class Types { b.i32_const(encodedNullability(type)); b.i64_const(typeParameterOffset); - // WasmObjectArray<_Type> typeParameterBounds + // WasmArray<_Type> typeParameterBounds _makeTypeArray(codeGen, type.typeParameters.map((p) => p.bound)); - // WasmObjectArray<_Type> typeParameterDefaults + // WasmArray<_Type> typeParameterDefaults _makeTypeArray(codeGen, type.typeParameters.map((p) => p.defaultType)); // _Type returnType makeType(codeGen, type.returnType); - // WasmObjectArray<_Type> positionalParameters + // WasmArray<_Type> positionalParameters _makeTypeArray(codeGen, type.positionalParameters); // int requiredParameterCount b.i64_const(type.requiredParameterCount); - // WasmObjectArray<_NamedParameter> namedParameters + // WasmArray<_NamedParameter> namedParameters if (type.namedParameters.every((n) => _isTypeConstant(n.type))) { translator.constants.instantiateConstant( codeGen.function, diff --git a/pkg/dart2wasm/pubspec.yaml b/pkg/dart2wasm/pubspec.yaml index 108cc6e8f79..bb198747d30 100644 --- a/pkg/dart2wasm/pubspec.yaml +++ b/pkg/dart2wasm/pubspec.yaml @@ -2,7 +2,7 @@ name: dart2wasm # This package is not intended for consumption on pub.dev. DO NOT publish. publish_to: none environment: - sdk: '>=2.17.0' + sdk: '>=3.1.0' # Use 'any' constraints here; we get our versions from the DEPS file. dependencies: diff --git a/sdk/lib/_internal/wasm/lib/convert_patch.dart b/sdk/lib/_internal/wasm/lib/convert_patch.dart index 58ffa999d6d..5a49ca8be2a 100644 --- a/sdk/lib/_internal/wasm/lib/convert_patch.dart +++ b/sdk/lib/_internal/wasm/lib/convert_patch.dart @@ -7,6 +7,7 @@ import "dart:_js_string_convert"; import "dart:_js_types"; import "dart:_string"; import "dart:_typed_data"; +import "dart:_wasm"; import "dart:typed_data" show Uint8List, Uint16List; /// This patch library has no additional parts. diff --git a/sdk/lib/_internal/wasm/lib/growable_list.dart b/sdk/lib/_internal/wasm/lib/growable_list.dart index 7daa2462eda..513c1ef47e5 100644 --- a/sdk/lib/_internal/wasm/lib/growable_list.dart +++ b/sdk/lib/_internal/wasm/lib/growable_list.dart @@ -8,7 +8,7 @@ part of "core_patch.dart"; class _GrowableList extends _ModifiableList { _GrowableList._(int length, int capacity) : super(length, capacity); - _GrowableList._withData(WasmObjectArray data) + _GrowableList._withData(WasmArray data) : super._withData(data.length, data); factory _GrowableList(int length) { @@ -38,7 +38,7 @@ class _GrowableList extends _ModifiableList { factory _GrowableList.generate(int length, E generator(int index)) { final result = _GrowableList(length); for (int i = 0; i < result.length; ++i) { - result._data.write(i, generator(i)); + result._data[i] = generator(i); } return result; } @@ -92,9 +92,9 @@ class _GrowableList extends _ModifiableList { throw RangeError.range(index, 0, length); } - final WasmObjectArray data; + final WasmArray data; if (length == _capacity) { - data = WasmObjectArray(_nextCapacity(_capacity), null); + data = WasmArray(_nextCapacity(_capacity)); if (index != 0) { // Copy elements before the insertion point. data.copy(0, _data, 0, index - 1); @@ -108,7 +108,7 @@ class _GrowableList extends _ModifiableList { data.copy(index + 1, _data, index, length - index); // Insert new element. - data.write(index, element); + data[index] = element; _data = data; _length += 1; @@ -129,7 +129,7 @@ class _GrowableList extends _ModifiableList { bool remove(Object? element) { for (int i = 0; i < this.length; i++) { - if (_data.read(i) == element) { + if (_data[i] == element) { removeAt(i); return true; } @@ -204,7 +204,7 @@ class _GrowableList extends _ModifiableList { _growToNextCapacity(); } _setLength(len + 1); - _data.write(len, value); + _data[len] = value; } void addAll(Iterable iterable) { @@ -233,7 +233,7 @@ class _GrowableList extends _ModifiableList { while (len < _capacity) { int newLen = len + 1; this._setLength(newLen); - _data.write(len, it.current); + _data[len] = it.current; if (!it.moveNext()) return; if (this.length != newLen) throw ConcurrentModificationError(this); len = newLen; @@ -250,10 +250,9 @@ class _GrowableList extends _ModifiableList { } // Shared array used as backing for new empty growable lists. - static final WasmObjectArray _emptyData = - WasmObjectArray(0, null); + static final WasmArray _emptyData = WasmArray(0); - static WasmObjectArray _allocateData(int capacity) { + static WasmArray _allocateData(int capacity) { if (capacity < 0) { throw RangeError.range(capacity, 0, _maxWasmArrayLength); } @@ -261,14 +260,14 @@ class _GrowableList extends _ModifiableList { // Use shared empty list as backing. return _emptyData; } - return WasmObjectArray(capacity, null); + return WasmArray(capacity); } // Grow from 0 to 3, and then double + 1. int _nextCapacity(int old_capacity) => (old_capacity * 2) | 3; void _grow(int new_capacity) { - var newData = WasmObjectArray(new_capacity, null); + var newData = WasmArray(new_capacity); newData.copy(0, _data, 0, length); _data = newData; } @@ -310,7 +309,7 @@ class _GrowableListIterator implements Iterator { _current = null; return false; } - _current = unsafeCast(_list._data.read(_index)); + _current = unsafeCast(_list._data[_index]); _index++; return true; } diff --git a/sdk/lib/_internal/wasm/lib/list.dart b/sdk/lib/_internal/wasm/lib/list.dart index 6b6009a2ddd..1394fd88a83 100644 --- a/sdk/lib/_internal/wasm/lib/list.dart +++ b/sdk/lib/_internal/wasm/lib/list.dart @@ -12,13 +12,12 @@ abstract class _ListBase extends ListBase { int _length; @pragma("wasm:entry-point") - WasmObjectArray _data; + WasmArray _data; _ListBase(int length, int capacity) : _length = length, - _data = WasmObjectArray( - RangeError.checkValueInInterval(capacity, 0, _maxWasmArrayLength), - null); + _data = WasmArray( + RangeError.checkValueInInterval(capacity, 0, _maxWasmArrayLength)); _ListBase._withData(this._length, this._data); @@ -26,7 +25,7 @@ abstract class _ListBase extends ListBase { if (WasmI64.fromInt(_length).leU(WasmI64.fromInt(index))) { throw IndexError.withLength(index, length, name: "[]"); } - return unsafeCast(_data.read(index)); + return unsafeCast(_data[index]); } int get length => _length; @@ -42,7 +41,7 @@ abstract class _ListBase extends ListBase { void forEach(f(E element)) { final initialLength = length; for (int i = 0; i < initialLength; i++) { - f(unsafeCast(_data.read(i))); + f(unsafeCast(_data[i])); if (length != initialLength) throw ConcurrentModificationError(this); } } @@ -56,14 +55,14 @@ abstract class _ListBase extends ListBase { abstract class _ModifiableList extends _ListBase { _ModifiableList(int length, int capacity) : super(length, capacity); - _ModifiableList._withData(int length, WasmObjectArray data) + _ModifiableList._withData(int length, WasmArray data) : super._withData(length, data); void operator []=(int index, E value) { if (WasmI64.fromInt(_length).leU(WasmI64.fromInt(index))) { throw IndexError.withLength(index, length, name: "[]="); } - _data.write(index, value); + _data[index] = value; } // List interface. @@ -84,7 +83,7 @@ abstract class _ModifiableList extends _ListBase { } for (int i = start; i < end; i++) { if (!it.moveNext()) return; - _data.write(i, it.current); + _data[i] = it.current; } } } @@ -137,7 +136,7 @@ class _List extends _ModifiableList with FixedLengthListMixin { factory _List.generate(int length, E generator(int index)) { final result = _List(length); for (int i = 0; i < result.length; ++i) { - result._data.write(i, generator(i)); + result._data[i] = generator(i); } return result; } @@ -201,7 +200,7 @@ class _ImmutableList extends _ListBase with UnmodifiableListMixin { // Iterator for lists with fixed size. class _FixedSizeListIterator implements Iterator { - final WasmObjectArray _data; + final WasmArray _data; final int _length; // Cache list length for faster access. int _index; E? _current; @@ -220,7 +219,7 @@ class _FixedSizeListIterator implements Iterator { _current = null; return false; } - _current = unsafeCast(_data.read(_index)); + _current = unsafeCast(_data[_index]); _index++; return true; } diff --git a/sdk/lib/_internal/wasm/lib/object_patch.dart b/sdk/lib/_internal/wasm/lib/object_patch.dart index 636811f93b2..1deb40d06ea 100644 --- a/sdk/lib/_internal/wasm/lib/object_patch.dart +++ b/sdk/lib/_internal/wasm/lib/object_patch.dart @@ -31,14 +31,13 @@ class Object { /// Concrete subclasses of [Object] will have overrides of [_typeArguments] /// which return their type arguments. - WasmObjectArray<_Type> get _typeArguments => - const WasmObjectArray<_Type>.literal([]); + WasmArray<_Type> get _typeArguments => const WasmArray<_Type>.literal([]); // An instance member needs a call from Dart code to be properly included in // the dispatch table. Hence we use an inlined static wrapper as entry point. @pragma("wasm:entry-point") @pragma("wasm:prefer-inline") - static WasmObjectArray<_Type> _getTypeArguments(Object object) => + static WasmArray<_Type> _getTypeArguments(Object object) => object._typeArguments; @patch diff --git a/sdk/lib/_internal/wasm/lib/string.dart b/sdk/lib/_internal/wasm/lib/string.dart index 21d076a0ddd..e45710d1c8c 100644 --- a/sdk/lib/_internal/wasm/lib/string.dart +++ b/sdk/lib/_internal/wasm/lib/string.dart @@ -40,7 +40,7 @@ void writeIntoTwoByteString(TwoByteString s, int index, int codePoint) => /// Static function for `OneByteString._array` to avoid making `_array` public. @pragma('wasm:prefer-inline') -WasmIntArray oneByteStringArray(OneByteString s) => s._array; +WasmArray oneByteStringArray(OneByteString s) => s._array; /// The [fromStart] and [toStart] indices together with the [length] must /// specify ranges within the bounds of the list / string. @@ -1035,14 +1035,14 @@ abstract final class StringBase implements String { @pragma("wasm:entry-point") final class OneByteString extends StringBase { @pragma("wasm:entry-point") - WasmIntArray _array; + WasmArray _array; - OneByteString.withLength(int length) : _array = WasmIntArray(length); + OneByteString.withLength(int length) : _array = WasmArray(length); // Same hash as VM @override int _computeHashCode() { - WasmIntArray array = _array; + WasmArray array = _array; int length = array.length; int hash = 0; for (int i = 0; i < length; i++) { @@ -1167,7 +1167,7 @@ final class OneByteString extends StringBase { final int length = this.length; if (length == 0) return this; // Don't clone empty string. final OneByteString result = OneByteString.withLength(length * times); - final WasmIntArray array = result._array; + final WasmArray array = result._array; for (int i = 0; i < times; i++) { array.copy(i * length, _array, 0, length); } @@ -1359,14 +1359,14 @@ final class OneByteString extends StringBase { @pragma("wasm:entry-point") final class TwoByteString extends StringBase { @pragma("wasm:entry-point") - WasmIntArray _array; + WasmArray _array; - TwoByteString.withLength(int length) : _array = WasmIntArray(length); + TwoByteString.withLength(int length) : _array = WasmArray(length); // Same hash as VM @override int _computeHashCode() { - WasmIntArray array = _array; + WasmArray array = _array; int length = array.length; int hash = 0; for (int i = 0; i < length; i++) { diff --git a/sdk/lib/_internal/wasm/lib/type.dart b/sdk/lib/_internal/wasm/lib/type.dart index d59c5f24781..bc24a366c00 100644 --- a/sdk/lib/_internal/wasm/lib/type.dart +++ b/sdk/lib/_internal/wasm/lib/type.dart @@ -14,13 +14,7 @@ part of 'core_patch.dart'; @pragma("wasm:prefer-inline") _Type _literal() => unsafeCast(T); -extension on WasmObjectArray<_Type> { - @pragma("wasm:prefer-inline") - _Type operator [](int index) => read(index); - - @pragma("wasm:prefer-inline") - void operator []=(int index, _Type value) => write(index, value); - +extension on WasmArray<_Type> { @pragma("wasm:prefer-inline") bool get isEmpty => length == 0; @@ -28,9 +22,9 @@ extension on WasmObjectArray<_Type> { bool get isNotEmpty => length != 0; @pragma("wasm:prefer-inline") - WasmObjectArray<_Type> map(_Type Function(_Type) fun) { - if (isEmpty) return const WasmObjectArray<_Type>.literal(<_Type>[]); - final mapped = WasmObjectArray<_Type>(length, fun(this[0])); + WasmArray<_Type> map(_Type Function(_Type) fun) { + if (isEmpty) return const WasmArray<_Type>.literal(<_Type>[]); + final mapped = WasmArray<_Type>.filled(length, fun(this[0])); for (int i = 1; i < length; ++i) { mapped[i] = fun(this[i]); } @@ -38,13 +32,7 @@ extension on WasmObjectArray<_Type> { } } -extension on WasmObjectArray<_NamedParameter> { - @pragma("wasm:prefer-inline") - _NamedParameter operator [](int index) => read(index); - - @pragma("wasm:prefer-inline") - void operator []=(int index, _NamedParameter value) => write(index, value); - +extension on WasmArray<_NamedParameter> { @pragma("wasm:prefer-inline") bool get isEmpty => length == 0; @@ -52,45 +40,24 @@ extension on WasmObjectArray<_NamedParameter> { bool get isNotEmpty => length != 0; @pragma("wasm:prefer-inline") - WasmObjectArray<_NamedParameter> map( + WasmArray<_NamedParameter> map( _NamedParameter Function(_NamedParameter) fun) { if (isEmpty) - return const WasmObjectArray<_NamedParameter>.literal( - <_NamedParameter>[]); - final mapped = WasmObjectArray<_NamedParameter>(length, this[0]); - for (int i = 0; i < length; ++i) { + return const WasmArray<_NamedParameter>.literal(<_NamedParameter>[]); + final mapped = WasmArray<_NamedParameter>.filled(length, fun(this[0])); + for (int i = 1; i < length; ++i) { mapped[i] = fun(this[i]); } return mapped; } } -extension on WasmObjectArray { - @pragma("wasm:prefer-inline") - String operator [](int index) => read(index); -} - -extension on WasmObjectArray> { - @pragma("wasm:prefer-inline") - WasmIntArray operator [](int index) => read(index); -} - -extension on WasmObjectArray> { - @pragma("wasm:prefer-inline") - WasmObjectArray<_Type> operator [](int index) => read(index); -} - -extension on WasmObjectArray>> { - @pragma("wasm:prefer-inline") - WasmObjectArray> operator [](int index) => read(index); -} - // TODO: Remove any occurence of `List`s in this file. extension on List<_Type> { @pragma("wasm:prefer-inline") - WasmObjectArray<_Type> toWasmArray() { - if (isEmpty) return const WasmObjectArray<_Type>.literal(<_Type>[]); - final result = WasmObjectArray<_Type>(length, this[0]); + WasmArray<_Type> toWasmArray() { + if (isEmpty) return const WasmArray<_Type>.literal(<_Type>[]); + final result = WasmArray<_Type>.filled(length, this[0]); for (int i = 1; i < length; ++i) { result[i] = this[i]; } @@ -104,7 +71,7 @@ extension on List<_Type> { extension _BypassListIndexingChecks on List { @pragma("wasm:prefer-inline") T _getUnchecked(int index) => - unsafeCast(unsafeCast<_ListBase>(this)._data.read(index)); + unsafeCast(unsafeCast<_ListBase>(this)._data[index]); } // TODO(joshualitt): We can cache the result of [_FutureOrType.asFuture]. @@ -265,7 +232,7 @@ class _FutureOrType extends _Type { const _FutureOrType(super.isDeclaredNullable, this.typeArgument); _InterfaceType get asFuture => _InterfaceType(ClassID.cidFuture, - isDeclaredNullable, WasmObjectArray<_Type>.literal([typeArgument])); + isDeclaredNullable, WasmArray<_Type>.literal([typeArgument])); @override _Type get _asNullable => @@ -308,11 +275,11 @@ class _FutureOrType extends _Type { @pragma("wasm:entry-point") class _InterfaceType extends _Type { final int classId; - final WasmObjectArray<_Type> typeArguments; + final WasmArray<_Type> typeArguments; @pragma("wasm:entry-point") const _InterfaceType(this.classId, super.isDeclaredNullable, - [this.typeArguments = const WasmObjectArray<_Type>.literal([])]); + [this.typeArguments = const WasmArray<_Type>.literal([])]); @override _Type get _asNullable => _InterfaceType(classId, true, typeArguments); @@ -429,12 +396,12 @@ class _FunctionType extends _Type { // an `i64` in every function type object for this. Consider alternative // representations that don't have this overhead in the common case. final int typeParameterOffset; - final WasmObjectArray<_Type> typeParameterBounds; - final WasmObjectArray<_Type> typeParameterDefaults; + final WasmArray<_Type> typeParameterBounds; + final WasmArray<_Type> typeParameterDefaults; final _Type returnType; - final WasmObjectArray<_Type> positionalParameters; + final WasmArray<_Type> positionalParameters; final int requiredParameterCount; - final WasmObjectArray<_NamedParameter> namedParameters; + final WasmArray<_NamedParameter> namedParameters; @pragma("wasm:entry-point") const _FunctionType( @@ -650,10 +617,9 @@ class _RecordType extends _Type { identical(names, other.names); } -external WasmObjectArray> _getTypeRulesSupers(); -external WasmObjectArray>> - _getTypeRulesSubstitutions(); -external WasmObjectArray _getTypeNames(); +external WasmArray> _getTypeRulesSupers(); +external WasmArray>> _getTypeRulesSubstitutions(); +external WasmArray _getTypeNames(); /// Type parameter environment used while comparing function types. /// @@ -702,12 +668,11 @@ class _Environment { class _TypeUniverse { /// 'Map' of classId to the transitive set of super classes it implements. - final WasmObjectArray> typeRulesSupers; + final WasmArray> typeRulesSupers; /// 'Map' of classId, and super offset(from [typeRulesSupers]) to a list of /// type substitutions. - final WasmObjectArray>> - typeRulesSubstitutions; + final WasmArray>> typeRulesSubstitutions; const _TypeUniverse._(this.typeRulesSupers, this.typeRulesSubstitutions); @@ -717,7 +682,7 @@ class _TypeUniverse { static _Type substituteInterfaceTypeParameter( _InterfaceTypeParameterType typeParameter, - WasmObjectArray<_Type> substitutions) { + WasmArray<_Type> substitutions) { // If the type parameter is non-nullable, or the substitution type is // nullable, then just return the substitution type. Otherwise, we return // [type] as nullable. @@ -730,7 +695,7 @@ class _TypeUniverse { static _Type substituteFunctionTypeParameter( _FunctionTypeParameterType typeParameter, - WasmObjectArray<_Type> substitutions, + WasmArray<_Type> substitutions, _FunctionType? rootFunction) { if (rootFunction != null && typeParameter.index >= rootFunction.typeParameterOffset) { @@ -745,7 +710,7 @@ class _TypeUniverse { @pragma("wasm:entry-point") static _FunctionType substituteFunctionTypeArgument( - _FunctionType functionType, WasmObjectArray<_Type> substitutions) { + _FunctionType functionType, WasmArray<_Type> substitutions) { return substituteTypeArgument(functionType, substitutions, functionType) .as<_FunctionType>(); } @@ -758,8 +723,8 @@ class _TypeUniverse { /// are being substituted, or `null` when inside a nested function type that /// is guaranteed not to contain any type parameter types that are to be /// substituted. - static _Type substituteTypeArgument(_Type type, - WasmObjectArray<_Type> substitutions, _FunctionType? rootFunction) { + static _Type substituteTypeArgument( + _Type type, WasmArray<_Type> substitutions, _FunctionType? rootFunction) { if (type.isBottom || type.isTop) { return type; } else if (type.isFutureOr) { @@ -769,7 +734,7 @@ class _TypeUniverse { substitutions, rootFunction)); } else if (type.isInterface) { _InterfaceType interfaceType = type.as<_InterfaceType>(); - WasmObjectArray<_Type> typeArguments = WasmObjectArray<_Type>( + final typeArguments = WasmArray<_Type>.filled( interfaceType.typeArguments.length, _literal()); for (int i = 0; i < typeArguments.length; i++) { typeArguments[i] = substituteTypeArgument( @@ -797,29 +762,28 @@ class _TypeUniverse { rootFunction = null; } - final WasmObjectArray<_Type> bounds; + final WasmArray<_Type> bounds; if (isRoot) { - bounds = const WasmObjectArray<_Type>.literal(<_Type>[]); + bounds = const WasmArray<_Type>.literal(<_Type>[]); } else { bounds = functionType.typeParameterBounds.map((_Type type) => substituteTypeArgument(type, substitutions, rootFunction)); } - final WasmObjectArray<_Type> defaults; + final WasmArray<_Type> defaults; if (isRoot) { - defaults = const WasmObjectArray<_Type>.literal(<_Type>[]); + defaults = const WasmArray<_Type>.literal(<_Type>[]); } else { defaults = functionType.typeParameterDefaults.map((_Type type) => substituteTypeArgument(type, substitutions, rootFunction)); } - final WasmObjectArray<_Type> positionals = - functionType.positionalParameters.map((_Type type) => + final WasmArray<_Type> positionals = functionType.positionalParameters + .map((_Type type) => substituteTypeArgument(type, substitutions, rootFunction)); - final WasmObjectArray<_NamedParameter> named = functionType - .namedParameters - .map((_NamedParameter named) => _NamedParameter( + final WasmArray<_NamedParameter> named = functionType.namedParameters.map( + (_NamedParameter named) => _NamedParameter( named.name, substituteTypeArgument(named.type, substitutions, rootFunction), named.isRequired)); @@ -852,7 +816,7 @@ class _TypeUniverse { return _InterfaceType( ClassID.cidFuture, isDeclaredNullable || typeArgument.isDeclaredNullable, - WasmObjectArray<_Type>.literal([typeArgument])); + WasmArray<_Type>.literal([typeArgument])); } // Note: We diverge from the spec here and normalize the type to nullable if @@ -864,8 +828,8 @@ class _TypeUniverse { return _FutureOrType(declaredNullability, typeArgument); } - bool areTypeArgumentsSubtypes(WasmObjectArray<_Type> sArgs, - _Environment? sEnv, WasmObjectArray<_Type> tArgs, _Environment? tEnv) { + bool areTypeArgumentsSubtypes(WasmArray<_Type> sArgs, _Environment? sEnv, + WasmArray<_Type> tArgs, _Environment? tEnv) { assert(sArgs.length == tArgs.length); for (int i = 0; i < sArgs.length; i++) { if (!isSubtype(sArgs[i], sEnv, tArgs[i], tEnv)) { @@ -880,7 +844,7 @@ class _TypeUniverse { return isInterfaceSubtypeInner(s.classId, s.typeArguments, sEnv, t, tEnv); } - bool isInterfaceSubtypeInner(int sId, WasmObjectArray<_Type> sTypeArguments, + bool isInterfaceSubtypeInner(int sId, WasmArray<_Type> sTypeArguments, _Environment? sEnv, _InterfaceType t, _Environment? tEnv) { int tId = t.classId; @@ -892,7 +856,7 @@ class _TypeUniverse { // Otherwise, check if [s] is a subtype of [t], and if it is then compare // [s]'s type substitutions with [t]'s type arguments. - final WasmIntArray sSupers = typeRulesSupers[sId]; + final WasmArray sSupers = typeRulesSupers[sId]; if (sSupers.length == 0) return false; int sSuperIndexOfT = -1; for (int i = 0; i < sSupers.length; i++) { @@ -905,7 +869,7 @@ class _TypeUniverse { assert(sSuperIndexOfT < typeRulesSubstitutions[sId].length); // Return early if we don't have to check type arguments. - WasmObjectArray<_Type> substitutions = + WasmArray<_Type> substitutions = typeRulesSubstitutions[sId][sSuperIndexOfT]; if (substitutions.isEmpty && sTypeArguments.isEmpty) { return true; @@ -913,17 +877,17 @@ class _TypeUniverse { // If we have empty type arguments then create a list of dynamic type // arguments. - WasmObjectArray<_Type> typeArgumentsForSubstitution = + WasmArray<_Type> typeArgumentsForSubstitution = substitutions.isNotEmpty && sTypeArguments.isEmpty - ? WasmObjectArray<_Type>(substitutions.length, _literal()) + ? WasmArray<_Type>.filled(substitutions.length, _literal()) : sTypeArguments; // Finally substitute arguments. We must do this upfront so we can normalize // the type. // TODO(joshualitt): This process is expensive so we should cache the // result. - WasmObjectArray<_Type> substituted = - WasmObjectArray<_Type>(substitutions.length, _literal()); + final substituted = + WasmArray<_Type>.filled(substitutions.length, _literal()); for (int i = 0; i < substitutions.length; i++) { substituted[i] = substituteTypeArgument( substitutions[i], typeArgumentsForSubstitution, null); @@ -960,8 +924,8 @@ class _TypeUniverse { // Check [s] has enough required and optional positional arguments to // potentially be a valid subtype of [t]. - WasmObjectArray<_Type> sPositional = s.positionalParameters; - WasmObjectArray<_Type> tPositional = t.positionalParameters; + WasmArray<_Type> sPositional = s.positionalParameters; + WasmArray<_Type> tPositional = t.positionalParameters; int sPositionalLength = sPositional.length; int tPositionalLength = tPositional.length; if (sPositionalLength < tPositionalLength) { @@ -980,8 +944,8 @@ class _TypeUniverse { // Check that [t]'s named arguments are subtypes of [s]'s named arguments. // This logic assumes the named arguments are stored in sorted order. - WasmObjectArray<_NamedParameter> sNamed = s.namedParameters; - WasmObjectArray<_NamedParameter> tNamed = t.namedParameters; + WasmArray<_NamedParameter> sNamed = s.namedParameters; + WasmArray<_NamedParameter> tNamed = t.namedParameters; int sNamedLength = sNamed.length; int tNamedLength = tNamed.length; int sIndex = 0; diff --git a/sdk/lib/_internal/wasm/lib/typed_data.dart b/sdk/lib/_internal/wasm/lib/typed_data.dart index 999dbf2738b..7fdfdb41eab 100644 --- a/sdk/lib/_internal/wasm/lib/typed_data.dart +++ b/sdk/lib/_internal/wasm/lib/typed_data.dart @@ -466,17 +466,17 @@ mixin _UnmodifiableByteDataMixin on ByteDataBase { } class I8ByteData extends ByteDataBase { - final WasmIntArray _data; + final WasmArray _data; I8ByteData(int length) - : _data = WasmIntArray(_newArrayLengthCheck(length)), + : _data = WasmArray(_newArrayLengthCheck(length)), super(0, length); I8ByteData._(this._data, int offsetInBytes, int lengthInBytes) : super(offsetInBytes, lengthInBytes); - factory I8ByteData._withMutability(WasmIntArray data, - int offsetInBytes, int lengthInBytes, bool mutable) => + factory I8ByteData._withMutability(WasmArray data, int offsetInBytes, + int lengthInBytes, bool mutable) => mutable ? I8ByteData._(data, offsetInBytes, lengthInBytes) : _UnmodifiableI8ByteData._(data, offsetInBytes, lengthInBytes); @@ -503,12 +503,12 @@ class I8ByteData extends ByteDataBase { } class _I16ByteData extends ByteDataBase { - final WasmIntArray _data; + final WasmArray _data; _I16ByteData._(this._data, int offsetInBytes, int lengthInBytes) : super(offsetInBytes, lengthInBytes); - factory _I16ByteData._withMutability(WasmIntArray data, + factory _I16ByteData._withMutability(WasmArray data, int offsetInBytes, int lengthInBytes, bool mutable) => mutable ? _I16ByteData._(data, offsetInBytes, lengthInBytes) @@ -566,12 +566,12 @@ class _I16ByteData extends ByteDataBase { } class _I32ByteData extends ByteDataBase { - final WasmIntArray _data; + final WasmArray _data; _I32ByteData._(this._data, int offsetInBytes, int lengthInBytes) : super(offsetInBytes, lengthInBytes); - factory _I32ByteData._withMutability(WasmIntArray data, + factory _I32ByteData._withMutability(WasmArray data, int offsetInBytes, int lengthInBytes, bool mutable) => mutable ? _I32ByteData._(data, offsetInBytes, lengthInBytes) @@ -652,12 +652,12 @@ class _I32ByteData extends ByteDataBase { } class _I64ByteData extends ByteDataBase { - final WasmIntArray _data; + final WasmArray _data; _I64ByteData._(this._data, int offsetInBytes, int lengthInBytes) : super(offsetInBytes, lengthInBytes); - factory _I64ByteData._withMutability(WasmIntArray data, + factory _I64ByteData._withMutability(WasmArray data, int offsetInBytes, int lengthInBytes, bool mutable) => mutable ? _I64ByteData._(data, offsetInBytes, lengthInBytes) @@ -677,14 +677,14 @@ class _I64ByteData extends ByteDataBase { int _getUint8Unchecked(int byteOffset) { byteOffset += offsetInBytes; final byteIndex = byteOffset ~/ elementSizeInBytes; - return (_data.readUnsigned(byteIndex) >> (8 * (byteOffset & 7))) & 0xFF; + return (_data.read(byteIndex) >> (8 * (byteOffset & 7))) & 0xFF; } @override void _setUint8Unchecked(int byteOffset, int value) { byteOffset += offsetInBytes; final byteIndex = byteOffset ~/ elementSizeInBytes; - final element = _data.readUnsigned(byteIndex); + final element = _data.read(byteIndex); final byteElementIndex = byteOffset & 7; final b1 = byteElementIndex == 0 ? value : (element & 0xFF); final b2 = byteElementIndex == 1 ? value : ((element >> 8) & 0xFF); @@ -709,7 +709,7 @@ class _I64ByteData extends ByteDataBase { int _getInt64Unchecked(int byteOffset, [Endian endian = Endian.big]) { final totalOffset = offsetInBytes + byteOffset; if (totalOffset & 7 == 0 && endian == Endian.little) { - return _data.readSigned(totalOffset ~/ elementSizeInBytes); + return _data.read(totalOffset ~/ elementSizeInBytes); } else { return super._getInt64Unchecked(byteOffset, endian); } @@ -719,7 +719,7 @@ class _I64ByteData extends ByteDataBase { int _getUint64Unchecked(int byteOffset, [Endian endian = Endian.big]) { final totalOffset = offsetInBytes + byteOffset; if (totalOffset & 7 == 0 && endian == Endian.little) { - return _data.readUnsigned(totalOffset ~/ elementSizeInBytes); + return _data.read(totalOffset ~/ elementSizeInBytes); } else { return super._getUint64Unchecked(byteOffset, endian); } @@ -749,12 +749,12 @@ class _I64ByteData extends ByteDataBase { } class _F32ByteData extends ByteDataBase { - final WasmFloatArray _data; + final WasmArray _data; _F32ByteData._(this._data, int offsetInBytes, int lengthInBytes) : super(offsetInBytes, lengthInBytes); - factory _F32ByteData._withMutability(WasmFloatArray data, + factory _F32ByteData._withMutability(WasmArray data, int offsetInBytes, int lengthInBytes, bool mutable) => mutable ? _F32ByteData._(data, offsetInBytes, lengthInBytes) @@ -815,12 +815,12 @@ class _F32ByteData extends ByteDataBase { } class _F64ByteData extends ByteDataBase { - final WasmFloatArray _data; + final WasmArray _data; _F64ByteData._(this._data, int offsetInBytes, int lengthInBytes) : super(offsetInBytes, lengthInBytes); - factory _F64ByteData._withMutability(WasmFloatArray data, + factory _F64ByteData._withMutability(WasmArray data, int offsetInBytes, int lengthInBytes, bool mutable) => mutable ? _F64ByteData._(data, offsetInBytes, lengthInBytes) @@ -895,7 +895,7 @@ class _UnmodifiableI8ByteData extends I8ByteData with _UnmodifiableByteDataMixin implements UnmodifiableByteDataView { _UnmodifiableI8ByteData._( - WasmIntArray _data, int offsetInBytes, int lengthInBytes) + WasmArray _data, int offsetInBytes, int lengthInBytes) : super._(_data, offsetInBytes, lengthInBytes); @override @@ -906,7 +906,7 @@ class _UnmodifiableI16ByteData extends _I16ByteData with _UnmodifiableByteDataMixin implements UnmodifiableByteDataView { _UnmodifiableI16ByteData._( - WasmIntArray _data, int offsetInBytes, int lengthInBytes) + WasmArray _data, int offsetInBytes, int lengthInBytes) : super._(_data, offsetInBytes, lengthInBytes); @override @@ -917,7 +917,7 @@ class _UnmodifiableI32ByteData extends _I32ByteData with _UnmodifiableByteDataMixin implements UnmodifiableByteDataView { _UnmodifiableI32ByteData._( - WasmIntArray _data, int offsetInBytes, int lengthInBytes) + WasmArray _data, int offsetInBytes, int lengthInBytes) : super._(_data, offsetInBytes, lengthInBytes); @override @@ -928,7 +928,7 @@ class _UnmodifiableI64ByteData extends _I64ByteData with _UnmodifiableByteDataMixin implements UnmodifiableByteDataView { _UnmodifiableI64ByteData._( - WasmIntArray _data, int offsetInBytes, int lengthInBytes) + WasmArray _data, int offsetInBytes, int lengthInBytes) : super._(_data, 0, _data.length * 8); @override @@ -939,7 +939,7 @@ class _UnmodifiableF32ByteData extends _F32ByteData with _UnmodifiableByteDataMixin implements UnmodifiableByteDataView { _UnmodifiableF32ByteData._( - WasmFloatArray _data, int offsetInBytes, int lengthInBytes) + WasmArray _data, int offsetInBytes, int lengthInBytes) : super._(_data, offsetInBytes, lengthInBytes); @override @@ -950,7 +950,7 @@ class _UnmodifiableF64ByteData extends _F64ByteData with _UnmodifiableByteDataMixin implements UnmodifiableByteDataView { _UnmodifiableF64ByteData._( - WasmFloatArray _data, int offsetInBytes, int lengthInBytes) + WasmArray _data, int offsetInBytes, int lengthInBytes) : super._(_data, offsetInBytes, lengthInBytes); @override @@ -1105,7 +1105,7 @@ abstract class ByteBufferBase extends ByteBuffer { } class _I8ByteBuffer extends ByteBufferBase { - final WasmIntArray _data; + final WasmArray _data; _I8ByteBuffer(this._data) : super(_data.length, true); @@ -1143,7 +1143,7 @@ class _I8ByteBuffer extends ByteBufferBase { } class _I16ByteBuffer extends ByteBufferBase { - final WasmIntArray _data; + final WasmArray _data; _I16ByteBuffer(this._data) : super(_data.length * 2, true); @@ -1185,7 +1185,7 @@ class _I16ByteBuffer extends ByteBufferBase { } class _I32ByteBuffer extends ByteBufferBase { - final WasmIntArray _data; + final WasmArray _data; _I32ByteBuffer(this._data) : super(_data.length * 4, true); @@ -1227,7 +1227,7 @@ class _I32ByteBuffer extends ByteBufferBase { } class _I64ByteBuffer extends ByteBufferBase { - final WasmIntArray _data; + final WasmArray _data; _I64ByteBuffer(this._data) : super(_data.length * 8, true); @@ -1269,7 +1269,7 @@ class _I64ByteBuffer extends ByteBufferBase { } class _F32ByteBuffer extends ByteBufferBase { - final WasmFloatArray _data; + final WasmArray _data; _F32ByteBuffer(this._data) : super(_data.length * 4, true); @@ -1301,7 +1301,7 @@ class _F32ByteBuffer extends ByteBufferBase { } class _F64ByteBuffer extends ByteBufferBase { - final WasmFloatArray _data; + final WasmArray _data; _F64ByteBuffer(this._data) : super(_data.length * 8, true); @@ -2243,12 +2243,12 @@ mixin _UnmodifiableDoubleListMixin { // abstract class _WasmI8ArrayBase { - final WasmIntArray _data; + final WasmArray _data; final int _offsetInElements; final int length; _WasmI8ArrayBase(this.length) - : _data = WasmIntArray(_newArrayLengthCheck(length)), + : _data = WasmArray(_newArrayLengthCheck(length)), _offsetInElements = 0; _WasmI8ArrayBase._(this._data, this._offsetInElements, this.length); @@ -2261,12 +2261,12 @@ abstract class _WasmI8ArrayBase { } abstract class _WasmI16ArrayBase { - final WasmIntArray _data; + final WasmArray _data; final int _offsetInElements; final int length; _WasmI16ArrayBase(this.length) - : _data = WasmIntArray(_newArrayLengthCheck(length)), + : _data = WasmArray(_newArrayLengthCheck(length)), _offsetInElements = 0; _WasmI16ArrayBase._(this._data, this._offsetInElements, this.length); @@ -2279,12 +2279,12 @@ abstract class _WasmI16ArrayBase { } abstract class _WasmI32ArrayBase { - final WasmIntArray _data; + final WasmArray _data; final int _offsetInElements; final int length; _WasmI32ArrayBase(this.length) - : _data = WasmIntArray(_newArrayLengthCheck(length)), + : _data = WasmArray(_newArrayLengthCheck(length)), _offsetInElements = 0; _WasmI32ArrayBase._(this._data, this._offsetInElements, this.length); @@ -2297,12 +2297,12 @@ abstract class _WasmI32ArrayBase { } abstract class _WasmI64ArrayBase { - final WasmIntArray _data; + final WasmArray _data; final int _offsetInElements; final int length; _WasmI64ArrayBase(this.length) - : _data = WasmIntArray(_newArrayLengthCheck(length)), + : _data = WasmArray(_newArrayLengthCheck(length)), _offsetInElements = 0; _WasmI64ArrayBase._(this._data, this._offsetInElements, this.length); @@ -2315,12 +2315,12 @@ abstract class _WasmI64ArrayBase { } abstract class _WasmF32ArrayBase { - final WasmFloatArray _data; + final WasmArray _data; final int _offsetInElements; final int length; _WasmF32ArrayBase(this.length) - : _data = WasmFloatArray(_newArrayLengthCheck(length)), + : _data = WasmArray(_newArrayLengthCheck(length)), _offsetInElements = 0; _WasmF32ArrayBase._(this._data, this._offsetInElements, this.length); @@ -2333,12 +2333,12 @@ abstract class _WasmF32ArrayBase { } abstract class _WasmF64ArrayBase { - final WasmFloatArray _data; + final WasmArray _data; final int _offsetInElements; final int length; _WasmF64ArrayBase(this.length) - : _data = WasmFloatArray(_newArrayLengthCheck(length)), + : _data = WasmArray(_newArrayLengthCheck(length)), _offsetInElements = 0; _WasmF64ArrayBase._(this._data, this._offsetInElements, this.length); @@ -2358,10 +2358,10 @@ class I8List extends _WasmI8ArrayBase implements Int8List { I8List(int length) : super(length); - I8List._(WasmIntArray data, int offsetInElements, int length) + I8List._(WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); - factory I8List._withMutability(WasmIntArray buffer, int offsetInBytes, + factory I8List._withMutability(WasmArray buffer, int offsetInBytes, int length, bool mutable) => mutable ? I8List._(buffer, offsetInBytes, length) @@ -2396,12 +2396,12 @@ class U8List extends _WasmI8ArrayBase implements Uint8List { U8List(int length) : super(length); - U8List._(WasmIntArray data, int offsetInElements, int length) + U8List._(WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); - WasmIntArray get data => _data; + WasmArray get data => _data; - factory U8List._withMutability(WasmIntArray buffer, int offsetInBytes, + factory U8List._withMutability(WasmArray buffer, int offsetInBytes, int length, bool mutable) => mutable ? U8List._(buffer, offsetInBytes, length) @@ -2436,10 +2436,10 @@ class U8ClampedList extends _WasmI8ArrayBase implements Uint8ClampedList { U8ClampedList(int length) : super(length); - U8ClampedList._(WasmIntArray data, int offsetInElements, int length) + U8ClampedList._(WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); - factory U8ClampedList._withMutability(WasmIntArray buffer, + factory U8ClampedList._withMutability(WasmArray buffer, int offsetInBytes, int length, bool mutable) => mutable ? U8ClampedList._(buffer, offsetInBytes, length) @@ -2475,11 +2475,11 @@ class I16List extends _WasmI16ArrayBase implements Int16List { I16List(int length) : super(length); - I16List._(WasmIntArray data, int offsetInElements, int length) + I16List._(WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); - factory I16List._withMutability(WasmIntArray buffer, - int offsetInBytes, int length, bool mutable) => + factory I16List._withMutability(WasmArray buffer, int offsetInBytes, + int length, bool mutable) => mutable ? I16List._(buffer, offsetInBytes, length) : UnmodifiableI16List._(buffer, offsetInBytes, length); @@ -2513,11 +2513,11 @@ class U16List extends _WasmI16ArrayBase implements Uint16List { U16List(int length) : super(length); - U16List._(WasmIntArray data, int offsetInElements, int length) + U16List._(WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); - factory U16List._withMutability(WasmIntArray buffer, - int offsetInBytes, int length, bool mutable) => + factory U16List._withMutability(WasmArray buffer, int offsetInBytes, + int length, bool mutable) => mutable ? U16List._(buffer, offsetInBytes, length) : UnmodifiableU16List._(buffer, offsetInBytes, length); @@ -2551,11 +2551,11 @@ class I32List extends _WasmI32ArrayBase implements Int32List { I32List(int length) : super(length); - I32List._(WasmIntArray data, int offsetInElements, int length) + I32List._(WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); - factory I32List._withMutability(WasmIntArray buffer, - int offsetInBytes, int length, bool mutable) => + factory I32List._withMutability(WasmArray buffer, int offsetInBytes, + int length, bool mutable) => mutable ? I32List._(buffer, offsetInBytes, length) : UnmodifiableI32List._(buffer, offsetInBytes, length); @@ -2589,11 +2589,11 @@ class U32List extends _WasmI32ArrayBase implements Uint32List { U32List(int length) : super(length); - U32List._(WasmIntArray data, int offsetInElements, int length) + U32List._(WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); - factory U32List._withMutability(WasmIntArray buffer, - int offsetInBytes, int length, bool mutable) => + factory U32List._withMutability(WasmArray buffer, int offsetInBytes, + int length, bool mutable) => mutable ? U32List._(buffer, offsetInBytes, length) : UnmodifiableU32List._(buffer, offsetInBytes, length); @@ -2627,11 +2627,11 @@ class I64List extends _WasmI64ArrayBase implements Int64List { I64List(int length) : super(length); - I64List._(WasmIntArray data, int offsetInElements, int length) + I64List._(WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); - factory I64List._withMutability(WasmIntArray buffer, - int offsetInBytes, int length, bool mutable) => + factory I64List._withMutability(WasmArray buffer, int offsetInBytes, + int length, bool mutable) => mutable ? I64List._(buffer, offsetInBytes, length) : UnmodifiableI64List._(buffer, offsetInBytes, length); @@ -2646,7 +2646,7 @@ class I64List extends _WasmI64ArrayBase @pragma("wasm:prefer-inline") int operator [](int index) { _indexCheck(index, length); - return _data.readSigned(_offsetInElements + index); + return _data.read(_offsetInElements + index); } @override @@ -2665,11 +2665,11 @@ class U64List extends _WasmI64ArrayBase implements Uint64List { U64List(int length) : super(length); - U64List._(WasmIntArray data, int offsetInElements, int length) + U64List._(WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); - factory U64List._withMutability(WasmIntArray buffer, - int offsetInBytes, int length, bool mutable) => + factory U64List._withMutability(WasmArray buffer, int offsetInBytes, + int length, bool mutable) => mutable ? U64List._(buffer, offsetInBytes, length) : UnmodifiableU64List._(buffer, offsetInBytes, length); @@ -2684,7 +2684,7 @@ class U64List extends _WasmI64ArrayBase @pragma("wasm:prefer-inline") int operator [](int index) { _indexCheck(index, length); - return _data.readUnsigned(_offsetInElements + index); + return _data.read(_offsetInElements + index); } @override @@ -2703,11 +2703,11 @@ class F32List extends _WasmF32ArrayBase implements Float32List { F32List(int length) : super(length); - F32List._(WasmFloatArray data, int offsetInElements, int length) + F32List._(WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); - factory F32List._withMutability(WasmFloatArray buffer, - int offsetInBytes, int length, bool mutable) => + factory F32List._withMutability(WasmArray buffer, int offsetInBytes, + int length, bool mutable) => mutable ? F32List._(buffer, offsetInBytes, length) : UnmodifiableF32List._(buffer, offsetInBytes, length); @@ -2741,11 +2741,11 @@ class F64List extends _WasmF64ArrayBase implements Float64List { F64List(int length) : super(length); - F64List._(WasmFloatArray data, int offsetInElements, int length) + F64List._(WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); - factory F64List._withMutability(WasmFloatArray buffer, - int offsetInBytes, int length, bool mutable) => + factory F64List._withMutability(WasmArray buffer, int offsetInBytes, + int length, bool mutable) => mutable ? F64List._(buffer, offsetInBytes, length) : UnmodifiableF64List._(buffer, offsetInBytes, length); @@ -2781,8 +2781,7 @@ class UnmodifiableI8List extends I8List UnmodifiableI8List(I8List list) : super._(list._data, list._offsetInElements, list.length); - UnmodifiableI8List._( - WasmIntArray data, int offsetInElements, int length) + UnmodifiableI8List._(WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); @override @@ -2795,8 +2794,7 @@ class UnmodifiableU8List extends U8List UnmodifiableU8List(U8List list) : super._(list._data, list._offsetInElements, list.length); - UnmodifiableU8List._( - WasmIntArray data, int offsetInElements, int length) + UnmodifiableU8List._(WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); @override @@ -2810,7 +2808,7 @@ class UnmodifiableU8ClampedList extends U8ClampedList : super._(list._data, list._offsetInElements, list.length); UnmodifiableU8ClampedList._( - WasmIntArray data, int offsetInElements, int length) + WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); @override @@ -2824,7 +2822,7 @@ class UnmodifiableI16List extends I16List : super._(list._data, list._offsetInElements, list.length); UnmodifiableI16List._( - WasmIntArray data, int offsetInElements, int length) + WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); @override @@ -2838,7 +2836,7 @@ class UnmodifiableU16List extends U16List : super._(list._data, list._offsetInElements, list.length); UnmodifiableU16List._( - WasmIntArray data, int offsetInElements, int length) + WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); @override @@ -2852,7 +2850,7 @@ class UnmodifiableI32List extends I32List : super._(list._data, list._offsetInElements, list.length); UnmodifiableI32List._( - WasmIntArray data, int offsetInElements, int length) + WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); @override @@ -2866,7 +2864,7 @@ class UnmodifiableU32List extends U32List : super._(list._data, list._offsetInElements, list.length); UnmodifiableU32List._( - WasmIntArray data, int offsetInElements, int length) + WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); @override @@ -2880,7 +2878,7 @@ class UnmodifiableI64List extends I64List : super._(list._data, list._offsetInElements, list.length); UnmodifiableI64List._( - WasmIntArray data, int offsetInElements, int length) + WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); @override @@ -2894,7 +2892,7 @@ class UnmodifiableU64List extends U64List : super._(list._data, list._offsetInElements, list.length); UnmodifiableU64List._( - WasmIntArray data, int offsetInElements, int length) + WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); @override @@ -2908,7 +2906,7 @@ class UnmodifiableF32List extends F32List : super._(list._data, list._offsetInElements, list.length); UnmodifiableF32List._( - WasmFloatArray data, int offsetInElements, int length) + WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); @override @@ -2922,7 +2920,7 @@ class UnmodifiableF64List extends F64List : super._(list._data, list._offsetInElements, list.length); UnmodifiableF64List._( - WasmFloatArray data, int offsetInElements, int length) + WasmArray data, int offsetInElements, int length) : super._(data, offsetInElements, length); @override diff --git a/sdk/lib/_wasm/wasm_types.dart b/sdk/lib/_wasm/wasm_types.dart index a43b38a79ec..1f63d168cc3 100644 --- a/sdk/lib/_wasm/wasm_types.dart +++ b/sdk/lib/_wasm/wasm_types.dart @@ -22,14 +22,6 @@ abstract class _WasmBase { const _WasmBase(); } -abstract class _WasmInt extends _WasmBase { - const _WasmInt(); -} - -abstract class _WasmFloat extends _WasmBase { - const _WasmFloat(); -} - /// The Wasm `anyref` type. @pragma("wasm:entry-point") class WasmAnyRef extends _WasmBase { @@ -115,15 +107,15 @@ class WasmArrayRef extends WasmEqRef { /// The Wasm `i8` storage type. @pragma("wasm:entry-point") -class WasmI8 extends _WasmInt {} +class WasmI8 extends _WasmBase {} /// The Wasm `i16` storage type. @pragma("wasm:entry-point") -class WasmI16 extends _WasmInt {} +class WasmI16 extends _WasmBase {} /// The Wasm `i32` type. @pragma("wasm:entry-point") -class WasmI32 extends _WasmInt { +class WasmI32 extends _WasmBase { /// Dummy value field to contain the value for constant instances. final int _value; @@ -143,7 +135,7 @@ class WasmI32 extends _WasmInt { /// The Wasm `i64` type. @pragma("wasm:entry-point") -class WasmI64 extends _WasmInt { +class WasmI64 extends _WasmBase { /// Dummy value field to contain the value for constant instances. final int _value; @@ -163,7 +155,7 @@ class WasmI64 extends _WasmInt { /// The Wasm `f32` type. @pragma("wasm:entry-point") -class WasmF32 extends _WasmFloat { +class WasmF32 extends _WasmBase { /// Dummy value field to contain the value for constant instances. final double _value; @@ -176,7 +168,7 @@ class WasmF32 extends _WasmFloat { /// The Wasm `f64` type. @pragma("wasm:entry-point") -class WasmF64 extends _WasmFloat { +class WasmF64 extends _WasmBase { /// Dummy value field to contain the value for constant instances. final double _value; @@ -191,53 +183,58 @@ class WasmF64 extends _WasmFloat { external WasmI64 truncSatS(); } -/// A Wasm array with integer element type. +/// A Wasm array. @pragma("wasm:entry-point") -class WasmIntArray extends WasmArrayRef { +class WasmArray extends WasmArrayRef { /// Dummy value field to contain the value for constant instances. @pragma("wasm:entry-point") - final List _value; + final List _value; - external factory WasmIntArray(int length); + external factory WasmArray(int length); + external factory WasmArray.filled(int length, T value); - const WasmIntArray.literal(this._value) : super._(); + const WasmArray.literal(this._value) : super._(); +} +extension WasmArrayExt on WasmArray { + external T operator [](int index); + external void operator []=(int index, T value); + external void copy( + int offset, WasmArray source, int sourceOffset, int size); + external void fill(int offset, T value, int size); +} + +extension I8ArrayExt on WasmArray { external int readSigned(int index); external int readUnsigned(int index); external void write(int index, int value); - external void copy( - int offset, WasmIntArray source, int sourceOffset, int size); - external void fill(int offset, int value, int size); } -/// A Wasm array with float element type. -@pragma("wasm:entry-point") -class WasmFloatArray extends WasmArrayRef { - external factory WasmFloatArray(int length); +extension I16ArrayExt on WasmArray { + external int readSigned(int index); + external int readUnsigned(int index); + external void write(int index, int value); +} +extension I32ArrayExt on WasmArray { + external int readSigned(int index); + external int readUnsigned(int index); + external void write(int index, int value); +} + +extension I64ArrayExt on WasmArray { + external int read(int index); + external void write(int index, int value); +} + +extension F32ArrayExt on WasmArray { external double read(int index); external void write(int index, double value); - external void copy( - int offset, WasmFloatArray source, int sourceOffset, int size); - external void fill(int offset, double value, int size); } -/// A Wasm array with reference element type, containing Dart objects. -@pragma("wasm:entry-point") -class WasmObjectArray extends WasmArrayRef { - /// Dummy value field to contain the value for constant instances. - @pragma("wasm:entry-point") - final List _value; - - external factory WasmObjectArray(int length, T initialValue); - - const WasmObjectArray.literal(this._value) : super._(); - - external T read(int index); - external void write(int index, T value); - external void copy( - int offset, WasmObjectArray source, int sourceOffset, int size); - external void fill(int offset, T value, int size); +extension F64ArrayExt on WasmArray { + external double read(int index); + external void write(int index, double value); } /// Wasm typed function reference. diff --git a/tests/web/wasm/wasm_types_test.dart b/tests/web/wasm/wasm_types_test.dart index 5b080a72ff2..44f843bb32a 100644 --- a/tests/web/wasm/wasm_types_test.dart +++ b/tests/web/wasm/wasm_types_test.dart @@ -126,26 +126,26 @@ test() { Expect.equals(3, funCount); // Instantiate some Wasm arrays - final arrayAN = WasmObjectArray(3, null); - final arrayA = WasmObjectArray(3, A()); + final arrayAN = WasmArray(3); + final arrayA = WasmArray.filled(3, A()); Expect.equals(3, arrayAN.length); Expect.equals(3, arrayA.length); - Expect.equals(null, arrayAN.read(0)); - Expect.identical(arrayA.read(0), arrayA.read(2)); + Expect.equals(null, arrayAN[0]); + Expect.identical(arrayA[0], arrayA[2]); // Instantiate some Wasm arrays as literals - final arrayAlit1 = WasmObjectArray.literal([A(), A(), A()]); - final arrayAlit2 = WasmObjectArray.literal([A(), B(), A()]); - final arrayAlit3 = const WasmObjectArray.literal([A(), B(), A()]); - final arrayAlit4 = const WasmObjectArray.literal([A(), B(), A()]); - Expect.notIdentical(arrayAlit1.read(0), arrayAlit1.read(2)); - Expect.notIdentical(arrayAlit2.read(0), arrayAlit2.read(1)); - Expect.notIdentical(arrayAlit2.read(0), arrayAlit2.read(2)); - Expect.notIdentical(arrayAlit3.read(0), arrayAlit3.read(1)); - Expect.identical(arrayAlit3.read(0), arrayAlit3.read(2)); + final arrayAlit1 = WasmArray.literal([A(), A(), A()]); + final arrayAlit2 = WasmArray.literal([A(), B(), A()]); + final arrayAlit3 = const WasmArray.literal([A(), B(), A()]); + final arrayAlit4 = const WasmArray.literal([A(), B(), A()]); + Expect.notIdentical(arrayAlit1[0], arrayAlit1[2]); + Expect.notIdentical(arrayAlit2[0], arrayAlit2[1]); + Expect.notIdentical(arrayAlit2[0], arrayAlit2[2]); + Expect.notIdentical(arrayAlit3[0], arrayAlit3[1]); + Expect.identical(arrayAlit3[0], arrayAlit3[2]); - final int32Array = WasmIntArray.literal([0, 1, 2, 3]); - final int32ArrayC = const WasmIntArray.literal([0, 10, 20, 30]); + final int32Array = WasmArray.literal([0, 1, 2, 3]); + final int32ArrayC = const WasmArray.literal([0, 10, 20, 30]); for (int i = 0; i < 4; ++i) { Expect.equals(int32Array.readSigned(i), i); } @@ -153,6 +153,16 @@ test() { Expect.equals(int32ArrayC.readSigned(i), i * 10); } + // Ensure we can obtain WasmI8 from arrays, use locals of WasmI8 type and + // store into arrays. + final i8Array = WasmArray.literal([1, 0xff]); + final WasmI8 tmp = i8Array[0]; + i8Array[0] = i8Array[1]; + i8Array[1] = tmp; + Expect.equals(i8Array.readSigned(1), 1); + Expect.equals(i8Array.readSigned(0), -1); + Expect.equals(i8Array.readUnsigned(0), 0xff); + Expect.isFalse(arrayA == arrayAlit1); Expect.isFalse(arrayAlit2 == arrayAlit3); Expect.isTrue(arrayAlit3 == arrayAlit4);