Move Wasm{Object,Int,Float}Array -> WasmArray, use extensions on WasmArray for static dispatc0h

The dart2wasm compiler treats wasm arrays of objects/ints/floats pretty
much the same, there's no reason to have complicated class hierarchy and
different kinds of wasm array classes.

Also: We rely on all operations on wasm arrays (and other built-in
types) to be handled on the call site. Wasm arrays are not dart objects,
don't support virtual dispatch. So we make operations operating on the
wasm types extensions.

This also makes now loads and stores into the wasm arrays simple `[]` and
`[]=` operations. We still have special extensions for reading/writing
to integer/double arrays that not only read/write but also
sign-extend/zero-extend and operate on Dart's `int` / `double`.

The compiler will allow `WasmArray<X>(length)` for types `X` that have
default-value in wasm arrays (nullable / integer / double types) and
have another `WasmArray<X>.filled(length, X)` for non-nullable reference
types.

Overall this reduces LOCs and simplifies things

Change-Id: I885bed3dfd1c602dc7b0747c69927d464376383d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/340881
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
This commit is contained in:
Martin Kustermann 2023-12-12 17:05:49 +00:00 committed by Commit Queue
parent 7e3b492cef
commit bdefe5fa7e
17 changed files with 464 additions and 461 deletions

View file

@ -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));
}

View file

