diff --git a/pkg/dart2wasm/lib/translator.dart b/pkg/dart2wasm/lib/translator.dart index 357de979bfe..4220112bd03 100644 --- a/pkg/dart2wasm/lib/translator.dart +++ b/pkg/dart2wasm/lib/translator.dart @@ -301,6 +301,12 @@ class Translator with KernelNodes { w.NumType.f64: boxedDoubleClass, }; + late final Set boxClasses = { + boxedBoolClass, + boxedIntClass, + boxedDoubleClass, + }; + /// Classes whose identity hash code is their hash code rather than the /// identity hash code field in the struct. Each implementation class maps to /// the class containing the implementation of its `hashCode` getter. @@ -689,7 +695,7 @@ class Translator with KernelNodes { bool isWasmType(Class cls) => cls == wasmTypesBaseClass || _hasSuperclass(cls, wasmTypesBaseClass); - w.StorageType translateStorageType(DartType type) { + w.StorageType translateStorageType(DartType type, {bool unbox = true}) { bool nullable = type.isPotentiallyNullable; if (type is InterfaceType) { Class cls = type.classNode; @@ -741,7 +747,8 @@ class Translator with KernelNodes { } // Other built-in type? - w.StorageType? builtin = builtinTypes[cls]; + w.StorageType? builtin = + (unbox || !boxClasses.contains(cls)) ? builtinTypes[cls] : null; if (builtin != null) { if (!nullable) { return builtin; @@ -816,8 +823,10 @@ class Translator with KernelNodes { while (type is TypeParameterType) { type = type.bound; } - return wasmArrayType( - translateStorageType(type), type.toText(defaultAstTextStrategy), + // If we write `WasmArray` we actually want an array of boxed + // integers and not a `WasmArray`. + return wasmArrayType(translateStorageType(type, unbox: false), + type.toText(defaultAstTextStrategy), mutable: mutable); } diff --git a/sdk/lib/_internal/wasm/lib/convert_patch.dart b/sdk/lib/_internal/wasm/lib/convert_patch.dart index 21752fb1db9..f86ffcb669e 100644 --- a/sdk/lib/_internal/wasm/lib/convert_patch.dart +++ b/sdk/lib/_internal/wasm/lib/convert_patch.dart @@ -2,6 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. +import "dart:_boxed_int"; import "dart:_compact_hash" show createMapFromStringKeyValueListUnsafe; import "dart:_error_utils"; import "dart:_internal" @@ -176,6 +177,15 @@ class _JsonListener { this.value = value; } + @pragma('wasm:prefer-inline') + void handleIntegerNumber(int value) { + if (value.toWasmI64().leU(0xff.toWasmI64())) { + handleNumber(_intBoxes256[value]); + return; + } + handleNumber(value); + } + void handleNumber(num value) { this.value = value; } @@ -1433,7 +1443,7 @@ mixin _ChunkedJsonParser on _ChunkedJsonParserState { void finishChunkNumber(int state, int start, int end) { if (state == NUM_ZERO) { - listener.handleNumber(0); + listener.handleIntegerNumber(0); numberBuffer.clear(); return; } @@ -1578,7 +1588,7 @@ mixin _ChunkedJsonParser on _ChunkedJsonParserState { if (!isDouble) { int bitFlag = -(sign + 1) >> 1; // 0 if sign == -1, -1 if sign == 1 // Negate if bitFlag is -1 by doing ~intValue + 1 - listener.handleNumber((intValue ^ bitFlag) - bitFlag); + listener.handleIntegerNumber((intValue ^ bitFlag) - bitFlag); return position; } // Double values at or above this value (2 ** 53) may have lost precision. @@ -2795,3 +2805,38 @@ double _jsParseFloat(String string) => JS( '(s) => parseFloat(s)', jsStringFromDartString(string).toExternRef, ); + +const ImmutableWasmArray _intBoxes256 = ImmutableWasmArray.literal([ + 0, 1, 2, 3, 4, 5, 6, 7, // + 8, 9, 10, 11, 12, 13, 14, 15, // + 16, 17, 18, 19, 20, 21, 22, 23, // + 24, 25, 26, 27, 28, 29, 30, 31, // + 32, 33, 34, 35, 36, 37, 38, 39, // + 40, 41, 42, 43, 44, 45, 46, 47, // + 48, 49, 50, 51, 52, 53, 54, 55, // + 56, 57, 58, 59, 60, 61, 62, 63, // + 64, 65, 66, 67, 68, 69, 70, 71, // + 72, 73, 74, 75, 76, 77, 78, 79, // + 80, 81, 82, 83, 84, 85, 86, 87, // + 88, 89, 90, 91, 92, 93, 94, 95, // + 96, 97, 98, 99, 100, 101, 102, 103, // + 104, 105, 106, 107, 108, 109, 110, 111, // + 112, 113, 114, 115, 116, 117, 118, 119, // + 120, 121, 122, 123, 124, 125, 126, 127, // + 128, 129, 130, 131, 132, 133, 134, 135, // + 136, 137, 138, 139, 140, 141, 142, 143, // + 144, 145, 146, 147, 148, 149, 150, 151, // + 152, 153, 154, 155, 156, 157, 158, 159, // + 160, 161, 162, 163, 164, 165, 166, 167, // + 168, 169, 170, 171, 172, 173, 174, 175, // + 176, 177, 178, 179, 180, 181, 182, 183, // + 184, 185, 186, 187, 188, 189, 190, 191, // + 192, 193, 194, 195, 196, 197, 198, 199, // + 200, 201, 202, 203, 204, 205, 206, 207, // + 208, 209, 210, 211, 212, 213, 214, 215, // + 216, 217, 218, 219, 220, 221, 222, 223, // + 224, 225, 226, 227, 228, 229, 230, 231, // + 232, 233, 234, 235, 236, 237, 238, 239, // + 240, 241, 242, 243, 244, 245, 246, 247, // + 248, 249, 250, 251, 252, 253, 254, 255, // +]);