summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gen-s-parser.inc86
-rw-r--r--src/ir/ReFinalize.cpp4
-rw-r--r--src/ir/cost.h8
-rw-r--r--src/ir/effects.h8
-rw-r--r--src/ir/possible-contents.cpp8
-rw-r--r--src/passes/Print.cpp15
-rw-r--r--src/wasm-binary.h5
-rw-r--r--src/wasm-builder.h24
-rw-r--r--src/wasm-delegations-fields.def16
-rw-r--r--src/wasm-delegations.def2
-rw-r--r--src/wasm-interpreter.h6
-rw-r--r--src/wasm-s-parser.h2
-rw-r--r--src/wasm.h31
-rw-r--r--src/wasm/wasm-binary.cpp34
-rw-r--r--src/wasm/wasm-s-parser.cpp11
-rw-r--r--src/wasm/wasm-stack.cpp19
-rw-r--r--src/wasm/wasm.cpp17
-rw-r--r--src/wasm/wat-parser.cpp16
-rw-r--r--src/wasm2js.h8
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");