diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gen-s-parser.inc | 86 | ||||
-rw-r--r-- | src/ir/ReFinalize.cpp | 4 | ||||
-rw-r--r-- | src/ir/cost.h | 8 | ||||
-rw-r--r-- | src/ir/effects.h | 8 | ||||
-rw-r--r-- | src/ir/possible-contents.cpp | 8 | ||||
-rw-r--r-- | src/passes/Print.cpp | 15 | ||||
-rw-r--r-- | src/wasm-binary.h | 5 | ||||
-rw-r--r-- | src/wasm-builder.h | 24 | ||||
-rw-r--r-- | src/wasm-delegations-fields.def | 16 | ||||
-rw-r--r-- | src/wasm-delegations.def | 2 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 6 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 2 | ||||
-rw-r--r-- | src/wasm.h | 31 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 34 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 11 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 19 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 17 | ||||
-rw-r--r-- | src/wasm/wat-parser.cpp | 16 | ||||
-rw-r--r-- | src/wasm2js.h | 8 |
19 files changed, 298 insertions, 22 deletions
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index 5fcbd3943..dd7b57917 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -3221,17 +3221,36 @@ switch (op[0]) { case 'r': if (strcmp(op, "stringview_iter.rewind") == 0) { return makeStringIterMove(s, StringIterMoveRewind); } goto parse_error; + case 's': + if (strcmp(op, "stringview_iter.slice") == 0) { return makeStringSliceIter(s); } + goto parse_error; default: goto parse_error; } } case 'w': { switch (op[14]) { - case '1': - if (strcmp(op, "stringview_wtf16.get_codeunit") == 0) { return makeStringWTF16Get(s); } - goto parse_error; - case '8': - if (strcmp(op, "stringview_wtf8.advance") == 0) { return makeStringWTF8Advance(s); } - goto parse_error; + case '1': { + switch (op[17]) { + case 'g': + if (strcmp(op, "stringview_wtf16.get_codeunit") == 0) { return makeStringWTF16Get(s); } + goto parse_error; + case 's': + if (strcmp(op, "stringview_wtf16.slice") == 0) { return makeStringSliceWTF(s, StringSliceWTF16); } + goto parse_error; + default: goto parse_error; + } + } + case '8': { + switch (op[16]) { + case 'a': + if (strcmp(op, "stringview_wtf8.advance") == 0) { return makeStringWTF8Advance(s); } + goto parse_error; + case 's': + if (strcmp(op, "stringview_wtf8.slice") == 0) { return makeStringSliceWTF(s, StringSliceWTF8); } + goto parse_error; + default: goto parse_error; + } + } default: goto parse_error; } } @@ -8941,25 +8960,56 @@ switch (op[0]) { return *ret; } goto parse_error; + case 's': + if (op == "stringview_iter.slice"sv) { + auto ret = makeStringSliceIter(ctx, in); + CHECK_ERR(ret); + return *ret; + } + goto parse_error; default: goto parse_error; } } case 'w': { switch (op[14]) { - case '1': - if (op == "stringview_wtf16.get_codeunit"sv) { - auto ret = makeStringWTF16Get(ctx, in); - CHECK_ERR(ret); - return *ret; + case '1': { + switch (op[17]) { + case 'g': + if (op == "stringview_wtf16.get_codeunit"sv) { + auto ret = makeStringWTF16Get(ctx, in); + CHECK_ERR(ret); + return *ret; + } + goto parse_error; + case 's': + if (op == "stringview_wtf16.slice"sv) { + auto ret = makeStringSliceWTF(ctx, in, StringSliceWTF16); + CHECK_ERR(ret); + return *ret; + } + goto parse_error; + default: goto parse_error; } - goto parse_error; - case '8': - if (op == "stringview_wtf8.advance"sv) { - auto ret = makeStringWTF8Advance(ctx, in); - CHECK_ERR(ret); - return *ret; + } + case '8': { + switch (op[16]) { + case 'a': + if (op == "stringview_wtf8.advance"sv) { + auto ret = makeStringWTF8Advance(ctx, in); + CHECK_ERR(ret); + return *ret; + } + goto parse_error; + case 's': + if (op == "stringview_wtf8.slice"sv) { + auto ret = makeStringSliceWTF(ctx, in, StringSliceWTF8); + CHECK_ERR(ret); + return *ret; + } + goto parse_error; + default: goto parse_error; } - goto parse_error; + } default: goto parse_error; } } diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp index 2c3b6c1f0..771553e11 100644 --- a/src/ir/ReFinalize.cpp +++ b/src/ir/ReFinalize.cpp @@ -185,6 +185,10 @@ void ReFinalize::visitStringWTF8Advance(StringWTF8Advance* curr) { void ReFinalize::visitStringWTF16Get(StringWTF16Get* curr) { curr->finalize(); } void ReFinalize::visitStringIterNext(StringIterNext* curr) { curr->finalize(); } void ReFinalize::visitStringIterMove(StringIterMove* curr) { curr->finalize(); } +void ReFinalize::visitStringSliceWTF(StringSliceWTF* curr) { curr->finalize(); } +void ReFinalize::visitStringSliceIter(StringSliceIter* curr) { + curr->finalize(); +} void ReFinalize::visitFunction(Function* curr) { // we may have changed the body from unreachable to none, which might be bad diff --git a/src/ir/cost.h b/src/ir/cost.h index 3ed37e297..8ebc6eb9b 100644 --- a/src/ir/cost.h +++ b/src/ir/cost.h @@ -672,7 +672,7 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> { } CostType visitRefAs(RefAs* curr) { return 1 + visit(curr->value); } CostType visitStringNew(StringNew* curr) { - return 4 + visit(curr->ptr) + visit(curr->length); + return 8 + visit(curr->ptr) + visit(curr->length); } CostType visitStringConst(StringConst* curr) { return 4; } CostType visitStringMeasure(StringMeasure* curr) { @@ -701,6 +701,12 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> { CostType visitStringIterMove(StringIterMove* curr) { return 4 + visit(curr->ref) + visit(curr->num); } + CostType visitStringSliceWTF(StringSliceWTF* curr) { + return 8 + visit(curr->ref) + visit(curr->start) + visit(curr->end); + } + CostType visitStringSliceIter(StringSliceIter* curr) { + return 8 + visit(curr->ref) + visit(curr->num); + } private: CostType nullCheckCost(Expression* ref) { diff --git a/src/ir/effects.h b/src/ir/effects.h index 7045d9382..58480f0ff 100644 --- a/src/ir/effects.h +++ b/src/ir/effects.h @@ -777,6 +777,14 @@ private: parent.readsArray = true; parent.writesArray = true; } + void visitStringSliceWTF(StringSliceWTF* curr) { + // traps when ref is null. + parent.implicitTrap = true; + } + void visitStringSliceIter(StringSliceIter* curr) { + // traps when ref is null. + parent.implicitTrap = true; + } }; public: diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp index 35a855614..a0e64e236 100644 --- a/src/ir/possible-contents.cpp +++ b/src/ir/possible-contents.cpp @@ -717,6 +717,14 @@ struct InfoCollector // TODO: optimize when possible addRoot(curr); } + void visitStringSliceWTF(StringSliceWTF* curr) { + // TODO: optimize when possible + addRoot(curr); + } + void visitStringSliceIter(StringSliceIter* curr) { + // TODO: optimize when possible + addRoot(curr); + } // TODO: Model which throws can go to which catches. For now, anything thrown // is sent to the location of that tag, and any catch of that tag can diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index f41bdcd26..526059a66 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2315,6 +2315,21 @@ struct PrintExpressionContents WASM_UNREACHABLE("invalid string.move*"); } } + void visitStringSliceWTF(StringSliceWTF* curr) { + switch (curr->op) { + case StringSliceWTF8: + printMedium(o, "stringview_wtf8.slice"); + break; + case StringSliceWTF16: + printMedium(o, "stringview_wtf16.slice"); + break; + default: + WASM_UNREACHABLE("invalid string.slice*"); + } + } + void visitStringSliceIter(StringSliceIter* curr) { + printMedium(o, "stringview_iter.slice"); + } }; // Prints an expression in s-expr format, including both the diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 9c5d6cd98..ba8d547d8 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1149,12 +1149,15 @@ enum ASTNodes { StringIsUSV = 0x8a, StringAsWTF8 = 0x90, StringViewWTF8Advance = 0x91, + StringViewWTF8Slice = 0x93, StringAsWTF16 = 0x98, StringViewWTF16GetCodePoint = 0x9a, + StringViewWTF16Slice = 0x9c, StringAsIter = 0xa0, StringViewIterNext = 0xa1, StringViewIterAdvance = 0xa2, StringViewIterRewind = 0xa3, + StringViewIterSlice = 0xa4, }; enum MemoryAccess { @@ -1746,6 +1749,8 @@ public: bool maybeVisitStringWTF16Get(Expression*& out, uint32_t code); bool maybeVisitStringIterNext(Expression*& out, uint32_t code); bool maybeVisitStringIterMove(Expression*& out, uint32_t code); + bool maybeVisitStringSliceWTF(Expression*& out, uint32_t code); + bool maybeVisitStringSliceIter(Expression*& out, uint32_t code); void visitSelect(Select* curr, uint8_t code); void visitReturn(Return* curr); void visitMemorySize(MemorySize* curr); diff --git a/src/wasm-builder.h b/src/wasm-builder.h index f636ea799..eec86bc50 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -1063,9 +1063,8 @@ public: ret->finalize(); return ret; } - StringIterMove* makeStringIterMove(StringIterMoveOp op, - Expression* ref, - Expression* num = nullptr) { + StringIterMove* + makeStringIterMove(StringIterMoveOp op, Expression* ref, Expression* num) { auto* ret = wasm.allocator.alloc<StringIterMove>(); ret->op = op; ret->ref = ref; @@ -1073,6 +1072,25 @@ public: ret->finalize(); return ret; } + StringSliceWTF* makeStringSliceWTF(StringSliceWTFOp op, + Expression* ref, + Expression* start, + Expression* end) { + auto* ret = wasm.allocator.alloc<StringSliceWTF>(); + ret->op = op; + ret->ref = ref; + ret->start = start; + ret->end = end; + ret->finalize(); + return ret; + } + StringSliceIter* makeStringSliceIter(Expression* ref, Expression* num) { + auto* ret = wasm.allocator.alloc<StringSliceIter>(); + ret->ref = ref; + ret->num = num; + ret->finalize(); + return ret; + } // Additional helpers diff --git a/src/wasm-delegations-fields.def b/src/wasm-delegations-fields.def index d474f007e..41dd7d660 100644 --- a/src/wasm-delegations-fields.def +++ b/src/wasm-delegations-fields.def @@ -792,6 +792,22 @@ switch (DELEGATE_ID) { DELEGATE_END(StringIterMove); break; } + case Expression::Id::StringSliceWTFId: { + DELEGATE_START(StringSliceWTF); + DELEGATE_FIELD_INT(StringSliceWTF, op); + DELEGATE_FIELD_CHILD(StringSliceWTF, end); + DELEGATE_FIELD_CHILD(StringSliceWTF, start); + DELEGATE_FIELD_CHILD(StringSliceWTF, ref); + DELEGATE_END(StringSliceWTF); + break; + } + case Expression::Id::StringSliceIterId: { + DELEGATE_START(StringSliceIter); + DELEGATE_FIELD_CHILD(StringSliceIter, num); + DELEGATE_FIELD_CHILD(StringSliceIter, ref); + DELEGATE_END(StringSliceIter); + break; + } } #undef DELEGATE_ID diff --git a/src/wasm-delegations.def b/src/wasm-delegations.def index 5b508f080..24531b149 100644 --- a/src/wasm-delegations.def +++ b/src/wasm-delegations.def @@ -96,5 +96,7 @@ DELEGATE(StringWTF8Advance); DELEGATE(StringWTF16Get); DELEGATE(StringIterNext); DELEGATE(StringIterMove); +DELEGATE(StringSliceWTF); +DELEGATE(StringSliceIter); #undef DELEGATE diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index a07103dca..478b33bc4 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -1988,6 +1988,12 @@ public: Flow visitStringIterMove(StringIterMove* curr) { WASM_UNREACHABLE("unimplemented stringview_adjust*"); } + Flow visitStringSliceWTF(StringSliceWTF* curr) { + WASM_UNREACHABLE("unimplemented stringview_adjust*"); + } + Flow visitStringSliceIter(StringSliceIter* curr) { + WASM_UNREACHABLE("unimplemented stringview_adjust*"); + } virtual void trap(const char* why) { WASM_UNREACHABLE("unimp"); } diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 6b2ddd711..0829a35f2 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -314,6 +314,8 @@ private: Expression* makeStringWTF16Get(Element& s); Expression* makeStringIterNext(Element& s); Expression* makeStringIterMove(Element& s, StringIterMoveOp op); + Expression* makeStringSliceWTF(Element& s, StringSliceWTFOp op); + Expression* makeStringSliceIter(Element& s); // Helper functions Type parseOptionalResultType(Element& s, Index& i); diff --git a/src/wasm.h b/src/wasm.h index 5bfd151a1..357c613a7 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -614,6 +614,11 @@ enum StringIterMoveOp { StringIterMoveRewind, }; +enum StringSliceWTFOp { + StringSliceWTF8, + StringSliceWTF16, +}; + // // Expressions // @@ -720,6 +725,8 @@ public: StringWTF16GetId, StringIterNextId, StringIterMoveId, + StringSliceWTFId, + StringSliceIterId, NumExpressionIds }; Id _id; @@ -1810,6 +1817,30 @@ public: void finalize(); }; +class StringSliceWTF : public SpecificExpression<Expression::StringSliceWTFId> { +public: + StringSliceWTF(MixedArena& allocator) {} + + StringSliceWTFOp op; + + Expression* ref; + Expression* start; + Expression* end; + + void finalize(); +}; + +class StringSliceIter + : public SpecificExpression<Expression::StringSliceIterId> { +public: + StringSliceIter(MixedArena& allocator) {} + + Expression* ref; + Expression* num; + + void finalize(); +}; + // Globals struct Named { diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index e61fd1e27..59276124e 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -3951,6 +3951,12 @@ BinaryConsts::ASTNodes WasmBinaryBuilder::readExpression(Expression*& curr) { if (maybeVisitStringIterMove(curr, opcode)) { break; } + if (maybeVisitStringSliceWTF(curr, opcode)) { + break; + } + if (maybeVisitStringSliceIter(curr, opcode)) { + break; + } if (opcode == BinaryConsts::RefIsFunc || opcode == BinaryConsts::RefIsData || opcode == BinaryConsts::RefIsI31) { @@ -7329,6 +7335,34 @@ bool WasmBinaryBuilder::maybeVisitStringIterMove(Expression*& out, return true; } +bool WasmBinaryBuilder::maybeVisitStringSliceWTF(Expression*& out, + uint32_t code) { + StringSliceWTFOp op; + if (code == BinaryConsts::StringViewWTF8Slice) { + op = StringSliceWTF8; + } else if (code == BinaryConsts::StringViewWTF16Slice) { + op = StringSliceWTF16; + } else { + return false; + } + auto* end = popNonVoidExpression(); + auto* start = popNonVoidExpression(); + auto* ref = popNonVoidExpression(); + out = Builder(wasm).makeStringSliceWTF(op, ref, start, end); + return true; +} + +bool WasmBinaryBuilder::maybeVisitStringSliceIter(Expression*& out, + uint32_t code) { + if (code != BinaryConsts::StringViewIterSlice) { + return false; + } + auto* num = popNonVoidExpression(); + auto* ref = popNonVoidExpression(); + out = Builder(wasm).makeStringSliceIter(ref, num); + return true; +} + void WasmBinaryBuilder::visitRefAs(RefAs* curr, uint8_t code) { BYN_TRACE("zz node: RefAs\n"); switch (code) { diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 905c77523..f3bafe3de 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -3024,6 +3024,17 @@ Expression* SExpressionWasmBuilder::makeStringIterMove(Element& s, op, parseExpression(s[1]), parseExpression(s[2])); } +Expression* SExpressionWasmBuilder::makeStringSliceWTF(Element& s, + StringSliceWTFOp op) { + return Builder(wasm).makeStringSliceWTF( + op, parseExpression(s[1]), parseExpression(s[2]), parseExpression(s[3])); +} + +Expression* SExpressionWasmBuilder::makeStringSliceIter(Element& s) { + return Builder(wasm).makeStringSliceIter(parseExpression(s[1]), + parseExpression(s[2])); +} + // converts an s-expression string representing binary data into an output // sequence of raw bytes this appends to data, which may already contain // content. diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 731f47568..3707848d1 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2357,6 +2357,25 @@ void BinaryInstWriter::visitStringIterMove(StringIterMove* curr) { } } +void BinaryInstWriter::visitStringSliceWTF(StringSliceWTF* curr) { + o << int8_t(BinaryConsts::GCPrefix); + switch (curr->op) { + case StringSliceWTF8: + o << U32LEB(BinaryConsts::StringViewWTF8Slice); + break; + case StringSliceWTF16: + o << U32LEB(BinaryConsts::StringViewWTF16Slice); + break; + default: + WASM_UNREACHABLE("invalid string.move*"); + } +} + +void BinaryInstWriter::visitStringSliceIter(StringSliceIter* curr) { + o << int8_t(BinaryConsts::GCPrefix) + << U32LEB(BinaryConsts::StringViewIterSlice); +} + void BinaryInstWriter::emitScopeEnd(Expression* curr) { assert(!breakStack.empty()); breakStack.pop_back(); diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index c4a5f362a..0a3ca1929 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -1269,6 +1269,23 @@ void StringIterMove::finalize() { } } +void StringSliceWTF::finalize() { + if (ref->type == Type::unreachable || start->type == Type::unreachable || + end->type == Type::unreachable) { + type = Type::unreachable; + } else { + type = Type(HeapType::string, NonNullable); + } +} + +void StringSliceIter::finalize() { + if (ref->type == Type::unreachable || num->type == Type::unreachable) { + type = Type::unreachable; + } else { + type = Type(HeapType::string, NonNullable); + } +} + size_t Function::getNumParams() { return getParams().size(); } size_t Function::getNumVars() { return vars.size(); } diff --git a/src/wasm/wat-parser.cpp b/src/wasm/wat-parser.cpp index 07503974d..e3a2ab588 100644 --- a/src/wasm/wat-parser.cpp +++ b/src/wasm/wat-parser.cpp @@ -1027,6 +1027,11 @@ Result<typename Ctx::InstrT> makeStringIterNext(Ctx&, ParseInput&); template<typename Ctx> Result<typename Ctx::InstrT> makeStringIterMove(Ctx&, ParseInput&, StringIterMoveOp op); +template<typename Ctx> +Result<typename Ctx::InstrT> +makeStringSliceWTF(Ctx&, ParseInput&, StringSliceWTFOp op); +template<typename Ctx> +Result<typename Ctx::InstrT> makeStringSliceIter(Ctx&, ParseInput&); // Modules template<typename Ctx> @@ -1924,6 +1929,17 @@ makeStringIterMove(Ctx& ctx, ParseInput& in, StringIterMoveOp op) { return in.err("unimplemented instruction"); } +template<typename Ctx> +Result<typename Ctx::InstrT> +makeStringSliceWTF(Ctx& ctx, ParseInput& in, StringSliceWTFOp op) { + return in.err("unimplemented instruction"); +} + +template<typename Ctx> +Result<typename Ctx::InstrT> makeStringSliceIter(Ctx& ctx, ParseInput& in) { + return in.err("unimplemented instruction"); +} + // ======= // Modules // ======= diff --git a/src/wasm2js.h b/src/wasm2js.h index 7762f525a..034f9a215 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -2347,6 +2347,14 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, unimplemented(curr); WASM_UNREACHABLE("unimp"); } + Ref visitStringSliceWTF(StringSliceWTF* curr) { + unimplemented(curr); + WASM_UNREACHABLE("unimp"); + } + Ref visitStringSliceIter(StringSliceIter* curr) { + unimplemented(curr); + WASM_UNREACHABLE("unimp"); + } Ref visitRefAs(RefAs* curr) { unimplemented(curr); WASM_UNREACHABLE("unimp"); |