Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Parser] Parse string types and operations #6161

Merged
merged 2 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions src/parser/contexts.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ struct NullTypeParserCtx {
HeapTypeT makeI31() { return Ok{}; }
HeapTypeT makeStructType() { return Ok{}; }
HeapTypeT makeArrayType() { return Ok{}; }
HeapTypeT makeStringType() { return Ok{}; }
HeapTypeT makeStringViewWTF8Type() { return Ok{}; }
HeapTypeT makeStringViewWTF16Type() { return Ok{}; }
HeapTypeT makeStringViewIterType() { return Ok{}; }

TypeT makeI32() { return Ok{}; }
TypeT makeI64() { return Ok{}; }
Expand Down Expand Up @@ -190,6 +194,10 @@ template<typename Ctx> struct TypeParserCtx {
HeapTypeT makeI31() { return HeapType::i31; }
HeapTypeT makeStructType() { return HeapType::struct_; }
HeapTypeT makeArrayType() { return HeapType::array; }
HeapTypeT makeStringType() { return HeapType::string; }
HeapTypeT makeStringViewWTF8Type() { return HeapType::stringview_wtf8; }
HeapTypeT makeStringViewWTF16Type() { return HeapType::stringview_wtf16; }
HeapTypeT makeStringViewIterType() { return HeapType::stringview_iter; }

TypeT makeI32() { return Type::i32; }
TypeT makeI64() { return Type::i64; }
Expand Down Expand Up @@ -491,6 +499,19 @@ struct NullInstrParserCtx {
return Ok{};
}
Result<> makeRefAs(Index, RefAsOp) { return Ok{}; }
Result<> makeStringNew(Index, StringNewOp, bool, MemoryIdxT*) { return Ok{}; }
Result<> makeStringConst(Index, std::string_view) { return Ok{}; }
Result<> makeStringMeasure(Index, StringMeasureOp) { return Ok{}; }
Result<> makeStringEncode(Index, StringEncodeOp, MemoryIdxT*) { return Ok{}; }
Result<> makeStringConcat(Index) { return Ok{}; }
Result<> makeStringEq(Index, StringEqOp) { return Ok{}; }
Result<> makeStringAs(Index, StringAsOp) { return Ok{}; }
Result<> makeStringWTF8Advance(Index) { return Ok{}; }
Result<> makeStringWTF16Get(Index) { return Ok{}; }
Result<> makeStringIterNext(Index) { return Ok{}; }
Result<> makeStringIterMove(Index, StringIterMoveOp) { return Ok{}; }
Result<> makeStringSliceWTF(Index, StringSliceWTFOp) { return Ok{}; }
Result<> makeStringSliceIter(Index) { return Ok{}; }
};

// Phase 1: Parse definition spans for top-level module elements and determine
Expand Down Expand Up @@ -1695,6 +1716,62 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
Result<> makeRefAs(Index pos, RefAsOp op) {
return withLoc(pos, irBuilder.makeRefAs(op));
}

Result<> makeStringNew(Index pos, StringNewOp op, bool try_, Name* mem) {
auto m = getMemory(pos, mem);
CHECK_ERR(m);
return withLoc(pos, irBuilder.makeStringNew(op, try_, *m));
}

Result<> makeStringConst(Index pos, std::string_view str) {
return withLoc(pos, irBuilder.makeStringConst(Name(str)));
}

Result<> makeStringMeasure(Index pos, StringMeasureOp op) {
return withLoc(pos, irBuilder.makeStringMeasure(op));
}

Result<> makeStringEncode(Index pos, StringEncodeOp op, Name* mem) {
auto m = getMemory(pos, mem);
CHECK_ERR(m);
return withLoc(pos, irBuilder.makeStringEncode(op, *m));
}

Result<> makeStringConcat(Index pos) {
return withLoc(pos, irBuilder.makeStringConcat());
}

Result<> makeStringEq(Index pos, StringEqOp op) {
return withLoc(pos, irBuilder.makeStringEq(op));
}

Result<> makeStringAs(Index pos, StringAsOp op) {
return withLoc(pos, irBuilder.makeStringAs(op));
}

Result<> makeStringWTF8Advance(Index pos) {
return withLoc(pos, irBuilder.makeStringWTF8Advance());
}

Result<> makeStringWTF16Get(Index pos) {
return withLoc(pos, irBuilder.makeStringWTF16Get());
}

Result<> makeStringIterNext(Index pos) {
return withLoc(pos, irBuilder.makeStringIterNext());
}

Result<> makeStringIterMove(Index pos, StringIterMoveOp op) {
return withLoc(pos, irBuilder.makeStringIterMove(op));
}

Result<> makeStringSliceWTF(Index pos, StringSliceWTFOp op) {
return withLoc(pos, irBuilder.makeStringSliceWTF(op));
}

Result<> makeStringSliceIter(Index pos) {
return withLoc(pos, irBuilder.makeStringSliceIter());
}
};

} // namespace wasm::WATParser
Expand Down
4 changes: 2 additions & 2 deletions src/parser/input-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,11 @@ inline std::optional<float> ParseInput::takeF32() {
return std::nullopt;
}

