diff options
-rw-r--r-- | src/ir/cost.h | 3 | ||||
-rw-r--r-- | src/wasm-builder.h | 12 | ||||
-rw-r--r-- | src/wasm-delegations-fields.def | 2 | ||||
-rw-r--r-- | src/wasm.h | 4 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 10 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 3 | ||||
-rw-r--r-- | test/lit/strings.wast | 14 |
7 files changed, 46 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); } diff --git a/test/lit/strings.wast b/test/lit/strings.wast index 859d49bee..5867a95ed 100644 --- a/test/lit/strings.wast +++ b/test/lit/strings.wast @@ -440,16 +440,22 @@ ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.new_wtf8_array utf8 ;; CHECK-NEXT: (local.get $array) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.const 2) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.new_wtf8_array wtf8 ;; CHECK-NEXT: (local.get $array) + ;; CHECK-NEXT: (i32.const 3) + ;; CHECK-NEXT: (i32.const 4) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.new_wtf8_array replace ;; CHECK-NEXT: (local.get $array) + ;; CHECK-NEXT: (i32.const 5) + ;; CHECK-NEXT: (i32.const 6) ;; CHECK-NEXT: ) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop @@ -462,21 +468,29 @@ (drop (string.new_wtf8_array utf8 (local.get $array) + (i32.const 1) + (i32.const 2) ) ) (drop (string.new_wtf8_array wtf8 (local.get $array) + (i32.const 3) + (i32.const 4) ) ) (drop (string.new_wtf8_array replace (local.get $array) + (i32.const 5) + (i32.const 6) ) ) (drop (string.new_wtf16_array (local.get $array) + (i32.const 7) + (i32.const 8) ) ) ) |