Skip to content

Commit 3ed93d0

Browse files
authored
[Wasm GC] ArrayInit support (#4138)
array.init is like array.new_with_rtt except that it takes as arguments the values to initialize the array with (as opposed to a size and an optional initial value). Spec: https://docs.google.com/document/d/1afthjsL_B9UaMqCA5ekgVmOm75BVFu6duHNsN9-gnXw/edit#
1 parent 23e452a commit 3ed93d0

31 files changed

+308
-23
lines changed

scripts/gen-s-parser.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -559,19 +559,20 @@
559559
("struct.set", "makeStructSet(s)"),
560560
("array.new_with_rtt", "makeArrayNew(s, false)"),
561561
("array.new_default_with_rtt", "makeArrayNew(s, true)"),
562-
("array.get", "makeArrayGet(s)"),
563-
("array.get_s", "makeArrayGet(s, true)"),
564-
("array.get_u", "makeArrayGet(s, false)"),
565-
("array.set", "makeArraySet(s)"),
566-
("array.len", "makeArrayLen(s)"),
567-
("array.copy", "makeArrayCopy(s)"),
568-
("ref.is_func", "makeRefIs(s, RefIsFunc)"),
569-
("ref.is_data", "makeRefIs(s, RefIsData)"),
570-
("ref.is_i31", "makeRefIs(s, RefIsI31)"),
571-
("ref.as_non_null", "makeRefAs(s, RefAsNonNull)"),
572-
("ref.as_func", "makeRefAs(s, RefAsFunc)"),
573-
("ref.as_data", "makeRefAs(s, RefAsData)"),
574-
("ref.as_i31", "makeRefAs(s, RefAsI31)"),
562+
("array.init", "makeArrayInit(s)"),
563+
("array.get", "makeArrayGet(s)"),
564+
("array.get_s", "makeArrayGet(s, true)"),
565+
("array.get_u", "makeArrayGet(s, false)"),
566+
("array.set", "makeArraySet(s)"),
567+
("array.len", "makeArrayLen(s)"),
568+
("array.copy", "makeArrayCopy(s)"),
569+
("ref.is_func", "makeRefIs(s, RefIsFunc)"),
570+
("ref.is_data", "makeRefIs(s, RefIsData)"),
571+
("ref.is_i31", "makeRefIs(s, RefIsI31)"),
572+
("ref.as_non_null", "makeRefAs(s, RefAsNonNull)"),
573+
("ref.as_func", "makeRefAs(s, RefAsFunc)"),
574+
("ref.as_data", "makeRefAs(s, RefAsData)"),
575+
("ref.as_i31", "makeRefAs(s, RefAsI31)"),
575576
]
576577

577578

src/gen-s-parser.inc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ switch (op[0]) {
3333
default: goto parse_error;
3434
}
3535
}
36+
case 'i':
37+
if (strcmp(op, "array.init") == 0) { return makeArrayInit(s); }
38+
goto parse_error;
3639
case 'l':
3740
if (strcmp(op, "array.len") == 0) { return makeArrayLen(s); }
3841
goto parse_error;

src/ir/ReFinalize.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ void ReFinalize::visitStructNew(StructNew* curr) { curr->finalize(); }
162162
void ReFinalize::visitStructGet(StructGet* curr) { curr->finalize(); }
163163
void ReFinalize::visitStructSet(StructSet* curr) { curr->finalize(); }
164164
void ReFinalize::visitArrayNew(ArrayNew* curr) { curr->finalize(); }
165+
void ReFinalize::visitArrayInit(ArrayInit* curr) { curr->finalize(); }
165166
void ReFinalize::visitArrayGet(ArrayGet* curr) { curr->finalize(); }
166167
void ReFinalize::visitArraySet(ArraySet* curr) { curr->finalize(); }
167168
void ReFinalize::visitArrayLen(ArrayLen* curr) { curr->finalize(); }

src/ir/cost.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,13 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> {
606606
CostType visitArrayNew(ArrayNew* curr) {
607607
return 4 + visit(curr->rtt) + visit(curr->size) + maybeVisit(curr->init);
608608
}
609+
CostType visitArrayInit(ArrayInit* curr) {
610+
CostType ret = 4 + visit(curr->rtt);
611+
for (auto* child : curr->values) {
612+
ret += visit(child);
613+
}
614+
return ret;
615+
}
609616
CostType visitArrayGet(ArrayGet* curr) {
610617
return 1 + nullCheckCost(curr->ref) + visit(curr->ref) + visit(curr->index);
611618
}

src/ir/effects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,7 @@ class EffectAnalyzer {
642642
}
643643
}
644644
void visitArrayNew(ArrayNew* curr) {}
645+
void visitArrayInit(ArrayInit* curr) {}
645646
void visitArrayGet(ArrayGet* curr) {
646647
parent.readsArray = true;
647648
// traps when the arg is null or the index out of bounds

src/ir/global-utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ inline bool canInitializeGlobal(Expression* curr) {
6565
}
6666
if (Properties::isSingleConstantExpression(curr) || curr->is<GlobalGet>() ||
6767
curr->is<RttCanon>() || curr->is<RttSub>() || curr->is<StructNew>() ||
68-
curr->is<ArrayNew>() || curr->is<I31New>()) {
68+
curr->is<ArrayNew>() || curr->is<ArrayInit>() || curr->is<I31New>()) {
6969
for (auto* child : ChildIterator(curr)) {
7070
if (!canInitializeGlobal(child)) {
7171
return false;

src/ir/properties.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ bool isGenerative(Expression* curr, FeatureSet features) {
3232
bool generative = false;
3333
void visitStructNew(StructNew* curr) { generative = true; }
3434
void visitArrayNew(ArrayNew* curr) { generative = true; }
35+
void visitArrayInit(ArrayInit* curr) { generative = true; }
3536
} scanner;
3637
scanner.walk(curr);
3738
return scanner.generative;

src/js/binaryen.js-post.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ function initializeConstants() {
109109
'StructGet',
110110
'StructSet',
111111
'ArrayNew',
112+
'ArrayInit',
112113
'ArrayGet',
113114
'ArraySet',
114115
'ArrayLen'

src/passes/Precompute.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class PrecomputingExpressionRunner
9494
Flow visitStructNew(StructNew* curr) { return Flow(NONCONSTANT_FLOW); }
9595
Flow visitStructGet(StructGet* curr) { return Flow(NONCONSTANT_FLOW); }
9696
Flow visitArrayNew(ArrayNew* curr) { return Flow(NONCONSTANT_FLOW); }
97+
Flow visitArrayInit(ArrayInit* curr) { return Flow(NONCONSTANT_FLOW); }
9798
Flow visitArrayGet(ArrayGet* curr) { return Flow(NONCONSTANT_FLOW); }
9899
Flow visitArrayLen(ArrayLen* curr) { return Flow(NONCONSTANT_FLOW); }
99100
Flow visitArrayCopy(ArrayCopy* curr) { return Flow(NONCONSTANT_FLOW); }

src/passes/Print.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2006,6 +2006,10 @@ struct PrintExpressionContents
20062006
o << "with_rtt ";
20072007
TypeNamePrinter(o, wasm).print(curr->rtt->type.getHeapType());
20082008
}
2009+
void visitArrayInit(ArrayInit* curr) {
2010+
printMedium(o, "array.init ");
2011+
TypeNamePrinter(o, wasm).print(curr->rtt->type.getHeapType());
2012+
}
20092013
void visitArrayGet(ArrayGet* curr) {
20102014
if (printUnreachableReplacement(curr->ref)) {
20112015
return;

0 commit comments

Comments
 (0)