inline std::optional<std::string_view> ParseInput::takeString() {
inline std::optional<std::string> ParseInput::takeString() {
if (auto t = peek()) {
if (auto s = t->getString()) {
++lexer;
return s;
return std::string(*s);
}
}
return {};
Expand Down
2 changes: 1 addition & 1 deletion src/parser/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ struct ParseInput {
std::optional<uint8_t> takeU8();
std::optional<double> takeF64();
std::optional<float> takeF32();
std::optional<std::string_view> takeString();
std::optional<std::string> takeString();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The string view this method returned was dangling whenever the string contained an escape sequence, so I had to change it to return an owned string to avoid ownership problems.

std::optional<Name> takeName();
bool takeSExprStart(std::string_view expected);
bool peekSExprStart(std::string_view expected);
Expand Down
60 changes: 46 additions & 14 deletions src/parser/parsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,18 @@ template<typename Ctx> Result<typename Ctx::HeapTypeT> heaptype(Ctx& ctx) {
if (ctx.in.takeKeyword("array"sv)) {
return ctx.makeArrayType();
}
if (ctx.in.takeKeyword("string"sv)) {
return ctx.makeStringType();
}
if (ctx.in.takeKeyword("stringview_wtf8"sv)) {
return ctx.makeStringViewWTF8Type();
}
if (ctx.in.takeKeyword("stringview_wtf16"sv)) {
return ctx.makeStringViewWTF16Type();
}
if (ctx.in.takeKeyword("stringview_iter"sv)) {
return ctx.makeStringViewIterType();
}
auto type = typeidx(ctx);
CHECK_ERR(type);
return *type;
Expand Down Expand Up @@ -283,7 +295,19 @@ template<typename Ctx> MaybeResult<typename Ctx::TypeT> reftype(Ctx& ctx) {
return ctx.makeRefType(ctx.makeStructType(), Nullable);
}
if (ctx.in.takeKeyword("arrayref"sv)) {
return ctx.in.err("arrayref not yet supported");
return ctx.makeRefType(ctx.makeArrayType(), Nullable);
}
if (ctx.in.takeKeyword("stringref"sv)) {
return ctx.makeRefType(ctx.makeStringType(), Nullable);
}
if (ctx.in.takeKeyword("stringview_wtf8"sv)) {
return ctx.makeRefType(ctx.makeStringViewWTF8Type(), Nullable);
}
if (ctx.in.takeKeyword("stringview_wtf16"sv)) {
return ctx.makeRefType(ctx.makeStringViewWTF16Type(), Nullable);
}
if (ctx.in.takeKeyword("stringview_iter"sv)) {
return ctx.makeRefType(ctx.makeStringViewIterType(), Nullable);
}

if (!ctx.in.takeSExprStart("ref"sv)) {
Expand Down Expand Up @@ -1650,61 +1674,69 @@ template<typename Ctx> Result<> makeRefAs(Ctx& ctx, Index pos, RefAsOp op) {

template<typename Ctx>
Result<> makeStringNew(Ctx& ctx, Index pos, StringNewOp op, bool try_) {
return ctx.in.err("unimplemented instruction");
auto mem = maybeMemidx(ctx);
CHECK_ERR(mem);
return ctx.makeStringNew(pos, op, try_, mem.getPtr());
}

template<typename Ctx> Result<> makeStringConst(Ctx& ctx, Index pos) {
return ctx.in.err("unimplemented instruction");
auto str = ctx.in.takeString();
if (!str) {
return ctx.in.err("expected string");
}
return ctx.makeStringConst(pos, *str);
}

template<typename Ctx>
Result<> makeStringMeasure(Ctx& ctx, Index pos, StringMeasureOp op) {
return ctx.in.err("unimplemented instruction");
return ctx.makeStringMeasure(pos, op);
}

template<typename Ctx>
Result<> makeStringEncode(Ctx& ctx, Index pos, StringEncodeOp op) {
return ctx.in.err("unimplemented instruction");
auto mem = maybeMemidx(ctx);
CHECK_ERR(mem);
return ctx.makeStringEncode(pos, op, mem.getPtr());
}

template<typename Ctx> Result<> makeStringConcat(Ctx& ctx, Index pos) {
return ctx.in.err("unimplemented instruction");
return ctx.makeStringConcat(pos);
}

template<typename Ctx>
Result<> makeStringEq(Ctx& ctx, Index pos, StringEqOp op) {
return ctx.in.err("unimplemented instruction");
return ctx.makeStringEq(pos, op);
}

template<typename Ctx>
Result<> makeStringAs(Ctx& ctx, Index pos, StringAsOp op) {
return ctx.in.err("unimplemented instruction");
return ctx.makeStringAs(pos, op);
}

template<typename Ctx> Result<> makeStringWTF8Advance(Ctx& ctx, Index pos) {
return ctx.in.err("unimplemented instruction");
return ctx.makeStringWTF8Advance(pos);
}

template<typename Ctx> Result<> makeStringWTF16Get(Ctx& ctx, Index pos) {
return ctx.in.err("unimplemented instruction");
return ctx.makeStringWTF16Get(pos);
}

template<typename Ctx> Result<> makeStringIterNext(Ctx& ctx, Index pos) {
return ctx.in.err("unimplemented instruction");
return ctx.makeStringIterNext(pos);
}

template<typename Ctx>
Result<> makeStringIterMove(Ctx& ctx, Index pos, StringIterMoveOp op) {
return ctx.in.err("unimplemented instruction");
return ctx.makeStringIterMove(pos, op);
}

template<typename Ctx>
Result<> makeStringSliceWTF(Ctx& ctx, Index pos, StringSliceWTFOp op) {
return ctx.in.err("unimplemented instruction");
return ctx.makeStringSliceWTF(pos, op);
}

template<typename Ctx> Result<> makeStringSliceIter(Ctx& ctx, Index pos) {
return ctx.in.err("unimplemented instruction");
return ctx.makeStringSliceIter(pos);
}

// =======
Expand Down
28 changes: 15 additions & 13 deletions src/wasm-ir-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,19 +184,19 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
[[nodiscard]] Result<> makeArrayInitData(HeapType type, Name data);
[[nodiscard]] Result<> makeArrayInitElem(HeapType type, Name elem);
[[nodiscard]] Result<> makeRefAs(RefAsOp op);
// [[nodiscard]] Result<> makeStringNew();
// [[nodiscard]] Result<> makeStringConst();
// [[nodiscard]] Result<> makeStringMeasure();
// [[nodiscard]] Result<> makeStringEncode();
// [[nodiscard]] Result<> makeStringConcat();
// [[nodiscard]] Result<> makeStringEq();
// [[nodiscard]] Result<> makeStringAs();
// [[nodiscard]] Result<> makeStringWTF8Advance();
// [[nodiscard]] Result<> makeStringWTF16Get();
// [[nodiscard]] Result<> makeStringIterNext();
// [[nodiscard]] Result<> makeStringIterMove();
// [[nodiscard]] Result<> makeStringSliceWTF();
// [[nodiscard]] Result<> makeStringSliceIter();
[[nodiscard]] Result<> makeStringNew(StringNewOp op, bool try_, Name mem);
[[nodiscard]] Result<> makeStringConst(Name string);
[[nodiscard]] Result<> makeStringMeasure(StringMeasureOp op);
[[nodiscard]] Result<> makeStringEncode(StringEncodeOp op, Name mem);
[[nodiscard]] Result<> makeStringConcat();
[[nodiscard]] Result<> makeStringEq(StringEqOp op);
[[nodiscard]] Result<> makeStringAs(StringAsOp op);
[[nodiscard]] Result<> makeStringWTF8Advance();
[[nodiscard]] Result<> makeStringWTF16Get();
[[nodiscard]] Result<> makeStringIterNext();
[[nodiscard]] Result<> makeStringIterMove(StringIterMoveOp op);
[[nodiscard]] Result<> makeStringSliceWTF(StringSliceWTFOp op);
[[nodiscard]] Result<> makeStringSliceIter();

// Private functions that must be public for technical reasons.
[[nodiscard]] Result<> visitExpression(Expression*);
Expand All @@ -213,6 +213,8 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
[[nodiscard]] Result<> visitCallIndirect(CallIndirect*);
[[nodiscard]] Result<> visitCallRef(CallRef*);
[[nodiscard]] Result<> visitThrow(Throw*);
[[nodiscard]] Result<> visitStringNew(StringNew*);
[[nodiscard]] Result<> visitStringEncode(StringEncode*);

private:
Module& wasm;
Expand Down
13 changes: 13 additions & 0 deletions src/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1776,6 +1776,7 @@ class RefAs : public SpecificExpression<Expression::RefAsId> {

class StringNew : public SpecificExpression<Expression::StringNewId> {
public:
StringNew() = default;
StringNew(MixedArena& allocator) {}

StringNewOp op;
Expand All @@ -1800,6 +1801,7 @@ class StringNew : public SpecificExpression<Expression::StringNewId> {

class StringConst : public SpecificExpression<Expression::StringConstId> {
public:
StringConst() = default;
StringConst(MixedArena& allocator) {}

// TODO: Use a different type to allow null bytes in the middle -
Expand All @@ -1812,6 +1814,7 @@ class StringConst : public SpecificExpression<Expression::StringConstId> {

class StringMeasure : public SpecificExpression<Expression::StringMeasureId> {
public:
StringMeasure() = default;
StringMeasure(MixedArena& allocator) {}

StringMeasureOp op;
Expand All @@ -1823,6 +1826,7 @@ class StringMeasure : public SpecificExpression<Expression::StringMeasureId> {

class StringEncode : public SpecificExpression<Expression::StringEncodeId> {
public:
StringEncode() = default;
StringEncode(MixedArena& allocator) {}

StringEncodeOp op;
Expand All @@ -1842,6 +1846,7 @@ class StringEncode : public SpecificExpression<Expression::StringEncodeId> {

class StringConcat : public SpecificExpression<Expression::StringConcatId> {
public:
StringConcat() = default;
StringConcat(MixedArena& allocator) {}

Expression* left;
Expand All @@ -1852,6 +1857,7 @@ class StringConcat : public SpecificExpression<Expression::StringConcatId> {

class StringEq : public SpecificExpression<Expression::StringEqId> {
public:
StringEq() = default;
StringEq(MixedArena& allocator) {}

StringEqOp op;
Expand All @@ -1864,6 +1870,7 @@ class StringEq : public SpecificExpression<Expression::StringEqId> {

class StringAs : public SpecificExpression<Expression::StringAsId> {
public:
StringAs() = default;
StringAs(MixedArena& allocator) {}

StringAsOp op;
Expand All @@ -1876,6 +1883,7 @@ class StringAs : public SpecificExpression<Expression::StringAsId> {
class StringWTF8Advance
: public SpecificExpression<Expression::StringWTF8AdvanceId> {
public:
StringWTF8Advance() = default;
StringWTF8Advance(MixedArena& allocator) {}

Expression* ref;
Expand All @@ -1887,6 +1895,7 @@ class StringWTF8Advance

class StringWTF16Get : public SpecificExpression<Expression::StringWTF16GetId> {
public:
StringWTF16Get() = default;
StringWTF16Get(MixedArena& allocator) {}

Expression* ref;
Expand All @@ -1897,6 +1906,7 @@ class StringWTF16Get : public SpecificExpression<Expression::StringWTF16GetId> {

class StringIterNext : public SpecificExpression<Expression::StringIterNextId> {
public:
StringIterNext() = default;
StringIterNext(MixedArena& allocator) {}

Expression* ref;
Expand All @@ -1906,6 +1916,7 @@ class StringIterNext : public SpecificExpression<Expression::StringIterNextId> {

class StringIterMove : public SpecificExpression<Expression::StringIterMoveId> {
public:
StringIterMove() = default;
StringIterMove(MixedArena& allocator) {}

// Whether the movement is to advance or reverse.
Expand All @@ -1921,6 +1932,7 @@ class StringIterMove : public SpecificExpression<Expression::StringIterMoveId> {

class StringSliceWTF : public SpecificExpression<Expression::StringSliceWTFId> {
public:
StringSliceWTF() = default;
StringSliceWTF(MixedArena& allocator) {}

StringSliceWTFOp op;
Expand All @@ -1935,6 +1947,7 @@ class StringSliceWTF : public SpecificExpression<Expression::StringSliceWTFId> {
class StringSliceIter
: public SpecificExpression<Expression::StringSliceIterId> {
public:
StringSliceIter() = default;
StringSliceIter(MixedArena& allocator) {}

Expression* ref;
Expand Down
Loading
Loading