@ -62,7 +62,7 @@ class Constants {
ListConstant makeTypeList(Iterable<DartType> types) => ListConstant(
translator.typeType, types.map((t) => TypeLiteralConstant(t)).toList());
/// Makes a `WasmObjectArray<_Type>` [InstanceConstant].
/// Makes a `WasmArray<_Type>` [InstanceConstant].
InstanceConstant makeTypeArray(Iterable<DartType> 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<T>` with the given [Constant]s
/// Creates a `WasmArray<T>` with the given [Constant]s
InstanceConstant makeArrayOf(
InterfaceType elementType, List<Constant> entries) =>
InstanceConstant(translator.wasmObjectArrayClass.reference, [
InstanceConstant(translator.wasmArrayClass.reference, [
elementType,
], {
translator.wasmObjectArrayValueField.fieldReference:
ListConstant(elementType, entries),
});
/// Creates a `WasmIntArray<T>` with the given [Constant]s
InstanceConstant makeIntArrayOf(
InterfaceType elementType, List<IntConstant> entries) =>
InstanceConstant(translator.wasmIntArrayClass.reference, [
elementType,
], {
translator.wasmIntArrayValueField.fieldReference:
translator.wasmArrayValueField.fieldReference:
ListConstant(elementType, entries),
});
@ -393,10 +383,7 @@ class ConstantCreator extends ConstantVisitor<ConstantInfo?>
@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);
}

View file

@ -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<T>
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<I*>.(readSigned|readUnsigned|write)
// WasmArray<F*>.(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);

View file

@ -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<Member, (Extension, ExtensionMemberDescriptor)>
_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';
});
}
}

View file

@ -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,

View file

@ -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) {

View file

@ -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 = <Constant>[];
for (List<int> 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 = <Constant>[];
for (List<List<DartType>> 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<DartType> 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,

View file

@ -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:

View file

@ -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.

View file

@ -8,7 +8,7 @@ part of "core_patch.dart";
class _GrowableList<E> extends _ModifiableList<E> {
_GrowableList._(int length, int capacity) : super(length, capacity);
_GrowableList._withData(WasmObjectArray<Object?> data)
_GrowableList._withData(WasmArray<Object?> data)
: super._withData(data.length, data);
factory _GrowableList(int length) {
@ -38,7 +38,7 @@ class _GrowableList<E> extends _ModifiableList<E> {
factory _GrowableList.generate(int length, E generator(int index)) {
final result = _GrowableList<E>(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<E> extends _ModifiableList<E> {
throw RangeError.range(index, 0, length);
}
final WasmObjectArray<Object?> data;
final WasmArray<Object?> data;
if (length == _capacity) {
data = WasmObjectArray<Object?>(_nextCapacity(_capacity), null);
data = WasmArray<Object?>(_nextCapacity(_capacity));
if (index != 0) {
// Copy elements before the insertion point.
data.copy(0, _data, 0, index - 1);
@ -108,7 +108,7 @@ class _GrowableList<E> extends _ModifiableList<E> {
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<E> extends _ModifiableList<E> {
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<E> extends _ModifiableList<E> {
_growToNextCapacity();
}
_setLength(len + 1);
_data.write(len, value);
_data[len] = value;
}
void addAll(Iterable<E> iterable) {
@ -233,7 +233,7 @@ class _GrowableList<E> extends _ModifiableList<E> {
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<E> extends _ModifiableList<E> {
}
// Shared array used as backing for new empty growable lists.
static final WasmObjectArray<Object?> _emptyData =
WasmObjectArray<Object?>(0, null);
static final WasmArray<Object?> _emptyData = WasmArray<Object?>(0);
static WasmObjectArray<Object?> _allocateData(int capacity) {
static WasmArray<Object?> _allocateData(int capacity) {
if (capacity < 0) {
throw RangeError.range(capacity, 0, _maxWasmArrayLength);
}
@ -261,14 +260,14 @@ class _GrowableList<E> extends _ModifiableList<E> {
// Use shared empty list as backing.
return _emptyData;
}
return WasmObjectArray<Object?>(capacity, null);
return WasmArray<Object?>(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<Object?>(new_capacity, null);
var newData = WasmArray<Object?>(new_capacity);
newData.copy(0, _data, 0, length);
_data = newData;
}
@ -310,7 +309,7 @@ class _GrowableListIterator<E> implements Iterator<E> {
_current = null;
return false;
}
_current = unsafeCast(_list._data.read(_index));
_current = unsafeCast(_list._data[_index]);
_index++;
return true;
}

View file

@ -12,13 +12,12 @@ abstract class _ListBase<E> extends ListBase<E> {
int _length;
@pragma("wasm:entry-point")
WasmObjectArray<Object?> _data;
WasmArray<Object?> _data;
_ListBase(int length, int capacity)
: _length = length,
_data = WasmObjectArray<Object?>(
RangeError.checkValueInInterval(capacity, 0, _maxWasmArrayLength),
null);
_data = WasmArray<Object?>(
RangeError.checkValueInInterval(capacity, 0, _maxWasmArrayLength));
_ListBase._withData(this._length, this._data);
@ -26,7 +25,7 @@ abstract class _ListBase<E> extends ListBase<E> {
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<E> extends ListBase<E> {
void forEach(f(E element)) {
final initialLength = length;
for (int i = 0; i < initialLength; i++) {
f(unsafeCast<E>(_data.read(i)));
f(unsafeCast<E>(_data[i]));
if (length != initialLength) throw ConcurrentModificationError(this);
}
}
@ -56,14 +55,14 @@ abstract class _ListBase<E> extends ListBase<E> {
abstract class _ModifiableList<E> extends _ListBase<E> {
_ModifiableList(int length, int capacity) : super(length, capacity);
_ModifiableList._withData(int length, WasmObjectArray<Object?> data)
_ModifiableList._withData(int length, WasmArray<Object?> 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<E> extends _ListBase<E> {
}
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<E> extends _ModifiableList<E> with FixedLengthListMixin<E> {
factory _List.generate(int length, E generator(int index)) {
final result = _List<E>(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<E> extends _ListBase<E> with UnmodifiableListMixin<E> {
// Iterator for lists with fixed size.
class _FixedSizeListIterator<E> implements Iterator<E> {
final WasmObjectArray<Object?> _data;
final WasmArray<Object?> _data;
final int _length; // Cache list length for faster access.
int _index;
E? _current;
@ -220,7 +219,7 @@ class _FixedSizeListIterator<E> implements Iterator<E> {
_current = null;
return false;
}
_current = unsafeCast(_data.read(_index));
_current = unsafeCast(_data[_index]);
_index++;
return true;
}

View file

@ -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

View file

@ -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<WasmI8> oneByteStringArray(OneByteString s) => s._array;
WasmArray<WasmI8> 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<WasmI8> _array;
WasmArray<WasmI8> _array;
OneByteString.withLength(int length) : _array = WasmIntArray<WasmI8>(length);
OneByteString.withLength(int length) : _array = WasmArray<WasmI8>(length);
// Same hash as VM
@override
int _computeHashCode() {
WasmIntArray<WasmI8> array = _array;
WasmArray<WasmI8> 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<WasmI8> array = result._array;
final WasmArray<WasmI8> 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<WasmI16> _array;
WasmArray<WasmI16> _array;
TwoByteString.withLength(int length) : _array = WasmIntArray<WasmI16>(length);
TwoByteString.withLength(int length) : _array = WasmArray<WasmI16>(length);
// Same hash as VM
@override
int _computeHashCode() {
WasmIntArray<WasmI16> array = _array;
WasmArray<WasmI16> array = _array;
int length = array.length;
int hash = 0;
for (int i = 0; i < length; i++) {

View file

@ -14,13 +14,7 @@ part of 'core_patch.dart';
@pragma("wasm:prefer-inline")
_Type _literal<T>() => 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<String> {
@pragma("wasm:prefer-inline")
String operator [](int index) => read(index);
}
extension on WasmObjectArray<WasmIntArray<WasmI32>> {
@pragma("wasm:prefer-inline")
WasmIntArray<WasmI32> operator [](int index) => read(index);
}
extension on WasmObjectArray<WasmObjectArray<_Type>> {
@pragma("wasm:prefer-inline")
WasmObjectArray<_Type> operator [](int index) => read(index);
}
extension on WasmObjectArray<WasmObjectArray<WasmObjectArray<_Type>>> {
@pragma("wasm:prefer-inline")
WasmObjectArray<WasmObjectArray<_Type>> 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<T> on List<T> {
@pragma("wasm:prefer-inline")
T _getUnchecked(int index) =>
unsafeCast(unsafeCast<_ListBase<T>>(this)._data.read(index));
unsafeCast(unsafeCast<_ListBase<T>>(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<WasmIntArray<WasmI32>> _getTypeRulesSupers();
external WasmObjectArray<WasmObjectArray<WasmObjectArray<_Type>>>
_getTypeRulesSubstitutions();
external WasmObjectArray<String> _getTypeNames();
external WasmArray<WasmArray<WasmI32>> _getTypeRulesSupers();
external WasmArray<WasmArray<WasmArray<_Type>>> _getTypeRulesSubstitutions();
external WasmArray<String> _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<WasmIntArray<WasmI32>> typeRulesSupers;
final WasmArray<WasmArray<WasmI32>> typeRulesSupers;
/// 'Map' of classId, and super offset(from [typeRulesSupers]) to a list of
/// type substitutions.
final WasmObjectArray<WasmObjectArray<WasmObjectArray<_Type>>>
typeRulesSubstitutions;
final WasmArray<WasmArray<WasmArray<_Type>>> 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<dynamic>());
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<WasmI32> sSupers = typeRulesSupers[sId];
final WasmArray<WasmI32> 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<dynamic>())
? WasmArray<_Type>.filled(substitutions.length, _literal<dynamic>())
: 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<dynamic>());
final substituted =
WasmArray<_Type>.filled(substitutions.length, _literal<dynamic>());
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;

View file

@ -466,17 +466,17 @@ mixin _UnmodifiableByteDataMixin on ByteDataBase {
}
class I8ByteData extends ByteDataBase {
final WasmIntArray<WasmI8> _data;
final WasmArray<WasmI8> _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<WasmI8> data,
int offsetInBytes, int lengthInBytes, bool mutable) =>
factory I8ByteData._withMutability(WasmArray<WasmI8> 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<WasmI16> _data;
final WasmArray<WasmI16> _data;
_I16ByteData._(this._data, int offsetInBytes, int lengthInBytes)
: super(offsetInBytes, lengthInBytes);
factory _I16ByteData._withMutability(WasmIntArray<WasmI16> data,
factory _I16ByteData._withMutability(WasmArray<WasmI16> 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<WasmI32> _data;
final WasmArray<WasmI32> _data;
_I32ByteData._(this._data, int offsetInBytes, int lengthInBytes)
: super(offsetInBytes, lengthInBytes);
factory _I32ByteData._withMutability(WasmIntArray<WasmI32> data,
factory _I32ByteData._withMutability(WasmArray<WasmI32> 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<WasmI64> _data;
final WasmArray<WasmI64> _data;
_I64ByteData._(this._data, int offsetInBytes, int lengthInBytes)
: super(offsetInBytes, lengthInBytes);
factory _I64ByteData._withMutability(WasmIntArray<WasmI64> data,
factory _I64ByteData._withMutability(WasmArray<WasmI64> 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<WasmF32> _data;
final WasmArray<WasmF32> _data;
_F32ByteData._(this._data, int offsetInBytes, int lengthInBytes)
: super(offsetInBytes, lengthInBytes);
factory _F32ByteData._withMutability(WasmFloatArray<WasmF32> data,
factory _F32ByteData._withMutability(WasmArray<WasmF32> 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<WasmF64> _data;
final WasmArray<WasmF64> _data;
_F64ByteData._(this._data, int offsetInBytes, int lengthInBytes)
: super(offsetInBytes, lengthInBytes);
factory _F64ByteData._withMutability(WasmFloatArray<WasmF64> data,
factory _F64ByteData._withMutability(WasmArray<WasmF64> 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<WasmI8> _data, int offsetInBytes, int lengthInBytes)
WasmArray<WasmI8> _data, int offsetInBytes, int lengthInBytes)
: super._(_data, offsetInBytes, lengthInBytes);
@override
@ -906,7 +906,7 @@ class _UnmodifiableI16ByteData extends _I16ByteData
with _UnmodifiableByteDataMixin
implements UnmodifiableByteDataView {
_UnmodifiableI16ByteData._(
WasmIntArray<WasmI16> _data, int offsetInBytes, int lengthInBytes)
WasmArray<WasmI16> _data, int offsetInBytes, int lengthInBytes)
: super._(_data, offsetInBytes, lengthInBytes);
@override
@ -917,7 +917,7 @@ class _UnmodifiableI32ByteData extends _I32ByteData
with _UnmodifiableByteDataMixin
implements UnmodifiableByteDataView {
_UnmodifiableI32ByteData._(
WasmIntArray<WasmI32> _data, int offsetInBytes, int lengthInBytes)
WasmArray<WasmI32> _data, int offsetInBytes, int lengthInBytes)
: super._(_data, offsetInBytes, lengthInBytes);
@override
@ -928,7 +928,7 @@ class _UnmodifiableI64ByteData extends _I64ByteData
with _UnmodifiableByteDataMixin
implements UnmodifiableByteDataView {
_UnmodifiableI64ByteData._(
WasmIntArray<WasmI64> _data, int offsetInBytes, int lengthInBytes)
WasmArray<WasmI64> _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<WasmF32> _data, int offsetInBytes, int lengthInBytes)
WasmArray<WasmF32> _data, int offsetInBytes, int lengthInBytes)
: super._(_data, offsetInBytes, lengthInBytes);
@override
@ -950,7 +950,7 @@ class _UnmodifiableF64ByteData extends _F64ByteData
with _UnmodifiableByteDataMixin
implements UnmodifiableByteDataView {
_UnmodifiableF64ByteData._(
WasmFloatArray<WasmF64> _data, int offsetInBytes, int lengthInBytes)
WasmArray<WasmF64> _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<WasmI8> _data;
final WasmArray<WasmI8> _data;
_I8ByteBuffer(this._data) : super(_data.length, true);
@ -1143,7 +1143,7 @@ class _I8ByteBuffer extends ByteBufferBase {
}
class _I16ByteBuffer extends ByteBufferBase {
final WasmIntArray<WasmI16> _data;
final WasmArray<WasmI16> _data;
_I16ByteBuffer(this._data) : super(_data.length * 2, true);
@ -1185,7 +1185,7 @@ class _I16ByteBuffer extends ByteBufferBase {
}
class _I32ByteBuffer extends ByteBufferBase {
final WasmIntArray<WasmI32> _data;
final WasmArray<WasmI32> _data;
_I32ByteBuffer(this._data) : super(_data.length * 4, true);
@ -1227,7 +1227,7 @@ class _I32ByteBuffer extends ByteBufferBase {
}
class _I64ByteBuffer extends ByteBufferBase {
final WasmIntArray<WasmI64> _data;
final WasmArray<WasmI64> _data;
_I64ByteBuffer(this._data) : super(_data.length * 8, true);
@ -1269,7 +1269,7 @@ class _I64ByteBuffer extends ByteBufferBase {
}
class _F32ByteBuffer extends ByteBufferBase {
final WasmFloatArray<WasmF32> _data;
final WasmArray<WasmF32> _data;
_F32ByteBuffer(this._data) : super(_data.length * 4, true);
@ -1301,7 +1301,7 @@ class _F32ByteBuffer extends ByteBufferBase {
}
class _F64ByteBuffer extends ByteBufferBase {
final WasmFloatArray<WasmF64> _data;
final WasmArray<WasmF64> _data;
_F64ByteBuffer(this._data) : super(_data.length * 8, true);
@ -2243,12 +2243,12 @@ mixin _UnmodifiableDoubleListMixin {
//
abstract class _WasmI8ArrayBase {
final WasmIntArray<WasmI8> _data;
final WasmArray<WasmI8> _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<WasmI16> _data;
final WasmArray<WasmI16> _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<WasmI32> _data;
final WasmArray<WasmI32> _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<WasmI64> _data;
final WasmArray<WasmI64> _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<WasmF32> _data;
final WasmArray<WasmF32> _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<WasmF64> _data;
final WasmArray<WasmF64> _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<WasmI8> data, int offsetInElements, int length)
I8List._(WasmArray<WasmI8> data, int offsetInElements, int length)
: super._(data, offsetInElements, length);
factory I8List._withMutability(WasmIntArray<WasmI8> buffer, int offsetInBytes,
factory I8List._withMutability(WasmArray<WasmI8> 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<WasmI8> data, int offsetInElements, int length)
U8List._(WasmArray<WasmI8> data, int offsetInElements, int length)
: super._(data, offsetInElements, length);
WasmIntArray<WasmI8> get data => _data;
WasmArray<WasmI8> get data => _data;
factory U8List._withMutability(WasmIntArray<WasmI8> buffer, int offsetInBytes,
factory U8List._withMutability(WasmArray<WasmI8> 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<WasmI8> data, int offsetInElements, int length)
U8ClampedList._(WasmArray<WasmI8> data, int offsetInElements, int length)
: super._(data, offsetInElements, length);
factory U8ClampedList._withMutability(WasmIntArray<WasmI8> buffer,
factory U8ClampedList._withMutability(WasmArray<WasmI8> 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<WasmI16> data, int offsetInElements, int length)
I16List._(WasmArray<WasmI16> data, int offsetInElements, int length)
: super._(data, offsetInElements, length);
factory I16List._withMutability(WasmIntArray<WasmI16> buffer,
int offsetInBytes, int length, bool mutable) =>
factory I16List._withMutability(WasmArray<WasmI16> 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<WasmI16> data, int offsetInElements, int length)
U16List._(WasmArray<WasmI16> data, int offsetInElements, int length)
: super._(data, offsetInElements, length);
factory U16List._withMutability(WasmIntArray<WasmI16> buffer,
int offsetInBytes, int length, bool mutable) =>
factory U16List._withMutability(WasmArray<WasmI16> 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<WasmI32> data, int offsetInElements, int length)
I32List._(WasmArray<WasmI32> data, int offsetInElements, int length)
: super._(data, offsetInElements, length);
factory I32List._withMutability(WasmIntArray<WasmI32> buffer,
int offsetInBytes, int length, bool mutable) =>
factory I32List._withMutability(WasmArray<WasmI32> 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<WasmI32> data, int offsetInElements, int length)
U32List._(WasmArray<WasmI32> data, int offsetInElements, int length)
: super._(data, offsetInElements, length);
factory U32List._withMutability(WasmIntArray<WasmI32> buffer,
int offsetInBytes, int length, bool mutable) =>
factory U32List._withMutability(WasmArray<WasmI32> 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<WasmI64> data, int offsetInElements, int length)
I64List._(WasmArray<WasmI64> data, int offsetInElements, int length)
: super._(data, offsetInElements, length);
factory I64List._withMutability(WasmIntArray<WasmI64> buffer,
int offsetInBytes, int length, bool mutable) =>
factory I64List._withMutability(WasmArray<WasmI64> 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<WasmI64> data, int offsetInElements, int length)
U64List._(WasmArray<WasmI64> data, int offsetInElements, int length)
: super._(data, offsetInElements, length);
factory U64List._withMutability(WasmIntArray<WasmI64> buffer,
int offsetInBytes, int length, bool mutable) =>
factory U64List._withMutability(WasmArray<WasmI64> 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<WasmF32> data, int offsetInElements, int length)
F32List._(WasmArray<WasmF32> data, int offsetInElements, int length)
: super._(data, offsetInElements, length);
factory F32List._withMutability(WasmFloatArray<WasmF32> buffer,
int offsetInBytes, int length, bool mutable) =>
factory F32List._withMutability(WasmArray<WasmF32> 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<WasmF64> data, int offsetInElements, int length)
F64List._(WasmArray<WasmF64> data, int offsetInElements, int length)
: super._(data, offsetInElements, length);
factory F64List._withMutability(WasmFloatArray<WasmF64> buffer,
int offsetInBytes, int length, bool mutable) =>
factory F64List._withMutability(WasmArray<WasmF64> 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<WasmI8> data, int offsetInElements, int length)
UnmodifiableI8List._(WasmArray<WasmI8> 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<WasmI8> data, int offsetInElements, int length)
UnmodifiableU8List._(WasmArray<WasmI8> 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<WasmI8> data, int offsetInElements, int length)
WasmArray<WasmI8> 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<WasmI16> data, int offsetInElements, int length)
WasmArray<WasmI16> 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<WasmI16> data, int offsetInElements, int length)
WasmArray<WasmI16> 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<WasmI32> data, int offsetInElements, int length)
WasmArray<WasmI32> 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<WasmI32> data, int offsetInElements, int length)
WasmArray<WasmI32> 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<WasmI64> data, int offsetInElements, int length)
WasmArray<WasmI64> 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<WasmI64> data, int offsetInElements, int length)
WasmArray<WasmI64> 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<WasmF32> data, int offsetInElements, int length)
WasmArray<WasmF32> 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<WasmF64> data, int offsetInElements, int length)
WasmArray<WasmF64> data, int offsetInElements, int length)
: super._(data, offsetInElements, length);
@override

View file

@ -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<T extends _WasmInt> extends WasmArrayRef {
class WasmArray<T> extends WasmArrayRef {
/// Dummy value field to contain the value for constant instances.
@pragma("wasm:entry-point")
final List<int> _value;
final List<Object?> _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<T> on WasmArray<T> {
external T operator [](int index);
external void operator []=(int index, T value);
external void copy(
int offset, WasmArray<T> source, int sourceOffset, int size);
external void fill(int offset, T value, int size);
}
extension I8ArrayExt on WasmArray<WasmI8> {
external int readSigned(int index);
external int readUnsigned(int index);
external void write(int index, int value);
external void copy(
int offset, WasmIntArray<T> 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<T extends _WasmFloat> extends WasmArrayRef {
external factory WasmFloatArray(int length);
extension I16ArrayExt on WasmArray<WasmI16> {
external int readSigned(int index);
external int readUnsigned(int index);
external void write(int index, int value);
}
extension I32ArrayExt on WasmArray<WasmI32> {
external int readSigned(int index);
external int readUnsigned(int index);
external void write(int index, int value);
}
extension I64ArrayExt on WasmArray<WasmI64> {
external int read(int index);
external void write(int index, int value);
}
extension F32ArrayExt on WasmArray<WasmF32> {
external double read(int index);
external void write(int index, double value);
external void copy(
int offset, WasmFloatArray<T> 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<T extends Object?> extends WasmArrayRef {
/// Dummy value field to contain the value for constant instances.
@pragma("wasm:entry-point")
final List<T> _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<T> source, int sourceOffset, int size);
external void fill(int offset, T value, int size);
extension F64ArrayExt on WasmArray<WasmF64> {
external double read(int index);
external void write(int index, double value);
}
/// Wasm typed function reference.

View file

@ -126,26 +126,26 @@ test() {
Expect.equals(3, funCount);
// Instantiate some Wasm arrays
final arrayAN = WasmObjectArray<A?>(3, null);
final arrayA = WasmObjectArray<A>(3, A());
final arrayAN = WasmArray<A?>(3);
final arrayA = WasmArray<A>.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<A>.literal([A(), A(), A()]);
final arrayAlit2 = WasmObjectArray<A>.literal([A(), B(), A()]);
final arrayAlit3 = const WasmObjectArray<A>.literal([A(), B(), A()]);
final arrayAlit4 = const WasmObjectArray<A>.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<A>.literal([A(), A(), A()]);
final arrayAlit2 = WasmArray<A>.literal([A(), B(), A()]);
final arrayAlit3 = const WasmArray<A>.literal([A(), B(), A()]);
final arrayAlit4 = const WasmArray<A>.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<WasmI32>.literal([0, 1, 2, 3]);
final int32ArrayC = const WasmIntArray<WasmI32>.literal([0, 10, 20, 30]);
final int32Array = WasmArray<WasmI32>.literal([0, 1, 2, 3]);
final int32ArrayC = const WasmArray<WasmI32>.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<WasmI8>.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);