Skip to content

Commit c6a061f

Browse files
askeksaCommit Bot
authored and
Commit Bot
committed
[dart2wasm] Implement set literals in the backend
Change-Id: I678a6c16248bfafce2e39c6c3e39505109250f35 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/242861 Reviewed-by: Joshua Litt <[email protected]> Commit-Queue: Aske Simon Christensen <[email protected]>
1 parent e31cc74 commit c6a061f

File tree

8 files changed

+113
-80
lines changed

8 files changed

+113
-80
lines changed

pkg/dart2wasm/lib/code_generator.dart

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,6 +1975,34 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
19751975
return mapLocal.type;
19761976
}
19771977

1978+
@override
1979+
w.ValueType visitSetLiteral(SetLiteral node, w.ValueType expectedType) {
1980+
w.BaseFunction setFactory =
1981+
translator.functions.getFunction(translator.setFactory.reference);
1982+
w.ValueType factoryReturnType = setFactory.type.outputs.single;
1983+
types.makeType(this, node.typeArgument, node);
1984+
b.call(setFactory);
1985+
if (node.expressions.isEmpty) {
1986+
return factoryReturnType;
1987+
}
1988+
w.BaseFunction setAdd =
1989+
translator.functions.getFunction(translator.setAdd.reference);
1990+
w.ValueType addReceiverType = setAdd.type.inputs[0];
1991+
w.ValueType addKeyType = setAdd.type.inputs[1];
1992+
w.Local setLocal = addLocal(addReceiverType);
1993+
translator.convertType(function, factoryReturnType, setLocal.type);
1994+
b.local_set(setLocal);
1995+
for (Expression element in node.expressions) {
1996+
b.local_get(setLocal);
1997+
translator.convertType(function, setLocal.type, addReceiverType);
1998+
wrap(element, addKeyType);
1999+
b.call(setAdd);
2000+
b.drop();
2001+
}
2002+
b.local_get(setLocal);
2003+
return setLocal.type;
2004+
}
2005+
19782006
@override
19792007
w.ValueType visitTypeLiteral(TypeLiteral node, w.ValueType expectedType) {
19802008
return types.makeType(this, node.type, node);

pkg/dart2wasm/lib/constants.dart

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -596,13 +596,6 @@ class ConstantCreator extends ConstantVisitor<ConstantInfo?> {
596596
translator.functions.allocateClass(info.classId);
597597
w.RefType type = info.nonNullableType;
598598
return createConstant(constant, type, (function, b) {
599-
// This computation of the hash mask follows the computations in
600-
// [_ImmutableLinkedHashMapMixin._createIndex] and
601-
// [_HashBase._indexSizeToHashMask].
602-
const int initialIndexSize = 8;
603-
final int indexSize = max(dataElements.length, initialIndexSize);
604-
final int hashMask = (1 << (31 - (indexSize - 1).bitLength)) - 1;
605-
606599
w.RefType indexType =
607600
info.struct.fields[FieldIndex.hashBaseIndex].type as w.RefType;
608601
w.RefType dataType =
@@ -611,7 +604,7 @@ class ConstantCreator extends ConstantVisitor<ConstantInfo?> {
611604
b.i32_const(info.classId);
612605
b.i32_const(initialIdentityHash);
613606
b.ref_null(indexType.heapType); // _index
614-
b.i64_const(hashMask); // _hashMask
607+
b.i64_const(_computeHashMask(constant.entries.length)); // _hashMask
615608
constants.instantiateConstant(function, b, dataList, dataType); // _data
616609
b.i64_const(dataElements.length); // _usedData
617610
b.i64_const(0); // _deletedKeys
@@ -623,6 +616,46 @@ class ConstantCreator extends ConstantVisitor<ConstantInfo?> {
623616
});
624617
}
625618

619+
@override
620+
ConstantInfo? visitSetConstant(SetConstant constant) {
621+
Constant elementTypeConstant = TypeLiteralConstant(constant.typeArgument);
622+
ensureConstant(elementTypeConstant);
623+
ListConstant dataList = ListConstant(const DynamicType(), constant.entries);
624+
ensureConstant(dataList);
625+
626+
ClassInfo info = translator.classInfo[translator.immutableSetClass]!;
627+
translator.functions.allocateClass(info.classId);
628+
w.RefType type = info.nonNullableType;
629+
return createConstant(constant, type, (function, b) {
630+
w.RefType indexType =
631+
info.struct.fields[FieldIndex.hashBaseIndex].type as w.RefType;
632+
w.RefType dataType =
633+
info.struct.fields[FieldIndex.hashBaseData].type as w.RefType;
634+
635+
b.i32_const(info.classId);
636+
b.i32_const(initialIdentityHash);
637+
b.ref_null(indexType.heapType); // _index
638+
b.i64_const(_computeHashMask(constant.entries.length)); // _hashMask
639+
constants.instantiateConstant(function, b, dataList, dataType); // _data
640+
b.i64_const(constant.entries.length); // _usedData
641+
b.i64_const(0); // _deletedKeys
642+
constants.instantiateConstant(
643+
function, b, elementTypeConstant, constants.typeInfo.nullableType);
644+
translator.struct_new(b, info);
645+
});
646+
}
647+
648+
int _computeHashMask(int entries) {
649+
// This computation of the hash mask follows the computations in
650+
// [_ImmutableLinkedHashMapMixin._createIndex],
651+
// [_ImmutableLinkedHashSetMixin._createIndex] and
652+
// [_HashBase._indexSizeToHashMask].
653+
const int initialIndexSize = 8;
654+
final int indexSize = max(entries * 2, initialIndexSize);
655+
final int hashMask = (1 << (31 - (indexSize - 1).bitLength)) - 1;
656+
return hashMask;
657+
}
658+
626659
@override
627660
ConstantInfo? visitStaticTearOffConstant(StaticTearOffConstant constant) {
628661
w.DefinedFunction closureFunction =

pkg/dart2wasm/lib/constants_backend.dart

Lines changed: 0 additions & 59 deletions
This file was deleted.

pkg/dart2wasm/lib/intrinsics.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ class Intrinsifier {
168168
}
169169

170170
// _HashAbstractImmutableBase._indexNullable
171-
if (target == translator.immutableMapIndexNullable) {
171+
if (target == translator.hashImmutableIndexNullable) {
172172
ClassInfo info = translator.classInfo[translator.hashFieldBaseClass]!;
173173
codeGen.wrap(receiver, info.nullableType);
174174
b.struct_get(info.struct, FieldIndex.hashBaseIndex);

pkg/dart2wasm/lib/target.dart

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,20 @@ import 'package:vm/transformations/ffi/definitions.dart'
2121
import 'package:vm/transformations/ffi/use_sites.dart' as transformFfiUseSites
2222
show transformLibraries;
2323

24-
import 'package:dart2wasm/constants_backend.dart';
2524
import 'package:dart2wasm/transformers.dart' as wasmTrans;
2625

2726
class WasmTarget extends Target {
2827
Class? _growableList;
2928
Class? _immutableList;
3029
Class? _wasmImmutableLinkedHashMap;
31-
Class? _unmodifiableSet;
30+
Class? _wasmImmutableLinkedHashSet;
3231
Class? _compactLinkedCustomHashMap;
33-
Class? _compactLinkedHashSet;
32+
Class? _compactLinkedCustomHashSet;
3433
Class? _oneByteString;
3534
Class? _twoByteString;
3635

3736
@override
38-
late final ConstantsBackend constantsBackend;
37+
ConstantsBackend get constantsBackend => const ConstantsBackend();
3938

4039
@override
4140
String get name => 'wasm';
@@ -85,7 +84,6 @@ class WasmTarget extends Target {
8584
DiagnosticReporter diagnosticReporter,
8685
{void Function(String msg)? logger,
8786
ChangedStructureNotifier? changedStructureNotifier}) {
88-
constantsBackend = WasmConstantsBackend(coreTypes);
8987
_patchHostEndian(coreTypes);
9088
}
9189

@@ -167,7 +165,7 @@ class WasmTarget extends Target {
167165
}
168166

169167
@override
170-
bool get supportsSetLiterals => false;
168+
bool get supportsSetLiterals => true;
171169

172170
@override
173171
int get enabledLateLowerings => LateLowering.all;
@@ -213,14 +211,14 @@ class WasmTarget extends Target {
213211

214212
@override
215213
Class concreteSetLiteralClass(CoreTypes coreTypes) {
216-
return _compactLinkedHashSet ??=
217-
coreTypes.index.getClass('dart:collection', '_CompactLinkedHashSet');
214+
return _compactLinkedCustomHashSet ??= coreTypes.index
215+
.getClass('dart:collection', '_CompactLinkedCustomHashSet');
218216
}
219217

220218
@override
221219
Class concreteConstSetLiteralClass(CoreTypes coreTypes) {
222-
return _unmodifiableSet ??=
223-
coreTypes.index.getClass('dart:collection', '_UnmodifiableSet');
220+
return _wasmImmutableLinkedHashSet ??= coreTypes.index
221+
.getClass('dart:collection', '_WasmImmutableLinkedHashSet');
224222
}
225223

226224
@override

pkg/dart2wasm/lib/translator.dart

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class Translator {
8383
late final Class growableListClass;
8484
late final Class immutableListClass;
8585
late final Class immutableMapClass;
86+
late final Class immutableSetClass;
8687
late final Class hashFieldBaseClass;
8788
late final Class stringBaseClass;
8889
late final Class oneByteStringClass;
@@ -105,7 +106,9 @@ class Translator {
105106
late final Procedure throwWasmRefError;
106107
late final Procedure mapFactory;
107108
late final Procedure mapPut;
108-
late final Procedure immutableMapIndexNullable;
109+
late final Procedure setFactory;
110+
late final Procedure setAdd;
111+
late final Procedure hashImmutableIndexNullable;
109112
late final Map<Class, w.StorageType> builtinTypes;
110113
late final Map<w.ValueType, Class> boxedClasses;
111114

@@ -183,6 +186,7 @@ class Translator {
183186
growableListClass = lookupCore("_GrowableList");
184187
immutableListClass = lookupCore("_ImmutableList");
185188
immutableMapClass = lookupCollection("_WasmImmutableLinkedHashMap");
189+
immutableSetClass = lookupCollection("_WasmImmutableLinkedHashSet");
186190
hashFieldBaseClass = lookupCollection("_HashFieldBase");
187191
stringBaseClass = lookupCore("_StringBase");
188192
oneByteStringClass = lookupCore("_OneByteString");
@@ -216,7 +220,13 @@ class Translator {
216220
.superclass! // _LinkedHashMapMixin<K, V>
217221
.procedures
218222
.firstWhere((p) => p.name.text == "[]=");
219-
immutableMapIndexNullable = lookupCollection("_HashAbstractImmutableBase")
223+
setFactory = lookupCollection("LinkedHashSet").procedures.firstWhere(
224+
(p) => p.kind == ProcedureKind.Factory && p.name.text == "_default");
225+
setAdd = lookupCollection("_CompactLinkedCustomHashSet")
226+
.superclass! // _LinkedHashSetMixin<K, V>
227+
.procedures
228+
.firstWhere((p) => p.name.text == "add");
229+
hashImmutableIndexNullable = lookupCollection("_HashAbstractImmutableBase")
220230
.procedures
221231
.firstWhere((p) => p.name.text == "_indexNullable");
222232
builtinTypes = {

sdk/lib/_internal/vm/lib/compact_hash.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,9 @@ class _CompactLinkedCustomHashSet<E> extends _HashFieldBase
10961096
E? lookup(Object? o) => _validKey(o) ? super.lookup(o) : null;
10971097
bool remove(Object? o) => _validKey(o) ? super.remove(o) : false;
10981098

1099+
@pragma("wasm:entry-point")
1100+
bool add(E key);
1101+
10991102
_CompactLinkedCustomHashSet(this._equality, this._hasher, validKey)
11001103
: _validKey = (validKey != null) ? validKey : new _TypeTest<E>().test;
11011104

sdk/lib/_internal/wasm/lib/hash_factories.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ class LinkedHashSet<E> {
4646
return new _CompactLinkedCustomHashSet<E>(equals, hashCode, isValidKey);
4747
}
4848

49+
@pragma("wasm:entry-point")
50+
factory LinkedHashSet._default() =>
51+
_CompactLinkedCustomHashSet<E>(_defaultEquals, _defaultHashCode, null);
52+
4953
@patch
5054
factory LinkedHashSet.identity() => new _CompactLinkedIdentityHashSet<E>();
5155
}
@@ -70,3 +74,19 @@ class _WasmImmutableLinkedHashMap<K, V> extends _HashWasmImmutableBase
7074
"Immutable maps can only be instantiated via constants");
7175
}
7276
}
77+
78+
@pragma("wasm:entry-point")
79+
class _WasmImmutableLinkedHashSet<E> extends _HashWasmImmutableBase
80+
with
81+
SetMixin<E>,
82+
_HashBase,
83+
_OperatorEqualsAndHashCode,
84+
_LinkedHashSetMixin<E>,
85+
_UnmodifiableSetMixin<E>,
86+
_ImmutableLinkedHashSetMixin<E>
87+
implements LinkedHashSet<E> {
88+
factory _WasmImmutableLinkedHashSet._uninstantiable() {
89+
throw new UnsupportedError(
90+
"Immutable sets can only be instantiated via constants");
91+
}
92+
}

0 commit comments

Comments
 (0)