summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ir/cost.h3
-rw-r--r--src/wasm-builder.h12
-rw-r--r--src/wasm-delegations-fields.def2
-rw-r--r--src/wasm.h4
-rw-r--r--src/wasm/wasm-binary.cpp10
-rw-r--r--src/wasm/wasm-s-parser.cpp3
6 files changed, 32 insertions, 2 deletions
diff --git a/src/ir/cost.h b/src/ir/cost.h
index 823e58ded..ff9bade10 100644
--- a/src/ir/cost.h
+++ b/src/ir/cost.h
@@ -660,7 +660,8 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> {
}
CostType visitRefAs(RefAs* curr) { return 1 + visit(curr->value); }
CostType visitStringNew(StringNew* curr) {
- return 8 + visit(curr->ptr) + maybeVisit(curr->length);
+ return 8 + visit(curr->ptr) + maybeVisit(curr->length) +
+ maybeVisit(curr->start) + maybeVisit(curr->end);
}
CostType visitStringConst(StringConst* curr) { return 4; }
CostType visitStringMeasure(StringMeasure* curr) {
diff --git a/src/wasm-builder.h b/src/wasm-builder.h
index 1faf95d73..3677b9796 100644
--- a/src/wasm-builder.h
+++ b/src/wasm-builder.h
@@ -934,6 +934,18 @@ public:
ret->finalize();
return ret;
}
+ StringNew* makeStringNew(StringNewOp op,
+ Expression* ptr,
+ Expression* start,
+ Expression* end) {
+ auto* ret = wasm.allocator.alloc<StringNew>();
+ ret->op = op;
+ ret->ptr = ptr;
+ ret->start = start;
+ ret->end = end;
+ ret->finalize();
+ return ret;
+ }
StringConst* makeStringConst(Name string) {
auto* ret = wasm.allocator.alloc<StringConst>();
ret->string = string;
diff --git a/src/wasm-delegations-fields.def b/src/wasm-delegations-fields.def
index fa1fa229f..0e3f60826 100644
--- a/src/wasm-delegations-fields.def
+++ b/src/wasm-delegations-fields.def
@@ -698,6 +698,8 @@ switch (DELEGATE_ID) {
case Expression::Id::StringNewId: {
DELEGATE_START(StringNew);
DELEGATE_FIELD_INT(StringNew, op);
+ DELEGATE_FIELD_OPTIONAL_CHILD(StringNew, end);
+ DELEGATE_FIELD_OPTIONAL_CHILD(StringNew, start);
DELEGATE_FIELD_OPTIONAL_CHILD(StringNew, length);
DELEGATE_FIELD_CHILD(StringNew, ptr);
DELEGATE_END(StringNew);
diff --git a/src/wasm.h b/src/wasm.h
index d0f632829..04d4391a2 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -1657,6 +1657,10 @@ public:
// Used only in linear memory variations.
Expression* length = nullptr;
+ // Used only in GC variations.
+ Expression* start = nullptr;
+ Expression* end = nullptr;
+
void finalize();
};
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index b74ef017b..44b07f945 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -6981,6 +6981,8 @@ bool WasmBinaryBuilder::maybeVisitArrayCopy(Expression*& out, uint32_t code) {
bool WasmBinaryBuilder::maybeVisitStringNew(Expression*& out, uint32_t code) {
StringNewOp op;
Expression* length = nullptr;
+ Expression* start = nullptr;
+ Expression* end = nullptr;
if (code == BinaryConsts::StringNewWTF8) {
auto policy = getU32LEB();
switch (policy) {
@@ -7015,13 +7017,19 @@ bool WasmBinaryBuilder::maybeVisitStringNew(Expression*& out, uint32_t code) {
default:
throwError("bad policy for string.new");
}
+ end = popNonVoidExpression();
+ start = popNonVoidExpression();
} else if (code == BinaryConsts::StringNewWTF16Array) {
op = StringNewWTF16Array;
} else {
return false;
}
auto* ptr = popNonVoidExpression();
- out = Builder(wasm).makeStringNew(op, ptr, length);
+ if (length) {
+ out = Builder(wasm).makeStringNew(op, ptr, length);
+ } else {
+ out = Builder(wasm).makeStringNew(op, ptr, start, end);
+ }
return true;
}
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index f13091c91..c1285c647 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -2837,6 +2837,9 @@ Expression* SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op) {
} else {
throw ParseException("bad string.new op", s.line, s.col);
}
+ auto* start = parseExpression(s[i + 1]);
+ auto* end = parseExpression(s[i + 2]);
+ return Builder(wasm).makeStringNew(op, parseExpression(s[i]), start, end);
}
return Builder(wasm).makeStringNew(op, parseExpression(s[i]), length);
}