diff --git a/include/wabt/expr-visitor.h b/include/wabt/expr-visitor.h index cbc317cde..21a311b98 100644 --- a/include/wabt/expr-visitor.h +++ b/include/wabt/expr-visitor.h @@ -88,6 +88,36 @@ class ExprVisitor::Delegate { virtual Result EndIfExpr(IfExpr*) = 0; virtual Result OnLoadExpr(LoadExpr*) = 0; virtual Result OnLocalGetExpr(LocalGetExpr*) = 0; + virtual Result OnStructNewExpr(StructNewExpr*) = 0; + virtual Result OnStructNewDefaultExpr(StructNewDefaultExpr*) = 0; + virtual Result OnStructGetExpr(StructGetExpr*) = 0; + virtual Result OnStructGetUExpr(StructGetUExpr*) = 0; + virtual Result OnStructGetSExpr(StructGetSExpr*) = 0; + virtual Result OnStructSetExpr(StructSetExpr*) = 0; + virtual Result OnArrayNewExpr(ArrayNewExpr*) = 0; + virtual Result OnArrayNewDefaultExpr(ArrayNewDefaultExpr*) = 0; + virtual Result OnArrayNewFixedExpr(ArrayNewFixedExpr*) = 0; + virtual Result OnArrayNewDataExpr(ArrayNewDataExpr*) = 0; + virtual Result OnArrayNewElemExpr(ArrayNewElemExpr*) = 0; + virtual Result OnArrayGetExpr(ArrayGetExpr*) = 0; + virtual Result OnArrayGetSExpr(ArrayGetSExpr*) = 0; + virtual Result OnArrayGetUExpr(ArrayGetUExpr*) = 0; + virtual Result OnArraySetExpr(ArraySetExpr*) = 0; + virtual Result OnArrayLenExpr(ArrayLenExpr*) = 0; + virtual Result OnArrayFillExpr(ArrayFillExpr*) = 0; + virtual Result OnArrayCopyExpr(ArrayCopyExpr*) = 0; + virtual Result OnArrayInitDataExpr(ArrayInitDataExpr*) = 0; + virtual Result OnArrayInitElemExpr(ArrayInitElemExpr*) = 0; + + virtual Result OnRefTestExpr(RefTestExpr*) = 0; + virtual Result OnRefCastExpr(RefCastExpr*) = 0; + virtual Result OnBrOnCastExpr(BrOnCastExpr*) = 0; + virtual Result OnBrOnCastFailExpr(BrOnCastFailExpr*) = 0; + virtual Result OnAnyConvertExternExpr(AnyConvertExternExpr*) = 0; + virtual Result OnExternConvertAnyExpr(ExternConvertAnyExpr*) = 0; + virtual Result OnRefI31Expr(RefI31Expr*) = 0; + virtual Result OnI31GetSExpr(I31GetSExpr*) = 0; + virtual Result OnI31GetUExpr(I31GetUExpr*) = 0; virtual Result OnLocalSetExpr(LocalSetExpr*) = 0; virtual Result OnLocalTeeExpr(LocalTeeExpr*) = 0; virtual Result BeginLoopExpr(LoopExpr*) = 0; @@ -106,6 +136,7 @@ class ExprVisitor::Delegate { virtual Result OnTableGrowExpr(TableGrowExpr*) = 0; virtual Result OnTableSizeExpr(TableSizeExpr*) = 0; virtual Result OnTableFillExpr(TableFillExpr*) = 0; + virtual Result OnRefEqExpr(RefEqExpr*) = 0; virtual Result OnRefFuncExpr(RefFuncExpr*) = 0; virtual Result OnRefNullExpr(RefNullExpr*) = 0; virtual Result OnRefIsNullExpr(RefIsNullExpr*) = 0; @@ -162,6 +193,36 @@ class ExprVisitor::DelegateNop : public ExprVisitor::Delegate { Result EndIfExpr(IfExpr*) override { return Result::Ok; } Result OnLoadExpr(LoadExpr*) override { return Result::Ok; } Result OnLocalGetExpr(LocalGetExpr*) override { return Result::Ok; } + Result OnStructNewExpr(StructNewExpr*) override { return Result::Ok; } + Result OnStructNewDefaultExpr(StructNewDefaultExpr*) override { return Result::Ok;} + Result OnStructGetExpr(StructGetExpr*) override { return Result::Ok; } + Result OnStructGetUExpr(StructGetUExpr*) override { return Result::Ok; } + Result OnStructGetSExpr(StructGetSExpr*) override { return Result::Ok; } + Result OnStructSetExpr(StructSetExpr*) override { return Result::Ok; } + Result OnArrayNewExpr(ArrayNewExpr*) override { return Result::Ok; } + Result OnArrayNewDefaultExpr(ArrayNewDefaultExpr*) override { return Result::Ok; } + Result OnArrayNewFixedExpr(ArrayNewFixedExpr*) override { return Result::Ok; } + Result OnArrayNewDataExpr(ArrayNewDataExpr*) override { return Result::Ok; } + Result OnArrayNewElemExpr(ArrayNewElemExpr*) override { return Result::Ok; } + Result OnArrayGetExpr(ArrayGetExpr*) override { return Result::Ok; } + Result OnArrayGetSExpr(ArrayGetSExpr*) override { return Result::Ok; } + Result OnArrayGetUExpr(ArrayGetUExpr*) override { return Result::Ok; } + Result OnArraySetExpr(ArraySetExpr*) override { return Result::Ok; } + Result OnArrayLenExpr(ArrayLenExpr*) override { return Result::Ok; } + Result OnArrayFillExpr(ArrayFillExpr*) override { return Result::Ok; } + Result OnArrayCopyExpr(ArrayCopyExpr*) override { return Result::Ok; } + Result OnArrayInitDataExpr(ArrayInitDataExpr*) override { return Result::Ok; } + Result OnArrayInitElemExpr(ArrayInitElemExpr*) override { return Result::Ok; } + + Result OnRefTestExpr(RefTestExpr*) override { return Result::Ok; } + Result OnRefCastExpr(RefCastExpr*) override { return Result::Ok; } + Result OnBrOnCastExpr(BrOnCastExpr*) override { return Result::Ok; } + Result OnBrOnCastFailExpr(BrOnCastFailExpr*) override { return Result::Ok; } + Result OnAnyConvertExternExpr(AnyConvertExternExpr*) override { return Result::Ok; } + Result OnExternConvertAnyExpr(ExternConvertAnyExpr*) override { return Result::Ok; } + Result OnRefI31Expr(RefI31Expr*) override { return Result::Ok; } + Result OnI31GetSExpr(I31GetSExpr*) override { return Result::Ok; } + Result OnI31GetUExpr(I31GetUExpr*) override { return Result::Ok; } Result OnLocalSetExpr(LocalSetExpr*) override { return Result::Ok; } Result OnLocalTeeExpr(LocalTeeExpr*) override { return Result::Ok; } Result BeginLoopExpr(LoopExpr*) override { return Result::Ok; } @@ -180,6 +241,7 @@ class ExprVisitor::DelegateNop : public ExprVisitor::Delegate { Result OnTableGrowExpr(TableGrowExpr*) override { return Result::Ok; } Result OnTableSizeExpr(TableSizeExpr*) override { return Result::Ok; } Result OnTableFillExpr(TableFillExpr*) override { return Result::Ok; } + Result OnRefEqExpr(RefEqExpr*) override { return Result::Ok; } Result OnRefFuncExpr(RefFuncExpr*) override { return Result::Ok; } Result OnRefNullExpr(RefNullExpr*) override { return Result::Ok; } Result OnRefIsNullExpr(RefIsNullExpr*) override { return Result::Ok; } diff --git a/include/wabt/ir.h b/include/wabt/ir.h index 49b7e2b04..94f2cef78 100644 --- a/include/wabt/ir.h +++ b/include/wabt/ir.h @@ -269,10 +269,12 @@ struct FuncSignature { bool operator==(const FuncSignature&) const; }; -enum class TypeEntryKind { - Func, - Struct, - Array, +enum class TypeEntryKind { Func, Struct, Array, Sub, Rec }; + +struct Field { + std::string name; + Type type = Type::Void; + bool mutable_ = false; }; class TypeEntry { @@ -319,12 +321,6 @@ class FuncType : public TypeEntry { } features_used; }; -struct Field { - std::string name; - Type type = Type::Void; - bool mutable_ = false; -}; - class StructType : public TypeEntry { public: static bool classof(const TypeEntry* entry) { @@ -332,7 +328,7 @@ class StructType : public TypeEntry { } explicit StructType(std::string_view name = std::string_view()) - : TypeEntry(TypeEntryKind::Struct) {} + : TypeEntry(TypeEntryKind::Struct, name) {} std::vector fields; }; @@ -344,11 +340,32 @@ class ArrayType : public TypeEntry { } explicit ArrayType(std::string_view name = std::string_view()) - : TypeEntry(TypeEntryKind::Array) {} - + : TypeEntry(TypeEntryKind::Array, name) {} Field field; }; +class SubType : public TypeEntry { + public: + static bool classof(const TypeEntry* entry) { + return entry->kind() == TypeEntryKind::Sub; + } + + explicit SubType(std::string name = std::string()) + : TypeEntry(TypeEntryKind::Sub, name) {} + std::unique_ptr typeEntry; +}; + +class RecType : public TypeEntry { + public: + static bool classof(const TypeEntry* entry) { + return entry->kind() == TypeEntryKind::Rec; + } + + explicit RecType(std::string name = std::string()) + : TypeEntry(TypeEntryKind::Rec, name) {} + std::vector> fields; +}; + struct FuncDeclaration { Index GetNumParams() const { return sig.GetNumParams(); } Index GetNumResults() const { return sig.GetNumResults(); } @@ -386,6 +403,36 @@ enum class ExprType { If, Load, LocalGet, + StructNew, + StructNewDefault, + StructGet, + StructGetU, + StructGetS, + StructSet, + ArrayNew, + ArrayNewDefault, + ArrayNewFixed, + ArrayNewData, + ArrayNewElem, + ArrayGet, + ArrayGetS, + ArrayGetU, + ArraySet, + ArrayLen, + ArrayFill, + ArrayCopy, + ArrayInitData, + ArrayInitElem, + + RefTest, + RefCast, + BrOnCast, + BrOnCastFail, + AnyConvertExtern, + ExternConvertAny, + RefI31, + I31GetS, + I31GetU, LocalSet, LocalTee, Loop, @@ -397,6 +444,7 @@ enum class ExprType { MemorySize, Nop, RefIsNull, + RefEq, RefFunc, RefNull, Rethrow, @@ -616,6 +664,42 @@ class VarExpr : public ExprMixin { Var var; }; +template +class StructGetVarExpr : public ExprMixin { + public: + StructGetVarExpr(const Var& var1, + const Var& var2, + const Location& loc = Location()) + : ExprMixin(loc), var1(var1), var2(var2) {} + + Var var1; + Var var2; +}; + +template +class Var2Expr : public ExprMixin { + public: + Var2Expr(const Var& var1, const Var& var2, const Location& loc = Location()) + : ExprMixin(loc), var1(var1), var2(var2) {} + + Var var1; + Var var2; +}; + +template +class Var3Expr : public ExprMixin { + public: + Var3Expr(const Var& var1, + const Var& var2, + const Var& var3, + const Location& loc = Location()) + : ExprMixin(loc), var1(var1), var2(var2), var3(var3) {} + + Var var1; + Var var2; + Var var3; +}; + template class MemoryVarExpr : public MemoryExpr { public: @@ -628,10 +712,42 @@ class MemoryVarExpr : public MemoryExpr { using BrExpr = VarExpr; using BrIfExpr = VarExpr; using CallExpr = VarExpr; +using RefEqExpr = ExprMixin; using RefFuncExpr = VarExpr; using GlobalGetExpr = VarExpr; using GlobalSetExpr = VarExpr; using LocalGetExpr = VarExpr; +using StructNewExpr = VarExpr; +using StructNewDefaultExpr = VarExpr; +using StructGetExpr = StructGetVarExpr; +using StructGetUExpr = StructGetVarExpr; +using StructGetSExpr = StructGetVarExpr; +using StructSetExpr = StructGetVarExpr; +using ArrayNewExpr = VarExpr; +using ArrayNewDefaultExpr = VarExpr; +using ArrayNewFixedExpr = Var2Expr; +using ArrayNewDataExpr = Var2Expr; +using ArrayNewElemExpr = Var2Expr; +using ArrayGetExpr = VarExpr; +using ArrayGetUExpr = VarExpr; +using ArrayGetSExpr = VarExpr; +using ArraySetExpr = VarExpr; +using ArrayLenExpr = ExprMixin; +using ArrayFillExpr = VarExpr; +using ArrayCopyExpr = Var2Expr; +using ArrayInitDataExpr = Var2Expr; +using ArrayInitElemExpr = Var2Expr; + +using RefTestExpr = VarExpr; +using RefCastExpr = VarExpr; +using BrOnCastExpr = Var3Expr; +using BrOnCastFailExpr = Var3Expr; +using AnyConvertExternExpr = ExprMixin; +using ExternConvertAnyExpr = ExprMixin; +using RefI31Expr = ExprMixin; +using I31GetSExpr = ExprMixin; +using I31GetUExpr = ExprMixin; + using LocalSetExpr = VarExpr; using LocalTeeExpr = VarExpr; using ReturnCallExpr = VarExpr; @@ -1229,6 +1345,7 @@ struct Module { void AppendField(std::unique_ptr); void AppendField(std::unique_ptr); void AppendField(std::unique_ptr); + void AppendFieldRec(std::unique_ptr); void AppendField(std::unique_ptr); void AppendField(std::unique_ptr); void AppendField(std::unique_ptr); @@ -1262,6 +1379,9 @@ struct Module { std::vector starts; std::vector customs; + // 处理类型声明 + std::unordered_map moduletypesname; + BindingHash tag_bindings; BindingHash func_bindings; BindingHash global_bindings; diff --git a/include/wabt/opcode.def b/include/wabt/opcode.def index 73554358a..b160dcd27 100644 --- a/include/wabt/opcode.def +++ b/include/wabt/opcode.def @@ -225,6 +225,11 @@ WABT_OPCODE(I64, I64, ___, ___, 0, 0, 0xC2, I64Extend8S, "i64.extend8_s" WABT_OPCODE(I64, I64, ___, ___, 0, 0, 0xC3, I64Extend16S, "i64.extend16_s", "") WABT_OPCODE(I64, I64, ___, ___, 0, 0, 0xC4, I64Extend32S, "i64.extend32_s", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xd0, RefNull, "ref.null", "") +WABT_OPCODE(I32, ___, ___, ___, 0, 0, 0xd1, RefIsNull, "ref.is_null", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xd2, RefFunc, "ref.func", "") +WABT_OPCODE(I32, ___, ___, ___, 0, 0, 0xd3, RefEq, "ref.eq", "") + /* Interpreter-only opcodes */ WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xe0, InterpAlloca, "alloca", "") WABT_OPCODE(___, I32, ___, ___, 0, 0, 0xe1, InterpBrUnless, "br_unless", "") @@ -234,6 +239,38 @@ WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xe4, InterpDropKeep, "drop_keep", WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xe5, InterpCatchDrop, "catch_drop", "") WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xe6, InterpAdjustFrameForReturnCall, "adjust_frame_for_return_call", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x00, StructNew, "struct.new", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x01, StructNewDefault, "struct.new_default", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x02, StructGet, "struct.get", "") +WABT_OPCODE(I32, ___, ___, ___, 0, 0xfb, 0x03, StructGetS, "struct.get_s", "") +WABT_OPCODE(I32, ___, ___, ___, 0, 0xfb, 0x04, StructGetU, "struct.get_u", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x05, StructSet, "struct.set", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x06, ArrayNew, "array.new", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x07, ArrayNewDefault, "array.new_default", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x08, ArrayNewFixed, "array.new_fixed", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x09, ArrayNewData, "array.new_data", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x0a, ArrayNewElem, "array.new_elem", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x0b, ArrayGet, "array.get", "") +WABT_OPCODE(I32, ___, ___, ___, 0, 0xfb, 0x0c, ArrayGetS, "array.get_s", "") +WABT_OPCODE(I32, ___, ___, ___, 0, 0xfb, 0x0d, ArrayGetU, "array.get_u", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x0e, ArraySet, "array.set", "") +WABT_OPCODE(I32, ___, ___, ___, 0, 0xfb, 0x0f, ArrayLen, "array.len", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x10, ArrayFill, "array.fill", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x11, ArrayCopy, "array.copy", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x12, ArrayInitData, "array.init_data", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x13, ArrayInitElem, "array.init_elem", "") +WABT_OPCODE(I32, ___, ___, ___, 0, 0xfb, 0x14, RefTestRef, "ref.test", "") +WABT_OPCODE(I32, ___, ___, ___, 0, 0xfb, 0x15, RefTestRefNull, "ref.test", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x16, RefCastRef, "ref.cast", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x17, RefCastRefNull, "ref.cast", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x18, BrOnCast, "br_on_cast", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x19, BrOnCastFail, "br_on_cast_fail", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x1a, AnyConvertExtern, "ant.convert_extern", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0xfb, 0x1b, ExternConvertAny, "extern.convert_any", "") +WABT_OPCODE(___, I32, ___, ___, 0, 0xfb, 0x1c, RefI31, "ref.i31", "") +WABT_OPCODE(I32, ___, ___, ___, 0, 0xfb, 0x1d, I31GetS, "i31.get_s", "") +WABT_OPCODE(I32, ___, ___, ___, 0, 0xfb, 0x1e, I31GetU, "i31.get_u", "") + /* Saturating float-to-int opcodes (--enable-saturating-float-to-int) */ WABT_OPCODE(I32, F32, ___, ___, 0, 0xfc, 0x00, I32TruncSatF32S, "i32.trunc_sat_f32_s", "") WABT_OPCODE(I32, F32, ___, ___, 0, 0xfc, 0x01, I32TruncSatF32U, "i32.trunc_sat_f32_u", "") @@ -259,9 +296,7 @@ WABT_OPCODE(___, I32, ___, ___, 0, 0, 0x26, TableSet, "table.set", "") WABT_OPCODE(___, ___, I32, ___, 0, 0xfc, 0x0f, TableGrow, "table.grow", "") WABT_OPCODE(___, ___, ___, ___, 0, 0xfc, 0x10, TableSize, "table.size", "") WABT_OPCODE(___, I32, ___, I32, 0, 0xfc, 0x11, TableFill, "table.fill", "") -WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xd0, RefNull, "ref.null", "") -WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xd1, RefIsNull, "ref.is_null", "") -WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xd2, RefFunc, "ref.func", "") + /* Simd opcodes */ WABT_OPCODE(V128, I32, ___, ___, 16, 0xfd, 0x00, V128Load, "v128.load", "") diff --git a/include/wabt/shared-validator.h b/include/wabt/shared-validator.h index 32add0122..b74c29fcd 100644 --- a/include/wabt/shared-validator.h +++ b/include/wabt/shared-validator.h @@ -72,6 +72,7 @@ class SharedValidator { Index type_index); Result OnStructType(const Location&, Index field_count, TypeMut* fields); Result OnArrayType(const Location&, TypeMut field); + Result OnSubType(const Location&); Result OnFunction(const Location&, Var sig_var); Result OnTable(const Location&, Type elem_type, const Limits&); @@ -166,6 +167,45 @@ class SharedValidator { Address align, Address offset); Result OnLocalGet(const Location&, Var); + Result OnStructNew(const Location&, Var); + Result OnStructNewDefault(const Location&, Var); + Result OnStructGet(const Location&, Var, Var); + Result OnStructGetU(const Location&, Var, Var); + Result OnStructGetS(const Location&, Var, Var); + Result OnStructSet(const Location&, Var, Var); + Result OnArrayNew(const Location&, Var); + Result OnArrayNewDefault(const Location&, Var); + Result OnArrayNewFixed(const Location&, Var, Var); + Result OnArrayNewData(const Location&, Var, Var); + Result OnArrayNewElem(const Location&, Var, Var); + Result OnArrayGet(const Location&, Var); + Result OnArrayGetS(const Location&, Var); + Result OnArrayGetU(const Location&, Var); + Result OnArraySet(const Location&, Var); + Result OnArrayLen(const Location&); + Result OnArrayFill(const Location&, Var); + Result OnArrayCopy(const Location&, Var, Var); + Result OnArrayInitData(const Location&, Var, Var); + Result OnArrayInitElem(const Location&, Var, Var); + bool isNumber(const std::string& str); + Type ParseVar2RefType(Var var); + Result OnRefTest(const Location&, Var, std::unordered_map&); + Result OnRefCast(const Location&, Var, std::unordered_map&); + Result OnBrOnCast(const Location&, + Var, + Var, + Var, + std::unordered_map&); + Result OnBrOnCastFail(const Location&, + Var, + Var, + Var, + std::unordered_map&); + Result OnAnyConvertExtern(const Location&); + Result OnExternConvertAny(const Location&); + Result OnRefI31(const Location&); + Result OnI31GetU(const Location&); + Result OnI31GetS(const Location&); Result OnLocalSet(const Location&, Var); Result OnLocalTee(const Location&, Var); Result OnLoop(const Location&, Type sig_type); @@ -175,6 +215,7 @@ class SharedValidator { Result OnMemoryInit(const Location&, Var segment_var, Var memidx); Result OnMemorySize(const Location&, Var memidx); Result OnNop(const Location&); + Result OnRefEq(const Location&); Result OnRefFunc(const Location&, Var func_var); Result OnRefIsNull(const Location&); Result OnRefNull(const Location&, Type type); @@ -215,7 +256,6 @@ class SharedValidator { Result OnUnary(const Location&, Opcode); Result OnUnreachable(const Location&); - private: struct FuncType { FuncType() = default; FuncType(const TypeVector& params, diff --git a/include/wabt/token.def b/include/wabt/token.def index 2c9ff2b85..23840f74e 100644 --- a/include/wabt/token.def +++ b/include/wabt/token.def @@ -21,7 +21,6 @@ /* Tokens with no additional data (i.e. bare). */ WABT_TOKEN(Invalid, "Invalid") WABT_TOKEN(After, "after") -WABT_TOKEN(Array, "array") WABT_TOKEN(AssertException, "assert_exception") WABT_TOKEN(AssertExhaustion, "assert_exhaustion") WABT_TOKEN(AssertInvalid, "assert_invalid") @@ -58,14 +57,14 @@ WABT_TOKEN(NanCanonical, "nan:canonical") WABT_TOKEN(Offset, "offset") WABT_TOKEN(Output, "output") WABT_TOKEN(Param, "param") -WABT_TOKEN(Ref, "ref") + WABT_TOKEN(Quote, "quote") WABT_TOKEN(Register, "register") WABT_TOKEN(Result, "result") WABT_TOKEN(Rpar, ")") WABT_TOKEN(Shared, "shared") WABT_TOKEN(Start, "start") -WABT_TOKEN(Struct, "struct") + WABT_TOKEN(Table, "table") WABT_TOKEN(Then, "then") WABT_TOKEN(Type, "type") @@ -117,6 +116,37 @@ WABT_TOKEN(GlobalSet, "global.set") WABT_TOKEN(If, "if") WABT_TOKEN(Load, "LOAD") WABT_TOKEN(LocalGet, "local.get") +WABT_TOKEN(StructNew, "struct.new") +WABT_TOKEN(StructNewDefault, "struct.new_default") +WABT_TOKEN(StructGet, "struct.get") +WABT_TOKEN(StructGetS, "struct.get_s") +WABT_TOKEN(StructGetU, "struct.get_u") +WABT_TOKEN(StructSet, "struct.set") +WABT_TOKEN(ArrayNew, "array.new") +WABT_TOKEN(ArrayNewDefault, "array.new_default") +WABT_TOKEN(ArrayNewFixed, "array.new_fixed") +WABT_TOKEN(ArrayNewData, "array.new_data") +WABT_TOKEN(ArrayNewElem, "array.new_elem") +WABT_TOKEN(ArrayGet, "array.get") +WABT_TOKEN(ArrayGetS, "array.get_s") +WABT_TOKEN(ArrayGetU, "array.get_u") +WABT_TOKEN(ArraySet, "array.set") +WABT_TOKEN(ArrayLen, "array.len") +WABT_TOKEN(ArrayFill, "array.fill") +WABT_TOKEN(ArrayCopy, "array.copy") +WABT_TOKEN(ArrayInitData, "array.init_data") +WABT_TOKEN(ArrayInitElem, "array.init_elem") + +WABT_TOKEN(RefTest, "ref.test") +WABT_TOKEN(RefCast, "ref.cast") +WABT_TOKEN(BrOnCast, "br_on_cast") +WABT_TOKEN(BrOnCastFail, "br_on_cast_fail") +WABT_TOKEN(AnyConvertExtern, "ant.convert_extern") +WABT_TOKEN(ExternConvertAny, "extern.convert_any") +WABT_TOKEN(RefI31, "ref.i31") +WABT_TOKEN(I31GetS, "i31.get_s") +WABT_TOKEN(I31GetU, "i31.get_u") + WABT_TOKEN(LocalSet, "local.set") WABT_TOKEN(LocalTee, "local.tee") WABT_TOKEN(Loop, "loop") @@ -130,6 +160,7 @@ WABT_TOKEN(RefExtern, "ref.extern") WABT_TOKEN(RefFunc, "ref.func") WABT_TOKEN(RefIsNull, "ref.is_null") WABT_TOKEN(RefNull, "ref.null") +WABT_TOKEN(RefEq, "ref.eq") WABT_TOKEN(Rethrow, "rethrow") WABT_TOKEN(ReturnCallIndirect, "return_call_indirect") WABT_TOKEN(ReturnCall, "return_call") @@ -173,7 +204,19 @@ WABT_TOKEN_LAST(Type, ValueType) /* Tokens with Type data, but are reference kinds. */ WABT_TOKEN(Func, "func") +WABT_TOKEN(NoFunc, "nofunc") +WABT_TOKEN(Struct, "struct") +WABT_TOKEN(Array, "array") +WABT_TOKEN(Sub, "sub") +WABT_TOKEN(Rec, "rec") +WABT_TOKEN(Ref, "ref") +WABT_TOKEN(Null, "null") +WABT_TOKEN(Any, "any") +WABT_TOKEN(I31, "i31") +WABT_TOKEN(Eq, "eq") +WABT_TOKEN(None, "none") WABT_TOKEN(Extern, "extern") +WABT_TOKEN(NoExtern, "noextern") WABT_TOKEN(Exn, "exn") WABT_TOKEN_FIRST(RefKind, Func) WABT_TOKEN_LAST(RefKind, Exn) diff --git a/include/wabt/token.h b/include/wabt/token.h index 7d17e1066..5ba4257b7 100644 --- a/include/wabt/token.h +++ b/include/wabt/token.h @@ -72,8 +72,9 @@ inline bool IsTokenTypeLiteral(TokenType token_type) { } inline bool IsTokenTypeRefKind(TokenType token_type) { - return token_type >= TokenType::First_RefKind && - token_type <= TokenType::Last_RefKind; + return (token_type >= TokenType::First_RefKind && + token_type <= TokenType::Last_RefKind) || + token_type == TokenType::Var; } struct Token { diff --git a/include/wabt/type-checker.h b/include/wabt/type-checker.h index 1e665c348..b303bff1c 100644 --- a/include/wabt/type-checker.h +++ b/include/wabt/type-checker.h @@ -24,6 +24,7 @@ #include "wabt/feature.h" #include "wabt/opcode.h" + namespace wabt { class TypeChecker { @@ -69,6 +70,29 @@ class TypeChecker { Result OnAtomicRmwCmpxchg(Opcode, const Limits& limits); Result OnAtomicWait(Opcode, const Limits& limits); Result OnBinary(Opcode); + Result OnStructNew(Index, const TypeVector&); + Result OnStructNewDefault(Index); + Result OnStructGet(Index, Type); + Result OnStructSet(Index, Type); + Result OnArrayNew(Index, Type); + Result OnArrayNewDefault(Index); + Result OnArrayNewFixed(Index, Type, Index); + Result OnArrayNewData(Index); + Result OnArrayNewElem(Index); + Result OnArrayGet(Index, Type); + Result OnArraySet(Index, Type); + Result OnArrayLen(); + Result OnArrayFill(Type, Type); + Result OnArrayCopy(Type, Type); + Result OnArrayInitData(Type); + Result OnRefTest(Type type); + Result OnRefCast(Type type); + Result OnBrOnCast(Type type1, Type type2); + Result OnBrOnCastFail(Type type1, Type type2); + Result OnAnyConvertExtern(); + Result OnExternConvertAny(); + Result OnRefI31(); + Result OnI31Get(); Result OnBlock(const TypeVector& param_types, const TypeVector& result_types); Result OnBr(Index depth); Result OnBrIf(Index depth); @@ -113,6 +137,7 @@ class TypeChecker { Result OnTableGrow(Type elem_type); Result OnTableSize(); Result OnTableFill(Type elem_type); + Result OnRefEq(); Result OnRefFuncExpr(Index func_type, bool force_generic_funcref); Result OnRefNullExpr(Type type); Result OnRefIsNullExpr(); @@ -136,7 +161,6 @@ class TypeChecker { static Result CheckType(Type actual, Type expected); - private: void WABT_PRINTF_FORMAT(2, 3) PrintError(const char* fmt, ...); Result TopLabel(Label** out_label); void ResetTypeStackToLabel(Label* label); diff --git a/include/wabt/type.h b/include/wabt/type.h index 96fcf9458..f787256f8 100644 --- a/include/wabt/type.h +++ b/include/wabt/type.h @@ -21,8 +21,8 @@ #include #include -#include "wabt/config.h" #include "wabt/base-types.h" +#include "wabt/config.h" #include "wabt/string-format.h" namespace wabt { @@ -35,26 +35,44 @@ class Type { public: // Matches binary format, do not change. enum Enum : int32_t { - I32 = -0x01, // 0x7f - I64 = -0x02, // 0x7e - F32 = -0x03, // 0x7d - F64 = -0x04, // 0x7c - V128 = -0x05, // 0x7b - I8 = -0x06, // 0x7a : packed-type only, used in gc and as v128 lane - I16 = -0x07, // 0x79 : packed-type only, used in gc and as v128 lane - FuncRef = -0x10, // 0x70 - ExternRef = -0x11, // 0x6f - Reference = -0x15, // 0x6b - Func = -0x20, // 0x60 - Struct = -0x21, // 0x5f - Array = -0x22, // 0x5e - Void = -0x40, // 0x40 - ___ = Void, // Convenient for the opcode table in opcode.h - - Any = 0, // Not actually specified, but useful for type-checking - I8U = 4, // Not actually specified, but used internally with load/store - I16U = 6, // Not actually specified, but used internally with load/store - I32U = 7, // Not actually specified, but used internally with load/store + I32 = -0x01, // 0x7f + I64 = -0x02, // 0x7e + F32 = -0x03, // 0x7d + F64 = -0x04, // 0x7c + V128 = -0x05, // 0x7b + I8 = -0x08, + I16 = -0x09, + Reference = -0x44, + // Heap type + NoFunc = -0x0D, + NoExtern = -0x0E, + NoneRef = -0x0F, + FuncRef = -0x10, + ExternRef = -0x11, + AnyRef = -0x12, + Eq = -0x13, + I31 = -0x14, + StructRef = -0x15, + ArrayRef = -0x16, + // reference type + Null = -0x1b, + Ref = -0x1c, + RefNull = -0x1d, + // composite type + Func = -0x20, + Struct = -0x21, + Array = -0x22, + // sub type and recursive type + Sub = -0x30, + SubFinal = -0x31, + Rec = -0x32, + + Void = -0x40, + ___ = Void, + Any = 0, + I8U = 4, + I16U = 6, + I32U = 7, }; Type() = default; // Provided so Type can be member of a union. @@ -62,16 +80,24 @@ class Type { : enum_(static_cast(code)), type_index_(kInvalidIndex) {} Type(Enum e) : enum_(e), type_index_(kInvalidIndex) {} Type(Enum e, Index type_index) : enum_(e), type_index_(type_index) { - assert(e == Enum::Reference); + // assert(e == Enum::Reference); } constexpr operator Enum() const { return enum_; } bool IsRef() const { return enum_ == Type::ExternRef || enum_ == Type::FuncRef || - enum_ == Type::Reference; + enum_ == Type::Reference || enum_ == Type::Ref || + enum_ == Type::RefNull; } - bool IsReferenceWithIndex() const { return enum_ == Type::Reference; } + bool IsReferenceWithIndex() const { + return enum_ == Type::Reference || enum_ == Type::Ref || + enum_ == Type::RefNull; + } + + bool IsNewReferenceWithIndex() const { + return enum_ == Type::Ref || enum_ == Type::RefNull; + } bool IsNullableRef() const { // Currently all reftypes are nullable @@ -80,18 +106,34 @@ class Type { std::string GetName() const { switch (enum_) { - case Type::I32: return "i32"; - case Type::I64: return "i64"; - case Type::F32: return "f32"; - case Type::F64: return "f64"; - case Type::V128: return "v128"; - case Type::I8: return "i8"; - case Type::I16: return "i16"; - case Type::FuncRef: return "funcref"; - case Type::Func: return "func"; - case Type::Void: return "void"; - case Type::Any: return "any"; - case Type::ExternRef: return "externref"; + case Type::I32: + return "i32"; + case Type::I64: + return "i64"; + case Type::F32: + return "f32"; + case Type::F64: + return "f64"; + case Type::V128: + return "v128"; + case Type::I8: + return "i8"; + case Type::I16: + return "i16"; + case Type::NoneRef: + return "noneref"; + case Type::FuncRef: + return "funcref"; + case Type::Func: + return "func"; + case Type::Void: + return "void"; + case Type::Any: + return "any"; + case Type::ExternRef: + return "externref"; + case Type::Ref: + case Type::RefNull: case Type::Reference: return StringPrintf("(ref %d)", type_index_); default: @@ -101,11 +143,18 @@ class Type { const char* GetRefKindName() const { switch (enum_) { - case Type::FuncRef: return "func"; - case Type::ExternRef: return "extern"; - case Type::Struct: return "struct"; - case Type::Array: return "array"; - default: return ""; + case Type::NoneRef: + return "none"; + case Type::FuncRef: + return "func"; + case Type::ExternRef: + return "extern"; + case Type::Struct: + return "struct"; + case Type::Array: + return "array"; + default: + return ""; } } @@ -123,13 +172,21 @@ class Type { // bool IsIndex() const { return static_cast(enum_) >= 0; } + bool isRef() const { return enum_ == Type::Ref; } + bool isRefNull() const { + return enum_ == Type::RefNull || enum_ == Type::FuncRef || + enum_ == Type::ExternRef; + } + bool isOldRef() const { + return enum_ == Type::FuncRef || enum_ == Type::ExternRef; + } + Index GetIndex() const { assert(IsIndex()); return static_cast(enum_); } Index GetReferenceIndex() const { - assert(enum_ == Enum::Reference); return type_index_; } @@ -144,6 +201,9 @@ class Type { case Type::F32: case Type::F64: case Type::V128: + case Type::Ref: + case Type::RefNull: + case Type::NoneRef: case Type::FuncRef: case Type::ExternRef: case Type::Reference: @@ -154,7 +214,6 @@ class Type { } } - private: Enum enum_; Index type_index_; // Only used for for Type::Reference }; diff --git a/include/wabt/wast-parser.h b/include/wabt/wast-parser.h index 36447c586..eb9785ce5 100644 --- a/include/wabt/wast-parser.h +++ b/include/wabt/wast-parser.h @@ -125,6 +125,7 @@ class WastParser { bool ParseBindVarOpt(std::string* name); Result ParseVar(Var* out_var); + Result ParseVarRef(Var* out_var); bool ParseVarOpt(Var* out_var, Var default_var = Var()); Result ParseOffsetExpr(ExprList* out_expr_list); bool ParseOffsetExprOpt(ExprList* out_expr_list); @@ -156,7 +157,9 @@ class WastParser { Result ParseTagModuleField(Module*); Result ParseExportModuleField(Module*); Result ParseFuncModuleField(Module*); + Result ParseRecModuleField(Module*); Result ParseTypeModuleField(Module*); + Result ParseSubType(std::unique_ptr& typeEntry); Result ParseGlobalModuleField(Module*); Result ParseImportModuleField(Module*); Result ParseMemoryModuleField(Module*); @@ -204,13 +207,22 @@ class WastParser { Result ParseExpr(ExprList*); Result ParseCatchInstrList(CatchVector* catches); Result ParseCatchExprList(CatchVector* catches); - Result ParseGlobalType(Global*); + Result ParseGlobalType(Global*, Module* m = nullptr); Result ParseField(Field*); + Result ParseStructField(std::vector& fields); Result ParseFieldList(std::vector*); template Result ParsePlainInstrVar(Location, std::unique_ptr*); template + Result ParsePlainStructGetInstrVar(Location, std::unique_ptr*); + template + Result ParsePlainInstrVar2(Location, std::unique_ptr*); + template + Result ParsePlainInstrVar3(Location, std::unique_ptr*); + template + Result ParsePlainInstrVarRef(Location, std::unique_ptr*); + template Result ParseMemoryInstrVar(Location, std::unique_ptr*); template Result ParseLoadStoreInstr(Location, Token, std::unique_ptr*); diff --git a/src/binary-writer.cc b/src/binary-writer.cc index 19443a44a..a5d9ecf0c 100644 --- a/src/binary-writer.cc +++ b/src/binary-writer.cc @@ -37,6 +37,8 @@ #define PRINT_HEADER_NO_INDEX -1 #define MAX_U32_LEB128_BYTES 5 +std::unordered_map moduletypesname4; + namespace wabt { void WriteStr(Stream* stream, @@ -705,7 +707,58 @@ void BinaryWriter::WriteSimdLoadStoreLaneExpr(const Func* func, auto* typed_expr = cast(expr); stream_->WriteU8(static_cast(typed_expr->val), "Simd Lane literal"); } - +bool isNumber(const std::string& str) { + for (char const& c : str) { + if (std::isdigit(c) == 0) + return false; + } + return true; +} +Type ParseVar2RefType(Var var) { + if (var.is_index()) + return Type(var.index()); + std::string name; + Type ans; + if (var.name().substr(0, 7) == "RefNull") { + ans = Type::RefNull; + name = var.name().substr(7); + } else { + ans = Type::Ref; + name = var.name(); + } + if (isNumber(name)) { + ans.type_index_ = std::stoi(name); + } else if (name == "NoFunc") { + ans.type_index_ = Type::NoFunc; + } else if (name == "NoExtern") { + ans.type_index_ = Type::NoExtern; + } else if (name == "None") { + ans.type_index_ = Type::NoneRef; + } else if (name == "Func") { + ans.type_index_ = Type::FuncRef; + } else if (name == "Extern") { + ans.type_index_ = Type::ExternRef; + } else if (name == "Any") { + ans.type_index_ = Type::AnyRef; + } else if (name == "Func") { + return Type::FuncRef; + } else if (name == "Extern") { + return Type::ExternRef; + } else if (name == "Eq") { + ans.type_index_ = Type::Eq; + } else if (name == "I31") { + ans.type_index_ = Type::I31; + } else if (name == "Struct") { + ans.type_index_ = Type::StructRef; + } else if (name == "Array") { + ans.type_index_ = Type::ArrayRef; + } else { + if (moduletypesname4.find(name) != moduletypesname4.end()) { + ans.type_index_ = moduletypesname4[name]; + } + } + return ans; +} void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) { switch (expr->type()) { case ExprType::AtomicLoad: @@ -874,12 +927,267 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) { WriteU32Leb128(stream_, index, "local index"); break; } + + case ExprType::StructNew: { + Index index = GetLocalIndex(func, cast(expr)->var); + WriteOpcode(stream_, Opcode::StructNew); + WriteU32Leb128(stream_, index, "struct new index"); + break; + } + case ExprType::StructNewDefault: { + Index index = GetLocalIndex(func, cast(expr)->var); + WriteOpcode(stream_, Opcode::StructNewDefault); + WriteU32Leb128(stream_, index, "struct new default index"); + break; + } + case ExprType::StructGet: { + Index index1 = GetLocalIndex(func, cast(expr)->var1); + Index index2 = GetLocalIndex(func, cast(expr)->var2); + WriteOpcode(stream_, Opcode::StructGet); + WriteU32Leb128(stream_, index1, "struct get index1"); + WriteU32Leb128(stream_, index2, "struct get index2"); + break; + } + case ExprType::StructGetU: { + Index index1 = GetLocalIndex(func, cast(expr)->var1); + Index index2 = GetLocalIndex(func, cast(expr)->var2); + WriteOpcode(stream_, Opcode::StructGetU); + WriteU32Leb128(stream_, index1, "struct getu index1"); + WriteU32Leb128(stream_, index2, "struct getu index2"); + break; + } + case ExprType::StructGetS: { + Index index1 = GetLocalIndex(func, cast(expr)->var1); + Index index2 = GetLocalIndex(func, cast(expr)->var2); + WriteOpcode(stream_, Opcode::StructGetS); + WriteU32Leb128(stream_, index1, "struct gets index1"); + WriteU32Leb128(stream_, index2, "struct gets index2"); + break; + } + case ExprType::StructSet: { + Index index1 = GetLocalIndex(func, cast(expr)->var1); + Index index2 = GetLocalIndex(func, cast(expr)->var2); + WriteOpcode(stream_, Opcode::StructSet); + WriteU32Leb128(stream_, index1, "struct set index1"); + WriteU32Leb128(stream_, index2, "struct set index2"); + break; + } + case ExprType::ArrayNew: { + Index index = GetLocalIndex(func, cast(expr)->var); + WriteOpcode(stream_, Opcode::ArrayNew); + WriteU32Leb128(stream_, index, "array new index"); + break; + } + case ExprType::ArrayNewDefault: { + Index index = GetLocalIndex(func, cast(expr)->var); + WriteOpcode(stream_, Opcode::ArrayNewDefault); + WriteU32Leb128(stream_, index, "array new default index"); + break; + } + case ExprType::ArrayNewFixed: { + Index index1 = GetLocalIndex(func, cast(expr)->var1); + Index index2 = GetLocalIndex(func, cast(expr)->var2); + WriteOpcode(stream_, Opcode::ArrayNewFixed); + WriteU32Leb128(stream_, index1, "array new fixed index1"); + WriteU32Leb128(stream_, index2, "array new fixed index2"); + break; + } + case ExprType::ArrayNewData: { + Index index1 = GetLocalIndex(func, cast(expr)->var1); + Index index2 = GetLocalIndex(func, cast(expr)->var2); + WriteOpcode(stream_, Opcode::ArrayNewData); + WriteU32Leb128(stream_, index1, "array new data index1"); + WriteU32Leb128(stream_, index2, "array new data index2"); + has_data_segment_instruction_ = true; + break; + } + case ExprType::ArrayNewElem: { + Index index1 = GetLocalIndex(func, cast(expr)->var1); + Index index2 = GetLocalIndex(func, cast(expr)->var2); + WriteOpcode(stream_, Opcode::ArrayNewElem); + WriteU32Leb128(stream_, index1, "array new elem index1"); + WriteU32Leb128(stream_, index2, "array new elem index2"); + break; + } + case ExprType::ArrayGet: { + Index index = GetLocalIndex(func, cast(expr)->var); + WriteOpcode(stream_, Opcode::ArrayGet); + WriteU32Leb128(stream_, index, "array get index"); + break; + } + case ExprType::ArrayGetU: { + Index index = GetLocalIndex(func, cast(expr)->var); + WriteOpcode(stream_, Opcode::ArrayGetU); + WriteU32Leb128(stream_, index, "array getu index"); + break; + } + case ExprType::ArrayGetS: { + Index index = GetLocalIndex(func, cast(expr)->var); + WriteOpcode(stream_, Opcode::ArrayGetS); + WriteU32Leb128(stream_, index, "array gets index"); + break; + } + case ExprType::ArraySet: { + Index index = GetLocalIndex(func, cast(expr)->var); + WriteOpcode(stream_, Opcode::ArraySet); + WriteU32Leb128(stream_, index, "array set index"); + break; + } + case ExprType::ArrayLen: { + WriteOpcode(stream_, Opcode::ArrayLen); + break; + } + case ExprType::ArrayFill: { + Index index1 = GetLocalIndex(func, cast(expr)->var); + WriteOpcode(stream_, Opcode::ArrayFill); + WriteU32Leb128(stream_, index1, "array fill index1"); + break; + } + case ExprType::ArrayCopy: { + Index index1 = GetLocalIndex(func, cast(expr)->var1); + Index index2 = GetLocalIndex(func, cast(expr)->var2); + WriteOpcode(stream_, Opcode::ArrayCopy); + WriteU32Leb128(stream_, index1, "array copy index1"); + WriteU32Leb128(stream_, index2, "array copy index2"); + break; + } + case ExprType::ArrayInitData: { + Index index1 = GetLocalIndex(func, cast(expr)->var1); + Index index2 = GetLocalIndex(func, cast(expr)->var2); + WriteOpcode(stream_, Opcode::ArrayInitData); + WriteU32Leb128(stream_, index1, "array init data index1"); + WriteU32Leb128(stream_, index2, "array init data index2"); + has_data_segment_instruction_ = true; + break; + } + case ExprType::ArrayInitElem: { + Index index1 = GetLocalIndex(func, cast(expr)->var1); + Index index2 = GetLocalIndex(func, cast(expr)->var2); + WriteOpcode(stream_, Opcode::ArrayInitElem); + WriteU32Leb128(stream_, index1, "array init elem index1"); + WriteU32Leb128(stream_, index2, "array init elem index2"); + break; + } case ExprType::LocalSet: { Index index = GetLocalIndex(func, cast(expr)->var); WriteOpcode(stream_, Opcode::LocalSet); WriteU32Leb128(stream_, index, "local index"); break; } + + case ExprType::RefCast: { + Var var = cast(expr)->var; + Type type = ParseVar2RefType(var); + if (type.isOldRef()) { + WriteType(stream_, type); + } else { + if (type.isRef()) { + WriteOpcode(stream_, Opcode::RefCastRef); + } else { + WriteOpcode(stream_, Opcode::RefCastRefNull); + } + WriteS32Leb128(stream_, type.type_index_, "type index"); + } + break; + } + case ExprType::RefTest: { + Var var = cast(expr)->var; + Type type = ParseVar2RefType(var); + if (type.isRef()) { + WriteOpcode(stream_, Opcode::RefTestRef); + } else { + WriteOpcode(stream_, Opcode::RefTestRefNull); + } + if (type.isOldRef()) { + WriteType(stream_, type); + } else { + WriteS32Leb128(stream_, type.type_index_, "type index"); + } + break; + } + case ExprType::BrOnCast: { + Index index = GetLabelVarDepth(&cast(expr)->var1); + WriteOpcode(stream_, Opcode::BrOnCast); + Var var2 = cast(expr)->var2; + Var var3 = cast(expr)->var3; + Type type2 = ParseVar2RefType(var2); + Type type3 = ParseVar2RefType(var3); + if (type2.isRef()) { + if (type3.isRefNull()) { + WriteU32Leb128(stream_, 2, "castflags"); + } else { + WriteU32Leb128(stream_, 0, "castflags"); + } + } else { + if (type3.isRefNull()) { + WriteU32Leb128(stream_, 3, "castflags"); + } else { + WriteU32Leb128(stream_, 1, "castflags"); + } + } + WriteU32Leb128(stream_, index, "br_on_cast index"); + if (!type2.isOldRef()) + WriteS32Leb128(stream_, type2.type_index_, "type index 2"); + else + WriteType(stream_, type2); + if (!type3.isOldRef()) + WriteS32Leb128(stream_, type3.type_index_, "type index 3"); + else + WriteType(stream_, type3); + break; + } + case ExprType::BrOnCastFail: { + Index index = GetLabelVarDepth(&cast(expr)->var1); + WriteOpcode(stream_, Opcode::BrOnCastFail); + Var var2 = cast(expr)->var2; + Var var3 = cast(expr)->var3; + Type type2 = ParseVar2RefType(var2); + Type type3 = ParseVar2RefType(var3); + if (type2.isRef()) { + if (type3.isRefNull()) { + WriteU32Leb128(stream_, 2, "castflags"); + } else { + WriteU32Leb128(stream_, 0, "castflags"); + } + } else { + if (type3.isRefNull()) { + WriteU32Leb128(stream_, 3, "castflags"); + } else { + WriteU32Leb128(stream_, 1, "castflags"); + } + } + WriteU32Leb128(stream_, index, "br_on_cast index"); + + if (!type2.isOldRef()) + WriteS32Leb128(stream_, type2.type_index_, "type index 2"); + else + WriteType(stream_, type2); + if (!type3.isOldRef()) + WriteS32Leb128(stream_, type3.type_index_, "type index 3"); + else + WriteType(stream_, type3); + break; + } + case ExprType::AnyConvertExtern: { + WriteOpcode(stream_, Opcode::AnyConvertExtern); + break; + } + case ExprType::ExternConvertAny: { + WriteOpcode(stream_, Opcode::ExternConvertAny); + break; + } + case ExprType::RefI31: { + WriteOpcode(stream_, Opcode::RefI31); + break; + } + case ExprType::I31GetS: { + WriteOpcode(stream_, Opcode::I31GetS); + break; + } + case ExprType::I31GetU: { + WriteOpcode(stream_, Opcode::I31GetU); + break; + } case ExprType::LocalTee: { Index index = GetLocalIndex(func, cast(expr)->var); WriteOpcode(stream_, Opcode::LocalTee); @@ -996,6 +1304,10 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) { WriteTableNumberWithReloc(index, "table.fill table index"); break; } + case ExprType::RefEq: { + WriteOpcode(stream_, Opcode::RefEq); + break; + } case ExprType::RefFunc: { WriteOpcode(stream_, Opcode::RefFunc); Index index = module_->GetFuncIndex(cast(expr)->var); @@ -1004,7 +1316,14 @@ void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) { } case ExprType::RefNull: { WriteOpcode(stream_, Opcode::RefNull); - WriteType(stream_, cast(expr)->type, "ref.null type"); + if (cast(expr)->type == Type::Ref || + cast(expr)->type == Type::RefNull) { + // WriteType(stream_, cast(expr)->type, "ref.null type"); + WriteType(stream_, cast(expr)->type.type_index_, + "ref.null type"); + } else { + WriteType(stream_, cast(expr)->type, "ref.null type"); + } break; } case ExprType::RefIsNull: @@ -1151,6 +1470,7 @@ void BinaryWriter::WriteFuncLocals(const Func* func, void BinaryWriter::WriteFunc(const Func* func) { WriteFuncLocals(func, func->local_types); + // 翻译函数指令 WriteExprList(func, func->exprs); WriteOpcode(stream_, Opcode::End); } @@ -1317,6 +1637,7 @@ Result BinaryWriter::WriteModule() { CHECK_RESULT(symtab_.Populate(module_)); } + // type section if (module_->types.size()) { BeginKnownSection(BinarySection::Type); WriteU32Leb128(stream_, module_->types.size(), "num types"); @@ -1365,11 +1686,198 @@ Result BinaryWriter::WriteModule() { stream_->WriteU8(array_type->field.mutable_, "field mutability"); break; } + + case TypeEntryKind::Sub: { + const SubType* sub_type = cast(type); + WriteHeader("sub type", i); + WriteType(stream_, Type::Sub); + std::string str = sub_type->typeEntry->name; + if (str == "") { + WriteU32Leb128(stream_, 0, "sub type index"); + } else { + int j = 0; + if (moduletypesname4.find(str) != moduletypesname4.end()) { + j = moduletypesname4[str]; + } + WriteU32Leb128(stream_, 1, "sub type index"); + WriteU32Leb128(stream_, j, "sub type index"); + } + const TypeEntry* type = sub_type->typeEntry.get(); + switch (type->kind()) { + case TypeEntryKind::Func: { + const FuncType* func_type = cast(type); + const FuncSignature* sig = &func_type->sig; + WriteHeader("func type", i); + WriteType(stream_, Type::Func); + + Index num_params = sig->param_types.size(); + Index num_results = sig->result_types.size(); + WriteU32Leb128(stream_, num_params, "num params"); + for (size_t j = 0; j < num_params; ++j) { + WriteType(stream_, sig->param_types[j]); + } + + WriteU32Leb128(stream_, num_results, "num results"); + for (size_t j = 0; j < num_results; ++j) { + WriteType(stream_, sig->result_types[j]); + } + break; + } + + case TypeEntryKind::Struct: { + const StructType* struct_type = cast(type); + WriteHeader("struct type", i); + WriteType(stream_, Type::Struct); + Index num_fields = struct_type->fields.size(); + WriteU32Leb128(stream_, num_fields, "num fields"); + for (size_t j = 0; j < num_fields; ++j) { + const Field& field = struct_type->fields[j]; + WriteType(stream_, field.type); + stream_->WriteU8(field.mutable_, "field mutability"); + } + break; + } + + case TypeEntryKind::Array: { + const ArrayType* array_type = cast(type); + WriteHeader("array type", i); + WriteType(stream_, Type::Array); + WriteType(stream_, array_type->field.type); + stream_->WriteU8(array_type->field.mutable_, "field mutability"); + break; + } + + default:; + } + break; + } + + case TypeEntryKind::Rec: { + const RecType* rec_type = cast(type); + WriteType(stream_, Type::Rec); + Index num_fields = rec_type->fields.size(); + WriteU32Leb128(stream_, num_fields, "num fields"); + auto& rec_type_fields = rec_type->fields; + for (auto& type : rec_type_fields) { + switch (type->kind()) { + case TypeEntryKind::Func: { + const FuncType* func_type = cast(type.get()); + const FuncSignature* sig = &func_type->sig; + WriteHeader("func type", i); + WriteType(stream_, Type::Func); + + Index num_params = sig->param_types.size(); + Index num_results = sig->result_types.size(); + WriteU32Leb128(stream_, num_params, "num params"); + for (size_t j = 0; j < num_params; ++j) { + WriteType(stream_, sig->param_types[j]); + } + + WriteU32Leb128(stream_, num_results, "num results"); + for (size_t j = 0; j < num_results; ++j) { + WriteType(stream_, sig->result_types[j]); + } + break; + } + + case TypeEntryKind::Struct: { + const StructType* struct_type = cast(type.get()); + WriteHeader("struct type", i); + WriteType(stream_, Type::Struct); + Index num_fields = struct_type->fields.size(); + WriteU32Leb128(stream_, num_fields, "num fields"); + for (size_t j = 0; j < num_fields; ++j) { + const Field& field = struct_type->fields[j]; + WriteType(stream_, field.type); + stream_->WriteU8(field.mutable_, "field mutability"); + } + break; + } + + case TypeEntryKind::Array: { + const ArrayType* array_type = cast(type.get()); + WriteHeader("array type", i); + WriteType(stream_, Type::Array); + WriteType(stream_, array_type->field.type); + stream_->WriteU8(array_type->field.mutable_, + "field mutability"); + break; + } + + case TypeEntryKind::Sub: { + const SubType* sub_type = cast(type.get()); + WriteHeader("sub type", i); + WriteType(stream_, Type::Sub); + std::string str = sub_type->typeEntry->name; + if (str == "") { + WriteU32Leb128(stream_, 0, "sub type index"); + } else { + int j = 0; + if (moduletypesname4.find(str) != moduletypesname4.end()) { + j = moduletypesname4[str]; + } + WriteU32Leb128(stream_, 1, "sub type index"); + WriteU32Leb128(stream_, j, "sub type index"); + } + const TypeEntry* type = sub_type->typeEntry.get(); + switch (type->kind()) { + case TypeEntryKind::Func: { + const FuncType* func_type = cast(type); + const FuncSignature* sig = &func_type->sig; + WriteHeader("func type", i); + WriteType(stream_, Type::Func); + + Index num_params = sig->param_types.size(); + Index num_results = sig->result_types.size(); + WriteU32Leb128(stream_, num_params, "num params"); + for (size_t j = 0; j < num_params; ++j) { + WriteType(stream_, sig->param_types[j]); + } + + WriteU32Leb128(stream_, num_results, "num results"); + for (size_t j = 0; j < num_results; ++j) { + WriteType(stream_, sig->result_types[j]); + } + break; + } + + case TypeEntryKind::Struct: { + const StructType* struct_type = cast(type); + WriteHeader("struct type", i); + WriteType(stream_, Type::Struct); + Index num_fields = struct_type->fields.size(); + WriteU32Leb128(stream_, num_fields, "num fields"); + for (size_t j = 0; j < num_fields; ++j) { + const Field& field = struct_type->fields[j]; + WriteType(stream_, field.type); + stream_->WriteU8(field.mutable_, "field mutability"); + } + break; + } + + case TypeEntryKind::Array: { + const ArrayType* array_type = cast(type); + WriteHeader("array type", i); + WriteType(stream_, Type::Array); + WriteType(stream_, array_type->field.type); + stream_->WriteU8(array_type->field.mutable_, + "field mutability"); + break; + } + default:; + } + break; + } + default:; + } + } + } } } EndSection(); } + // import section if (module_->imports.size()) { BeginKnownSection(BinarySection::Import); WriteU32Leb128(stream_, module_->imports.size(), "num imports"); @@ -1410,6 +1918,7 @@ Result BinaryWriter::WriteModule() { EndSection(); } + // func section assert(module_->funcs.size() >= module_->num_func_imports); Index num_funcs = module_->funcs.size() - module_->num_func_imports; if (num_funcs) { @@ -1426,6 +1935,7 @@ Result BinaryWriter::WriteModule() { EndSection(); } + // table section assert(module_->tables.size() >= module_->num_table_imports); Index num_tables = module_->tables.size() - module_->num_table_imports; if (num_tables) { @@ -1439,6 +1949,7 @@ Result BinaryWriter::WriteModule() { EndSection(); } + // memory section assert(module_->memories.size() >= module_->num_memory_imports); Index num_memories = module_->memories.size() - module_->num_memory_imports; if (num_memories) { @@ -1452,6 +1963,7 @@ Result BinaryWriter::WriteModule() { EndSection(); } + // tag section assert(module_->tags.size() >= module_->num_tag_imports); Index num_tags = module_->tags.size() - module_->num_tag_imports; if (num_tags) { @@ -1465,6 +1977,7 @@ Result BinaryWriter::WriteModule() { EndSection(); } + // global section assert(module_->globals.size() >= module_->num_global_imports); Index num_globals = module_->globals.size() - module_->num_global_imports; if (num_globals) { @@ -1479,6 +1992,7 @@ Result BinaryWriter::WriteModule() { EndSection(); } + // export section if (module_->exports.size()) { BeginKnownSection(BinarySection::Export); WriteU32Leb128(stream_, module_->exports.size(), "num exports"); @@ -1517,6 +2031,7 @@ Result BinaryWriter::WriteModule() { EndSection(); } + // start section if (module_->starts.size()) { Index start_func_index = module_->GetFuncIndex(*module_->starts[0]); if (start_func_index != kInvalidIndex) { @@ -1526,6 +2041,7 @@ Result BinaryWriter::WriteModule() { } } + // element section if (module_->elem_segments.size()) { BeginKnownSection(BinarySection::Elem); WriteU32Leb128(stream_, module_->elem_segments.size(), "num elem segments"); @@ -1575,8 +2091,8 @@ Result BinaryWriter::WriteModule() { if (options_.features.bulk_memory_enabled() && module_->data_segments.size()) { - // Keep track of the data count section offset so it can be removed if - // it isn't needed. + // Keep track of the data count section offset so it can be removed if it + // isn't needed. data_count_start_ = stream_->offset(); BeginKnownSection(BinarySection::DataCount); WriteU32Leb128(stream_, module_->data_segments.size(), "data count"); @@ -1584,6 +2100,7 @@ Result BinaryWriter::WriteModule() { data_count_end_ = stream_->offset(); } + // code section if (num_funcs) { code_start_ = stream_->offset(); BeginKnownSection(BinarySection::Code); @@ -1599,6 +2116,7 @@ Result BinaryWriter::WriteModule() { Offset body_size_offset = WriteU32Leb128Space(leb_size_guess, "func body size (guess)"); cur_func_start_offset_ = stream_->offset(); + // 函数体 翻译 WriteFunc(func); auto func_start_offset = body_size_offset - last_section_payload_offset_; auto func_end_offset = stream_->offset() - last_section_payload_offset_; @@ -1645,6 +2163,7 @@ Result BinaryWriter::WriteModule() { WriteCodeMetadataSections(); + // data section if (module_->data_segments.size()) { BeginKnownSection(BinarySection::Data); WriteU32Leb128(stream_, module_->data_segments.size(), "num data segments"); @@ -1809,6 +2328,7 @@ Result WriteBinaryModule(Stream* stream, const Module* module, const WriteBinaryOptions& options) { BinaryWriter binary_writer(stream, options, module); + moduletypesname4 = module->moduletypesname; return binary_writer.WriteModule(); } diff --git a/src/c-writer.cc b/src/c-writer.cc index d7a61f421..77c8e1f58 100644 --- a/src/c-writer.cc +++ b/src/c-writer.cc @@ -3975,6 +3975,7 @@ void CWriter::Write(const ExprList& exprs) { case ExprType::CallRef: UNIMPLEMENTED("..."); break; + default:; } } } diff --git a/src/expr-visitor.cc b/src/expr-visitor.cc index 05cd2798c..371bb639d 100644 --- a/src/expr-visitor.cc +++ b/src/expr-visitor.cc @@ -270,6 +270,111 @@ Result ExprVisitor::HandleDefaultState(Expr* expr) { CHECK_RESULT(delegate_->OnLocalGetExpr(cast(expr))); break; + case ExprType::StructNew: + CHECK_RESULT(delegate_->OnStructNewExpr(cast(expr))); + break; + + case ExprType::StructNewDefault: + CHECK_RESULT( + delegate_->OnStructNewDefaultExpr(cast(expr))); + break; + + case ExprType::StructGet: + CHECK_RESULT(delegate_->OnStructGetExpr(cast(expr))); + break; + + case ExprType::StructGetU: + CHECK_RESULT(delegate_->OnStructGetUExpr(cast(expr))); + break; + + case ExprType::StructGetS: + CHECK_RESULT(delegate_->OnStructGetSExpr(cast(expr))); + break; + + case ExprType::StructSet: + CHECK_RESULT(delegate_->OnStructSetExpr(cast(expr))); + break; + + case ExprType::ArrayNew: + CHECK_RESULT(delegate_->OnArrayNewExpr(cast(expr))); + break; + + case ExprType::ArrayNewDefault: + CHECK_RESULT( + delegate_->OnArrayNewDefaultExpr(cast(expr))); + break; + + case ExprType::ArrayNewFixed: + CHECK_RESULT( + delegate_->OnArrayNewFixedExpr(cast(expr))); + break; + + case ExprType::ArrayNewData: + CHECK_RESULT(delegate_->OnArrayNewDataExpr(cast(expr))); + break; + + case ExprType::ArrayNewElem: + CHECK_RESULT(delegate_->OnArrayNewElemExpr(cast(expr))); + break; + case ExprType::ArrayGet: + CHECK_RESULT(delegate_->OnArrayGetExpr(cast(expr))); + break; + case ExprType::ArrayGetU: + CHECK_RESULT(delegate_->OnArrayGetUExpr(cast(expr))); + break; + case ExprType::ArrayGetS: + CHECK_RESULT(delegate_->OnArrayGetSExpr(cast(expr))); + break; + case ExprType::ArraySet: + CHECK_RESULT(delegate_->OnArraySetExpr(cast(expr))); + break; + case ExprType::ArrayLen: + CHECK_RESULT(delegate_->OnArrayLenExpr(cast(expr))); + break; + case ExprType::ArrayFill: + CHECK_RESULT(delegate_->OnArrayFillExpr(cast(expr))); + break; + case ExprType::ArrayCopy: + CHECK_RESULT(delegate_->OnArrayCopyExpr(cast(expr))); + break; + case ExprType::ArrayInitData: + CHECK_RESULT( + delegate_->OnArrayInitDataExpr(cast(expr))); + break; + case ExprType::ArrayInitElem: + CHECK_RESULT( + delegate_->OnArrayInitElemExpr(cast(expr))); + break; + case ExprType::RefTest: + CHECK_RESULT(delegate_->OnRefTestExpr(cast(expr))); + break; + case ExprType::RefCast: + CHECK_RESULT(delegate_->OnRefCastExpr(cast(expr))); + break; + case ExprType::BrOnCast: + CHECK_RESULT(delegate_->OnBrOnCastExpr(cast(expr))); + break; + case ExprType::BrOnCastFail: + CHECK_RESULT(delegate_->OnBrOnCastFailExpr(cast(expr))); + break; + case ExprType::AnyConvertExtern: + CHECK_RESULT( + delegate_->OnAnyConvertExternExpr(cast(expr))); + break; + case ExprType::ExternConvertAny: + CHECK_RESULT( + delegate_->OnExternConvertAnyExpr(cast(expr))); + break; + case ExprType::RefI31: + CHECK_RESULT(delegate_->OnRefI31Expr(cast(expr))); + break; + case ExprType::I31GetU: + CHECK_RESULT(delegate_->OnI31GetUExpr(cast(expr))); + break; + case ExprType::I31GetS: + CHECK_RESULT(delegate_->OnI31GetSExpr(cast(expr))); + break; + case ExprType::LocalSet: CHECK_RESULT(delegate_->OnLocalSetExpr(cast(expr))); break; @@ -341,6 +446,9 @@ Result ExprVisitor::HandleDefaultState(Expr* expr) { CHECK_RESULT(delegate_->OnTableFillExpr(cast(expr))); break; + case ExprType::RefEq: + CHECK_RESULT(delegate_->OnRefEqExpr(cast(expr))); + break; case ExprType::RefFunc: CHECK_RESULT(delegate_->OnRefFuncExpr(cast(expr))); break; diff --git a/src/interp/interp-util.cc b/src/interp/interp-util.cc index 5267f4ae2..455e190f1 100644 --- a/src/interp/interp-util.cc +++ b/src/interp/interp-util.cc @@ -66,6 +66,8 @@ std::string TypedValueToString(const TypedValue& tv) { case Type::I32U: // These types are not concrete types and should never exist as a value WABT_UNREACHABLE; + default: + WABT_UNREACHABLE; } WABT_UNREACHABLE; } diff --git a/src/interp/interp.cc b/src/interp/interp.cc index ae1e7bb9e..1395db8ea 100644 --- a/src/interp/interp.cc +++ b/src/interp/interp.cc @@ -1948,7 +1948,8 @@ RunResult Thread::StepInternal(Trap::Ptr* out_trap) { case O::Invalid: WABT_UNREACHABLE; break; - } + default:; +} // clang-format on return RunResult::Ok; diff --git a/src/interp/istream.cc b/src/interp/istream.cc index 8e5cb5a33..5fb63a919 100644 --- a/src/interp/istream.cc +++ b/src/interp/istream.cc @@ -796,6 +796,7 @@ Instr Istream::Read(Offset* offset) const { case Opcode::ReturnCall: // Not used. break; + default:; } return instr; } diff --git a/src/ir-util.cc b/src/ir-util.cc index ee9262cc0..70cda377f 100644 --- a/src/ir-util.cc +++ b/src/ir-util.cc @@ -265,6 +265,7 @@ ModuleContext::Arities ModuleContext::GetExprArity(const Expr& expr) const { case ExprType::SimdShuffleOp: return {2, 1}; + default:; } WABT_UNREACHABLE; diff --git a/src/ir.cc b/src/ir.cc index 88db7d5f4..0495929b2 100644 --- a/src/ir.cc +++ b/src/ir.cc @@ -50,6 +50,36 @@ const char* ExprTypeName[] = { "If", "Load", "LocalGet", + "StructNew", + "StructNewDefault", + "StructGet", + "StructGetU", + "StructGetS", + "StructSet", + "ArrayNew", + "ArrayNewDefault", + "ArrayNewFixed", + "ArrayNewData", + "ArrayNewElem", + "ArrayGet", + "ArrayGetS", + "ArrayGetU", + "ArraySet", + "ArrayLen", + "ArrayFill", + "ArrayCopy", + "ArrayInitData", + "ArrayInitElem", + + "RefTest", + "RefCast", + "BrOnCast", + "BrOnCastFail", + "AnyConvertExtern", + "ExternConvertAny", + "RefI31", + "I31GetS", + "I31GetU", "LocalSet", "LocalTee", "Loop", @@ -61,6 +91,7 @@ const char* ExprTypeName[] = { "MemorySize", "Nop", "RefIsNull", + "RefEq", "RefFunc", "RefNull", "Rethrow", @@ -105,7 +136,36 @@ const char* GetExprTypeName(const Expr& expr) { } bool FuncSignature::operator==(const FuncSignature& rhs) const { - return param_types == rhs.param_types && result_types == rhs.result_types; + // param_types == rhs.param_types + if (param_types.size() != rhs.param_types.size()) { + return false; + } + for (size_t i = 0; i < param_types.size(); ++i) { + if (param_types[i].enum_ != rhs.param_types[i].enum_) { + return false; + } + if (param_types[i].IsReferenceWithIndex()) { + if (param_types[i].type_index_ != rhs.param_types[i].type_index_) { + return false; + } + } + } + // result_types == rhs.result_types + if (result_types.size() != rhs.result_types.size()) { + return false; + } + for (size_t i = 0; i < result_types.size(); ++i) { + if (result_types[i].enum_ != rhs.result_types[i].enum_) { + return false; + } + if (result_types[i].IsReferenceWithIndex()) { + if (result_types[i].type_index_ != rhs.result_types[i].type_index_) { + return false; + } + } + } + return true; + //return param_types == rhs.param_types && result_types == rhs.result_types; } const Export* Module::GetExport(std::string_view name) const { @@ -323,11 +383,17 @@ FuncType* Module::GetFuncType(const Var& var) { } Index Module::GetFuncTypeIndex(const FuncSignature& sig) const { + size_t index = 0; for (size_t i = 0; i < types.size(); ++i) { if (auto* func_type = dyn_cast(types[i])) { if (func_type->sig == sig) { - return i; + return index; } + ++index; + } else if (auto* rec_type = dyn_cast(types[i])) { + index += rec_type->fields.size(); + } else { + ++index; } } return kInvalidIndex; @@ -396,6 +462,29 @@ void Module::AppendField(std::unique_ptr field) { fields.push_back(std::move(field)); } +void Module::AppendFieldRec(std::unique_ptr field) { + TypeEntry& type = *field->type; + RecType& rec_type = dynamic_cast(type); + std::vector>& items = rec_type.fields; + std::vector::size_type s = 0; + for (auto& i : types) { + if (i->kind() == TypeEntryKind::Rec) { + s += dynamic_cast(i)->fields.size(); + } else { + s++; + } + } + wabt::Index j = 0; + for (auto& item : items) { + if (!item->name.empty()) { + type_bindings.emplace(item->name, Binding(field->loc, s + j)); + } + j++; + } + types.push_back(&type); + fields.push_back(std::move(field)); +} + void Module::AppendField(std::unique_ptr field) { Global& global = field->global; if (!global.name.empty()) { diff --git a/src/lexer-keywords.txt b/src/lexer-keywords.txt index 7836339c1..c8a12a0c9 100644 --- a/src/lexer-keywords.txt +++ b/src/lexer-keywords.txt @@ -18,6 +18,8 @@ struct TokenInfo { }; %% array, Type::Array, TokenType::Array +sub, TokenType::Sub +rec, TokenType::Rec after, TokenType::After assert_exception, TokenType::AssertException assert_exhaustion, TokenType::AssertExhaustion @@ -180,7 +182,9 @@ f64x2.promote_low_f32x4, TokenType::Unary, Opcode::F64X2PromoteLowF32X4 f64x2, TokenType::F64X2 field, TokenType::Field funcref, Type::FuncRef +anyref,Type::Any func, Type::FuncRef, TokenType::Func +none, Type::NoneRef, TokenType::None function, TokenType::Function get, TokenType::Get global.get, TokenType::GlobalGet, Opcode::GlobalGet @@ -314,6 +318,12 @@ i32.trunc_sat_f32_u, TokenType::Convert, Opcode::I32TruncSatF32U i32.trunc_sat_f64_s, TokenType::Convert, Opcode::I32TruncSatF64S i32.trunc_sat_f64_u, TokenType::Convert, Opcode::I32TruncSatF64U i32, Type::I32 +i8, Type::I8 +i16, Type::I16 +i31, Type::I31, TokenType::I31 +eq, Type::Eq, TokenType::Eq +nofunc, Type::NoFunc, TokenType::NoFunc +noextern, Type::NoExtern, TokenType::NoExtern i32.wrap_i64, TokenType::Convert, Opcode::I32WrapI64 i32x4.abs, TokenType::Unary, Opcode::I32X4Abs i32x4.add, TokenType::Binary, Opcode::I32X4Add @@ -555,10 +565,13 @@ nop, TokenType::Nop, Opcode::Nop offset, TokenType::Offset output, TokenType::Output param, TokenType::Param -ref, TokenType::Ref +ref, Type::Ref, TokenType::Ref +null, Type::Null, TokenType::Null +any, Type::Any, TokenType::Any quote, TokenType::Quote ref.extern, TokenType::RefExtern ref.func, TokenType::RefFunc, Opcode::RefFunc +ref.eq, TokenType::RefEq, Opcode::RefEq ref.is_null, TokenType::RefIsNull, Opcode::RefIsNull ref.null, TokenType::RefNull, Opcode::RefNull register, TokenType::Register @@ -571,6 +584,35 @@ select, TokenType::Select, Opcode::Select shared, TokenType::Shared start, TokenType::Start struct, Type::Struct, TokenType::Struct +struct.new, TokenType::StructNew, Opcode::StructNew +struct.new_default, TokenType::StructNewDefault, Opcode::StructNewDefault +struct.get, TokenType::StructGet, Opcode::StructGet +struct.get_s,TokenType::StructGetS, Opcode::StructGetS +struct.get_u,TokenType::StructGetU, Opcode::StructGetU +struct.set, TokenType::StructSet, Opcode::StructSet +array.new, TokenType::ArrayNew, Opcode::ArrayNew +array.new_default, TokenType::ArrayNewDefault, Opcode::ArrayNewDefault +array.new_fixed, TokenType::ArrayNewFixed, Opcode::ArrayNewFixed +array.new_data, TokenType::ArrayNewData, Opcode::ArrayNewData +array.new_elem, TokenType::ArrayNewElem, Opcode::ArrayNewElem +array.get, TokenType::ArrayGet, Opcode::ArrayGet +array.get_s, TokenType::ArrayGetS, Opcode::ArrayGetS +array.get_u, TokenType::ArrayGetU, Opcode::ArrayGetU +array.set, TokenType::ArraySet, Opcode::ArraySet +array.len, TokenType::ArrayLen, Opcode::ArrayLen +array.fill, TokenType::ArrayFill, Opcode::ArrayFill +array.copy, TokenType::ArrayCopy, Opcode::ArrayCopy +array.init_data, TokenType::ArrayInitData, Opcode::ArrayInitData +array.init_elem, TokenType::ArrayInitElem, Opcode::ArrayInitElem +ref.cast, TokenType::RefCast +ref.test, TokenType::RefTest +br_on_cast, TokenType::BrOnCast, Opcode::BrOnCast +br_on_cast_fail, TokenType::BrOnCastFail, Opcode::BrOnCastFail +any.convert_extern, TokenType::AnyConvertExtern, Opcode::AnyConvertExtern +extern.convert_any, TokenType::ExternConvertAny, Opcode::ExternConvertAny +ref.i31, TokenType::RefI31, Opcode::RefI31 +i31.get_s, TokenType::I31GetS, Opcode::I31GetS +i31.get_u, TokenType::I31GetU, Opcode::I31GetU table.copy, TokenType::TableCopy, Opcode::TableCopy table.fill, TokenType::TableFill, Opcode::TableFill table.get, TokenType::TableGet, Opcode::TableGet diff --git a/src/opcode.cc b/src/opcode.cc index 3a62fa718..5037b0c58 100644 --- a/src/opcode.cc +++ b/src/opcode.cc @@ -1,19 +1,3 @@ -/* - * Copyright 2017 WebAssembly Community Group participants - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - #include "wabt/opcode.h" #include "wabt/feature.h" diff --git a/src/prebuilt/lexer-keywords.cc b/src/prebuilt/lexer-keywords.cc index 3712f6ffd..84dfe93bc 100644 --- a/src/prebuilt/lexer-keywords.cc +++ b/src/prebuilt/lexer-keywords.cc @@ -1,5 +1,5 @@ /* C++ code produced by gperf version 3.1 */ -/* Command-line: gperf -m 50 -L C++ -N InWordSet -E -t -c --output-file=src/prebuilt/lexer-keywords.cc src/lexer-keywords.txt */ +/* Command-line: gperf -m 50 -L C++ -N InWordSet -E -t -c --output-file=./prebuilt/lexer-keywords.cc ./lexer-keywords.txt */ /* Computed positions: -k'1,3,5-8,10,12,15,17-19,23,27,$' */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -29,26 +29,26 @@ #error "gperf generated tables don't work with this execution character set. Please report a bug to ." #endif -#line 1 "src/lexer-keywords.txt" -struct TokenInfo { - TokenInfo(const char* name) : name(name) {} - TokenInfo(const char* name, TokenType token_type) - : name(name), token_type(token_type) {} - TokenInfo(const char* name, Type value_type) - : name(name), token_type(TokenType::ValueType), value_type(value_type) {} - TokenInfo(const char* name, Type value_type, TokenType token_type) - : name(name), token_type(token_type), value_type(value_type) {} - TokenInfo(const char* name, TokenType token_type, Opcode opcode) - : name(name), token_type(token_type), opcode(opcode) {} - - const char* name; - TokenType token_type; - union { - Type value_type; - Opcode opcode; - }; -}; -/* maximum key range = 2533, duplicates = 0 */ +#line 1 "./lexer-keywords.txt" +struct TokenInfo { + TokenInfo(const char* name) : name(name) {} + TokenInfo(const char* name, TokenType token_type) + : name(name), token_type(token_type) {} + TokenInfo(const char* name, Type value_type) + : name(name), token_type(TokenType::ValueType), value_type(value_type) {} + TokenInfo(const char* name, Type value_type, TokenType token_type) + : name(name), token_type(token_type), value_type(value_type) {} + TokenInfo(const char* name, TokenType token_type, Opcode opcode) + : name(name), token_type(token_type), opcode(opcode) {} + + const char* name; + TokenType token_type; + union { + Type value_type; + Opcode opcode; + }; +}; ; +/* maximum key range = 2998, duplicates = 0 */ class Perfect_Hash { @@ -63,32 +63,32 @@ Perfect_Hash::hash (const char *str, size_t len) { static unsigned short asso_values[] = { - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 6, 2553, 2553, 769, - 407, 7, 15, 6, 171, 492, 70, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 224, 7, 12, 777, 7, - 66, 10, 671, 6, 280, 65, 13, 6, 8, 131, - 61, 92, 552, 652, 11, 8, 18, 6, 689, 459, - 127, 554, 100, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, - 2553, 2553, 2553, 2553, 2553, 2553, 2553 + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 2, 3011, 3011, 700, + 359, 1, 30, 0, 346, 541, 246, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 261, 0, 3, 217, 66, + 64, 6, 832, 4, 647, 235, 0, 2, 20, 116, + 53, 80, 753, 703, 19, 2, 0, 0, 390, 383, + 328, 83, 314, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, 3011, + 3011, 3011, 3011, 3011, 3011, 3011, 3011 }; unsigned int hval = len; @@ -96,55 +96,55 @@ Perfect_Hash::hash (const char *str, size_t len) { default: hval += asso_values[static_cast(str[26])]; - [[fallthrough]]; + /*FALLTHROUGH*/ case 26: case 25: case 24: case 23: hval += asso_values[static_cast(str[22])]; - [[fallthrough]]; + /*FALLTHROUGH*/ case 22: case 21: case 20: case 19: hval += asso_values[static_cast(str[18])]; - [[fallthrough]]; + /*FALLTHROUGH*/ case 18: hval += asso_values[static_cast(str[17])]; - [[fallthrough]]; + /*FALLTHROUGH*/ case 17: hval += asso_values[static_cast(str[16])]; - [[fallthrough]]; + /*FALLTHROUGH*/ case 16: case 15: hval += asso_values[static_cast(str[14])]; - [[fallthrough]]; + /*FALLTHROUGH*/ case 14: case 13: case 12: hval += asso_values[static_cast(str[11])]; - [[fallthrough]]; + /*FALLTHROUGH*/ case 11: case 10: hval += asso_values[static_cast(str[9])]; - [[fallthrough]]; + /*FALLTHROUGH*/ case 9: case 8: hval += asso_values[static_cast(str[7])]; - [[fallthrough]]; + /*FALLTHROUGH*/ case 7: hval += asso_values[static_cast(str[6])]; - [[fallthrough]]; + /*FALLTHROUGH*/ case 6: hval += asso_values[static_cast(str[5])]; - [[fallthrough]]; + /*FALLTHROUGH*/ case 5: hval += asso_values[static_cast(str[4])]; - [[fallthrough]]; + /*FALLTHROUGH*/ case 4: case 3: hval += asso_values[static_cast(str[2]+1)]; - [[fallthrough]]; + /*FALLTHROUGH*/ case 2: case 1: hval += asso_values[static_cast(str[0]+1)]; @@ -158,1581 +158,1713 @@ Perfect_Hash::InWordSet (const char *str, size_t len) { enum { - TOTAL_KEYWORDS = 594, + TOTAL_KEYWORDS = 636, MIN_WORD_LENGTH = 2, MAX_WORD_LENGTH = 32, - MIN_HASH_VALUE = 20, - MAX_HASH_VALUE = 2552 + MIN_HASH_VALUE = 13, + MAX_HASH_VALUE = 3010 }; static struct TokenInfo wordlist[] = { {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, -#line 35 "src/lexer-keywords.txt" - {"br", TokenType::Br, Opcode::Br}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 148 "src/lexer-keywords.txt" - {"f64", Type::F64}, - {""}, -#line 43 "src/lexer-keywords.txt" - {"data", TokenType::Data}, {""}, {""}, {""}, {""}, -#line 460 "src/lexer-keywords.txt" - {"i64", Type::I64}, -#line 581 "src/lexer-keywords.txt" - {"table", TokenType::Table}, - {""}, {""}, {""}, {""}, {""}, -#line 131 "src/lexer-keywords.txt" - {"f64.ge", TokenType::Compare, Opcode::F64Ge}, -#line 70 "src/lexer-keywords.txt" - {"f32.ge", TokenType::Compare, Opcode::F32Ge}, -#line 133 "src/lexer-keywords.txt" - {"f64.le", TokenType::Compare, Opcode::F64Le}, -#line 72 "src/lexer-keywords.txt" - {"f32.le", TokenType::Compare, Opcode::F32Le}, -#line 118 "src/lexer-keywords.txt" - {"f32x4", TokenType::F32X4}, - {""}, -#line 30 "src/lexer-keywords.txt" - {"before", TokenType::Before}, - {""}, {""}, {""}, {""}, -#line 360 "src/lexer-keywords.txt" - {"i32x4", TokenType::I32X4}, - {""}, {""}, {""}, {""}, -#line 132 "src/lexer-keywords.txt" - {"f64.gt", TokenType::Compare, Opcode::F64Gt}, -#line 71 "src/lexer-keywords.txt" - {"f32.gt", TokenType::Compare, Opcode::F32Gt}, -#line 135 "src/lexer-keywords.txt" - {"f64.lt", TokenType::Compare, Opcode::F64Lt}, -#line 74 "src/lexer-keywords.txt" - {"f32.lt", TokenType::Compare, Opcode::F32Lt}, +#line 45 "./lexer-keywords.txt" + {"data", TokenType::Data }, +#line 134 "./lexer-keywords.txt" + {"f64.gt", TokenType::Compare, Opcode::F64Gt }, +#line 73 "./lexer-keywords.txt" + {"f32.gt", TokenType::Compare, Opcode::F32Gt }, + {""}, {""}, {""}, {""}, {""}, {""}, +#line 608 "./lexer-keywords.txt" + {"ref.test", TokenType::RefTest }, + {""}, {""}, {""}, +#line 133 "./lexer-keywords.txt" + {"f64.ge", TokenType::Compare, Opcode::F64Ge }, +#line 72 "./lexer-keywords.txt" + {"f32.ge", TokenType::Compare, Opcode::F32Ge }, +#line 578 "./lexer-keywords.txt" + {"result", TokenType::Result }, + {""}, +#line 137 "./lexer-keywords.txt" + {"f64.lt", TokenType::Compare, Opcode::F64Lt }, +#line 76 "./lexer-keywords.txt" + {"f32.lt", TokenType::Compare, Opcode::F32Lt }, + {""}, +#line 470 "./lexer-keywords.txt" + {"i64", Type::I64 }, + {""}, {""}, {""}, +#line 150 "./lexer-keywords.txt" + {"f64", Type::F64 }, {""}, {""}, {""}, {""}, -#line 96 "src/lexer-keywords.txt" - {"f32x4.ge", TokenType::Compare, Opcode::F32X4Ge}, - {""}, -#line 98 "src/lexer-keywords.txt" - {"f32x4.le", TokenType::Compare, Opcode::F32X4Le}, - {""}, -#line 576 "src/lexer-keywords.txt" - {"table.get", TokenType::TableGet, Opcode::TableGet}, - {""}, -#line 579 "src/lexer-keywords.txt" - {"table.set", TokenType::TableSet, Opcode::TableSet}, -#line 573 "src/lexer-keywords.txt" - {"struct", Type::Struct, TokenType::Struct}, -#line 565 "src/lexer-keywords.txt" - {"result", TokenType::Result}, -#line 89 "src/lexer-keywords.txt" - {"f32x4.ceil", TokenType::Unary, Opcode::F32X4Ceil}, - {""}, -#line 326 "src/lexer-keywords.txt" - {"i32x4.ge_u", TokenType::Compare, Opcode::I32X4GeU}, - {""}, -#line 330 "src/lexer-keywords.txt" - {"i32x4.le_u", TokenType::Compare, Opcode::I32X4LeU}, - {""}, -#line 325 "src/lexer-keywords.txt" - {"i32x4.ge_s", TokenType::Compare, Opcode::I32X4GeS}, -#line 97 "src/lexer-keywords.txt" - {"f32x4.gt", TokenType::Compare, Opcode::F32X4Gt}, -#line 329 "src/lexer-keywords.txt" - {"i32x4.le_s", TokenType::Compare, Opcode::I32X4LeS}, -#line 99 "src/lexer-keywords.txt" - {"f32x4.lt", TokenType::Compare, Opcode::F32X4Lt}, -#line 328 "src/lexer-keywords.txt" - {"i32x4.gt_u", TokenType::Compare, Opcode::I32X4GtU}, -#line 551 "src/lexer-keywords.txt" - {"mut", TokenType::Mut}, -#line 338 "src/lexer-keywords.txt" - {"i32x4.lt_u", TokenType::Compare, Opcode::I32X4LtU}, -#line 41 "src/lexer-keywords.txt" - {"code", TokenType::Code}, -#line 327 "src/lexer-keywords.txt" - {"i32x4.gt_s", TokenType::Compare, Opcode::I32X4GtS}, - {""}, -#line 337 "src/lexer-keywords.txt" - {"i32x4.lt_s", TokenType::Compare, Opcode::I32X4LtS}, - {""}, {""}, {""}, {""}, {""}, -#line 141 "src/lexer-keywords.txt" - {"f64.ne", TokenType::Compare, Opcode::F64Ne}, -#line 80 "src/lexer-keywords.txt" - {"f32.ne", TokenType::Compare, Opcode::F32Ne}, - {""}, -#line 140 "src/lexer-keywords.txt" - {"f64.neg", TokenType::Unary, Opcode::F64Neg}, -#line 79 "src/lexer-keywords.txt" - {"f32.neg", TokenType::Unary, Opcode::F32Neg}, -#line 46 "src/lexer-keywords.txt" - {"do", TokenType::Do}, -#line 550 "src/lexer-keywords.txt" - {"module", TokenType::Module}, -#line 436 "src/lexer-keywords.txt" - {"i64.ne", TokenType::Compare, Opcode::I64Ne}, -#line 293 "src/lexer-keywords.txt" - {"i32.ne", TokenType::Compare, Opcode::I32Ne}, - {""}, -#line 183 "src/lexer-keywords.txt" - {"func", Type::FuncRef, TokenType::Func}, +#line 135 "./lexer-keywords.txt" + {"f64.le", TokenType::Compare, Opcode::F64Le }, +#line 74 "./lexer-keywords.txt" + {"f32.le", TokenType::Compare, Opcode::F32Le }, + {""}, {""}, {""}, +#line 338 "./lexer-keywords.txt" + {"i32x4.gt_u", TokenType::Compare, Opcode::I32X4GtU }, + {""}, +#line 99 "./lexer-keywords.txt" + {"f32x4.gt", TokenType::Compare, Opcode::F32X4Gt }, + {""}, +#line 337 "./lexer-keywords.txt" + {"i32x4.gt_s", TokenType::Compare, Opcode::I32X4GtS }, + {""}, +#line 336 "./lexer-keywords.txt" + {"i32x4.ge_u", TokenType::Compare, Opcode::I32X4GeU }, + {""}, {""}, +#line 561 "./lexer-keywords.txt" + {"mut", TokenType::Mut }, +#line 335 "./lexer-keywords.txt" + {"i32x4.ge_s", TokenType::Compare, Opcode::I32X4GeS }, {""}, {""}, {""}, -#line 563 "src/lexer-keywords.txt" - {"ref.null", TokenType::RefNull, Opcode::RefNull}, +#line 98 "./lexer-keywords.txt" + {"f32x4.ge", TokenType::Compare, Opcode::F32X4Ge }, + {""}, +#line 348 "./lexer-keywords.txt" + {"i32x4.lt_u", TokenType::Compare, Opcode::I32X4LtU }, + {""}, +#line 101 "./lexer-keywords.txt" + {"f32x4.lt", TokenType::Compare, Opcode::F32X4Lt }, +#line 370 "./lexer-keywords.txt" + {"i32x4", TokenType::I32X4 }, +#line 347 "./lexer-keywords.txt" + {"i32x4.lt_s", TokenType::Compare, Opcode::I32X4LtS }, + {""}, +#line 340 "./lexer-keywords.txt" + {"i32x4.le_u", TokenType::Compare, Opcode::I32X4LeU }, +#line 120 "./lexer-keywords.txt" + {"f32x4", TokenType::F32X4 }, +#line 446 "./lexer-keywords.txt" + {"i64.ne", TokenType::Compare, Opcode::I64Ne }, +#line 297 "./lexer-keywords.txt" + {"i32.ne", TokenType::Compare, Opcode::I32Ne }, +#line 339 "./lexer-keywords.txt" + {"i32x4.le_s", TokenType::Compare, Opcode::I32X4LeS }, +#line 586 "./lexer-keywords.txt" + {"struct", Type::Struct, TokenType::Struct }, +#line 143 "./lexer-keywords.txt" + {"f64.ne", TokenType::Compare, Opcode::F64Ne }, +#line 82 "./lexer-keywords.txt" + {"f32.ne", TokenType::Compare, Opcode::F32Ne }, +#line 100 "./lexer-keywords.txt" + {"f32x4.le", TokenType::Compare, Opcode::F32X4Le }, +#line 142 "./lexer-keywords.txt" + {"f64.neg", TokenType::Unary, Opcode::F64Neg }, +#line 81 "./lexer-keywords.txt" + {"f32.neg", TokenType::Unary, Opcode::F32Neg }, +#line 43 "./lexer-keywords.txt" + {"code", TokenType::Code }, + {""}, +#line 592 "./lexer-keywords.txt" + {"struct.set", TokenType::StructSet, Opcode::StructSet }, +#line 623 "./lexer-keywords.txt" + {"table", TokenType::Table }, +#line 589 "./lexer-keywords.txt" + {"struct.get", TokenType::StructGet, Opcode::StructGet }, +#line 607 "./lexer-keywords.txt" + {"ref.cast", TokenType::RefCast }, +#line 591 "./lexer-keywords.txt" + {"struct.get_u",TokenType::StructGetU, Opcode::StructGetU }, +#line 37 "./lexer-keywords.txt" + {"br", TokenType::Br, Opcode::Br }, +#line 48 "./lexer-keywords.txt" + {"do", TokenType::Do }, + {""}, +#line 590 "./lexer-keywords.txt" + {"struct.get_s",TokenType::StructGetS, Opcode::StructGetS }, +#line 621 "./lexer-keywords.txt" + {"table.set", TokenType::TableSet, Opcode::TableSet }, + {""}, +#line 618 "./lexer-keywords.txt" + {"table.get", TokenType::TableGet, Opcode::TableGet }, + {""}, {""}, {""}, +#line 560 "./lexer-keywords.txt" + {"module", TokenType::Module }, +#line 141 "./lexer-keywords.txt" + {"f64.nearest", TokenType::Unary, Opcode::F64Nearest }, +#line 80 "./lexer-keywords.txt" + {"f32.nearest", TokenType::Unary, Opcode::F32Nearest }, + {""}, {""}, {""}, {""}, {""}, +#line 355 "./lexer-keywords.txt" + {"i32x4.neg", TokenType::Unary, Opcode::I32X4Neg }, +#line 356 "./lexer-keywords.txt" + {"i32x4.ne", TokenType::Compare, Opcode::I32X4Ne }, +#line 32 "./lexer-keywords.txt" + {"before", TokenType::Before }, + {""}, +#line 106 "./lexer-keywords.txt" + {"f32x4.neg", TokenType::Unary, Opcode::F32X4Neg }, +#line 107 "./lexer-keywords.txt" + {"f32x4.ne", TokenType::Compare, Opcode::F32X4Ne }, +#line 46 "./lexer-keywords.txt" + {"declare", TokenType::Declare }, {""}, {""}, {""}, {""}, -#line 121 "src/lexer-keywords.txt" - {"f64.ceil", TokenType::Unary, Opcode::F64Ceil}, -#line 59 "src/lexer-keywords.txt" - {"f32.ceil", TokenType::Unary, Opcode::F32Ceil}, -#line 104 "src/lexer-keywords.txt" - {"f32x4.neg", TokenType::Unary, Opcode::F32X4Neg}, - {""}, {""}, -#line 105 "src/lexer-keywords.txt" - {"f32x4.ne", TokenType::Compare, Opcode::F32X4Ne}, -#line 147 "src/lexer-keywords.txt" - {"f64.trunc", TokenType::Unary, Opcode::F64Trunc}, -#line 85 "src/lexer-keywords.txt" - {"f32.trunc", TokenType::Unary, Opcode::F32Trunc}, -#line 44 "src/lexer-keywords.txt" - {"declare", TokenType::Declare}, -#line 345 "src/lexer-keywords.txt" - {"i32x4.neg", TokenType::Unary, Opcode::I32X4Neg}, - {""}, {""}, -#line 346 "src/lexer-keywords.txt" - {"i32x4.ne", TokenType::Compare, Opcode::I32X4Ne}, - {""}, -#line 580 "src/lexer-keywords.txt" - {"table.size", TokenType::TableSize, Opcode::TableSize}, - {""}, {""}, {""}, {""}, {""}, {""}, -#line 437 "src/lexer-keywords.txt" - {"i64.or", TokenType::Binary, Opcode::I64Or}, -#line 294 "src/lexer-keywords.txt" - {"i32.or", TokenType::Binary, Opcode::I32Or}, - {""}, -#line 116 "src/lexer-keywords.txt" - {"f32x4.trunc", TokenType::Unary, Opcode::F32X4Trunc}, -#line 139 "src/lexer-keywords.txt" - {"f64.nearest", TokenType::Unary, Opcode::F64Nearest}, -#line 78 "src/lexer-keywords.txt" - {"f32.nearest", TokenType::Unary, Opcode::F32Nearest}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 569 "src/lexer-keywords.txt" - {"return", TokenType::Return, Opcode::Return}, +#line 460 "./lexer-keywords.txt" + {"i64.store", TokenType::Store, Opcode::I64Store }, +#line 310 "./lexer-keywords.txt" + {"i32.store", TokenType::Store, Opcode::I32Store }, + {""}, {""}, +#line 147 "./lexer-keywords.txt" + {"f64.store", TokenType::Store, Opcode::F64Store }, +#line 85 "./lexer-keywords.txt" + {"f32.store", TokenType::Store, Opcode::F32Store }, + {""}, {""}, +#line 447 "./lexer-keywords.txt" + {"i64.or", TokenType::Binary, Opcode::I64Or }, +#line 298 "./lexer-keywords.txt" + {"i32.or", TokenType::Binary, Opcode::I32Or }, {""}, -#line 103 "src/lexer-keywords.txt" - {"f32x4.nearest", TokenType::Unary, Opcode::F32X4Nearest}, +#line 576 "./lexer-keywords.txt" + {"ref.null", TokenType::RefNull, Opcode::RefNull }, + {""}, {""}, +#line 105 "./lexer-keywords.txt" + {"f32x4.nearest", TokenType::Unary, Opcode::F32X4Nearest }, + {""}, {""}, +#line 582 "./lexer-keywords.txt" + {"return", TokenType::Return, Opcode::Return }, + {""}, +#line 22 "./lexer-keywords.txt" + {"rec", TokenType::Rec }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 453 "./lexer-keywords.txt" + {"i64.rotr", TokenType::Binary, Opcode::I64Rotr }, +#line 304 "./lexer-keywords.txt" + {"i32.rotr", TokenType::Binary, Opcode::I32Rotr }, +#line 452 "./lexer-keywords.txt" + {"i64.rotl", TokenType::Binary, Opcode::I64Rotl }, +#line 303 "./lexer-keywords.txt" + {"i32.rotl", TokenType::Binary, Opcode::I32Rotl }, +#line 47 "./lexer-keywords.txt" + {"delegate", TokenType::Delegate }, + {""}, +#line 149 "./lexer-keywords.txt" + {"f64.trunc", TokenType::Unary, Opcode::F64Trunc }, +#line 87 "./lexer-keywords.txt" + {"f32.trunc", TokenType::Unary, Opcode::F32Trunc }, + {""}, +#line 186 "./lexer-keywords.txt" + {"func", Type::FuncRef, TokenType::Func }, {""}, {""}, {""}, {""}, -#line 145 "src/lexer-keywords.txt" - {"f64.store", TokenType::Store, Opcode::F64Store}, -#line 83 "src/lexer-keywords.txt" - {"f32.store", TokenType::Store, Opcode::F32Store}, - {""}, {""}, -#line 442 "src/lexer-keywords.txt" - {"i64.rotl", TokenType::Binary, Opcode::I64Rotl}, -#line 299 "src/lexer-keywords.txt" - {"i32.rotl", TokenType::Binary, Opcode::I32Rotl}, - {""}, -#line 450 "src/lexer-keywords.txt" - {"i64.store", TokenType::Store, Opcode::I64Store}, -#line 306 "src/lexer-keywords.txt" - {"i32.store", TokenType::Store, Opcode::I32Store}, - {""}, -#line 443 "src/lexer-keywords.txt" - {"i64.rotr", TokenType::Binary, Opcode::I64Rotr}, -#line 300 "src/lexer-keywords.txt" - {"i32.rotr", TokenType::Binary, Opcode::I32Rotr}, -#line 138 "src/lexer-keywords.txt" - {"f64.mul", TokenType::Binary, Opcode::F64Mul}, -#line 77 "src/lexer-keywords.txt" - {"f32.mul", TokenType::Binary, Opcode::F32Mul}, +#line 91 "./lexer-keywords.txt" + {"f32x4.ceil", TokenType::Unary, Opcode::F32X4Ceil }, {""}, {""}, {""}, -#line 112 "src/lexer-keywords.txt" - {"f32x4.replace_lane", TokenType::SimdLaneOp, Opcode::F32X4ReplaceLane}, +#line 445 "./lexer-keywords.txt" + {"i64.mul", TokenType::Binary, Opcode::I64Mul }, +#line 296 "./lexer-keywords.txt" + {"i32.mul", TokenType::Binary, Opcode::I32Mul }, + {""}, {""}, +#line 140 "./lexer-keywords.txt" + {"f64.mul", TokenType::Binary, Opcode::F64Mul }, +#line 79 "./lexer-keywords.txt" + {"f32.mul", TokenType::Binary, Opcode::F32Mul }, {""}, -#line 435 "src/lexer-keywords.txt" - {"i64.mul", TokenType::Binary, Opcode::I64Mul}, -#line 292 "src/lexer-keywords.txt" - {"i32.mul", TokenType::Binary, Opcode::I32Mul}, +#line 187 "./lexer-keywords.txt" + {"none", Type::NoneRef, TokenType::None }, + {""}, {""}, +#line 329 "./lexer-keywords.txt" + {"i32x4.add", TokenType::Binary, Opcode::I32X4Add }, + {""}, {""}, {""}, +#line 90 "./lexer-keywords.txt" + {"f32x4.add", TokenType::Binary, Opcode::F32X4Add }, +#line 354 "./lexer-keywords.txt" + {"i32x4.mul", TokenType::Binary, Opcode::I32X4Mul }, {""}, {""}, {""}, -#line 348 "src/lexer-keywords.txt" - {"i32x4.replace_lane", TokenType::SimdLaneOp, Opcode::I32X4ReplaceLane}, +#line 104 "./lexer-keywords.txt" + {"f32x4.mul", TokenType::Binary, Opcode::F32X4Mul }, + {""}, {""}, {""}, +#line 118 "./lexer-keywords.txt" + {"f32x4.trunc", TokenType::Unary, Opcode::F32X4Trunc }, + {""}, +#line 583 "./lexer-keywords.txt" + {"select", TokenType::Select, Opcode::Select }, {""}, {""}, -#line 88 "src/lexer-keywords.txt" - {"f32x4.add", TokenType::Binary, Opcode::F32X4Add}, -#line 102 "src/lexer-keywords.txt" - {"f32x4.mul", TokenType::Binary, Opcode::F32X4Mul}, - {""}, {""}, {""}, {""}, {""}, -#line 319 "src/lexer-keywords.txt" - {"i32x4.add", TokenType::Binary, Opcode::I32X4Add}, -#line 344 "src/lexer-keywords.txt" - {"i32x4.mul", TokenType::Binary, Opcode::I32X4Mul}, +#line 381 "./lexer-keywords.txt" + {"i64.and", TokenType::Binary, Opcode::I64And }, +#line 246 "./lexer-keywords.txt" + {"i32.and", TokenType::Binary, Opcode::I32And }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 380 "./lexer-keywords.txt" + {"i64.add", TokenType::Binary, Opcode::I64Add }, +#line 245 "./lexer-keywords.txt" + {"i32.add", TokenType::Binary, Opcode::I32Add }, +#line 40 "./lexer-keywords.txt" + {"call", TokenType::Call, Opcode::Call }, + {""}, +#line 122 "./lexer-keywords.txt" + {"f64.add", TokenType::Binary, Opcode::F64Add }, +#line 60 "./lexer-keywords.txt" + {"f32.add", TokenType::Binary, Opcode::F32Add }, {""}, {""}, -#line 570 "src/lexer-keywords.txt" - {"select", TokenType::Select, Opcode::Select}, +#line 419 "./lexer-keywords.txt" + {"i64.const", TokenType::Const, Opcode::I64Const }, +#line 275 "./lexer-keywords.txt" + {"i32.const", TokenType::Const, Opcode::I32Const }, {""}, {""}, -#line 578 "src/lexer-keywords.txt" - {"table.init", TokenType::TableInit, Opcode::TableInit}, +#line 124 "./lexer-keywords.txt" + {"f64.const", TokenType::Const, Opcode::F64Const }, +#line 62 "./lexer-keywords.txt" + {"f32.const", TokenType::Const, Opcode::F32Const }, {""}, {""}, {""}, -#line 45 "src/lexer-keywords.txt" - {"delegate", TokenType::Delegate}, - {""}, -#line 122 "src/lexer-keywords.txt" - {"f64.const", TokenType::Const, Opcode::F64Const}, -#line 60 "src/lexer-keywords.txt" - {"f32.const", TokenType::Const, Opcode::F32Const}, -#line 38 "src/lexer-keywords.txt" - {"call", TokenType::Call, Opcode::Call}, +#line 547 "./lexer-keywords.txt" + {"local.set", TokenType::LocalSet, Opcode::LocalSet }, +#line 569 "./lexer-keywords.txt" + {"null", Type::Null, TokenType::Null }, +#line 546 "./lexer-keywords.txt" + {"local.get", TokenType::LocalGet, Opcode::LocalGet }, +#line 585 "./lexer-keywords.txt" + {"start", TokenType::Start }, +#line 548 "./lexer-keywords.txt" + {"local.tee", TokenType::LocalTee, Opcode::LocalTee }, + {""}, +#line 549 "./lexer-keywords.txt" + {"local", TokenType::Local }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 121 "./lexer-keywords.txt" + {"f64.abs", TokenType::Unary, Opcode::F64Abs }, +#line 59 "./lexer-keywords.txt" + {"f32.abs", TokenType::Unary, Opcode::F32Abs }, + {""}, +#line 357 "./lexer-keywords.txt" + {"i32x4.relaxed_laneselect", TokenType::Ternary, Opcode::I32X4RelaxedLaneSelect }, +#line 442 "./lexer-keywords.txt" + {"i64.load", TokenType::Load, Opcode::I64Load }, +#line 293 "./lexer-keywords.txt" + {"i32.load", TokenType::Load, Opcode::I32Load }, + {""}, {""}, +#line 136 "./lexer-keywords.txt" + {"f64.load", TokenType::Load, Opcode::F64Load }, +#line 75 "./lexer-keywords.txt" + {"f32.load", TokenType::Load, Opcode::F32Load }, + {""}, {""}, +#line 358 "./lexer-keywords.txt" + {"i32x4.replace_lane", TokenType::SimdLaneOp, Opcode::I32X4ReplaceLane }, +#line 321 "./lexer-keywords.txt" + {"i8", Type::I8 }, + {""}, {""}, +#line 114 "./lexer-keywords.txt" + {"f32x4.replace_lane", TokenType::SimdLaneOp, Opcode::F32X4ReplaceLane }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 23 "./lexer-keywords.txt" + {"after", TokenType::After }, +#line 363 "./lexer-keywords.txt" + {"i32x4.sub", TokenType::Binary, Opcode::I32X4Sub }, + {""}, {""}, +#line 328 "./lexer-keywords.txt" + {"i32x4.abs", TokenType::Unary, Opcode::I32X4Abs }, +#line 117 "./lexer-keywords.txt" + {"f32x4.sub", TokenType::Binary, Opcode::F32X4Sub }, + {""}, {""}, +#line 89 "./lexer-keywords.txt" + {"f32x4.abs", TokenType::Unary, Opcode::F32X4Abs }, {""}, {""}, {""}, {""}, -#line 409 "src/lexer-keywords.txt" - {"i64.const", TokenType::Const, Opcode::I64Const}, -#line 271 "src/lexer-keywords.txt" - {"i32.const", TokenType::Const, Opcode::I32Const}, +#line 433 "./lexer-keywords.txt" + {"i64.gt_u", TokenType::Compare, Opcode::I64GtU }, +#line 286 "./lexer-keywords.txt" + {"i32.gt_u", TokenType::Compare, Opcode::I32GtU }, +#line 325 "./lexer-keywords.txt" + {"nofunc", Type::NoFunc, TokenType::NoFunc }, + {""}, +#line 432 "./lexer-keywords.txt" + {"i64.gt_s", TokenType::Compare, Opcode::I64GtS }, +#line 285 "./lexer-keywords.txt" + {"i32.gt_s", TokenType::Compare, Opcode::I32GtS }, +#line 431 "./lexer-keywords.txt" + {"i64.ge_u", TokenType::Compare, Opcode::I64GeU }, +#line 284 "./lexer-keywords.txt" + {"i32.ge_u", TokenType::Compare, Opcode::I32GeU }, {""}, {""}, -#line 539 "src/lexer-keywords.txt" - {"local", TokenType::Local}, +#line 430 "./lexer-keywords.txt" + {"i64.ge_s", TokenType::Compare, Opcode::I64GeS }, +#line 283 "./lexer-keywords.txt" + {"i32.ge_s", TokenType::Compare, Opcode::I32GeS }, {""}, -#line 347 "src/lexer-keywords.txt" - {"i32x4.relaxed_laneselect", TokenType::Ternary, Opcode::I32X4RelaxedLaneSelect}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 120 "src/lexer-keywords.txt" - {"f64.add", TokenType::Binary, Opcode::F64Add}, -#line 58 "src/lexer-keywords.txt" - {"f32.add", TokenType::Binary, Opcode::F32Add}, -#line 371 "src/lexer-keywords.txt" - {"i64.and", TokenType::Binary, Opcode::I64And}, -#line 242 "src/lexer-keywords.txt" - {"i32.and", TokenType::Binary, Opcode::I32And}, - {""}, {""}, {""}, -#line 370 "src/lexer-keywords.txt" - {"i64.add", TokenType::Binary, Opcode::I64Add}, -#line 241 "src/lexer-keywords.txt" - {"i32.add", TokenType::Binary, Opcode::I32Add}, +#line 21 "./lexer-keywords.txt" + {"sub", TokenType::Sub }, + {""}, {""}, +#line 444 "./lexer-keywords.txt" + {"i64.lt_u", TokenType::Compare, Opcode::I64LtU }, +#line 295 "./lexer-keywords.txt" + {"i32.lt_u", TokenType::Compare, Opcode::I32LtU }, + {""}, {""}, +#line 443 "./lexer-keywords.txt" + {"i64.lt_s", TokenType::Compare, Opcode::I64LtS }, +#line 294 "./lexer-keywords.txt" + {"i32.lt_s", TokenType::Compare, Opcode::I32LtS }, +#line 435 "./lexer-keywords.txt" + {"i64.le_u", TokenType::Compare, Opcode::I64LeU }, +#line 288 "./lexer-keywords.txt" + {"i32.le_u", TokenType::Compare, Opcode::I32LeU }, +#line 559 "./lexer-keywords.txt" + {"memory", TokenType::Memory }, + {""}, +#line 434 "./lexer-keywords.txt" + {"i64.le_s", TokenType::Compare, Opcode::I64LeS }, +#line 287 "./lexer-keywords.txt" + {"i32.le_s", TokenType::Compare, Opcode::I32LeS }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 417 "./lexer-keywords.txt" + {"i64.atomic.store", TokenType::AtomicStore, Opcode::I64AtomicStore }, +#line 273 "./lexer-keywords.txt" + {"i32.atomic.store", TokenType::AtomicStore, Opcode::I32AtomicStore }, +#line 112 "./lexer-keywords.txt" + {"f32x4.relaxed_min", TokenType::Binary, Opcode::F32X4RelaxedMin }, +#line 397 "./lexer-keywords.txt" + {"i64.atomic.rmw32.sub_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw32SubU }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 601 "./lexer-keywords.txt" + {"array.set", TokenType::ArraySet, Opcode::ArraySet }, + {""}, +#line 598 "./lexer-keywords.txt" + {"array.get", TokenType::ArrayGet, Opcode::ArrayGet }, + {""}, {""}, +#line 36 "./lexer-keywords.txt" + {"br_table", TokenType::BrTable, Opcode::BrTable }, + {""}, +#line 344 "./lexer-keywords.txt" + {"i32x4.relaxed_trunc_f64x2_u_zero", TokenType::Unary, Opcode::I32X4RelaxedTruncF64X2UZero }, + {""}, +#line 343 "./lexer-keywords.txt" + {"i32x4.relaxed_trunc_f64x2_s_zero", TokenType::Unary, Opcode::I32X4RelaxedTruncF64X2SZero }, + {""}, {""}, +#line 622 "./lexer-keywords.txt" + {"table.size", TokenType::TableSize, Opcode::TableSize }, {""}, {""}, {""}, -#line 408 "src/lexer-keywords.txt" - {"i64.clz", TokenType::Unary, Opcode::I64Clz}, -#line 270 "src/lexer-keywords.txt" - {"i32.clz", TokenType::Unary, Opcode::I32Clz}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 410 "src/lexer-keywords.txt" - {"i64.ctz", TokenType::Unary, Opcode::I64Ctz}, -#line 272 "src/lexer-keywords.txt" - {"i32.ctz", TokenType::Unary, Opcode::I32Ctz}, +#line 33 "./lexer-keywords.txt" + {"binary", TokenType::Bin }, +#line 113 "./lexer-keywords.txt" + {"f32x4.relaxed_nmadd", TokenType::Ternary, Opcode::F32X4RelaxedNmadd }, + {""}, {""}, +#line 410 "./lexer-keywords.txt" + {"i64.atomic.rmw.or", TokenType::AtomicRmw, Opcode::I64AtomicRmwOr }, +#line 267 "./lexer-keywords.txt" + {"i32.atomic.rmw.or", TokenType::AtomicRmw, Opcode::I32AtomicRmwOr }, + {""}, {""}, {""}, {""}, {""}, {""}, +#line 463 "./lexer-keywords.txt" + {"i64.trunc_f32_u", TokenType::Convert, Opcode::I64TruncF32U }, +#line 313 "./lexer-keywords.txt" + {"i32.trunc_f32_u", TokenType::Convert, Opcode::I32TruncF32U }, + {""}, {""}, +#line 462 "./lexer-keywords.txt" + {"i64.trunc_f32_s", TokenType::Convert, Opcode::I64TruncF32S }, +#line 312 "./lexer-keywords.txt" + {"i32.trunc_f32_s", TokenType::Convert, Opcode::I32TruncF32S }, + {""}, +#line 330 "./lexer-keywords.txt" + {"i32x4.all_true", TokenType::Unary, Opcode::I32X4AllTrue }, +#line 584 "./lexer-keywords.txt" + {"shared", TokenType::Shared }, + {""}, +#line 123 "./lexer-keywords.txt" + {"f64.ceil", TokenType::Unary, Opcode::F64Ceil }, +#line 61 "./lexer-keywords.txt" + {"f32.ceil", TokenType::Unary, Opcode::F32Ceil }, + {""}, {""}, +#line 320 "./lexer-keywords.txt" + {"i32", Type::I32 }, {""}, -#line 536 "src/lexer-keywords.txt" - {"local.get", TokenType::LocalGet, Opcode::LocalGet}, +#line 394 "./lexer-keywords.txt" + {"i64.atomic.rmw32.and_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw32AndU }, {""}, -#line 537 "src/lexer-keywords.txt" - {"local.set", TokenType::LocalSet, Opcode::LocalSet}, +#line 88 "./lexer-keywords.txt" + {"f32", Type::F32 }, + {""}, {""}, {""}, {""}, +#line 620 "./lexer-keywords.txt" + {"table.init", TokenType::TableInit, Opcode::TableInit }, + {""}, {""}, {""}, +#line 393 "./lexer-keywords.txt" + {"i64.atomic.rmw32.add_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw32AddU }, +#line 159 "./lexer-keywords.txt" + {"f64x2.gt", TokenType::Compare, Opcode::F64X2Gt }, {""}, -#line 538 "src/lexer-keywords.txt" - {"local.tee", TokenType::LocalTee, Opcode::LocalTee}, +#line 479 "./lexer-keywords.txt" + {"i64x2.gt_s", TokenType::Binary, Opcode::I64X2GtS }, {""}, {""}, {""}, {""}, {""}, -#line 134 "src/lexer-keywords.txt" - {"f64.load", TokenType::Load, Opcode::F64Load}, -#line 73 "src/lexer-keywords.txt" - {"f32.load", TokenType::Load, Opcode::F32Load}, - {""}, -#line 492 "src/lexer-keywords.txt" - {"i64.xor", TokenType::Binary, Opcode::I64Xor}, -#line 369 "src/lexer-keywords.txt" - {"i32.xor", TokenType::Binary, Opcode::I32Xor}, - {""}, {""}, -#line 432 "src/lexer-keywords.txt" - {"i64.load", TokenType::Load, Opcode::I64Load}, -#line 289 "src/lexer-keywords.txt" - {"i32.load", TokenType::Load, Opcode::I32Load}, - {""}, {""}, {""}, {""}, {""}, {""}, -#line 421 "src/lexer-keywords.txt" - {"i64.ge_u", TokenType::Compare, Opcode::I64GeU}, -#line 280 "src/lexer-keywords.txt" - {"i32.ge_u", TokenType::Compare, Opcode::I32GeU}, -#line 425 "src/lexer-keywords.txt" - {"i64.le_u", TokenType::Compare, Opcode::I64LeU}, -#line 284 "src/lexer-keywords.txt" - {"i32.le_u", TokenType::Compare, Opcode::I32LeU}, -#line 420 "src/lexer-keywords.txt" - {"i64.ge_s", TokenType::Compare, Opcode::I64GeS}, -#line 279 "src/lexer-keywords.txt" - {"i32.ge_s", TokenType::Compare, Opcode::I32GeS}, -#line 424 "src/lexer-keywords.txt" - {"i64.le_s", TokenType::Compare, Opcode::I64LeS}, -#line 283 "src/lexer-keywords.txt" - {"i32.le_s", TokenType::Compare, Opcode::I32LeS}, -#line 423 "src/lexer-keywords.txt" - {"i64.gt_u", TokenType::Compare, Opcode::I64GtU}, -#line 282 "src/lexer-keywords.txt" - {"i32.gt_u", TokenType::Compare, Opcode::I32GtU}, -#line 434 "src/lexer-keywords.txt" - {"i64.lt_u", TokenType::Compare, Opcode::I64LtU}, -#line 291 "src/lexer-keywords.txt" - {"i32.lt_u", TokenType::Compare, Opcode::I32LtU}, -#line 422 "src/lexer-keywords.txt" - {"i64.gt_s", TokenType::Compare, Opcode::I64GtS}, -#line 281 "src/lexer-keywords.txt" - {"i32.gt_s", TokenType::Compare, Opcode::I32GtS}, -#line 433 "src/lexer-keywords.txt" - {"i64.lt_s", TokenType::Compare, Opcode::I64LtS}, -#line 290 "src/lexer-keywords.txt" - {"i32.lt_s", TokenType::Compare, Opcode::I32LtS}, -#line 53 "src/lexer-keywords.txt" - {"tag", TokenType::Tag}, -#line 94 "src/lexer-keywords.txt" - {"f32x4.extract_lane", TokenType::SimdLaneOp, Opcode::F32X4ExtractLane}, - {""}, -#line 449 "src/lexer-keywords.txt" - {"i64.store8", TokenType::Store, Opcode::I64Store8}, -#line 305 "src/lexer-keywords.txt" - {"i32.store8", TokenType::Store, Opcode::I32Store8}, -#line 101 "src/lexer-keywords.txt" - {"f32x4.min", TokenType::Binary, Opcode::F32X4Min}, - {""}, {""}, -#line 324 "src/lexer-keywords.txt" - {"i32x4.extract_lane", TokenType::SimdLaneOp, Opcode::I32X4ExtractLane}, +#line 481 "./lexer-keywords.txt" + {"i64x2.ge_s", TokenType::Binary, Opcode::I64X2GeS }, {""}, {""}, {""}, -#line 185 "src/lexer-keywords.txt" - {"get", TokenType::Get}, +#line 158 "./lexer-keywords.txt" + {"f64x2.ge", TokenType::Compare, Opcode::F64X2Ge }, +#line 20 "./lexer-keywords.txt" + {"array", Type::Array, TokenType::Array }, + {""}, +#line 602 "./lexer-keywords.txt" + {"array.len", TokenType::ArrayLen, Opcode::ArrayLen }, +#line 161 "./lexer-keywords.txt" + {"f64x2.lt", TokenType::Compare, Opcode::F64X2Lt }, + {""}, +#line 478 "./lexer-keywords.txt" + {"i64x2.lt_s", TokenType::Binary, Opcode::I64X2LtS }, +#line 616 "./lexer-keywords.txt" + {"table.copy", TokenType::TableCopy, Opcode::TableCopy }, +#line 110 "./lexer-keywords.txt" + {"f32x4.relaxed_madd", TokenType::Ternary, Opcode::F32X4RelaxedMadd }, + {""}, {""}, +#line 626 "./lexer-keywords.txt" + {"try", TokenType::Try, Opcode::Try }, +#line 480 "./lexer-keywords.txt" + {"i64x2.le_s", TokenType::Binary, Opcode::I64X2LeS }, + {""}, +#line 544 "./lexer-keywords.txt" + {"invoke", TokenType::Invoke }, + {""}, +#line 160 "./lexer-keywords.txt" + {"f64x2.le", TokenType::Compare, Opcode::F64X2Le }, + {""}, +#line 396 "./lexer-keywords.txt" + {"i64.atomic.rmw32.or_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw32OrU }, + {""}, {""}, {""}, +#line 451 "./lexer-keywords.txt" + {"i64.rem_u", TokenType::Binary, Opcode::I64RemU }, +#line 302 "./lexer-keywords.txt" + {"i32.rem_u", TokenType::Binary, Opcode::I32RemU }, +#line 450 "./lexer-keywords.txt" + {"i64.rem_s", TokenType::Binary, Opcode::I64RemS }, +#line 301 "./lexer-keywords.txt" + {"i32.rem_s", TokenType::Binary, Opcode::I32RemS }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 413 "./lexer-keywords.txt" + {"i64.atomic.rmw.xor", TokenType::AtomicRmw, Opcode::I64AtomicRmwXor }, +#line 270 "./lexer-keywords.txt" + {"i32.atomic.rmw.xor", TokenType::AtomicRmw, Opcode::I32AtomicRmwXor }, +#line 350 "./lexer-keywords.txt" + {"i32x4.max_u", TokenType::Binary, Opcode::I32X4MaxU }, + {""}, +#line 349 "./lexer-keywords.txt" + {"i32x4.max_s", TokenType::Binary, Opcode::I32X4MaxS }, + {""}, +#line 385 "./lexer-keywords.txt" + {"i64.atomic.load", TokenType::AtomicLoad, Opcode::I64AtomicLoad }, +#line 249 "./lexer-keywords.txt" + {"i32.atomic.load", TokenType::AtomicLoad, Opcode::I32AtomicLoad }, {""}, {""}, {""}, -#line 560 "src/lexer-keywords.txt" - {"ref.extern", TokenType::RefExtern}, +#line 483 "./lexer-keywords.txt" + {"i64x2.neg", TokenType::Unary, Opcode::I64X2Neg }, +#line 477 "./lexer-keywords.txt" + {"i64x2.ne", TokenType::Binary, Opcode::I64X2Ne }, + {""}, {""}, +#line 166 "./lexer-keywords.txt" + {"f64x2.neg", TokenType::Unary, Opcode::F64X2Neg }, +#line 167 "./lexer-keywords.txt" + {"f64x2.ne", TokenType::Compare, Opcode::F64X2Ne }, +#line 441 "./lexer-keywords.txt" + {"i64.load8_u", TokenType::Load, Opcode::I64Load8U }, +#line 292 "./lexer-keywords.txt" + {"i32.load8_u", TokenType::Load, Opcode::I32Load8U }, +#line 440 "./lexer-keywords.txt" + {"i64.load8_s", TokenType::Load, Opcode::I64Load8S }, +#line 291 "./lexer-keywords.txt" + {"i32.load8_s", TokenType::Load, Opcode::I32Load8S }, +#line 461 "./lexer-keywords.txt" + {"i64.sub", TokenType::Binary, Opcode::I64Sub }, +#line 311 "./lexer-keywords.txt" + {"i32.sub", TokenType::Binary, Opcode::I32Sub }, +#line 516 "./lexer-keywords.txt" + {"i8x16.gt_u", TokenType::Compare, Opcode::I8X16GtU }, + {""}, +#line 148 "./lexer-keywords.txt" + {"f64.sub", TokenType::Binary, Opcode::F64Sub }, +#line 86 "./lexer-keywords.txt" + {"f32.sub", TokenType::Binary, Opcode::F32Sub }, +#line 515 "./lexer-keywords.txt" + {"i8x16.gt_s", TokenType::Compare, Opcode::I8X16GtS }, +#line 103 "./lexer-keywords.txt" + {"f32x4.min", TokenType::Binary, Opcode::F32X4Min }, +#line 514 "./lexer-keywords.txt" + {"i8x16.ge_u", TokenType::Compare, Opcode::I8X16GeU }, +#line 581 "./lexer-keywords.txt" + {"return_call", TokenType::ReturnCall, Opcode::ReturnCall }, +#line 502 "./lexer-keywords.txt" + {"i64.xor", TokenType::Binary, Opcode::I64Xor }, +#line 379 "./lexer-keywords.txt" + {"i32.xor", TokenType::Binary, Opcode::I32Xor }, +#line 513 "./lexer-keywords.txt" + {"i8x16.ge_s", TokenType::Compare, Opcode::I8X16GeS }, + {""}, {""}, +#line 165 "./lexer-keywords.txt" + {"f64x2.nearest", TokenType::Unary, Opcode::F64X2Nearest }, +#line 609 "./lexer-keywords.txt" + {"br_on_cast", TokenType::BrOnCast, Opcode::BrOnCast }, + {""}, +#line 520 "./lexer-keywords.txt" + {"i8x16.lt_u", TokenType::Compare, Opcode::I8X16LtU }, +#line 572 "./lexer-keywords.txt" + {"ref.extern", TokenType::RefExtern }, + {""}, {""}, +#line 519 "./lexer-keywords.txt" + {"i8x16.lt_s", TokenType::Compare, Opcode::I8X16LtS }, {""}, -#line 100 "src/lexer-keywords.txt" - {"f32x4.max", TokenType::Binary, Opcode::F32X4Max}, - {""}, {""}, {""}, {""}, {""}, {""}, -#line 320 "src/lexer-keywords.txt" - {"i32x4.all_true", TokenType::Unary, Opcode::I32X4AllTrue}, -#line 334 "src/lexer-keywords.txt" - {"i32x4.relaxed_trunc_f64x2_u_zero", TokenType::Unary, Opcode::I32X4RelaxedTruncF64X2UZero}, - {""}, -#line 333 "src/lexer-keywords.txt" - {"i32x4.relaxed_trunc_f64x2_s_zero", TokenType::Unary, Opcode::I32X4RelaxedTruncF64X2SZero}, -#line 407 "src/lexer-keywords.txt" - {"i64.atomic.store", TokenType::AtomicStore, Opcode::I64AtomicStore}, -#line 269 "src/lexer-keywords.txt" - {"i32.atomic.store", TokenType::AtomicStore, Opcode::I32AtomicStore}, - {""}, {""}, {""}, {""}, -#line 444 "src/lexer-keywords.txt" - {"i64.shl", TokenType::Binary, Opcode::I64Shl}, -#line 301 "src/lexer-keywords.txt" - {"i32.shl", TokenType::Binary, Opcode::I32Shl}, +#line 518 "./lexer-keywords.txt" + {"i8x16.le_u", TokenType::Compare, Opcode::I8X16LeU }, +#line 139 "./lexer-keywords.txt" + {"f64.min", TokenType::Binary, Opcode::F64Min }, +#line 78 "./lexer-keywords.txt" + {"f32.min", TokenType::Binary, Opcode::F32Min }, + {""}, +#line 517 "./lexer-keywords.txt" + {"i8x16.le_s", TokenType::Compare, Opcode::I8X16LeS }, +#line 458 "./lexer-keywords.txt" + {"i64.store32", TokenType::Store, Opcode::I64Store32 }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 400 "src/lexer-keywords.txt" - {"i64.atomic.rmw.or", TokenType::AtomicRmw, Opcode::I64AtomicRmwOr}, -#line 263 "src/lexer-keywords.txt" - {"i32.atomic.rmw.or", TokenType::AtomicRmw, Opcode::I32AtomicRmwOr}, -#line 137 "src/lexer-keywords.txt" - {"f64.min", TokenType::Binary, Opcode::F64Min}, -#line 76 "src/lexer-keywords.txt" - {"f32.min", TokenType::Binary, Opcode::F32Min}, +#line 408 "./lexer-keywords.txt" + {"i64.atomic.rmw.and", TokenType::AtomicRmw, Opcode::I64AtomicRmwAnd }, +#line 265 "./lexer-keywords.txt" + {"i32.atomic.rmw.and", TokenType::AtomicRmw, Opcode::I32AtomicRmwAnd }, +#line 153 "./lexer-keywords.txt" + {"f64x2.ceil", TokenType::Unary, Opcode::F64X2Ceil }, + {""}, {""}, +#line 639 "./lexer-keywords.txt" + {"v128.store", TokenType::Store, Opcode::V128Store }, + {""}, {""}, +#line 102 "./lexer-keywords.txt" + {"f32x4.max", TokenType::Binary, Opcode::F32X4Max }, + {""}, {""}, +#line 407 "./lexer-keywords.txt" + {"i64.atomic.rmw.add", TokenType::AtomicRmw, Opcode::I64AtomicRmwAdd }, +#line 264 "./lexer-keywords.txt" + {"i32.atomic.rmw.add", TokenType::AtomicRmw, Opcode::I32AtomicRmwAdd }, + {""}, {""}, {""}, +#line 471 "./lexer-keywords.txt" + {"i64x2.add", TokenType::Binary, Opcode::I64X2Add }, + {""}, +#line 527 "./lexer-keywords.txt" + {"i8x16.neg", TokenType::Unary, Opcode::I8X16Neg }, +#line 529 "./lexer-keywords.txt" + {"i8x16.ne", TokenType::Compare, Opcode::I8X16Ne }, +#line 152 "./lexer-keywords.txt" + {"f64x2.add", TokenType::Binary, Opcode::F64X2Add }, +#line 475 "./lexer-keywords.txt" + {"i64x2.mul", TokenType::Binary, Opcode::I64X2Mul }, + {""}, {""}, {""}, +#line 164 "./lexer-keywords.txt" + {"f64x2.mul", TokenType::Binary, Opcode::F64X2Mul }, +#line 635 "./lexer-keywords.txt" + {"v128.or", TokenType::Binary, Opcode::V128Or }, + {""}, +#line 188 "./lexer-keywords.txt" + {"function", TokenType::Function }, +#line 178 "./lexer-keywords.txt" + {"f64x2.trunc", TokenType::Unary, Opcode::F64X2Trunc }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, +#line 437 "./lexer-keywords.txt" + {"i64.load16_u", TokenType::Load, Opcode::I64Load16U }, +#line 290 "./lexer-keywords.txt" + {"i32.load16_u", TokenType::Load, Opcode::I32Load16U }, +#line 634 "./lexer-keywords.txt" + {"v128.not", TokenType::Unary, Opcode::V128Not }, + {""}, +#line 436 "./lexer-keywords.txt" + {"i64.load16_s", TokenType::Load, Opcode::I64Load16S }, +#line 289 "./lexer-keywords.txt" + {"i32.load16_s", TokenType::Load, Opcode::I32Load16S }, {""}, {""}, {""}, {""}, {""}, -#line 568 "src/lexer-keywords.txt" - {"return_call", TokenType::ReturnCall, Opcode::ReturnCall}, -#line 387 "src/lexer-keywords.txt" - {"i64.atomic.rmw32.sub_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw32SubU}, -#line 349 "src/lexer-keywords.txt" - {"i32x4.shl", TokenType::Binary, Opcode::I32X4Shl}, -#line 110 "src/lexer-keywords.txt" - {"f32x4.relaxed_min", TokenType::Binary, Opcode::F32X4RelaxedMin}, - {""}, {""}, {""}, {""}, {""}, {""}, -#line 564 "src/lexer-keywords.txt" - {"register", TokenType::Register}, +#line 653 "./lexer-keywords.txt" + {"v128.store64_lane", TokenType::SimdStoreLane, Opcode::V128Store64Lane }, + {""}, +#line 439 "./lexer-keywords.txt" + {"i64.load32_u", TokenType::Load, Opcode::I64Load32U }, + {""}, {""}, {""}, +#line 438 "./lexer-keywords.txt" + {"i64.load32_s", TokenType::Load, Opcode::I64Load32S }, +#line 558 "./lexer-keywords.txt" + {"memory.size", TokenType::MemorySize, Opcode::MemorySize }, +#line 636 "./lexer-keywords.txt" + {"v128.any_true", TokenType::Unary, Opcode::V128AnyTrue }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, +#line 334 "./lexer-keywords.txt" + {"i32x4.extract_lane", TokenType::SimdLaneOp, Opcode::I32X4ExtractLane }, {""}, {""}, {""}, -#line 111 "src/lexer-keywords.txt" - {"f32x4.relaxed_nmadd", TokenType::Ternary, Opcode::F32X4RelaxedNmadd}, - {""}, {""}, {""}, {""}, {""}, -#line 453 "src/lexer-keywords.txt" - {"i64.trunc_f32_u", TokenType::Convert, Opcode::I64TruncF32U}, -#line 309 "src/lexer-keywords.txt" - {"i32.trunc_f32_u", TokenType::Convert, Opcode::I32TruncF32U}, +#line 96 "./lexer-keywords.txt" + {"f32x4.extract_lane", TokenType::SimdLaneOp, Opcode::F32X4ExtractLane }, {""}, {""}, -#line 452 "src/lexer-keywords.txt" - {"i64.trunc_f32_s", TokenType::Convert, Opcode::I64TruncF32S}, -#line 308 "src/lexer-keywords.txt" - {"i32.trunc_f32_s", TokenType::Convert, Opcode::I32TruncF32S}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, {""}, -#line 427 "src/lexer-keywords.txt" - {"i64.load16_u", TokenType::Load, Opcode::I64Load16U}, -#line 286 "src/lexer-keywords.txt" - {"i32.load16_u", TokenType::Load, Opcode::I32Load16U}, - {""}, {""}, -#line 426 "src/lexer-keywords.txt" - {"i64.load16_s", TokenType::Load, Opcode::I64Load16S}, -#line 285 "src/lexer-keywords.txt" - {"i32.load16_s", TokenType::Load, Opcode::I32Load16S}, - {""}, -#line 562 "src/lexer-keywords.txt" - {"ref.is_null", TokenType::RefIsNull, Opcode::RefIsNull}, +#line 633 "./lexer-keywords.txt" + {"v128.load", TokenType::Load, Opcode::V128Load }, {""}, {""}, {""}, -#line 184 "src/lexer-keywords.txt" - {"function", TokenType::Function}, -#line 384 "src/lexer-keywords.txt" - {"i64.atomic.rmw32.and_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw32AndU}, +#line 490 "./lexer-keywords.txt" + {"i64x2.relaxed_laneselect", TokenType::Ternary, Opcode::I64X2RelaxedLaneSelect }, {""}, {""}, {""}, {""}, -#line 383 "src/lexer-keywords.txt" - {"i64.atomic.rmw32.add_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw32AddU}, -#line 441 "src/lexer-keywords.txt" - {"i64.rem_u", TokenType::Binary, Opcode::I64RemU}, -#line 298 "src/lexer-keywords.txt" - {"i32.rem_u", TokenType::Binary, Opcode::I32RemU}, -#line 440 "src/lexer-keywords.txt" - {"i64.rem_s", TokenType::Binary, Opcode::I64RemS}, -#line 297 "src/lexer-keywords.txt" - {"i32.rem_s", TokenType::Binary, Opcode::I32RemS}, - {""}, {""}, -#line 136 "src/lexer-keywords.txt" - {"f64.max", TokenType::Binary, Opcode::F64Max}, -#line 75 "src/lexer-keywords.txt" - {"f32.max", TokenType::Binary, Opcode::F32Max}, - {""}, {""}, {""}, {""}, {""}, -#line 86 "src/lexer-keywords.txt" - {"f32", Type::F32}, -#line 108 "src/lexer-keywords.txt" - {"f32x4.relaxed_madd", TokenType::Ternary, Opcode::F32X4RelaxedMadd}, -#line 340 "src/lexer-keywords.txt" - {"i32x4.max_u", TokenType::Binary, Opcode::I32X4MaxU}, - {""}, -#line 339 "src/lexer-keywords.txt" - {"i32x4.max_s", TokenType::Binary, Opcode::I32X4MaxS}, -#line 403 "src/lexer-keywords.txt" - {"i64.atomic.rmw.xor", TokenType::AtomicRmw, Opcode::I64AtomicRmwXor}, -#line 266 "src/lexer-keywords.txt" - {"i32.atomic.rmw.xor", TokenType::AtomicRmw, Opcode::I32AtomicRmwXor}, -#line 316 "src/lexer-keywords.txt" - {"i32", Type::I32}, - {""}, {""}, -#line 386 "src/lexer-keywords.txt" - {"i64.atomic.rmw32.or_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw32OrU}, -#line 375 "src/lexer-keywords.txt" - {"i64.atomic.load", TokenType::AtomicLoad, Opcode::I64AtomicLoad}, -#line 245 "src/lexer-keywords.txt" - {"i32.atomic.load", TokenType::AtomicLoad, Opcode::I32AtomicLoad}, - {""}, {""}, -#line 431 "src/lexer-keywords.txt" - {"i64.load8_u", TokenType::Load, Opcode::I64Load8U}, -#line 288 "src/lexer-keywords.txt" - {"i32.load8_u", TokenType::Load, Opcode::I32Load8U}, -#line 430 "src/lexer-keywords.txt" - {"i64.load8_s", TokenType::Load, Opcode::I64Load8S}, -#line 287 "src/lexer-keywords.txt" - {"i32.load8_s", TokenType::Load, Opcode::I32Load8S}, - {""}, -#line 415 "src/lexer-keywords.txt" - {"i64.extend16_s", TokenType::Unary, Opcode::I64Extend16S}, -#line 277 "src/lexer-keywords.txt" - {"i32.extend16_s", TokenType::Unary, Opcode::I32Extend16S}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 553 "src/lexer-keywords.txt" - {"nan:canonical", TokenType::NanCanonical}, -#line 406 "src/lexer-keywords.txt" - {"i64.atomic.store8", TokenType::AtomicStore, Opcode::I64AtomicStore8}, -#line 268 "src/lexer-keywords.txt" - {"i32.atomic.store8", TokenType::AtomicStore, Opcode::I32AtomicStore8}, - {""}, {""}, -#line 156 "src/lexer-keywords.txt" - {"f64x2.ge", TokenType::Compare, Opcode::F64X2Ge}, -#line 552 "src/lexer-keywords.txt" - {"nan:arithmetic", TokenType::NanArithmetic}, -#line 158 "src/lexer-keywords.txt" - {"f64x2.le", TokenType::Compare, Opcode::F64X2Le}, +#line 506 "./lexer-keywords.txt" + {"i8x16.add", TokenType::Binary, Opcode::I8X16Add }, +#line 342 "./lexer-keywords.txt" + {"i32x4.relaxed_trunc_f32x4_u", TokenType::Unary, Opcode::I32X4RelaxedTruncF32X4U }, + {""}, {""}, +#line 491 "./lexer-keywords.txt" + {"i64x2.replace_lane", TokenType::SimdLaneOp, Opcode::I64X2ReplaceLane }, +#line 341 "./lexer-keywords.txt" + {"i32x4.relaxed_trunc_f32x4_s", TokenType::Unary, Opcode::I32X4RelaxedTruncF32X4S }, + {""}, +#line 630 "./lexer-keywords.txt" + {"v128.and", TokenType::Binary, Opcode::V128And }, +#line 174 "./lexer-keywords.txt" + {"f64x2.replace_lane", TokenType::SimdLaneOp, Opcode::F64X2ReplaceLane }, {""}, {""}, {""}, {""}, {""}, {""}, -#line 151 "src/lexer-keywords.txt" - {"f64x2.ceil", TokenType::Unary, Opcode::F64X2Ceil}, +#line 600 "./lexer-keywords.txt" + {"array.get_u", TokenType::ArrayGetU, Opcode::ArrayGetU }, + {""}, +#line 599 "./lexer-keywords.txt" + {"array.get_s", TokenType::ArrayGetS, Opcode::ArrayGetS }, +#line 496 "./lexer-keywords.txt" + {"i64x2.sub", TokenType::Binary, Opcode::I64X2Sub }, + {""}, {""}, +#line 482 "./lexer-keywords.txt" + {"i64x2.abs", TokenType::Unary, Opcode::I64X2Abs }, +#line 177 "./lexer-keywords.txt" + {"f64x2.sub", TokenType::Binary, Opcode::F64X2Sub }, + {""}, +#line 632 "./lexer-keywords.txt" + {"v128.const", TokenType::Const, Opcode::V128Const }, +#line 151 "./lexer-keywords.txt" + {"f64x2.abs", TokenType::Unary, Opcode::F64X2Abs }, +#line 629 "./lexer-keywords.txt" + {"v128.andnot", TokenType::Binary, Opcode::V128Andnot }, {""}, {""}, {""}, -#line 388 "src/lexer-keywords.txt" - {"i64.atomic.rmw32.xchg_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw32XchgU}, - {""}, -#line 471 "src/lexer-keywords.txt" - {"i64x2.ge_s", TokenType::Binary, Opcode::I64X2GeS}, -#line 157 "src/lexer-keywords.txt" - {"f64x2.gt", TokenType::Compare, Opcode::F64X2Gt}, -#line 470 "src/lexer-keywords.txt" - {"i64x2.le_s", TokenType::Binary, Opcode::I64X2LeS}, -#line 159 "src/lexer-keywords.txt" - {"f64x2.lt", TokenType::Compare, Opcode::F64X2Lt}, -#line 342 "src/lexer-keywords.txt" - {"i32x4.min_u", TokenType::Binary, Opcode::I32X4MinU}, -#line 109 "src/lexer-keywords.txt" - {"f32x4.relaxed_max", TokenType::Binary, Opcode::F32X4RelaxedMax}, -#line 341 "src/lexer-keywords.txt" - {"i32x4.min_s", TokenType::Binary, Opcode::I32X4MinS}, - {""}, -#line 469 "src/lexer-keywords.txt" - {"i64x2.gt_s", TokenType::Binary, Opcode::I64X2GtS}, - {""}, -#line 468 "src/lexer-keywords.txt" - {"i64x2.lt_s", TokenType::Binary, Opcode::I64X2LtS}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, -#line 417 "src/lexer-keywords.txt" - {"i64.extend8_s", TokenType::Unary, Opcode::I64Extend8S}, -#line 278 "src/lexer-keywords.txt" - {"i32.extend8_s", TokenType::Unary, Opcode::I32Extend8S}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 534 "src/lexer-keywords.txt" - {"invoke", TokenType::Invoke}, - {""}, {""}, -#line 398 "src/lexer-keywords.txt" - {"i64.atomic.rmw.and", TokenType::AtomicRmw, Opcode::I64AtomicRmwAnd}, -#line 261 "src/lexer-keywords.txt" - {"i32.atomic.rmw.and", TokenType::AtomicRmw, Opcode::I32AtomicRmwAnd}, - {""}, {""}, -#line 164 "src/lexer-keywords.txt" - {"f64x2.neg", TokenType::Unary, Opcode::F64X2Neg}, -#line 397 "src/lexer-keywords.txt" - {"i64.atomic.rmw.add", TokenType::AtomicRmw, Opcode::I64AtomicRmwAdd}, -#line 260 "src/lexer-keywords.txt" - {"i32.atomic.rmw.add", TokenType::AtomicRmw, Opcode::I32AtomicRmwAdd}, -#line 165 "src/lexer-keywords.txt" - {"f64x2.ne", TokenType::Compare, Opcode::F64X2Ne}, +#line 28 "./lexer-keywords.txt" + {"assert_return", TokenType::AssertReturn }, + {""}, +#line 459 "./lexer-keywords.txt" + {"i64.store8", TokenType::Store, Opcode::I64Store8 }, +#line 309 "./lexer-keywords.txt" + {"i32.store8", TokenType::Store, Opcode::I32Store8 }, {""}, {""}, {""}, -#line 473 "src/lexer-keywords.txt" - {"i64x2.neg", TokenType::Unary, Opcode::I64X2Neg}, +#line 575 "./lexer-keywords.txt" + {"ref.is_null", TokenType::RefIsNull, Opcode::RefIsNull }, {""}, {""}, -#line 467 "src/lexer-keywords.txt" - {"i64x2.ne", TokenType::Binary, Opcode::I64X2Ne}, - {""}, {""}, {""}, {""}, -#line 391 "src/lexer-keywords.txt" - {"i64.atomic.rmw8.and_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw8AndU}, -#line 254 "src/lexer-keywords.txt" - {"i32.atomic.rmw8.and_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw8AndU}, +#line 588 "./lexer-keywords.txt" + {"struct.new_default", TokenType::StructNewDefault, Opcode::StructNewDefault }, + {""}, +#line 562 "./lexer-keywords.txt" + {"nan:arithmetic", TokenType::NanArithmetic }, {""}, {""}, {""}, -#line 390 "src/lexer-keywords.txt" - {"i64.atomic.rmw8.add_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw8AddU}, -#line 253 "src/lexer-keywords.txt" - {"i32.atomic.rmw8.add_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw8AddU}, -#line 176 "src/lexer-keywords.txt" - {"f64x2.trunc", TokenType::Unary, Opcode::F64X2Trunc}, +#line 570 "./lexer-keywords.txt" + {"any", Type::Any, TokenType::Any }, +#line 331 "./lexer-keywords.txt" + {"i32x4.bitmask", TokenType::Unary, Opcode::I32X4Bitmask }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 604 "./lexer-keywords.txt" + {"array.copy", TokenType::ArrayCopy, Opcode::ArrayCopy }, + {""}, +#line 384 "./lexer-keywords.txt" + {"i64.atomic.load8_u", TokenType::AtomicLoad, Opcode::I64AtomicLoad8U }, +#line 248 "./lexer-keywords.txt" + {"i32.atomic.load8_u", TokenType::AtomicLoad, Opcode::I32AtomicLoad8U }, {""}, {""}, {""}, -#line 455 "src/lexer-keywords.txt" - {"i64.trunc_f64_u", TokenType::Convert, Opcode::I64TruncF64U}, -#line 311 "src/lexer-keywords.txt" - {"i32.trunc_f64_u", TokenType::Convert, Opcode::I32TruncF64U}, - {""}, -#line 598 "src/lexer-keywords.txt" - {"v128", Type::V128}, -#line 454 "src/lexer-keywords.txt" - {"i64.trunc_f64_s", TokenType::Convert, Opcode::I64TruncF64S}, -#line 310 "src/lexer-keywords.txt" - {"i32.trunc_f64_s", TokenType::Convert, Opcode::I32TruncF64S}, +#line 563 "./lexer-keywords.txt" + {"nan:canonical", TokenType::NanCanonical }, +#line 640 "./lexer-keywords.txt" + {"v128", Type::V128 }, + {""}, +#line 531 "./lexer-keywords.txt" + {"i8x16.relaxed_laneselect", TokenType::Ternary, Opcode::I8X16RelaxedLaneSelect }, + {""}, +#line 172 "./lexer-keywords.txt" + {"f64x2.relaxed_min", TokenType::Binary, Opcode::F64X2RelaxedMin }, +#line 615 "./lexer-keywords.txt" + {"i31.get_u", TokenType::I31GetU, Opcode::I31GetU }, + {""}, +#line 614 "./lexer-keywords.txt" + {"i31.get_s", TokenType::I31GetS, Opcode::I31GetS }, + {""}, {""}, +#line 596 "./lexer-keywords.txt" + {"array.new_data", TokenType::ArrayNewData, Opcode::ArrayNewData }, +#line 532 "./lexer-keywords.txt" + {"i8x16.replace_lane", TokenType::SimdLaneOp, Opcode::I8X16ReplaceLane }, + {""}, +#line 594 "./lexer-keywords.txt" + {"array.new_default", TokenType::ArrayNewDefault, Opcode::ArrayNewDefault }, + {""}, {""}, +#line 189 "./lexer-keywords.txt" + {"get", TokenType::Get }, {""}, {""}, {""}, -#line 163 "src/lexer-keywords.txt" - {"f64x2.nearest", TokenType::Unary, Opcode::F64X2Nearest}, +#line 55 "./lexer-keywords.txt" + {"tag", TokenType::Tag }, + {""}, +#line 352 "./lexer-keywords.txt" + {"i32x4.min_u", TokenType::Binary, Opcode::I32X4MinU }, + {""}, +#line 351 "./lexer-keywords.txt" + {"i32x4.min_s", TokenType::Binary, Opcode::I32X4MinS }, +#line 539 "./lexer-keywords.txt" + {"i8x16.sub", TokenType::Binary, Opcode::I8X16Sub }, + {""}, {""}, +#line 503 "./lexer-keywords.txt" + {"i8x16.abs", TokenType::Unary, Opcode::I8X16Abs }, {""}, {""}, {""}, -#line 389 "src/lexer-keywords.txt" - {"i64.atomic.rmw32.xor_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw32XorU}, - {""}, {""}, {""}, {""}, {""}, {""}, -#line 446 "src/lexer-keywords.txt" - {"i64.shr_u", TokenType::Binary, Opcode::I64ShrU}, -#line 303 "src/lexer-keywords.txt" - {"i32.shr_u", TokenType::Binary, Opcode::I32ShrU}, -#line 445 "src/lexer-keywords.txt" - {"i64.shr_s", TokenType::Binary, Opcode::I64ShrS}, -#line 302 "src/lexer-keywords.txt" - {"i32.shr_s", TokenType::Binary, Opcode::I32ShrS}, -#line 419 "src/lexer-keywords.txt" - {"i64.extend_i32_u", TokenType::Convert, Opcode::I64ExtendI32U}, - {""}, -#line 418 "src/lexer-keywords.txt" - {"i64.extend_i32_s", TokenType::Convert, Opcode::I64ExtendI32S}, +#line 173 "./lexer-keywords.txt" + {"f64x2.relaxed_nmadd", TokenType::Ternary, Opcode::F64X2RelaxedNmadd }, {""}, {""}, {""}, {""}, -#line 172 "src/lexer-keywords.txt" - {"f64x2.replace_lane", TokenType::SimdLaneOp, Opcode::F64X2ReplaceLane}, - {""}, -#line 351 "src/lexer-keywords.txt" - {"i32x4.shr_u", TokenType::Binary, Opcode::I32X4ShrU}, - {""}, -#line 350 "src/lexer-keywords.txt" - {"i32x4.shr_s", TokenType::Binary, Opcode::I32X4ShrS}, -#line 448 "src/lexer-keywords.txt" - {"i64.store32", TokenType::Store, Opcode::I64Store32}, - {""}, -#line 481 "src/lexer-keywords.txt" - {"i64x2.replace_lane", TokenType::SimdLaneOp, Opcode::I64X2ReplaceLane}, -#line 32 "src/lexer-keywords.txt" - {"block", TokenType::Block, Opcode::Block}, - {""}, -#line 150 "src/lexer-keywords.txt" - {"f64x2.add", TokenType::Binary, Opcode::F64X2Add}, -#line 162 "src/lexer-keywords.txt" - {"f64x2.mul", TokenType::Binary, Opcode::F64X2Mul}, - {""}, {""}, {""}, {""}, {""}, -#line 461 "src/lexer-keywords.txt" - {"i64x2.add", TokenType::Binary, Opcode::I64X2Add}, -#line 465 "src/lexer-keywords.txt" - {"i64x2.mul", TokenType::Binary, Opcode::I64X2Mul}, - {""}, -#line 559 "src/lexer-keywords.txt" - {"quote", TokenType::Quote}, +#line 401 "./lexer-keywords.txt" + {"i64.atomic.rmw8.and_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw8AndU }, +#line 258 "./lexer-keywords.txt" + {"i32.atomic.rmw8.and_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw8AndU }, {""}, {""}, {""}, {""}, -#line 593 "src/lexer-keywords.txt" - {"v128.or", TokenType::Binary, Opcode::V128Or}, +#line 605 "./lexer-keywords.txt" + {"array.init_data", TokenType::ArrayInitData, Opcode::ArrayInitData }, + {""}, {""}, +#line 427 "./lexer-keywords.txt" + {"i64.extend8_s", TokenType::Unary, Opcode::I64Extend8S }, +#line 282 "./lexer-keywords.txt" + {"i32.extend8_s", TokenType::Unary, Opcode::I32Extend8S }, +#line 400 "./lexer-keywords.txt" + {"i64.atomic.rmw8.add_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw8AddU }, +#line 257 "./lexer-keywords.txt" + {"i32.atomic.rmw8.add_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw8AddU }, +#line 484 "./lexer-keywords.txt" + {"i64x2.all_true", TokenType::Unary, Opcode::I64X2AllTrue }, + {""}, {""}, {""}, +#line 556 "./lexer-keywords.txt" + {"memory.grow", TokenType::MemoryGrow, Opcode::MemoryGrow }, + {""}, {""}, +#line 557 "./lexer-keywords.txt" + {"memory.init", TokenType::MemoryInit, Opcode::MemoryInit }, + {""}, {""}, +#line 465 "./lexer-keywords.txt" + {"i64.trunc_f64_u", TokenType::Convert, Opcode::I64TruncF64U }, +#line 315 "./lexer-keywords.txt" + {"i32.trunc_f64_u", TokenType::Convert, Opcode::I32TruncF64U }, +#line 454 "./lexer-keywords.txt" + {"i64.shl", TokenType::Binary, Opcode::I64Shl }, +#line 305 "./lexer-keywords.txt" + {"i32.shl", TokenType::Binary, Opcode::I32Shl }, +#line 464 "./lexer-keywords.txt" + {"i64.trunc_f64_s", TokenType::Convert, Opcode::I64TruncF64S }, +#line 314 "./lexer-keywords.txt" + {"i32.trunc_f64_s", TokenType::Convert, Opcode::I32TruncF64S }, + {""}, +#line 420 "./lexer-keywords.txt" + {"i64.ctz", TokenType::Unary, Opcode::I64Ctz }, +#line 276 "./lexer-keywords.txt" + {"i32.ctz", TokenType::Unary, Opcode::I32Ctz }, +#line 577 "./lexer-keywords.txt" + {"register", TokenType::Register }, +#line 398 "./lexer-keywords.txt" + {"i64.atomic.rmw32.xchg_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw32XchgU }, + {""}, {""}, {""}, +#line 543 "./lexer-keywords.txt" + {"input", TokenType::Input }, + {""}, {""}, +#line 359 "./lexer-keywords.txt" + {"i32x4.shl", TokenType::Binary, Opcode::I32X4Shl }, +#line 538 "./lexer-keywords.txt" + {"i8x16.sub_sat_u", TokenType::Binary, Opcode::I8X16SubSatU }, +#line 627 "./lexer-keywords.txt" + {"type", TokenType::Type }, + {""}, {""}, +#line 537 "./lexer-keywords.txt" + {"i8x16.sub_sat_s", TokenType::Binary, Opcode::I8X16SubSatS }, +#line 399 "./lexer-keywords.txt" + {"i64.atomic.rmw32.xor_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw32XorU }, + {""}, {""}, {""}, +#line 418 "./lexer-keywords.txt" + {"i64.clz", TokenType::Unary, Opcode::I64Clz }, +#line 274 "./lexer-keywords.txt" + {"i32.clz", TokenType::Unary, Opcode::I32Clz }, +#line 501 "./lexer-keywords.txt" + {"i64x2", TokenType::I64X2 }, + {""}, +#line 170 "./lexer-keywords.txt" + {"f64x2.relaxed_madd", TokenType::Ternary, Opcode::F64X2RelaxedMadd }, + {""}, +#line 182 "./lexer-keywords.txt" + {"f64x2", TokenType::F64X2 }, +#line 542 "./lexer-keywords.txt" + {"import", TokenType::Import }, + {""}, {""}, {""}, {""}, {""}, {""}, +#line 94 "./lexer-keywords.txt" + {"f32x4.div", TokenType::Binary, Opcode::F32X4Div }, +#line 146 "./lexer-keywords.txt" + {"f64.sqrt", TokenType::Unary, Opcode::F64Sqrt }, +#line 84 "./lexer-keywords.txt" + {"f32.sqrt", TokenType::Unary, Opcode::F32Sqrt }, +#line 411 "./lexer-keywords.txt" + {"i64.atomic.rmw.sub", TokenType::AtomicRmw, Opcode::I64AtomicRmwSub }, +#line 268 "./lexer-keywords.txt" + {"i32.atomic.rmw.sub", TokenType::AtomicRmw, Opcode::I32AtomicRmwSub }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 556 "src/lexer-keywords.txt" - {"output", TokenType::Output}, -#line 374 "src/lexer-keywords.txt" - {"i64.atomic.load8_u", TokenType::AtomicLoad, Opcode::I64AtomicLoad8U}, -#line 244 "src/lexer-keywords.txt" - {"i32.atomic.load8_u", TokenType::AtomicLoad, Opcode::I32AtomicLoad8U}, - {""}, -#line 555 "src/lexer-keywords.txt" - {"offset", TokenType::Offset}, -#line 480 "src/lexer-keywords.txt" - {"i64x2.relaxed_laneselect", TokenType::Ternary, Opcode::I64X2RelaxedLaneSelect}, - {""}, -#line 40 "src/lexer-keywords.txt" - {"catch_all", TokenType::CatchAll, Opcode::CatchAll}, -#line 402 "src/lexer-keywords.txt" - {"i64.atomic.rmw.xchg", TokenType::AtomicRmw, Opcode::I64AtomicRmwXchg}, -#line 265 "src/lexer-keywords.txt" - {"i32.atomic.rmw.xchg", TokenType::AtomicRmw, Opcode::I32AtomicRmwXchg}, - {""}, -#line 396 "src/lexer-keywords.txt" - {"i64.atomic.rmw8.xor_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw8XorU}, -#line 259 "src/lexer-keywords.txt" - {"i32.atomic.rmw8.xor_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw8XorU}, -#line 201 "src/lexer-keywords.txt" - {"i16x8.ge_u", TokenType::Compare, Opcode::I16X8GeU}, -#line 597 "src/lexer-keywords.txt" - {"v128.store", TokenType::Store, Opcode::V128Store}, -#line 205 "src/lexer-keywords.txt" - {"i16x8.le_u", TokenType::Compare, Opcode::I16X8LeU}, -#line 332 "src/lexer-keywords.txt" - {"i32x4.relaxed_trunc_f32x4_u", TokenType::Unary, Opcode::I32X4RelaxedTruncF32X4U}, -#line 200 "src/lexer-keywords.txt" - {"i16x8.ge_s", TokenType::Compare, Opcode::I16X8GeS}, - {""}, -#line 204 "src/lexer-keywords.txt" - {"i16x8.le_s", TokenType::Compare, Opcode::I16X8LeS}, -#line 331 "src/lexer-keywords.txt" - {"i32x4.relaxed_trunc_f32x4_s", TokenType::Unary, Opcode::I32X4RelaxedTruncF32X4S}, -#line 203 "src/lexer-keywords.txt" - {"i16x8.gt_u", TokenType::Compare, Opcode::I16X8GtU}, -#line 429 "src/lexer-keywords.txt" - {"i64.load32_u", TokenType::Load, Opcode::I64Load32U}, -#line 209 "src/lexer-keywords.txt" - {"i16x8.lt_u", TokenType::Compare, Opcode::I16X8LtU}, - {""}, -#line 202 "src/lexer-keywords.txt" - {"i16x8.gt_s", TokenType::Compare, Opcode::I16X8GtS}, -#line 428 "src/lexer-keywords.txt" - {"i64.load32_s", TokenType::Load, Opcode::I64Load32S}, -#line 208 "src/lexer-keywords.txt" - {"i16x8.lt_s", TokenType::Compare, Opcode::I16X8LtS}, - {""}, -#line 113 "src/lexer-keywords.txt" - {"f32x4.splat", TokenType::Unary, Opcode::F32X4Splat}, - {""}, -#line 39 "src/lexer-keywords.txt" - {"catch", TokenType::Catch, Opcode::Catch}, - {""}, {""}, {""}, {""}, -#line 352 "src/lexer-keywords.txt" - {"i32x4.splat", TokenType::Unary, Opcode::I32X4Splat}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 236 "src/lexer-keywords.txt" - {"i16x8", TokenType::I16X8}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 591 "src/lexer-keywords.txt" - {"v128.load", TokenType::Load, Opcode::V128Load}, - {""}, {""}, -#line 36 "src/lexer-keywords.txt" - {"call_indirect", TokenType::CallIndirect, Opcode::CallIndirect}, -#line 584 "src/lexer-keywords.txt" - {"try", TokenType::Try, Opcode::Try}, -#line 611 "src/lexer-keywords.txt" - {"v128.store64_lane", TokenType::SimdStoreLane, Opcode::V128Store64Lane}, - {""}, {""}, -#line 217 "src/lexer-keywords.txt" - {"i16x8.neg", TokenType::Unary, Opcode::I16X8Neg}, - {""}, -#line 592 "src/lexer-keywords.txt" - {"v128.not", TokenType::Unary, Opcode::V128Not}, -#line 219 "src/lexer-keywords.txt" - {"i16x8.ne", TokenType::Compare, Opcode::I16X8Ne}, - {""}, -#line 585 "src/lexer-keywords.txt" - {"type", TokenType::Type}, - {""}, {""}, {""}, {""}, {""}, -#line 590 "src/lexer-keywords.txt" - {"v128.const", TokenType::Const, Opcode::V128Const}, -#line 416 "src/lexer-keywords.txt" - {"i64.extend32_s", TokenType::Unary, Opcode::I64Extend32S}, - {""}, -#line 567 "src/lexer-keywords.txt" - {"return_call_indirect", TokenType::ReturnCallIndirect, Opcode::ReturnCallIndirect}, +#line 116 "./lexer-keywords.txt" + {"f32x4.sqrt", TokenType::Unary, Opcode::F32X4Sqrt }, + {""}, +#line 507 "./lexer-keywords.txt" + {"i8x16.all_true", TokenType::Unary, Opcode::I8X16AllTrue }, +#line 593 "./lexer-keywords.txt" + {"array.new", TokenType::ArrayNew, Opcode::ArrayNew }, +#line 645 "./lexer-keywords.txt" + {"v128.load8_splat", TokenType::Load, Opcode::V128Load8Splat }, + {""}, {""}, +#line 566 "./lexer-keywords.txt" + {"output", TokenType::Output }, + {""}, {""}, {""}, {""}, {""}, {""}, +#line 425 "./lexer-keywords.txt" + {"i64.extend16_s", TokenType::Unary, Opcode::I64Extend16S }, +#line 281 "./lexer-keywords.txt" + {"i32.extend16_s", TokenType::Unary, Opcode::I32Extend16S }, + {""}, +#line 565 "./lexer-keywords.txt" + {"offset", TokenType::Offset }, +#line 404 "./lexer-keywords.txt" + {"i64.atomic.rmw8.sub_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw8SubU }, +#line 261 "./lexer-keywords.txt" + {"i32.atomic.rmw8.sub_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw8SubU }, + {""}, +#line 625 "./lexer-keywords.txt" + {"throw", TokenType::Throw, Opcode::Throw }, +#line 597 "./lexer-keywords.txt" + {"array.new_elem", TokenType::ArrayNewElem, Opcode::ArrayNewElem }, + {""}, {""}, +#line 505 "./lexer-keywords.txt" + {"i8x16.add_sat_u", TokenType::Binary, Opcode::I8X16AddSatU }, +#line 163 "./lexer-keywords.txt" + {"f64x2.min", TokenType::Binary, Opcode::F64X2Min }, +#line 426 "./lexer-keywords.txt" + {"i64.extend32_s", TokenType::Unary, Opcode::I64Extend32S }, +#line 540 "./lexer-keywords.txt" + {"i8x16", TokenType::I8X16 }, +#line 504 "./lexer-keywords.txt" + {"i8x16.add_sat_s", TokenType::Binary, Opcode::I8X16AddSatS }, +#line 646 "./lexer-keywords.txt" + {"v128.load8_lane", TokenType::SimdLoadLane, Opcode::V128Load8Lane }, {""}, {""}, {""}, -#line 588 "src/lexer-keywords.txt" - {"v128.and", TokenType::Binary, Opcode::V128And}, -#line 531 "src/lexer-keywords.txt" - {"if", TokenType::If, Opcode::If}, -#line 154 "src/lexer-keywords.txt" - {"f64x2.extract_lane", TokenType::SimdLaneOp, Opcode::F64X2ExtractLane}, -#line 558 "src/lexer-keywords.txt" - {"ref", TokenType::Ref}, - {""}, {""}, -#line 161 "src/lexer-keywords.txt" - {"f64x2.min", TokenType::Binary, Opcode::F64X2Min}, - {""}, {""}, -#line 462 "src/lexer-keywords.txt" - {"i64x2.extract_lane", TokenType::SimdLaneOp, Opcode::I64X2ExtractLane}, - {""}, {""}, -#line 604 "src/lexer-keywords.txt" - {"v128.load8_lane", TokenType::SimdLoadLane, Opcode::V128Load8Lane}, +#line 138 "./lexer-keywords.txt" + {"f64.max", TokenType::Binary, Opcode::F64Max }, +#line 77 "./lexer-keywords.txt" + {"f32.max", TokenType::Binary, Opcode::F32Max }, +#line 643 "./lexer-keywords.txt" + {"v128.load32_splat", TokenType::Load, Opcode::V128Load32Splat }, +#line 571 "./lexer-keywords.txt" + {"quote", TokenType::Quote }, {""}, {""}, {""}, {""}, {""}, -#line 51 "src/lexer-keywords.txt" - {"else", TokenType::Else, Opcode::Else}, -#line 160 "src/lexer-keywords.txt" - {"f64x2.max", TokenType::Binary, Opcode::F64X2Max}, - {""}, -#line 533 "src/lexer-keywords.txt" - {"input", TokenType::Input}, - {""}, -#line 603 "src/lexer-keywords.txt" - {"v128.load8_splat", TokenType::Load, Opcode::V128Load8Splat}, +#line 416 "./lexer-keywords.txt" + {"i64.atomic.store8", TokenType::AtomicStore, Opcode::I64AtomicStore8 }, +#line 272 "./lexer-keywords.txt" + {"i32.atomic.store8", TokenType::AtomicStore, Opcode::I32AtomicStore8 }, {""}, {""}, -#line 474 "src/lexer-keywords.txt" - {"i64x2.all_true", TokenType::Unary, Opcode::I64X2AllTrue}, - {""}, -#line 393 "src/lexer-keywords.txt" - {"i64.atomic.rmw8.or_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw8OrU}, -#line 256 "src/lexer-keywords.txt" - {"i32.atomic.rmw8.or_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw8OrU}, -#line 48 "src/lexer-keywords.txt" - {"either", TokenType::Either}, +#line 27 "./lexer-keywords.txt" + {"assert_malformed", TokenType::AssertMalformed }, {""}, {""}, -#line 532 "src/lexer-keywords.txt" - {"import", TokenType::Import}, +#line 362 "./lexer-keywords.txt" + {"i32x4.splat", TokenType::Unary, Opcode::I32X4Splat }, +#line 207 "./lexer-keywords.txt" + {"i16x8.gt_u", TokenType::Compare, Opcode::I16X8GtU }, {""}, {""}, -#line 599 "src/lexer-keywords.txt" - {"v128.xor", TokenType::Binary, Opcode::V128Xor}, +#line 115 "./lexer-keywords.txt" + {"f32x4.splat", TokenType::Unary, Opcode::F32X4Splat }, +#line 206 "./lexer-keywords.txt" + {"i16x8.gt_s", TokenType::Compare, Opcode::I16X8GtS }, + {""}, +#line 205 "./lexer-keywords.txt" + {"i16x8.ge_u", TokenType::Compare, Opcode::I16X8GeU }, +#line 650 "./lexer-keywords.txt" + {"v128.store8_lane", TokenType::SimdStoreLane, Opcode::V128Store8Lane }, {""}, {""}, -#line 222 "src/lexer-keywords.txt" - {"i16x8.replace_lane", TokenType::SimdLaneOp, Opcode::I16X8ReplaceLane}, +#line 204 "./lexer-keywords.txt" + {"i16x8.ge_s", TokenType::Compare, Opcode::I16X8GeS }, {""}, {""}, -#line 144 "src/lexer-keywords.txt" - {"f64.sqrt", TokenType::Unary, Opcode::F64Sqrt}, -#line 82 "src/lexer-keywords.txt" - {"f32.sqrt", TokenType::Unary, Opcode::F32Sqrt}, +#line 30 "./lexer-keywords.txt" + {"assert_unlinkable", TokenType::AssertUnlinkable }, + {""}, {""}, +#line 213 "./lexer-keywords.txt" + {"i16x8.lt_u", TokenType::Compare, Opcode::I16X8LtU }, + {""}, +#line 162 "./lexer-keywords.txt" + {"f64x2.max", TokenType::Binary, Opcode::F64X2Max }, +#line 522 "./lexer-keywords.txt" + {"i8x16.max_u", TokenType::Binary, Opcode::I8X16MaxU }, +#line 212 "./lexer-keywords.txt" + {"i16x8.lt_s", TokenType::Compare, Opcode::I16X8LtS }, +#line 521 "./lexer-keywords.txt" + {"i8x16.max_s", TokenType::Binary, Opcode::I8X16MaxS }, +#line 209 "./lexer-keywords.txt" + {"i16x8.le_u", TokenType::Compare, Opcode::I16X8LeU }, +#line 648 "./lexer-keywords.txt" + {"v128.load32_lane", TokenType::SimdLoadLane, Opcode::V128Load32Lane }, + {""}, +#line 34 "./lexer-keywords.txt" + {"block", TokenType::Block, Opcode::Block }, +#line 208 "./lexer-keywords.txt" + {"i16x8.le_s", TokenType::Compare, Opcode::I16X8LeS }, {""}, {""}, {""}, -#line 587 "src/lexer-keywords.txt" - {"v128.andnot", TokenType::Binary, Opcode::V128Andnot}, - {""}, -#line 192 "src/lexer-keywords.txt" - {"i16x8.add", TokenType::Binary, Opcode::I16X8Add}, -#line 214 "src/lexer-keywords.txt" - {"i16x8.mul", TokenType::Binary, Opcode::I16X8Mul}, - {""}, -#line 482 "src/lexer-keywords.txt" - {"i64x2.shl", TokenType::Binary, Opcode::I64X2Shl}, -#line 170 "src/lexer-keywords.txt" - {"f64x2.relaxed_min", TokenType::Binary, Opcode::F64X2RelaxedMin}, - {""}, -#line 114 "src/lexer-keywords.txt" - {"f32x4.sqrt", TokenType::Unary, Opcode::F32X4Sqrt}, - {""}, -#line 582 "src/lexer-keywords.txt" - {"then", TokenType::Then}, - {""}, -#line 207 "src/lexer-keywords.txt" - {"v128.load8x8_u", TokenType::Load, Opcode::V128Load8X8U}, -#line 464 "src/lexer-keywords.txt" - {"v128.load32x2_u", TokenType::Load, Opcode::V128Load32X2U}, -#line 206 "src/lexer-keywords.txt" - {"v128.load8x8_s", TokenType::Load, Opcode::V128Load8X8S}, - {""}, {""}, -#line 463 "src/lexer-keywords.txt" - {"v128.load32x2_s", TokenType::Load, Opcode::V128Load32X2S}, -#line 52 "src/lexer-keywords.txt" - {"end", TokenType::End, Opcode::End}, - {""}, -#line 42 "src/lexer-keywords.txt" - {"data.drop", TokenType::DataDrop, Opcode::DataDrop}, -#line 385 "src/lexer-keywords.txt" - {"i64.atomic.rmw32.cmpxchg_u", TokenType::AtomicRmwCmpxchg, Opcode::I64AtomicRmw32CmpxchgU}, - {""}, {""}, {""}, {""}, -#line 171 "src/lexer-keywords.txt" - {"f64x2.relaxed_nmadd", TokenType::Ternary, Opcode::F64X2RelaxedNmadd}, +#line 474 "./lexer-keywords.txt" + {"v128.load32x2_u", TokenType::Load, Opcode::V128Load32X2U }, +#line 541 "./lexer-keywords.txt" + {"if", TokenType::If, Opcode::If }, + {""}, {""}, +#line 473 "./lexer-keywords.txt" + {"v128.load32x2_s", TokenType::Load, Opcode::V128Load32X2S }, + {""}, {""}, +#line 641 "./lexer-keywords.txt" + {"v128.xor", TokenType::Binary, Opcode::V128Xor }, +#line 568 "./lexer-keywords.txt" + {"ref", Type::Ref, TokenType::Ref }, +#line 53 "./lexer-keywords.txt" + {"else", TokenType::Else, Opcode::Else }, + {""}, {""}, +#line 606 "./lexer-keywords.txt" + {"array.init_elem", TokenType::ArrayInitElem, Opcode::ArrayInitElem }, + {""}, {""}, {""}, {""}, {""}, {""}, +#line 651 "./lexer-keywords.txt" + {"v128.store16_lane", TokenType::SimdStoreLane, Opcode::V128Store16Lane }, + {""}, {""}, +#line 508 "./lexer-keywords.txt" + {"i8x16.avgr_u", TokenType::Binary, Opcode::I8X16AvgrU }, {""}, -#line 220 "src/lexer-keywords.txt" - {"i16x8.relaxed_laneselect", TokenType::Ternary, Opcode::I16X8RelaxedLaneSelect}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 580 "./lexer-keywords.txt" + {"return_call_indirect", TokenType::ReturnCallIndirect, Opcode::ReturnCallIndirect }, + {""}, {""}, +#line 111 "./lexer-keywords.txt" + {"f32x4.relaxed_max", TokenType::Binary, Opcode::F32X4RelaxedMax }, +#line 221 "./lexer-keywords.txt" + {"i16x8.neg", TokenType::Unary, Opcode::I16X8Neg }, +#line 223 "./lexer-keywords.txt" + {"i16x8.ne", TokenType::Compare, Opcode::I16X8Ne }, + {""}, +#line 631 "./lexer-keywords.txt" + {"v128.bitselect", TokenType::Ternary, Opcode::V128BitSelect }, +#line 652 "./lexer-keywords.txt" + {"v128.store32_lane", TokenType::SimdStoreLane, Opcode::V128Store32Lane }, +#line 637 "./lexer-keywords.txt" + {"v128.load32_zero", TokenType::Load, Opcode::V128Load32Zero }, + {""}, {""}, {""}, {""}, {""}, {""}, +#line 619 "./lexer-keywords.txt" + {"table.grow", TokenType::TableGrow, Opcode::TableGrow }, +#line 579 "./lexer-keywords.txt" + {"rethrow", TokenType::Rethrow, Opcode::Rethrow }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 50 "./lexer-keywords.txt" + {"either", TokenType::Either }, +#line 472 "./lexer-keywords.txt" + {"i64x2.extract_lane", TokenType::SimdLaneOp, Opcode::I64X2ExtractLane }, + {""}, {""}, {""}, +#line 156 "./lexer-keywords.txt" + {"f64x2.extract_lane", TokenType::SimdLaneOp, Opcode::F64X2ExtractLane }, + {""}, +#line 624 "./lexer-keywords.txt" + {"then", TokenType::Then }, +#line 322 "./lexer-keywords.txt" + {"i16", Type::I16 }, +#line 38 "./lexer-keywords.txt" + {"call_indirect", TokenType::CallIndirect, Opcode::CallIndirect }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 587 "./lexer-keywords.txt" + {"struct.new", TokenType::StructNew, Opcode::StructNew }, + {""}, {""}, {""}, {""}, {""}, +#line 54 "./lexer-keywords.txt" + {"end", TokenType::End, Opcode::End }, {""}, {""}, {""}, {""}, -#line 561 "src/lexer-keywords.txt" - {"ref.func", TokenType::RefFunc, Opcode::RefFunc}, +#line 403 "./lexer-keywords.txt" + {"i64.atomic.rmw8.or_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw8OrU }, +#line 260 "./lexer-keywords.txt" + {"i32.atomic.rmw8.or_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw8OrU }, {""}, {""}, {""}, {""}, -#line 372 "src/lexer-keywords.txt" - {"i64.atomic.load16_u", TokenType::AtomicLoad, Opcode::I64AtomicLoad16U}, -#line 243 "src/lexer-keywords.txt" - {"i32.atomic.load16_u", TokenType::AtomicLoad, Opcode::I32AtomicLoad16U}, - {""}, -#line 504 "src/lexer-keywords.txt" - {"i8x16.ge_u", TokenType::Compare, Opcode::I8X16GeU}, - {""}, -#line 508 "src/lexer-keywords.txt" - {"i8x16.le_u", TokenType::Compare, Opcode::I8X16LeU}, - {""}, -#line 503 "src/lexer-keywords.txt" - {"i8x16.ge_s", TokenType::Compare, Opcode::I8X16GeS}, - {""}, -#line 507 "src/lexer-keywords.txt" - {"i8x16.le_s", TokenType::Compare, Opcode::I8X16LeS}, - {""}, -#line 506 "src/lexer-keywords.txt" - {"i8x16.gt_u", TokenType::Compare, Opcode::I8X16GtU}, -#line 575 "src/lexer-keywords.txt" - {"table.fill", TokenType::TableFill, Opcode::TableFill}, -#line 510 "src/lexer-keywords.txt" - {"i8x16.lt_u", TokenType::Compare, Opcode::I8X16LtU}, +#line 429 "./lexer-keywords.txt" + {"i64.extend_i32_u", TokenType::Convert, Opcode::I64ExtendI32U }, {""}, -#line 505 "src/lexer-keywords.txt" - {"i8x16.gt_s", TokenType::Compare, Opcode::I8X16GtS}, +#line 428 "./lexer-keywords.txt" + {"i64.extend_i32_s", TokenType::Convert, Opcode::I64ExtendI32S }, {""}, -#line 509 "src/lexer-keywords.txt" - {"i8x16.lt_s", TokenType::Compare, Opcode::I8X16LtS}, - {""}, {""}, {""}, {""}, {""}, -#line 395 "src/lexer-keywords.txt" - {"i64.atomic.rmw8.xchg_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw8XchgU}, -#line 258 "src/lexer-keywords.txt" - {"i32.atomic.rmw8.xchg_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw8XchgU}, - {""}, {""}, {""}, {""}, {""}, {""}, -#line 21 "src/lexer-keywords.txt" - {"after", TokenType::After}, +#line 128 "./lexer-keywords.txt" + {"f64.convert_i64_u", TokenType::Convert, Opcode::F64ConvertI64U }, +#line 66 "./lexer-keywords.txt" + {"f32.convert_i64_u", TokenType::Convert, Opcode::F32ConvertI64U }, + {""}, {""}, +#line 127 "./lexer-keywords.txt" + {"f64.convert_i64_s", TokenType::Convert, Opcode::F64ConvertI64S }, +#line 65 "./lexer-keywords.txt" + {"f32.convert_i64_s", TokenType::Convert, Opcode::F32ConvertI64S }, + {""}, {""}, {""}, +#line 196 "./lexer-keywords.txt" + {"i16x8.add", TokenType::Binary, Opcode::I16X8Add }, + {""}, {""}, {""}, +#line 44 "./lexer-keywords.txt" + {"data.drop", TokenType::DataDrop, Opcode::DataDrop }, +#line 218 "./lexer-keywords.txt" + {"i16x8.mul", TokenType::Binary, Opcode::I16X8Mul }, {""}, {""}, {""}, -#line 181 "src/lexer-keywords.txt" - {"field", TokenType::Field}, -#line 168 "src/lexer-keywords.txt" - {"f64x2.relaxed_madd", TokenType::Ternary, Opcode::F64X2RelaxedMadd}, -#line 54 "src/lexer-keywords.txt" - {"extern", Type::ExternRef, TokenType::Extern}, - {""}, {""}, -#line 535 "src/lexer-keywords.txt" - {"item", TokenType::Item}, -#line 609 "src/lexer-keywords.txt" - {"v128.store16_lane", TokenType::SimdStoreLane, Opcode::V128Store16Lane}, - {""}, -#line 548 "src/lexer-keywords.txt" - {"memory.size", TokenType::MemorySize, Opcode::MemorySize}, - {""}, -#line 119 "src/lexer-keywords.txt" - {"f64.abs", TokenType::Unary, Opcode::F64Abs}, -#line 57 "src/lexer-keywords.txt" - {"f32.abs", TokenType::Unary, Opcode::F32Abs}, - {""}, -#line 95 "src/lexer-keywords.txt" - {"f32x4.floor", TokenType::Unary, Opcode::F32X4Floor}, - {""}, {""}, -#line 517 "src/lexer-keywords.txt" - {"i8x16.neg", TokenType::Unary, Opcode::I8X16Neg}, -#line 180 "src/lexer-keywords.txt" - {"f64x2", TokenType::F64X2}, - {""}, -#line 519 "src/lexer-keywords.txt" - {"i8x16.ne", TokenType::Compare, Opcode::I8X16Ne}, -#line 115 "src/lexer-keywords.txt" - {"f32x4.sub", TokenType::Binary, Opcode::F32X4Sub}, - {""}, -#line 572 "src/lexer-keywords.txt" - {"start", TokenType::Start}, - {""}, -#line 491 "src/lexer-keywords.txt" - {"i64x2", TokenType::I64X2}, -#line 34 "src/lexer-keywords.txt" - {"br_table", TokenType::BrTable, Opcode::BrTable}, -#line 87 "src/lexer-keywords.txt" - {"f32x4.abs", TokenType::Unary, Opcode::F32X4Abs}, -#line 353 "src/lexer-keywords.txt" - {"i32x4.sub", TokenType::Binary, Opcode::I32X4Sub}, +#line 456 "./lexer-keywords.txt" + {"i64.shr_u", TokenType::Binary, Opcode::I64ShrU }, +#line 307 "./lexer-keywords.txt" + {"i32.shr_u", TokenType::Binary, Opcode::I32ShrU }, +#line 455 "./lexer-keywords.txt" + {"i64.shr_s", TokenType::Binary, Opcode::I64ShrS }, +#line 306 "./lexer-keywords.txt" + {"i32.shr_s", TokenType::Binary, Opcode::I32ShrS }, +#line 567 "./lexer-keywords.txt" + {"param", TokenType::Param }, + {""}, {""}, {""}, +#line 485 "./lexer-keywords.txt" + {"i64x2.bitmask", TokenType::Unary, Opcode::I64X2Bitmask }, {""}, {""}, {""}, {""}, {""}, -#line 318 "src/lexer-keywords.txt" - {"i32x4.abs", TokenType::Unary, Opcode::I32X4Abs}, +#line 545 "./lexer-keywords.txt" + {"item", TokenType::Item }, + {""}, +#line 361 "./lexer-keywords.txt" + {"i32x4.shr_u", TokenType::Binary, Opcode::I32X4ShrU }, {""}, -#line 107 "src/lexer-keywords.txt" - {"f32x4.pmin", TokenType::Binary, Opcode::F32X4PMin}, +#line 360 "./lexer-keywords.txt" + {"i32x4.shr_s", TokenType::Binary, Opcode::I32X4ShrS }, {""}, {""}, -#line 547 "src/lexer-keywords.txt" - {"memory.init", TokenType::MemoryInit, Opcode::MemoryInit}, +#line 422 "./lexer-keywords.txt" + {"i64.div_u", TokenType::Binary, Opcode::I64DivU }, +#line 278 "./lexer-keywords.txt" + {"i32.div_u", TokenType::Binary, Opcode::I32DivU }, +#line 421 "./lexer-keywords.txt" + {"i64.div_s", TokenType::Binary, Opcode::I64DivS }, +#line 277 "./lexer-keywords.txt" + {"i32.div_s", TokenType::Binary, Opcode::I32DivS }, +#line 56 "./lexer-keywords.txt" + {"extern", Type::ExternRef, TokenType::Extern }, + {""}, {""}, {""}, {""}, {""}, +#line 183 "./lexer-keywords.txt" + {"field", TokenType::Field }, {""}, {""}, {""}, {""}, {""}, -#line 228 "src/lexer-keywords.txt" - {"i16x8.sub_sat_u", TokenType::Binary, Opcode::I16X8SubSatU}, +#line 382 "./lexer-keywords.txt" + {"i64.atomic.load16_u", TokenType::AtomicLoad, Opcode::I64AtomicLoad16U }, +#line 247 "./lexer-keywords.txt" + {"i32.atomic.load16_u", TokenType::AtomicLoad, Opcode::I32AtomicLoad16U }, + {""}, +#line 406 "./lexer-keywords.txt" + {"i64.atomic.rmw8.xor_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw8XorU }, +#line 263 "./lexer-keywords.txt" + {"i32.atomic.rmw8.xor_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw8XorU }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 383 "./lexer-keywords.txt" + {"i64.atomic.load32_u", TokenType::AtomicLoad, Opcode::I64AtomicLoad32U }, + {""}, {""}, {""}, {""}, {""}, +#line 224 "./lexer-keywords.txt" + {"i16x8.relaxed_laneselect", TokenType::Ternary, Opcode::I16X8RelaxedLaneSelect }, +#line 211 "./lexer-keywords.txt" + {"v128.load8x8_u", TokenType::Load, Opcode::V128Load8X8U }, {""}, -#line 193 "src/lexer-keywords.txt" - {"i16x8.all_true", TokenType::Unary, Opcode::I16X8AllTrue}, +#line 210 "./lexer-keywords.txt" + {"v128.load8x8_s", TokenType::Load, Opcode::V128Load8X8S }, {""}, -#line 227 "src/lexer-keywords.txt" - {"i16x8.sub_sat_s", TokenType::Binary, Opcode::I16X8SubSatS}, -#line 92 "src/lexer-keywords.txt" - {"f32x4.div", TokenType::Binary, Opcode::F32X4Div}, +#line 97 "./lexer-keywords.txt" + {"f32x4.floor", TokenType::Unary, Opcode::F32X4Floor }, {""}, {""}, -#line 188 "src/lexer-keywords.txt" - {"global", TokenType::Global}, - {""}, {""}, {""}, -#line 169 "src/lexer-keywords.txt" - {"f64x2.relaxed_max", TokenType::Binary, Opcode::F64X2RelaxedMax}, - {""}, {""}, {""}, {""}, {""}, -#line 601 "src/lexer-keywords.txt" - {"v128.load32_splat", TokenType::Load, Opcode::V128Load32Splat}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 223 "src/lexer-keywords.txt" - {"i16x8.shl", TokenType::Binary, Opcode::I16X8Shl}, -#line 522 "src/lexer-keywords.txt" - {"i8x16.replace_lane", TokenType::SimdLaneOp, Opcode::I8X16ReplaceLane}, -#line 414 "src/lexer-keywords.txt" - {"i64.eqz", TokenType::Convert, Opcode::I64Eqz}, -#line 276 "src/lexer-keywords.txt" - {"i32.eqz", TokenType::Convert, Opcode::I32Eqz}, - {""}, {""}, {""}, {""}, {""}, -#line 130 "src/lexer-keywords.txt" - {"f64.floor", TokenType::Unary, Opcode::F64Floor}, -#line 69 "src/lexer-keywords.txt" - {"f32.floor", TokenType::Unary, Opcode::F32Floor}, -#line 496 "src/lexer-keywords.txt" - {"i8x16.add", TokenType::Binary, Opcode::I8X16Add}, - {""}, {""}, {""}, {""}, -#line 606 "src/lexer-keywords.txt" - {"v128.load32_lane", TokenType::SimdLoadLane, Opcode::V128Load32Lane}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 186 "src/lexer-keywords.txt" - {"global.get", TokenType::GlobalGet, Opcode::GlobalGet}, -#line 608 "src/lexer-keywords.txt" - {"v128.store8_lane", TokenType::SimdStoreLane, Opcode::V128Store8Lane}, -#line 187 "src/lexer-keywords.txt" - {"global.set", TokenType::GlobalSet, Opcode::GlobalSet}, - {""}, -#line 530 "src/lexer-keywords.txt" - {"i8x16", TokenType::I8X16}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 191 "src/lexer-keywords.txt" - {"i16x8.add_sat_u", TokenType::Binary, Opcode::I16X8AddSatU}, -#line 521 "src/lexer-keywords.txt" - {"i8x16.relaxed_laneselect", TokenType::Ternary, Opcode::I8X16RelaxedLaneSelect}, - {""}, {""}, -#line 190 "src/lexer-keywords.txt" - {"i16x8.add_sat_s", TokenType::Binary, Opcode::I16X8AddSatS}, -#line 557 "src/lexer-keywords.txt" - {"param", TokenType::Param}, +#line 595 "./lexer-keywords.txt" + {"array.new_fixed", TokenType::ArrayNewFixed, Opcode::ArrayNewFixed }, +#line 226 "./lexer-keywords.txt" + {"i16x8.replace_lane", TokenType::SimdLaneOp, Opcode::I16X8ReplaceLane }, {""}, {""}, {""}, {""}, {""}, {""}, -#line 595 "src/lexer-keywords.txt" - {"v128.load32_zero", TokenType::Load, Opcode::V128Load32Zero}, +#line 390 "./lexer-keywords.txt" + {"i64.atomic.rmw16.sub_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw16SubU }, +#line 254 "./lexer-keywords.txt" + {"i32.atomic.rmw16.sub_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw16SubU }, + {""}, {""}, {""}, {""}, +#line 509 "./lexer-keywords.txt" + {"i8x16.bitmask", TokenType::Unary, Opcode::I8X16Bitmask }, +#line 233 "./lexer-keywords.txt" + {"i16x8.sub", TokenType::Binary, Opcode::I16X8Sub }, {""}, {""}, -#line 583 "src/lexer-keywords.txt" - {"throw", TokenType::Throw, Opcode::Throw}, +#line 193 "./lexer-keywords.txt" + {"i16x8.abs", TokenType::Unary, Opcode::I16X8Abs }, + {""}, +#line 109 "./lexer-keywords.txt" + {"f32x4.pmin", TokenType::Binary, Opcode::F32X4PMin }, +#line 415 "./lexer-keywords.txt" + {"i64.atomic.store32", TokenType::AtomicStore, Opcode::I64AtomicStore32 }, +#line 42 "./lexer-keywords.txt" + {"catch_all", TokenType::CatchAll, Opcode::CatchAll }, + {""}, +#line 412 "./lexer-keywords.txt" + {"i64.atomic.rmw.xchg", TokenType::AtomicRmw, Opcode::I64AtomicRmwXchg }, +#line 269 "./lexer-keywords.txt" + {"i32.atomic.rmw.xchg", TokenType::AtomicRmw, Opcode::I32AtomicRmwXchg }, + {""}, {""}, {""}, +#line 573 "./lexer-keywords.txt" + {"ref.func", TokenType::RefFunc, Opcode::RefFunc }, + {""}, {""}, {""}, {""}, {""}, {""}, +#line 240 "./lexer-keywords.txt" + {"i16x8", TokenType::I16X8 }, +#line 492 "./lexer-keywords.txt" + {"i64x2.shl", TokenType::Binary, Opcode::I64X2Shl }, + {""}, {""}, {""}, {""}, +#line 132 "./lexer-keywords.txt" + {"f64.floor", TokenType::Unary, Opcode::F64Floor }, +#line 71 "./lexer-keywords.txt" + {"f32.floor", TokenType::Unary, Opcode::F32Floor }, {""}, {""}, {""}, {""}, {""}, -#line 571 "src/lexer-keywords.txt" - {"shared", TokenType::Shared}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 484 "src/lexer-keywords.txt" - {"i64x2.shr_u", TokenType::Binary, Opcode::I64X2ShrU}, - {""}, -#line 483 "src/lexer-keywords.txt" - {"i64x2.shr_s", TokenType::Binary, Opcode::I64X2ShrS}, - {""}, -#line 211 "src/lexer-keywords.txt" - {"i16x8.max_u", TokenType::Binary, Opcode::I16X8MaxU}, +#line 326 "./lexer-keywords.txt" + {"noextern", Type::NoExtern, TokenType::NoExtern }, + {""}, {""}, +#line 524 "./lexer-keywords.txt" + {"i8x16.min_u", TokenType::Binary, Opcode::I8X16MinU }, {""}, -#line 210 "src/lexer-keywords.txt" - {"i16x8.max_s", TokenType::Binary, Opcode::I16X8MaxS}, +#line 523 "./lexer-keywords.txt" + {"i8x16.min_s", TokenType::Binary, Opcode::I8X16MinS }, {""}, {""}, {""}, {""}, {""}, -#line 355 "src/lexer-keywords.txt" - {"i32x4.extadd_pairwise_i16x8_u", TokenType::Unary, Opcode::I32X4ExtaddPairwiseI16X8U}, -#line 577 "src/lexer-keywords.txt" - {"table.grow", TokenType::TableGrow, Opcode::TableGrow}, -#line 354 "src/lexer-keywords.txt" - {"i32x4.extadd_pairwise_i16x8_s", TokenType::Unary, Opcode::I32X4ExtaddPairwiseI16X8S}, - {""}, {""}, {""}, {""}, {""}, -#line 106 "src/lexer-keywords.txt" - {"f32x4.pmax", TokenType::Binary, Opcode::F32X4PMax}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 364 "src/lexer-keywords.txt" - {"i32x4.extend_high_i16x8_u", TokenType::Unary, Opcode::I32X4ExtendHighI16X8U}, +#line 323 "./lexer-keywords.txt" + {"i31", Type::I31, TokenType::I31 }, +#line 154 "./lexer-keywords.txt" + {"f64x2.div", TokenType::Binary, Opcode::F64X2Div }, +#line 387 "./lexer-keywords.txt" + {"i64.atomic.rmw16.and_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw16AndU }, +#line 251 "./lexer-keywords.txt" + {"i32.atomic.rmw16.and_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw16AndU }, + {""}, {""}, {""}, {""}, +#line 232 "./lexer-keywords.txt" + {"i16x8.sub_sat_u", TokenType::Binary, Opcode::I16X8SubSatU }, + {""}, {""}, {""}, +#line 231 "./lexer-keywords.txt" + {"i16x8.sub_sat_s", TokenType::Binary, Opcode::I16X8SubSatS }, +#line 386 "./lexer-keywords.txt" + {"i64.atomic.rmw16.add_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw16AddU }, +#line 250 "./lexer-keywords.txt" + {"i32.atomic.rmw16.add_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw16AddU }, + {""}, {""}, {""}, +#line 176 "./lexer-keywords.txt" + {"f64x2.sqrt", TokenType::Unary, Opcode::F64X2Sqrt }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 130 "./lexer-keywords.txt" + {"f64.div", TokenType::Binary, Opcode::F64Div }, +#line 69 "./lexer-keywords.txt" + {"f32.div", TokenType::Binary, Opcode::F32Div }, {""}, -#line 363 "src/lexer-keywords.txt" - {"i32x4.extend_high_i16x8_s", TokenType::Unary, Opcode::I32X4ExtendHighI16X8S}, +#line 555 "./lexer-keywords.txt" + {"memory.fill", TokenType::MemoryFill, Opcode::MemoryFill }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, +#line 389 "./lexer-keywords.txt" + {"i64.atomic.rmw16.or_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw16OrU }, +#line 253 "./lexer-keywords.txt" + {"i32.atomic.rmw16.or_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw16OrU }, + {""}, +#line 533 "./lexer-keywords.txt" + {"i8x16.shl", TokenType::Binary, Opcode::I8X16Shl }, + {""}, {""}, +#line 197 "./lexer-keywords.txt" + {"i16x8.all_true", TokenType::Unary, Opcode::I16X8AllTrue }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, {""}, {""}, -#line 373 "src/lexer-keywords.txt" - {"i64.atomic.load32_u", TokenType::AtomicLoad, Opcode::I64AtomicLoad32U}, - {""}, {""}, -#line 213 "src/lexer-keywords.txt" - {"i16x8.min_u", TokenType::Binary, Opcode::I16X8MinU}, - {""}, -#line 212 "src/lexer-keywords.txt" - {"i16x8.min_s", TokenType::Binary, Opcode::I16X8MinS}, -#line 528 "src/lexer-keywords.txt" - {"i8x16.sub_sat_u", TokenType::Binary, Opcode::I8X16SubSatU}, -#line 66 "src/lexer-keywords.txt" - {"f32.demote_f64", TokenType::Convert, Opcode::F32DemoteF64}, -#line 497 "src/lexer-keywords.txt" - {"i8x16.all_true", TokenType::Unary, Opcode::I8X16AllTrue}, -#line 143 "src/lexer-keywords.txt" - {"f64.reinterpret_i64", TokenType::Convert, Opcode::F64ReinterpretI64}, -#line 527 "src/lexer-keywords.txt" - {"i8x16.sub_sat_s", TokenType::Binary, Opcode::I8X16SubSatS}, -#line 173 "src/lexer-keywords.txt" - {"f64x2.splat", TokenType::Unary, Opcode::F64X2Splat}, + {""}, +#line 554 "./lexer-keywords.txt" + {"memory.copy", TokenType::MemoryCopy, Opcode::MemoryCopy }, {""}, {""}, {""}, {""}, {""}, {""}, -#line 485 "src/lexer-keywords.txt" - {"i64x2.splat", TokenType::Unary, Opcode::I64X2Splat}, +#line 495 "./lexer-keywords.txt" + {"i64x2.splat", TokenType::Unary, Opcode::I64X2Splat }, + {""}, {""}, +#line 644 "./lexer-keywords.txt" + {"v128.load64_splat", TokenType::Load, Opcode::V128Load64Splat }, +#line 175 "./lexer-keywords.txt" + {"f64x2.splat", TokenType::Unary, Opcode::F64X2Splat }, +#line 195 "./lexer-keywords.txt" + {"i16x8.add_sat_u", TokenType::Binary, Opcode::I16X8AddSatU }, {""}, {""}, {""}, -#line 586 "src/lexer-keywords.txt" - {"unreachable", TokenType::Unreachable, Opcode::Unreachable}, - {""}, {""}, -#line 602 "src/lexer-keywords.txt" - {"v128.load64_splat", TokenType::Load, Opcode::V128Load64Splat}, -#line 321 "src/lexer-keywords.txt" - {"i32x4.bitmask", TokenType::Unary, Opcode::I32X4Bitmask}, -#line 566 "src/lexer-keywords.txt" - {"rethrow", TokenType::Rethrow, Opcode::Rethrow}, - {""}, {""}, {""}, {""}, {""}, {""}, -#line 523 "src/lexer-keywords.txt" - {"i8x16.shl", TokenType::Binary, Opcode::I8X16Shl}, +#line 194 "./lexer-keywords.txt" + {"i16x8.add_sat_s", TokenType::Binary, Opcode::I16X8AddSatS }, {""}, {""}, -#line 359 "src/lexer-keywords.txt" - {"i32x4.extmul_high_i16x8_u", TokenType::Binary, Opcode::I32X4ExtmulHighI16X8U}, - {""}, -#line 357 "src/lexer-keywords.txt" - {"i32x4.extmul_high_i16x8_s", TokenType::Binary, Opcode::I32X4ExtmulHighI16X8S}, +#line 395 "./lexer-keywords.txt" + {"i64.atomic.rmw32.cmpxchg_u", TokenType::AtomicRmwCmpxchg, Opcode::I64AtomicRmw32CmpxchgU }, + {""}, {""}, {""}, {""}, {""}, +#line 628 "./lexer-keywords.txt" + {"unreachable", TokenType::Unreachable, Opcode::Unreachable }, + {""}, {""}, {""}, {""}, +#line 68 "./lexer-keywords.txt" + {"f32.demote_f64", TokenType::Convert, Opcode::F32DemoteF64 }, + {""}, {""}, {""}, {""}, +#line 457 "./lexer-keywords.txt" + {"i64.store16", TokenType::Store, Opcode::I64Store16 }, +#line 308 "./lexer-keywords.txt" + {"i32.store16", TokenType::Store, Opcode::I32Store16 }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 655 "./lexer-keywords.txt" + {"i8x16.swizzle", TokenType::Binary, Opcode::I8X16Swizzle }, {""}, -#line 610 "src/lexer-keywords.txt" - {"v128.store32_lane", TokenType::SimdStoreLane, Opcode::V128Store32Lane}, +#line 649 "./lexer-keywords.txt" + {"v128.load64_lane", TokenType::SimdLoadLane, Opcode::V128Load64Lane }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 199 "src/lexer-keywords.txt" - {"i16x8.extract_lane_u", TokenType::SimdLaneOp, Opcode::I16X8ExtractLaneU}, -#line 607 "src/lexer-keywords.txt" - {"v128.load64_lane", TokenType::SimdLoadLane, Opcode::V128Load64Lane}, -#line 198 "src/lexer-keywords.txt" - {"i16x8.extract_lane_s", TokenType::SimdLaneOp, Opcode::I16X8ExtractLaneS}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, -#line 412 "src/lexer-keywords.txt" - {"i64.div_u", TokenType::Binary, Opcode::I64DivU}, -#line 274 "src/lexer-keywords.txt" - {"i32.div_u", TokenType::Binary, Opcode::I32DivU}, -#line 411 "src/lexer-keywords.txt" - {"i64.div_s", TokenType::Binary, Opcode::I64DivS}, -#line 273 "src/lexer-keywords.txt" - {"i32.div_s", TokenType::Binary, Opcode::I32DivS}, - {""}, {""}, {""}, -#line 495 "src/lexer-keywords.txt" - {"i8x16.add_sat_u", TokenType::Binary, Opcode::I8X16AddSatU}, - {""}, -#line 392 "src/lexer-keywords.txt" - {"i64.atomic.rmw8.cmpxchg_u", TokenType::AtomicRmwCmpxchg, Opcode::I64AtomicRmw8CmpxchgU}, -#line 255 "src/lexer-keywords.txt" - {"i32.atomic.rmw8.cmpxchg_u", TokenType::AtomicRmwCmpxchg, Opcode::I32AtomicRmw8CmpxchgU}, -#line 494 "src/lexer-keywords.txt" - {"i8x16.add_sat_s", TokenType::Binary, Opcode::I8X16AddSatS}, - {""}, -#line 520 "src/lexer-keywords.txt" - {"i8x16.relaxed_swizzle", TokenType::Binary, Opcode::I8X16RelaxedSwizzle}, - {""}, {""}, {""}, {""}, {""}, {""}, -#line 596 "src/lexer-keywords.txt" - {"v128.load64_zero", TokenType::Load, Opcode::V128Load64Zero}, -#line 447 "src/lexer-keywords.txt" - {"i64.store16", TokenType::Store, Opcode::I64Store16}, -#line 304 "src/lexer-keywords.txt" - {"i32.store16", TokenType::Store, Opcode::I32Store16}, - {""}, {""}, {""}, {""}, {""}, {""}, -#line 380 "src/lexer-keywords.txt" - {"i64.atomic.rmw16.sub_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw16SubU}, -#line 250 "src/lexer-keywords.txt" - {"i32.atomic.rmw16.sub_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw16SubU}, - {""}, -#line 225 "src/lexer-keywords.txt" - {"i16x8.shr_u", TokenType::Binary, Opcode::I16X8ShrU}, +#line 215 "./lexer-keywords.txt" + {"i16x8.max_u", TokenType::Binary, Opcode::I16X8MaxU }, {""}, -#line 224 "src/lexer-keywords.txt" - {"i16x8.shr_s", TokenType::Binary, Opcode::I16X8ShrS}, +#line 214 "./lexer-keywords.txt" + {"i16x8.max_s", TokenType::Binary, Opcode::I16X8MaxS }, {""}, {""}, {""}, {""}, {""}, -#line 47 "src/lexer-keywords.txt" - {"drop", TokenType::Drop, Opcode::Drop}, +#line 171 "./lexer-keywords.txt" + {"f64x2.relaxed_max", TokenType::Binary, Opcode::F64X2RelaxedMax }, + {""}, {""}, +#line 617 "./lexer-keywords.txt" + {"table.fill", TokenType::TableFill, Opcode::TableFill }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 536 "./lexer-keywords.txt" + {"i8x16.splat", TokenType::Unary, Opcode::I8X16Splat }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 512 "./lexer-keywords.txt" + {"i8x16.extract_lane_u", TokenType::SimdLaneOp, Opcode::I8X16ExtractLaneU }, +#line 638 "./lexer-keywords.txt" + {"v128.load64_zero", TokenType::Load, Opcode::V128Load64Zero }, +#line 511 "./lexer-keywords.txt" + {"i8x16.extract_lane_s", TokenType::SimdLaneOp, Opcode::I8X16ExtractLaneS }, +#line 198 "./lexer-keywords.txt" + {"i16x8.avgr_u", TokenType::Binary, Opcode::I16X8AvgrU }, + {""}, {""}, {""}, {""}, {""}, {""}, +#line 26 "./lexer-keywords.txt" + {"assert_invalid", TokenType::AssertInvalid }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 512 "src/lexer-keywords.txt" - {"i8x16.max_u", TokenType::Binary, Opcode::I8X16MaxU}, {""}, -#line 511 "src/lexer-keywords.txt" - {"i8x16.max_s", TokenType::Binary, Opcode::I8X16MaxS}, -#line 174 "src/lexer-keywords.txt" - {"f64x2.sqrt", TokenType::Unary, Opcode::F64X2Sqrt}, +#line 126 "./lexer-keywords.txt" + {"f64.convert_i32_u", TokenType::Convert, Opcode::F64ConvertI32U }, +#line 64 "./lexer-keywords.txt" + {"f32.convert_i32_u", TokenType::Convert, Opcode::F32ConvertI32U }, {""}, {""}, -#line 399 "src/lexer-keywords.txt" - {"i64.atomic.rmw.cmpxchg", TokenType::AtomicRmwCmpxchg, Opcode::I64AtomicRmwCmpxchg}, -#line 262 "src/lexer-keywords.txt" - {"i32.atomic.rmw.cmpxchg", TokenType::AtomicRmwCmpxchg, Opcode::I32AtomicRmwCmpxchg}, +#line 125 "./lexer-keywords.txt" + {"f64.convert_i32_s", TokenType::Convert, Opcode::F64ConvertI32S }, +#line 63 "./lexer-keywords.txt" + {"f32.convert_i32_s", TokenType::Convert, Opcode::F32ConvertI32S }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 29 "./lexer-keywords.txt" + {"assert_trap", TokenType::AssertTrap }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 494 "./lexer-keywords.txt" + {"i64x2.shr_u", TokenType::Binary, Opcode::I64X2ShrU }, {""}, -#line 405 "src/lexer-keywords.txt" - {"i64.atomic.store32", TokenType::AtomicStore, Opcode::I64AtomicStore32}, +#line 493 "./lexer-keywords.txt" + {"i64x2.shr_s", TokenType::Binary, Opcode::I64X2ShrS }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, +#line 157 "./lexer-keywords.txt" + {"f64x2.floor", TokenType::Unary, Opcode::F64X2Floor }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 610 "./lexer-keywords.txt" + {"br_on_cast_fail", TokenType::BrOnCastFail, Opcode::BrOnCastFail }, {""}, {""}, -#line 126 "src/lexer-keywords.txt" - {"f64.convert_i64_u", TokenType::Convert, Opcode::F64ConvertI64U}, -#line 64 "src/lexer-keywords.txt" - {"f32.convert_i64_u", TokenType::Convert, Opcode::F32ConvertI64U}, +#line 129 "./lexer-keywords.txt" + {"f64.copysign", TokenType::Binary, Opcode::F64Copysign }, +#line 67 "./lexer-keywords.txt" + {"f32.copysign", TokenType::Binary, Opcode::F32Copysign }, + {""}, +#line 528 "./lexer-keywords.txt" + {"i8x16.popcnt", TokenType::Unary, Opcode::I8X16Popcnt }, + {""}, +#line 424 "./lexer-keywords.txt" + {"i64.eqz", TokenType::Convert, Opcode::I64Eqz }, +#line 280 "./lexer-keywords.txt" + {"i32.eqz", TokenType::Convert, Opcode::I32Eqz }, + {""}, {""}, {""}, {""}, +#line 169 "./lexer-keywords.txt" + {"f64x2.pmin", TokenType::Binary, Opcode::F64X2PMin }, + {""}, +#line 535 "./lexer-keywords.txt" + {"i8x16.shr_u", TokenType::Binary, Opcode::I8X16ShrU }, + {""}, +#line 534 "./lexer-keywords.txt" + {"i8x16.shr_s", TokenType::Binary, Opcode::I8X16ShrS }, {""}, {""}, -#line 125 "src/lexer-keywords.txt" - {"f64.convert_i64_s", TokenType::Convert, Opcode::F64ConvertI64S}, -#line 63 "src/lexer-keywords.txt" - {"f32.convert_i64_s", TokenType::Convert, Opcode::F32ConvertI64S}, -#line 594 "src/lexer-keywords.txt" - {"v128.any_true", TokenType::Unary, Opcode::V128AnyTrue}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 530 "./lexer-keywords.txt" + {"i8x16.relaxed_swizzle", TokenType::Binary, Opcode::I8X16RelaxedSwizzle }, {""}, {""}, {""}, {""}, {""}, -#line 317 "src/lexer-keywords.txt" - {"i32.wrap_i64", TokenType::Convert, Opcode::I32WrapI64}, -#line 26 "src/lexer-keywords.txt" - {"assert_return", TokenType::AssertReturn}, - {""}, {""}, {""}, -#line 377 "src/lexer-keywords.txt" - {"i64.atomic.rmw16.and_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw16AndU}, -#line 247 "src/lexer-keywords.txt" - {"i32.atomic.rmw16.and_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw16AndU}, - {""}, {""}, {""}, -#line 376 "src/lexer-keywords.txt" - {"i64.atomic.rmw16.add_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw16AddU}, -#line 246 "src/lexer-keywords.txt" - {"i32.atomic.rmw16.add_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw16AddU}, - {""}, {""}, {""}, {""}, {""}, -#line 394 "src/lexer-keywords.txt" - {"i64.atomic.rmw8.sub_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw8SubU}, -#line 257 "src/lexer-keywords.txt" - {"i32.atomic.rmw8.sub_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw8SubU}, +#line 41 "./lexer-keywords.txt" + {"catch", TokenType::Catch, Opcode::Catch }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 514 "src/lexer-keywords.txt" - {"i8x16.min_u", TokenType::Binary, Opcode::I8X16MinU}, -#line 226 "src/lexer-keywords.txt" - {"i16x8.splat", TokenType::Unary, Opcode::I16X8Splat}, -#line 513 "src/lexer-keywords.txt" - {"i8x16.min_s", TokenType::Binary, Opcode::I8X16MinS}, +#line 199 "./lexer-keywords.txt" + {"i16x8.bitmask", TokenType::Unary, Opcode::I16X8Bitmask }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, -#line 379 "src/lexer-keywords.txt" - {"i64.atomic.rmw16.or_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw16OrU}, -#line 249 "src/lexer-keywords.txt" - {"i32.atomic.rmw16.or_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw16OrU}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, -#line 155 "src/lexer-keywords.txt" - {"f64x2.floor", TokenType::Unary, Opcode::F64X2Floor}, - {""}, {""}, {""}, {""}, {""}, -#line 31 "src/lexer-keywords.txt" - {"binary", TokenType::Bin}, -#line 175 "src/lexer-keywords.txt" - {"f64x2.sub", TokenType::Binary, Opcode::F64X2Sub}, - {""}, {""}, -#line 502 "src/lexer-keywords.txt" - {"i8x16.extract_lane_u", TokenType::SimdLaneOp, Opcode::I8X16ExtractLaneU}, - {""}, -#line 501 "src/lexer-keywords.txt" - {"i8x16.extract_lane_s", TokenType::SimdLaneOp, Opcode::I8X16ExtractLaneS}, -#line 149 "src/lexer-keywords.txt" - {"f64x2.abs", TokenType::Unary, Opcode::F64X2Abs}, -#line 486 "src/lexer-keywords.txt" - {"i64x2.sub", TokenType::Binary, Opcode::I64X2Sub}, - {""}, -#line 381 "src/lexer-keywords.txt" - {"i64.atomic.rmw16.xchg_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw16XchgU}, -#line 251 "src/lexer-keywords.txt" - {"i32.atomic.rmw16.xchg_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw16XchgU}, - {""}, {""}, -#line 472 "src/lexer-keywords.txt" - {"i64x2.abs", TokenType::Unary, Opcode::I64X2Abs}, -#line 540 "src/lexer-keywords.txt" - {"loop", TokenType::Loop, Opcode::Loop}, -#line 167 "src/lexer-keywords.txt" - {"f64x2.pmin", TokenType::Binary, Opcode::F64X2PMin}, - {""}, {""}, {""}, {""}, {""}, -#line 574 "src/lexer-keywords.txt" - {"table.copy", TokenType::TableCopy, Opcode::TableCopy}, -#line 549 "src/lexer-keywords.txt" - {"memory", TokenType::Memory}, - {""}, {""}, {""}, {""}, {""}, {""}, -#line 152 "src/lexer-keywords.txt" - {"f64x2.div", TokenType::Binary, Opcode::F64X2Div}, - {""}, {""}, {""}, {""}, {""}, {""}, -#line 546 "src/lexer-keywords.txt" - {"memory.grow", TokenType::MemoryGrow, Opcode::MemoryGrow}, + {""}, +#line 391 "./lexer-keywords.txt" + {"i64.atomic.rmw16.xchg_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw16XchgU }, +#line 255 "./lexer-keywords.txt" + {"i32.atomic.rmw16.xchg_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw16XchgU }, +#line 353 "./lexer-keywords.txt" + {"i32x4.dot_i16x8_s", TokenType::Binary, Opcode::I32X4DotI16X8S }, {""}, {""}, {""}, {""}, {""}, {""}, -#line 438 "src/lexer-keywords.txt" - {"i64.popcnt", TokenType::Unary, Opcode::I64Popcnt}, -#line 295 "src/lexer-keywords.txt" - {"i32.popcnt", TokenType::Unary, Opcode::I32Popcnt}, +#line 217 "./lexer-keywords.txt" + {"i16x8.min_u", TokenType::Binary, Opcode::I16X8MinU }, + {""}, +#line 216 "./lexer-keywords.txt" + {"i16x8.min_s", TokenType::Binary, Opcode::I16X8MinS }, + {""}, +#line 392 "./lexer-keywords.txt" + {"i64.atomic.rmw16.xor_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw16XorU }, +#line 256 "./lexer-keywords.txt" + {"i32.atomic.rmw16.xor_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw16XorU }, +#line 423 "./lexer-keywords.txt" + {"i64.eq", TokenType::Compare, Opcode::I64Eq }, +#line 279 "./lexer-keywords.txt" + {"i32.eq", TokenType::Compare, Opcode::I32Eq }, + {""}, +#line 603 "./lexer-keywords.txt" + {"array.fill", TokenType::ArrayFill, Opcode::ArrayFill }, +#line 131 "./lexer-keywords.txt" + {"f64.eq", TokenType::Compare, Opcode::F64Eq }, +#line 70 "./lexer-keywords.txt" + {"f32.eq", TokenType::Compare, Opcode::F32Eq }, +#line 574 "./lexer-keywords.txt" + {"ref.eq", TokenType::RefEq, Opcode::RefEq }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 525 "src/lexer-keywords.txt" - {"i8x16.shr_u", TokenType::Binary, Opcode::I8X16ShrU}, +#line 191 "./lexer-keywords.txt" + {"global.set", TokenType::GlobalSet, Opcode::GlobalSet }, {""}, -#line 524 "src/lexer-keywords.txt" - {"i8x16.shr_s", TokenType::Binary, Opcode::I8X16ShrS}, +#line 190 "./lexer-keywords.txt" + {"global.get", TokenType::GlobalGet, Opcode::GlobalGet }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 192 "./lexer-keywords.txt" + {"global", TokenType::Global }, + {""}, {""}, {""}, +#line 333 "./lexer-keywords.txt" + {"i32x4.eq", TokenType::Compare, Opcode::I32X4Eq }, + {""}, {""}, {""}, +#line 95 "./lexer-keywords.txt" + {"f32x4.eq", TokenType::Compare, Opcode::F32X4Eq }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 327 "./lexer-keywords.txt" + {"i32.wrap_i64", TokenType::Convert, Opcode::I32WrapI64 }, +#line 227 "./lexer-keywords.txt" + {"i16x8.shl", TokenType::Binary, Opcode::I16X8Shl }, + {""}, {""}, {""}, +#line 24 "./lexer-keywords.txt" + {"assert_exception", TokenType::AssertException }, + {""}, {""}, {""}, {""}, {""}, {""}, +#line 469 "./lexer-keywords.txt" + {"i64.trunc_sat_f64_u", TokenType::Convert, Opcode::I64TruncSatF64U }, +#line 319 "./lexer-keywords.txt" + {"i32.trunc_sat_f64_u", TokenType::Convert, Opcode::I32TruncSatF64U }, {""}, {""}, -#line 478 "src/lexer-keywords.txt" - {"i64x2.extend_low_i32x4_u", TokenType::Unary, Opcode::I64X2ExtendLowI32X4U}, - {""}, -#line 476 "src/lexer-keywords.txt" - {"i64x2.extend_low_i32x4_s", TokenType::Unary, Opcode::I64X2ExtendLowI32X4S}, - {""}, {""}, -#line 459 "src/lexer-keywords.txt" - {"i64.trunc_sat_f64_u", TokenType::Convert, Opcode::I64TruncSatF64U}, -#line 315 "src/lexer-keywords.txt" - {"i32.trunc_sat_f64_u", TokenType::Convert, Opcode::I32TruncSatF64U}, - {""}, -#line 343 "src/lexer-keywords.txt" - {"i32x4.dot_i16x8_s", TokenType::Binary, Opcode::I32X4DotI16X8S}, -#line 458 "src/lexer-keywords.txt" - {"i64.trunc_sat_f64_s", TokenType::Convert, Opcode::I64TruncSatF64S}, -#line 314 "src/lexer-keywords.txt" - {"i32.trunc_sat_f64_s", TokenType::Convert, Opcode::I32TruncSatF64S}, - {""}, -#line 554 "src/lexer-keywords.txt" - {"nop", TokenType::Nop, Opcode::Nop}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 468 "./lexer-keywords.txt" + {"i64.trunc_sat_f64_s", TokenType::Convert, Opcode::I64TruncSatF64S }, +#line 318 "./lexer-keywords.txt" + {"i32.trunc_sat_f64_s", TokenType::Convert, Opcode::I32TruncSatF64S }, {""}, {""}, {""}, -#line 382 "src/lexer-keywords.txt" - {"i64.atomic.rmw16.xor_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw16XorU}, -#line 252 "src/lexer-keywords.txt" - {"i32.atomic.rmw16.xor_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw16XorU}, +#line 642 "./lexer-keywords.txt" + {"v128.load16_splat", TokenType::Load, Opcode::V128Load16Splat }, + {""}, {""}, {""}, {""}, {""}, {""}, +#line 402 "./lexer-keywords.txt" + {"i64.atomic.rmw8.cmpxchg_u", TokenType::AtomicRmwCmpxchg, Opcode::I64AtomicRmw8CmpxchgU }, +#line 259 "./lexer-keywords.txt" + {"i32.atomic.rmw8.cmpxchg_u", TokenType::AtomicRmwCmpxchg, Opcode::I32AtomicRmw8CmpxchgU }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 194 "src/lexer-keywords.txt" - {"i16x8.avgr_u", TokenType::Binary, Opcode::I16X8AvgrU}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 479 "src/lexer-keywords.txt" - {"i64x2.extend_high_i32x4_u", TokenType::Unary, Opcode::I64X2ExtendHighI32X4U}, - {""}, -#line 477 "src/lexer-keywords.txt" - {"i64x2.extend_high_i32x4_s", TokenType::Unary, Opcode::I64X2ExtendHighI32X4S}, - {""}, {""}, {""}, {""}, -#line 129 "src/lexer-keywords.txt" - {"f64.eq", TokenType::Compare, Opcode::F64Eq}, -#line 68 "src/lexer-keywords.txt" - {"f32.eq", TokenType::Compare, Opcode::F32Eq}, +#line 25 "./lexer-keywords.txt" + {"assert_exhaustion", TokenType::AssertExhaustion }, +#line 409 "./lexer-keywords.txt" + {"i64.atomic.rmw.cmpxchg", TokenType::AtomicRmwCmpxchg, Opcode::I64AtomicRmwCmpxchg }, +#line 266 "./lexer-keywords.txt" + {"i32.atomic.rmw.cmpxchg", TokenType::AtomicRmwCmpxchg, Opcode::I32AtomicRmwCmpxchg }, {""}, {""}, {""}, {""}, {""}, -#line 413 "src/lexer-keywords.txt" - {"i64.eq", TokenType::Compare, Opcode::I64Eq}, -#line 275 "src/lexer-keywords.txt" - {"i32.eq", TokenType::Compare, Opcode::I32Eq}, - {""}, -#line 613 "src/lexer-keywords.txt" - {"i8x16.swizzle", TokenType::Binary, Opcode::I8X16Swizzle}, +#line 49 "./lexer-keywords.txt" + {"drop", TokenType::Drop, Opcode::Drop }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 647 "./lexer-keywords.txt" + {"v128.load16_lane", TokenType::SimdLoadLane, Opcode::V128Load16Lane }, +#line 552 "./lexer-keywords.txt" + {"memory.atomic.wait32", TokenType::AtomicWait, Opcode::MemoryAtomicWait32 }, {""}, {""}, -#line 526 "src/lexer-keywords.txt" - {"i8x16.splat", TokenType::Unary, Opcode::I8X16Splat}, +#line 612 "./lexer-keywords.txt" + {"extern.convert_any", TokenType::ExternConvertAny, Opcode::ExternConvertAny }, {""}, {""}, -#line 117 "src/lexer-keywords.txt" - {"f32x4.demote_f64x2_zero", TokenType::Unary, Opcode::F32X4DemoteF64X2Zero}, +#line 346 "./lexer-keywords.txt" + {"v128.load16x4_u", TokenType::Load, Opcode::V128Load16X4U }, + {""}, {""}, {""}, +#line 345 "./lexer-keywords.txt" + {"v128.load16x4_s", TokenType::Load, Opcode::V128Load16X4S }, +#line 324 "./lexer-keywords.txt" + {"eq", Type::Eq, TokenType::Eq }, {""}, -#line 489 "src/lexer-keywords.txt" - {"i64x2.extmul_low_i32x4_u", TokenType::Binary, Opcode::I64X2ExtmulLowI32X4U}, +#line 564 "./lexer-keywords.txt" + {"nop", TokenType::Nop, Opcode::Nop }, + {""}, {""}, +#line 553 "./lexer-keywords.txt" + {"memory.atomic.wait64", TokenType::AtomicWait, Opcode::MemoryAtomicWait64 }, +#line 611 "./lexer-keywords.txt" + {"any.convert_extern", TokenType::AnyConvertExtern, Opcode::AnyConvertExtern }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, +#line 230 "./lexer-keywords.txt" + {"i16x8.splat", TokenType::Unary, Opcode::I16X8Splat }, {""}, -#line 487 "src/lexer-keywords.txt" - {"i64x2.extmul_low_i32x4_s", TokenType::Binary, Opcode::I64X2ExtmulLowI32X4S}, - {""}, {""}, {""}, -#line 93 "src/lexer-keywords.txt" - {"f32x4.eq", TokenType::Compare, Opcode::F32X4Eq}, +#line 58 "./lexer-keywords.txt" + {"export", TokenType::Export }, {""}, {""}, {""}, {""}, -#line 33 "src/lexer-keywords.txt" - {"br_if", TokenType::BrIf, Opcode::BrIf}, +#line 93 "./lexer-keywords.txt" + {"f32x4.convert_i32x4_u", TokenType::Unary, Opcode::F32X4ConvertI32X4U }, {""}, -#line 323 "src/lexer-keywords.txt" - {"i32x4.eq", TokenType::Compare, Opcode::I32X4Eq}, - {""}, {""}, {""}, -#line 368 "src/lexer-keywords.txt" - {"i32x4.trunc_sat_f64x2_u_zero", TokenType::Unary, Opcode::I32X4TruncSatF64X2UZero}, +#line 92 "./lexer-keywords.txt" + {"f32x4.convert_i32x4_s", TokenType::Unary, Opcode::F32X4ConvertI32X4S }, +#line 203 "./lexer-keywords.txt" + {"i16x8.extract_lane_u", TokenType::SimdLaneOp, Opcode::I16X8ExtractLaneU }, {""}, -#line 367 "src/lexer-keywords.txt" - {"i32x4.trunc_sat_f64x2_s_zero", TokenType::Unary, Opcode::I32X4TruncSatF64X2SZero}, +#line 202 "./lexer-keywords.txt" + {"i16x8.extract_lane_s", TokenType::SimdLaneOp, Opcode::I16X8ExtractLaneS }, {""}, -#line 25 "src/lexer-keywords.txt" - {"assert_malformed", TokenType::AssertMalformed}, -#line 166 "src/lexer-keywords.txt" - {"f64x2.pmax", TokenType::Binary, Opcode::F64X2PMax}, - {""}, {""}, {""}, -#line 56 "src/lexer-keywords.txt" - {"export", TokenType::Export}, - {""}, {""}, {""}, {""}, -#line 229 "src/lexer-keywords.txt" - {"i16x8.sub", TokenType::Binary, Opcode::I16X8Sub}, - {""}, {""}, -#line 589 "src/lexer-keywords.txt" - {"v128.bitselect", TokenType::Ternary, Opcode::V128BitSelect}, +#line 108 "./lexer-keywords.txt" + {"f32x4.pmax", TokenType::Binary, Opcode::F32X4PMax }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 372 "./lexer-keywords.txt" + {"i32x4.trunc_sat_f32x4_u", TokenType::Unary, Opcode::I32X4TruncSatF32X4U }, {""}, {""}, -#line 189 "src/lexer-keywords.txt" - {"i16x8.abs", TokenType::Unary, Opcode::I16X8Abs}, -#line 490 "src/lexer-keywords.txt" - {"i64x2.extmul_high_i32x4_u", TokenType::Binary, Opcode::I64X2ExtmulHighI32X4U}, +#line 365 "./lexer-keywords.txt" + {"i32x4.extadd_pairwise_i16x8_u", TokenType::Unary, Opcode::I32X4ExtaddPairwiseI16X8U }, +#line 371 "./lexer-keywords.txt" + {"i32x4.trunc_sat_f32x4_s", TokenType::Unary, Opcode::I32X4TruncSatF32X4S }, +#line 364 "./lexer-keywords.txt" + {"i32x4.extadd_pairwise_i16x8_s", TokenType::Unary, Opcode::I32X4ExtaddPairwiseI16X8S }, + {""}, {""}, {""}, {""}, {""}, {""}, +#line 405 "./lexer-keywords.txt" + {"i64.atomic.rmw8.xchg_u", TokenType::AtomicRmw, Opcode::I64AtomicRmw8XchgU }, +#line 262 "./lexer-keywords.txt" + {"i32.atomic.rmw8.xchg_u", TokenType::AtomicRmw, Opcode::I32AtomicRmw8XchgU }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, +#line 550 "./lexer-keywords.txt" + {"loop", TokenType::Loop, Opcode::Loop }, +#line 488 "./lexer-keywords.txt" + {"i64x2.extend_low_i32x4_u", TokenType::Unary, Opcode::I64X2ExtendLowI32X4U }, {""}, -#line 488 "src/lexer-keywords.txt" - {"i64x2.extmul_high_i32x4_s", TokenType::Binary, Opcode::I64X2ExtmulHighI32X4S}, -#line 545 "src/lexer-keywords.txt" - {"memory.fill", TokenType::MemoryFill, Opcode::MemoryFill}, +#line 486 "./lexer-keywords.txt" + {"i64x2.extend_low_i32x4_s", TokenType::Unary, Opcode::I64X2ExtendLowI32X4S }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, -#line 322 "src/lexer-keywords.txt" - {"i32x4.dot_i8x16_i7x16_add_s", TokenType::Ternary, Opcode::I32X4DotI8X16I7X16AddS}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, +#line 613 "./lexer-keywords.txt" + {"ref.i31", TokenType::RefI31, Opcode::RefI31 }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 127 "src/lexer-keywords.txt" - {"f64.copysign", TokenType::Binary, Opcode::F64Copysign}, -#line 65 "src/lexer-keywords.txt" - {"f32.copysign", TokenType::Binary, Opcode::F32Copysign}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 404 "src/lexer-keywords.txt" - {"i64.atomic.store16", TokenType::AtomicStore, Opcode::I64AtomicStore16}, -#line 267 "src/lexer-keywords.txt" - {"i32.atomic.store16", TokenType::AtomicStore, Opcode::I32AtomicStore16}, - {""}, {""}, {""}, -#line 475 "src/lexer-keywords.txt" - {"i64x2.bitmask", TokenType::Unary, Opcode::I64X2Bitmask}, +#line 448 "./lexer-keywords.txt" + {"i64.popcnt", TokenType::Unary, Opcode::I64Popcnt }, +#line 299 "./lexer-keywords.txt" + {"i32.popcnt", TokenType::Unary, Opcode::I32Popcnt }, + {""}, {""}, {""}, {""}, {""}, +#line 225 "./lexer-keywords.txt" + {"i16x8.relaxed_q15mulr_s", TokenType::Binary, Opcode::I16X8RelaxedQ15mulrS }, +#line 119 "./lexer-keywords.txt" + {"f32x4.demote_f64x2_zero", TokenType::Unary, Opcode::F32X4DemoteF64X2Zero }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, +#line 499 "./lexer-keywords.txt" + {"i64x2.extmul_low_i32x4_u", TokenType::Binary, Opcode::I64X2ExtmulLowI32X4U }, + {""}, +#line 497 "./lexer-keywords.txt" + {"i64x2.extmul_low_i32x4_s", TokenType::Binary, Opcode::I64X2ExtmulLowI32X4S }, +#line 414 "./lexer-keywords.txt" + {"i64.atomic.store16", TokenType::AtomicStore, Opcode::I64AtomicStore16 }, +#line 271 "./lexer-keywords.txt" + {"i32.atomic.store16", TokenType::AtomicStore, Opcode::I32AtomicStore16 }, + {""}, {""}, {""}, +#line 378 "./lexer-keywords.txt" + {"i32x4.trunc_sat_f64x2_u_zero", TokenType::Unary, Opcode::I32X4TruncSatF64X2UZero }, {""}, -#line 518 "src/lexer-keywords.txt" - {"i8x16.popcnt", TokenType::Unary, Opcode::I8X16Popcnt}, +#line 377 "./lexer-keywords.txt" + {"i32x4.trunc_sat_f64x2_s_zero", TokenType::Unary, Opcode::I32X4TruncSatF64X2SZero }, {""}, {""}, {""}, {""}, {""}, {""}, -#line 55 "src/lexer-keywords.txt" - {"externref", Type::ExternRef}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 221 "src/lexer-keywords.txt" - {"i16x8.relaxed_q15mulr_s", TokenType::Binary, Opcode::I16X8RelaxedQ15mulrS}, +#line 229 "./lexer-keywords.txt" + {"i16x8.shr_u", TokenType::Binary, Opcode::I16X8ShrU }, + {""}, +#line 228 "./lexer-keywords.txt" + {"i16x8.shr_s", TokenType::Binary, Opcode::I16X8ShrS }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, +#line 35 "./lexer-keywords.txt" + {"br_if", TokenType::BrIf, Opcode::BrIf }, +#line 145 "./lexer-keywords.txt" + {"f64.reinterpret_i64", TokenType::Convert, Opcode::F64ReinterpretI64 }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 182 "src/lexer-keywords.txt" - {"funcref", Type::FuncRef}, {""}, {""}, {""}, {""}, {""}, -#line 91 "src/lexer-keywords.txt" - {"f32x4.convert_i32x4_u", TokenType::Unary, Opcode::F32X4ConvertI32X4U}, - {""}, -#line 90 "src/lexer-keywords.txt" - {"f32x4.convert_i32x4_s", TokenType::Unary, Opcode::F32X4ConvertI32X4S}, -#line 50 "src/lexer-keywords.txt" - {"elem", TokenType::Elem}, +#line 551 "./lexer-keywords.txt" + {"memory.atomic.notify", TokenType::AtomicNotify, Opcode::MemoryAtomicNotify }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 57 "./lexer-keywords.txt" + {"externref", Type::ExternRef }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 184 "./lexer-keywords.txt" + {"funcref", Type::FuncRef }, +#line 476 "./lexer-keywords.txt" + {"i64x2.eq", TokenType::Binary, Opcode::I64X2Eq }, {""}, {""}, -#line 498 "src/lexer-keywords.txt" - {"i8x16.avgr_u", TokenType::Binary, Opcode::I8X16AvgrU}, +#line 52 "./lexer-keywords.txt" + {"elem", TokenType::Elem }, +#line 155 "./lexer-keywords.txt" + {"f64x2.eq", TokenType::Compare, Opcode::F64X2Eq }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 362 "src/lexer-keywords.txt" - {"i32x4.trunc_sat_f32x4_u", TokenType::Unary, Opcode::I32X4TruncSatF32X4U}, - {""}, {""}, {""}, -#line 361 "src/lexer-keywords.txt" - {"i32x4.trunc_sat_f32x4_s", TokenType::Unary, Opcode::I32X4TruncSatF32X4S}, +#line 467 "./lexer-keywords.txt" + {"i64.trunc_sat_f32_u", TokenType::Convert, Opcode::I64TruncSatF32U }, +#line 317 "./lexer-keywords.txt" + {"i32.trunc_sat_f32_u", TokenType::Convert, Opcode::I32TruncSatF32U }, + {""}, {""}, +#line 466 "./lexer-keywords.txt" + {"i64.trunc_sat_f32_s", TokenType::Convert, Opcode::I64TruncSatF32S }, +#line 316 "./lexer-keywords.txt" + {"i32.trunc_sat_f32_s", TokenType::Convert, Opcode::I32TruncSatF32S }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 240 "src/lexer-keywords.txt" - {"i16x8.extend_low_i8x16_u", TokenType::Unary, Opcode::I16X8ExtendLowI8X16U}, +#line 388 "./lexer-keywords.txt" + {"i64.atomic.rmw16.cmpxchg_u", TokenType::AtomicRmwCmpxchg, Opcode::I64AtomicRmw16CmpxchgU }, +#line 252 "./lexer-keywords.txt" + {"i32.atomic.rmw16.cmpxchg_u", TokenType::AtomicRmwCmpxchg, Opcode::I32AtomicRmw16CmpxchgU }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 510 "./lexer-keywords.txt" + {"i8x16.eq", TokenType::Compare, Opcode::I8X16Eq }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, +#line 180 "./lexer-keywords.txt" + {"f64x2.convert_low_i32x4_u", TokenType::Unary, Opcode::F64X2ConvertLowI32X4U }, {""}, -#line 239 "src/lexer-keywords.txt" - {"i16x8.extend_low_i8x16_s", TokenType::Unary, Opcode::I16X8ExtendLowI8X16S}, - {""}, {""}, {""}, {""}, {""}, -#line 336 "src/lexer-keywords.txt" - {"v128.load16x4_u", TokenType::Load, Opcode::V128Load16X4U}, - {""}, {""}, {""}, -#line 335 "src/lexer-keywords.txt" - {"v128.load16x4_s", TokenType::Load, Opcode::V128Load16X4S}, - {""}, {""}, {""}, -#line 378 "src/lexer-keywords.txt" - {"i64.atomic.rmw16.cmpxchg_u", TokenType::AtomicRmwCmpxchg, Opcode::I64AtomicRmw16CmpxchgU}, -#line 248 "src/lexer-keywords.txt" - {"i32.atomic.rmw16.cmpxchg_u", TokenType::AtomicRmwCmpxchg, Opcode::I32AtomicRmw16CmpxchgU}, - {""}, {""}, {""}, {""}, {""}, {""}, -#line 216 "src/lexer-keywords.txt" - {"i16x8.narrow_i32x4_u", TokenType::Binary, Opcode::I16X8NarrowI32X4U}, - {""}, -#line 215 "src/lexer-keywords.txt" - {"i16x8.narrow_i32x4_s", TokenType::Binary, Opcode::I16X8NarrowI32X4S}, - {""}, {""}, -#line 128 "src/lexer-keywords.txt" - {"f64.div", TokenType::Binary, Opcode::F64Div}, -#line 67 "src/lexer-keywords.txt" - {"f32.div", TokenType::Binary, Opcode::F32Div}, - {""}, {""}, -#line 124 "src/lexer-keywords.txt" - {"f64.convert_i32_u", TokenType::Convert, Opcode::F64ConvertI32U}, -#line 62 "src/lexer-keywords.txt" - {"f32.convert_i32_u", TokenType::Convert, Opcode::F32ConvertI32U}, - {""}, {""}, -#line 123 "src/lexer-keywords.txt" - {"f64.convert_i32_s", TokenType::Convert, Opcode::F64ConvertI32S}, -#line 61 "src/lexer-keywords.txt" - {"f32.convert_i32_s", TokenType::Convert, Opcode::F32ConvertI32S}, - {""}, {""}, {""}, {""}, {""}, {""}, -#line 529 "src/lexer-keywords.txt" - {"i8x16.sub", TokenType::Binary, Opcode::I8X16Sub}, - {""}, {""}, {""}, -#line 23 "src/lexer-keywords.txt" - {"assert_exhaustion", TokenType::AssertExhaustion}, +#line 179 "./lexer-keywords.txt" + {"f64x2.convert_low_i32x4_s", TokenType::Unary, Opcode::F64X2ConvertLowI32X4S }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 493 "src/lexer-keywords.txt" - {"i8x16.abs", TokenType::Unary, Opcode::I8X16Abs}, +#line 220 "./lexer-keywords.txt" + {"i16x8.narrow_i32x4_u", TokenType::Binary, Opcode::I16X8NarrowI32X4U }, + {""}, +#line 219 "./lexer-keywords.txt" + {"i16x8.narrow_i32x4_s", TokenType::Binary, Opcode::I16X8NarrowI32X4S }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, -#line 234 "src/lexer-keywords.txt" - {"i16x8.extmul_low_i8x16_u", TokenType::Binary, Opcode::I16X8ExtmulLowI8X16U}, {""}, -#line 232 "src/lexer-keywords.txt" - {"i16x8.extmul_low_i8x16_s", TokenType::Binary, Opcode::I16X8ExtmulLowI8X16S}, +#line 168 "./lexer-keywords.txt" + {"f64x2.pmax", TokenType::Binary, Opcode::F64X2PMax }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 195 "src/lexer-keywords.txt" - {"i16x8.bitmask", TokenType::Unary, Opcode::I16X8Bitmask}, - {""}, {""}, {""}, {""}, {""}, -#line 146 "src/lexer-keywords.txt" - {"f64.sub", TokenType::Binary, Opcode::F64Sub}, -#line 84 "src/lexer-keywords.txt" - {"f32.sub", TokenType::Binary, Opcode::F32Sub}, {""}, {""}, {""}, {""}, {""}, -#line 451 "src/lexer-keywords.txt" - {"i64.sub", TokenType::Binary, Opcode::I64Sub}, -#line 307 "src/lexer-keywords.txt" - {"i32.sub", TokenType::Binary, Opcode::I32Sub}, +#line 654 "./lexer-keywords.txt" + {"i8x16.shuffle", TokenType::SimdShuffleOp, Opcode::I8X16Shuffle }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 543 "src/lexer-keywords.txt" - {"memory.atomic.wait64", TokenType::AtomicWait, Opcode::MemoryAtomicWait64}, - {""}, {""}, {""}, -#line 231 "src/lexer-keywords.txt" - {"i16x8.extadd_pairwise_i8x16_u", TokenType::Unary, Opcode::I16X8ExtaddPairwiseI8X16U}, - {""}, -#line 230 "src/lexer-keywords.txt" - {"i16x8.extadd_pairwise_i8x16_s", TokenType::Unary, Opcode::I16X8ExtaddPairwiseI8X16S}, +#line 144 "./lexer-keywords.txt" + {"f64.promote_f32", TokenType::Convert, Opcode::F64PromoteF32 }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 238 "src/lexer-keywords.txt" - {"i16x8.extend_high_i8x16_u", TokenType::Unary, Opcode::I16X8ExtendHighI8X16U}, +#line 376 "./lexer-keywords.txt" + {"i32x4.extend_low_i16x8_u", TokenType::Unary, Opcode::I32X4ExtendLowI16X8U }, {""}, -#line 237 "src/lexer-keywords.txt" - {"i16x8.extend_high_i8x16_s", TokenType::Unary, Opcode::I16X8ExtendHighI8X16S}, +#line 375 "./lexer-keywords.txt" + {"i32x4.extend_low_i16x8_s", TokenType::Unary, Opcode::I32X4ExtendLowI16X8S }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 439 "src/lexer-keywords.txt" - {"i64.reinterpret_f64", TokenType::Convert, Opcode::I64ReinterpretF64}, -#line 600 "src/lexer-keywords.txt" - {"v128.load16_splat", TokenType::Load, Opcode::V128Load16Splat}, - {""}, {""}, -#line 27 "src/lexer-keywords.txt" - {"assert_trap", TokenType::AssertTrap}, - {""}, {""}, {""}, -#line 81 "src/lexer-keywords.txt" - {"f32.reinterpret_i32", TokenType::Convert, Opcode::F32ReinterpretI32}, +#line 83 "./lexer-keywords.txt" + {"f32.reinterpret_i32", TokenType::Convert, Opcode::F32ReinterpretI32 }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, -#line 366 "src/lexer-keywords.txt" - {"i32x4.extend_low_i16x8_u", TokenType::Unary, Opcode::I32X4ExtendLowI16X8U}, + {""}, {""}, {""}, {""}, +#line 368 "./lexer-keywords.txt" + {"i32x4.extmul_low_i16x8_u", TokenType::Binary, Opcode::I32X4ExtmulLowI16X8U }, {""}, -#line 365 "src/lexer-keywords.txt" - {"i32x4.extend_low_i16x8_s", TokenType::Unary, Opcode::I32X4ExtendLowI16X8S}, - {""}, {""}, {""}, -#line 605 "src/lexer-keywords.txt" - {"v128.load16_lane", TokenType::SimdLoadLane, Opcode::V128Load16Lane}, +#line 366 "./lexer-keywords.txt" + {"i32x4.extmul_low_i16x8_s", TokenType::Binary, Opcode::I32X4ExtmulLowI16X8S }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 457 "src/lexer-keywords.txt" - {"i64.trunc_sat_f32_u", TokenType::Convert, Opcode::I64TruncSatF32U}, -#line 313 "src/lexer-keywords.txt" - {"i32.trunc_sat_f32_u", TokenType::Convert, Opcode::I32TruncSatF32U}, - {""}, {""}, -#line 456 "src/lexer-keywords.txt" - {"i64.trunc_sat_f32_s", TokenType::Convert, Opcode::I64TruncSatF32S}, -#line 312 "src/lexer-keywords.txt" - {"i32.trunc_sat_f32_s", TokenType::Convert, Opcode::I32TruncSatF32S}, - {""}, {""}, {""}, -#line 235 "src/lexer-keywords.txt" - {"i16x8.extmul_high_i8x16_u", TokenType::Binary, Opcode::I16X8ExtmulHighI8X16U}, +#line 374 "./lexer-keywords.txt" + {"i32x4.extend_high_i16x8_u", TokenType::Unary, Opcode::I32X4ExtendHighI16X8U }, {""}, -#line 233 "src/lexer-keywords.txt" - {"i16x8.extmul_high_i8x16_s", TokenType::Binary, Opcode::I16X8ExtmulHighI8X16S}, +#line 373 "./lexer-keywords.txt" + {"i32x4.extend_high_i16x8_s", TokenType::Unary, Opcode::I32X4ExtendHighI16X8S }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 358 "src/lexer-keywords.txt" - {"i32x4.extmul_low_i16x8_u", TokenType::Binary, Opcode::I32X4ExtmulLowI16X8U}, - {""}, -#line 356 "src/lexer-keywords.txt" - {"i32x4.extmul_low_i16x8_s", TokenType::Binary, Opcode::I32X4ExtmulLowI16X8S}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, -#line 612 "src/lexer-keywords.txt" - {"i8x16.shuffle", TokenType::SimdShuffleOp, Opcode::I8X16Shuffle}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 499 "src/lexer-keywords.txt" - {"i8x16.bitmask", TokenType::Unary, Opcode::I8X16Bitmask}, - {""}, {""}, -#line 153 "src/lexer-keywords.txt" - {"f64x2.eq", TokenType::Compare, Opcode::F64X2Eq}, - {""}, {""}, {""}, {""}, {""}, {""}, -#line 466 "src/lexer-keywords.txt" - {"i64x2.eq", TokenType::Binary, Opcode::I64X2Eq}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, +#line 39 "./lexer-keywords.txt" + {"call_ref", TokenType::CallRef, Opcode::CallRef }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, +#line 369 "./lexer-keywords.txt" + {"i32x4.extmul_high_i16x8_u", TokenType::Binary, Opcode::I32X4ExtmulHighI16X8U }, + {""}, +#line 367 "./lexer-keywords.txt" + {"i32x4.extmul_high_i16x8_s", TokenType::Binary, Opcode::I32X4ExtmulHighI16X8S }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 22 "src/lexer-keywords.txt" - {"assert_exception", TokenType::AssertException}, - {""}, {""}, {""}, {""}, {""}, -#line 37 "src/lexer-keywords.txt" - {"call_ref", TokenType::CallRef, Opcode::CallRef}, +#line 332 "./lexer-keywords.txt" + {"i32x4.dot_i8x16_i7x16_add_s", TokenType::Ternary, Opcode::I32X4DotI8X16I7X16AddS }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, +#line 31 "./lexer-keywords.txt" + {"atomic.fence", TokenType::AtomicFence, Opcode::AtomicFence }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 544 "src/lexer-keywords.txt" - {"memory.copy", TokenType::MemoryCopy, Opcode::MemoryCopy}, +#line 489 "./lexer-keywords.txt" + {"i64x2.extend_high_i32x4_u", TokenType::Unary, Opcode::I64X2ExtendHighI32X4U }, + {""}, +#line 487 "./lexer-keywords.txt" + {"i64x2.extend_high_i32x4_s", TokenType::Unary, Opcode::I64X2ExtendHighI32X4S }, + {""}, {""}, {""}, {""}, {""}, {""}, +#line 185 "./lexer-keywords.txt" + {"anyref",Type::Any }, + {""}, +#line 201 "./lexer-keywords.txt" + {"i16x8.eq", TokenType::Compare, Opcode::I16X8Eq }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, -#line 542 "src/lexer-keywords.txt" - {"memory.atomic.wait32", TokenType::AtomicWait, Opcode::MemoryAtomicWait32}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, -#line 142 "src/lexer-keywords.txt" - {"f64.promote_f32", TokenType::Convert, Opcode::F64PromoteF32}, - {""}, {""}, {""}, {""}, -#line 401 "src/lexer-keywords.txt" - {"i64.atomic.rmw.sub", TokenType::AtomicRmw, Opcode::I64AtomicRmwSub}, -#line 264 "src/lexer-keywords.txt" - {"i32.atomic.rmw.sub", TokenType::AtomicRmw, Opcode::I32AtomicRmwSub}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, {""}, {""}, -#line 24 "src/lexer-keywords.txt" - {"assert_invalid", TokenType::AssertInvalid}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 20 "src/lexer-keywords.txt" - {"array", Type::Array, TokenType::Array}, - {""}, {""}, {""}, {""}, -#line 197 "src/lexer-keywords.txt" - {"i16x8.eq", TokenType::Compare, Opcode::I16X8Eq}, +#line 500 "./lexer-keywords.txt" + {"i64x2.extmul_high_i32x4_u", TokenType::Binary, Opcode::I64X2ExtmulHighI32X4U }, + {""}, +#line 498 "./lexer-keywords.txt" + {"i64x2.extmul_high_i32x4_s", TokenType::Binary, Opcode::I64X2ExtmulHighI32X4S }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, {""}, {""}, -#line 196 "src/lexer-keywords.txt" - {"i16x8.dot_i8x16_i7x16_s", TokenType::Binary, Opcode::I16X8DotI8X16I7X16S}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 28 "src/lexer-keywords.txt" - {"assert_unlinkable", TokenType::AssertUnlinkable}, + {""}, {""}, {""}, {""}, {""}, {""}, +#line 244 "./lexer-keywords.txt" + {"i16x8.extend_low_i8x16_u", TokenType::Unary, Opcode::I16X8ExtendLowI8X16U }, + {""}, +#line 243 "./lexer-keywords.txt" + {"i16x8.extend_low_i8x16_s", TokenType::Unary, Opcode::I16X8ExtendLowI8X16S }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 449 "./lexer-keywords.txt" + {"i64.reinterpret_f64", TokenType::Convert, Opcode::I64ReinterpretF64 }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 238 "./lexer-keywords.txt" + {"i16x8.extmul_low_i8x16_u", TokenType::Binary, Opcode::I16X8ExtmulLowI8X16U }, + {""}, +#line 236 "./lexer-keywords.txt" + {"i16x8.extmul_low_i8x16_s", TokenType::Binary, Opcode::I16X8ExtmulLowI8X16S }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 178 "src/lexer-keywords.txt" - {"f64x2.convert_low_i32x4_u", TokenType::Unary, Opcode::F64X2ConvertLowI32X4U}, - {""}, -#line 177 "src/lexer-keywords.txt" - {"f64x2.convert_low_i32x4_s", TokenType::Unary, Opcode::F64X2ConvertLowI32X4S}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 235 "./lexer-keywords.txt" + {"i16x8.extadd_pairwise_i8x16_u", TokenType::Unary, Opcode::I16X8ExtaddPairwiseI8X16U }, {""}, -#line 500 "src/lexer-keywords.txt" - {"i8x16.eq", TokenType::Compare, Opcode::I8X16Eq}, +#line 234 "./lexer-keywords.txt" + {"i16x8.extadd_pairwise_i8x16_s", TokenType::Unary, Opcode::I16X8ExtaddPairwiseI8X16S }, + {""}, +#line 526 "./lexer-keywords.txt" + {"i8x16.narrow_i16x8_u", TokenType::Binary, Opcode::I8X16NarrowI16X8U }, + {""}, +#line 525 "./lexer-keywords.txt" + {"i8x16.narrow_i16x8_s", TokenType::Binary, Opcode::I8X16NarrowI16X8S }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, -#line 49 "src/lexer-keywords.txt" - {"elem.drop", TokenType::ElemDrop, Opcode::ElemDrop}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, @@ -1743,25 +1875,24 @@ Perfect_Hash::InWordSet (const char *str, size_t len) {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, -#line 29 "src/lexer-keywords.txt" - {"atomic.fence", TokenType::AtomicFence, Opcode::AtomicFence}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 51 "./lexer-keywords.txt" + {"elem.drop", TokenType::ElemDrop, Opcode::ElemDrop }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, +#line 222 "./lexer-keywords.txt" + {"i16x8.q15mulr_sat_s", TokenType::Binary, Opcode::I16X8Q15mulrSatS }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 541 "src/lexer-keywords.txt" - {"memory.atomic.notify", TokenType::AtomicNotify, Opcode::MemoryAtomicNotify}, - {""}, {""}, {""}, {""}, {""}, {""}, -#line 296 "src/lexer-keywords.txt" - {"i32.reinterpret_f32", TokenType::Convert, Opcode::I32ReinterpretF32}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, +#line 300 "./lexer-keywords.txt" + {"i32.reinterpret_f32", TokenType::Convert, Opcode::I32ReinterpretF32 }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, @@ -1778,31 +1909,45 @@ Perfect_Hash::InWordSet (const char *str, size_t len) {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, {""}, {""}, -#line 218 "src/lexer-keywords.txt" - {"i16x8.q15mulr_sat_s", TokenType::Binary, Opcode::I16X8Q15mulrSatS}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 181 "./lexer-keywords.txt" + {"f64x2.promote_low_f32x4", TokenType::Unary, Opcode::F64X2PromoteLowF32X4 }, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, - {""}, {""}, {""}, {""}, -#line 516 "src/lexer-keywords.txt" - {"i8x16.narrow_i16x8_u", TokenType::Binary, Opcode::I8X16NarrowI16X8U}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, +#line 200 "./lexer-keywords.txt" + {"i16x8.dot_i8x16_i7x16_s", TokenType::Binary, Opcode::I16X8DotI8X16I7X16S }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, +#line 242 "./lexer-keywords.txt" + {"i16x8.extend_high_i8x16_u", TokenType::Unary, Opcode::I16X8ExtendHighI8X16U }, {""}, -#line 515 "src/lexer-keywords.txt" - {"i8x16.narrow_i16x8_s", TokenType::Binary, Opcode::I8X16NarrowI16X8S}, +#line 241 "./lexer-keywords.txt" + {"i16x8.extend_high_i8x16_s", TokenType::Unary, Opcode::I16X8ExtendHighI8X16S }, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, + {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, +#line 239 "./lexer-keywords.txt" + {"i16x8.extmul_high_i8x16_u", TokenType::Binary, Opcode::I16X8ExtmulHighI8X16U }, {""}, -#line 179 "src/lexer-keywords.txt" - {"f64x2.promote_low_f32x4", TokenType::Unary, Opcode::F64X2PromoteLowF32X4} +#line 237 "./lexer-keywords.txt" + {"i16x8.extmul_high_i8x16_s", TokenType::Binary, Opcode::I16X8ExtmulHighI8X16S } }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) diff --git a/src/resolve-names.cc b/src/resolve-names.cc index 9fc8e4430..a166860b5 100644 --- a/src/resolve-names.cc +++ b/src/resolve-names.cc @@ -53,6 +53,27 @@ class NameResolver : public ExprVisitor::DelegateNop { Result EndIfExpr(IfExpr*) override; Result OnLoadExpr(LoadExpr*) override; Result OnLocalGetExpr(LocalGetExpr*) override; + Result OnStructNewExpr(StructNewExpr*) override; + Result OnStructNewDefaultExpr(StructNewDefaultExpr*) override; + Result OnStructGetExpr(StructGetExpr* expr) override; + Result OnStructGetSExpr(StructGetSExpr* expr) override; + Result OnStructGetUExpr(StructGetUExpr* expr) override; + Result OnStructSetExpr(StructSetExpr* expr) override; + Result OnArrayNewExpr(ArrayNewExpr*) override; + Result OnArrayNewDefaultExpr(ArrayNewDefaultExpr*) override; + Result OnArrayNewDataExpr(ArrayNewDataExpr*) override; + Result OnArrayNewFixedExpr(ArrayNewFixedExpr*) override; + Result OnArrayNewElemExpr(ArrayNewElemExpr*) override; + Result OnArrayGetExpr(ArrayGetExpr* expr) override; + Result OnArrayGetSExpr(ArrayGetSExpr* expr) override; + Result OnArrayGetUExpr(ArrayGetUExpr* expr) override; + Result OnArraySetExpr(ArraySetExpr* expr) override; + Result OnArrayFillExpr(ArrayFillExpr* expr) override; + Result OnArrayCopyExpr(ArrayCopyExpr* expr) override; + Result OnArrayInitDataExpr(ArrayInitDataExpr* expr) override; + Result OnArrayInitElemExpr(ArrayInitElemExpr* expr) override; + Result OnBrOnCastExpr(BrOnCastExpr*) override; + Result OnBrOnCastFailExpr(BrOnCastFailExpr*) override; Result OnLocalSetExpr(LocalSetExpr*) override; Result OnLocalTeeExpr(LocalTeeExpr*) override; Result BeginLoopExpr(LoopExpr*) override; @@ -99,6 +120,12 @@ class NameResolver : public ExprVisitor::DelegateNop { void ResolveDataSegmentVar(Var* var); void ResolveElemSegmentVar(Var* var); void ResolveLocalVar(Var* var); + void ResolveStructVar(Var* var); + void ResolveStructVar2(Var* var, Var* var2); + void ResolveArrayVar(Var* var); + void ResolveArrayNewDataVar(Var* var, Var* var2); + void ResolveArrayNewElemVar(Var* var, Var* var2); + void ResolveArrayCopyVar(Var* var, Var* var2); void ResolveBlockDeclarationVar(BlockDeclaration* decl); void VisitFunc(Func* func); void VisitExport(Export* export_); @@ -181,7 +208,6 @@ void NameResolver::ResolveVar(const BindingHash* bindings, var->name().c_str()); return; } - var->set_index(index); } } @@ -235,6 +261,196 @@ void NameResolver::ResolveLocalVar(Var* var) { } } +void NameResolver::ResolveStructVar(Var* var) { + if (var->is_name()) { + std::vector items = current_module_->types; + std::vector::size_type i = 0; + for (i = 0; i < items.size(); i++) { + if (strcmp(items[i]->name.c_str(), var->name().c_str()) == 0) { + var->set_index(i); + return; + } + } + if (i == items.size()) { + PrintError(&var->loc, "undefined struct variable \"%s\"", + var->name().c_str()); + return; + } + var->set_index(kInvalidIndex); + } +} + +void NameResolver::ResolveStructVar2(Var* var, Var* var2) { + // 首先判断struct + if (var->is_name()) { + std::vector items = current_module_->types; + std::vector::size_type i = 0; + for (i = 0; i < items.size(); i++) { + if (strcmp(items[i]->name.c_str(), var->name().c_str()) == 0) { + var->set_index(i); + goto help; + } + } + if (i == items.size()) { + var->set_index(kInvalidIndex); + PrintError(&var->loc, "undefined struct variable \"%s\"", + var->name().c_str()); + return; + } + } + +help:; + // 再判断struct的成员 + if (var2->is_name()) { + wabt::StructType* a = + static_cast(current_module_->types[var->index()]); + std::vector items = a->fields; + std::vector::size_type i = 0; + for (i = 0; i < items.size(); i++) { + if (strcmp(items[i].name.c_str(), var2->name().c_str()) == 0) { + var2->set_index(i); + return; + } + } + if (i == items.size()) { + var2->set_index(kInvalidIndex); + PrintError(&var2->loc, "undefined struct variable \"%s\"", + var2->name().c_str()); + return; + } + } +} + +void NameResolver::ResolveArrayVar(Var* var) { + if (var->is_name()) { + std::vector items = current_module_->types; + std::vector::size_type i = 0; + for (i = 0; i < items.size(); i++) { + if (strcmp(items[i]->name.c_str(), var->name().c_str()) == 0) { + var->set_index(i); + return; + } + } + if (i == items.size()) { + PrintError(&var->loc, "undefined struct variable \"%s\"", + var->name().c_str()); + return; + } + var->set_index(kInvalidIndex); + } +} + +void NameResolver::ResolveArrayNewDataVar(Var* var, Var* var2) { + if (var->is_name()) { + std::vector items = current_module_->types; + std::vector::size_type i = 0; + for (i = 0; i < items.size(); i++) { + if (strcmp(items[i]->name.c_str(), var->name().c_str()) == 0) { + var->set_index(i); + goto help; + } + } + if (i == items.size()) { + var->set_index(kInvalidIndex); + PrintError(&var->loc, "undefined struct variable \"%s\"", + var->name().c_str()); + return; + } + } + +help:; + if (var2->is_name()) { + std::vector items = current_module_->data_segments; + std::vector::size_type i = 0; + for (i = 0; i < items.size(); i++) { + if (strcmp(items[i]->name.c_str(), var2->name().c_str()) == 0) { + var2->set_index(i); + return; + } + } + if (i == items.size()) { + var2->set_index(kInvalidIndex); + PrintError(&var2->loc, "undefined data variable \"%s\"", + var2->name().c_str()); + return; + } + } +} + +void NameResolver::ResolveArrayNewElemVar(Var* var, Var* var2) { + if (var->is_name()) { + std::vector items = current_module_->types; + std::vector::size_type i = 0; + for (i = 0; i < items.size(); i++) { + if (strcmp(items[i]->name.c_str(), var->name().c_str()) == 0) { + var->set_index(i); + goto help; + } + } + if (i == items.size()) { + var->set_index(kInvalidIndex); + PrintError(&var->loc, "undefined struct variable \"%s\"", + var->name().c_str()); + return; + } + } + +help:; + if (var2->is_name()) { + std::vector items = current_module_->elem_segments; + std::vector::size_type i = 0; + for (i = 0; i < items.size(); i++) { + if (strcmp(items[i]->name.c_str(), var2->name().c_str()) == 0) { + var2->set_index(i); + return; + } + } + if (i == items.size()) { + var2->set_index(kInvalidIndex); + PrintError(&var2->loc, "undefined data variable \"%s\"", + var2->name().c_str()); + return; + } + } +} + +void NameResolver::ResolveArrayCopyVar(Var* var, Var* var2) { + if (var->is_name()) { + std::vector items = current_module_->types; + std::vector::size_type i = 0; + for (i = 0; i < items.size(); i++) { + if (strcmp(items[i]->name.c_str(), var->name().c_str()) == 0) { + var->set_index(i); + goto help; + } + } + if (i == items.size()) { + var->set_index(kInvalidIndex); + PrintError(&var->loc, "undefined struct variable \"%s\"", + var->name().c_str()); + return; + } + } + +help:; + if (var2->is_name()) { + std::vector items = current_module_->types; + std::vector::size_type i = 0; + for (i = 0; i < items.size(); i++) { + if (strcmp(items[i]->name.c_str(), var2->name().c_str()) == 0) { + var2->set_index(i); + return; + } + } + if (i == items.size()) { + var2->set_index(kInvalidIndex); + PrintError(&var2->loc, "undefined data variable \"%s\"", + var2->name().c_str()); + return; + } + } +} + void NameResolver::ResolveBlockDeclarationVar(BlockDeclaration* decl) { if (decl->has_func_type) { ResolveFuncTypeVar(&decl->type_var); @@ -337,6 +553,95 @@ Result NameResolver::OnLocalGetExpr(LocalGetExpr* expr) { return Result::Ok; } +Result NameResolver::OnStructNewExpr(StructNewExpr* expr) { + ResolveStructVar(&expr->var); + return Result::Ok; +} + +Result NameResolver::OnStructNewDefaultExpr(StructNewDefaultExpr* expr) { + ResolveStructVar(&expr->var); + return Result::Ok; +} + +Result NameResolver::OnStructGetExpr(StructGetExpr* expr) { + ResolveStructVar2(&expr->var1, &expr->var2); + return Result::Ok; +} +Result NameResolver::OnStructGetSExpr(StructGetSExpr* expr) { + ResolveStructVar2(&expr->var1, &expr->var2); + return Result::Ok; +} +Result NameResolver::OnStructGetUExpr(StructGetUExpr* expr) { + ResolveStructVar2(&expr->var1, &expr->var2); + return Result::Ok; +} +Result NameResolver::OnStructSetExpr(StructSetExpr* expr) { + ResolveStructVar2(&expr->var1, &expr->var2); + return Result::Ok; +} + +Result NameResolver::OnArrayNewExpr(ArrayNewExpr* expr) { + ResolveArrayVar(&expr->var); + return Result::Ok; +} +Result NameResolver::OnArrayNewDefaultExpr(ArrayNewDefaultExpr* expr) { + ResolveArrayVar(&expr->var); + return Result::Ok; +} +Result NameResolver::OnArrayNewFixedExpr(ArrayNewFixedExpr* expr) { + ResolveArrayVar(&expr->var1); + return Result::Ok; +} +Result NameResolver::OnArrayNewDataExpr(ArrayNewDataExpr* expr) { + ResolveArrayNewDataVar(&expr->var1, &expr->var2); + return Result::Ok; +} +Result NameResolver::OnArrayNewElemExpr(ArrayNewElemExpr* expr) { + ResolveArrayNewElemVar(&expr->var1, &expr->var2); + return Result::Ok; +} +Result NameResolver::OnArrayGetExpr(ArrayGetExpr* expr) { + ResolveArrayVar(&expr->var); + return Result::Ok; +} +Result NameResolver::OnArrayGetSExpr(ArrayGetSExpr* expr) { + ResolveArrayVar(&expr->var); + return Result::Ok; +} +Result NameResolver::OnArrayGetUExpr(ArrayGetUExpr* expr) { + ResolveArrayVar(&expr->var); + return Result::Ok; +} +Result NameResolver::OnArraySetExpr(ArraySetExpr* expr) { + ResolveArrayVar(&expr->var); + return Result::Ok; +} +Result NameResolver::OnArrayFillExpr(ArrayFillExpr* expr) { + ResolveArrayVar(&expr->var); + return Result::Ok; +} +Result NameResolver::OnArrayCopyExpr(ArrayCopyExpr* expr) { + ResolveArrayCopyVar(&expr->var1, &expr->var2); + return Result::Ok; +} +Result NameResolver::OnArrayInitDataExpr(ArrayInitDataExpr* expr) { + ResolveArrayNewDataVar(&expr->var1, &expr->var2); + return Result::Ok; +} +Result NameResolver::OnArrayInitElemExpr(ArrayInitElemExpr* expr) { + ResolveArrayNewElemVar(&expr->var1, &expr->var2); + return Result::Ok; +} + +Result NameResolver::OnBrOnCastExpr(BrOnCastExpr* expr) { + ResolveLabelVar(&expr->var1); + return Result::Ok; +} +Result NameResolver::OnBrOnCastFailExpr(BrOnCastFailExpr* expr) { + ResolveLabelVar(&expr->var1); + return Result::Ok; +} + Result NameResolver::OnLocalSetExpr(LocalSetExpr* expr) { ResolveLocalVar(&expr->var); return Result::Ok; @@ -537,10 +842,11 @@ void NameResolver::VisitElemSegment(ElemSegment* segment) { ResolveTableVar(&segment->table_var); visitor_.VisitExprList(segment->offset); for (ExprList& elem_expr : segment->elem_exprs) { - if (elem_expr.size() == 1 && + visitor_.VisitExprList(elem_expr); + /*if (elem_expr.size() == 1 && elem_expr.front().type() == ExprType::RefFunc) { ResolveFuncVar(&cast(&elem_expr.front())->var); - } + }*/ } } diff --git a/src/shared-validator.cc b/src/shared-validator.cc index 629b62385..78dba8c0d 100644 --- a/src/shared-validator.cc +++ b/src/shared-validator.cc @@ -20,6 +20,9 @@ #include #include +extern std::vector moduletypes; +std::unordered_map moduletypesname3; + namespace wabt { TypeVector SharedValidator::ToTypeVector(Index count, const Type* types) { @@ -656,6 +659,256 @@ Result SharedValidator::OnBinary(const Location& loc, Opcode opcode) { return result; } +Result SharedValidator::OnStructNew(const Location& loc, Var var) { + Result result = Result::Ok; + wabt::StructType* a = + static_cast(moduletypes[var.index()]); + TypeVector typeVector; + for (auto field : a->fields) + typeVector.push_back(field.type); + assert(var.is_index()); + result |= typechecker_.OnStructNew(var.index(), typeVector); + return result; +} +Result SharedValidator::OnStructNewDefault(const Location& loc, Var var) { + Result result = Result::Ok; + assert(var.is_index()); + result |= typechecker_.OnStructNewDefault(var.index()); + return result; +} +Result SharedValidator::OnStructGet(const Location& loc, Var var1, Var var2) { + Result result = Result::Ok; + wabt::StructType* a = + static_cast(moduletypes[var1.index()]); + Field field = a->fields[var2.index()]; + result |= typechecker_.OnStructGet(var1.index(), field.type); + return result; +} +Result SharedValidator::OnStructGetU(const Location& loc, Var var1, Var var2) { + Result result = Result::Ok; + result |= typechecker_.OnStructGet(var1.index(), Type::I32); + return result; +} +Result SharedValidator::OnStructGetS(const Location& loc, Var var1, Var var2) { + Result result = Result::Ok; + result |= typechecker_.OnStructGet(var1.index(), Type::I32); + return result; +} +Result SharedValidator::OnStructSet(const Location& loc, Var var1, Var var2) { + Result result = Result::Ok; + wabt::StructType* a = + static_cast(moduletypes[var1.index()]); + Field field = a->fields[var2.index()]; + result |= typechecker_.OnStructSet(var1.index(), field.type); + return result; +} + +Result SharedValidator::OnArrayNew(const Location& loc, Var var) { + Result result = Result::Ok; + wabt::ArrayType* a = + static_cast(moduletypes[var.index()]); + Type type = a->field.type; + result |= typechecker_.OnArrayNew(var.index(), type); + return result; +} +Result SharedValidator::OnArrayNewDefault(const Location& loc, Var var) { + Result result = Result::Ok; + result |= typechecker_.OnArrayNewDefault(var.index()); + return result; +} +Result SharedValidator::OnArrayNewFixed(const Location& loc, + Var var, + Var size_var) { + Result result = Result::Ok; + wabt::ArrayType* a = static_cast(moduletypes[var.index()]); + result |= typechecker_.OnArrayNewFixed(var.index(), a->field.type, + size_var.index()); + return result; +} +Result SharedValidator::OnArrayNewData(const Location& loc, + Var var1, + Var var2) { + Result result = Result::Ok; + result |= typechecker_.OnArrayNewData(var1.index()); + return result; +} +Result SharedValidator::OnArrayNewElem(const Location& loc, + Var var1, + Var var2) { + Result result = Result::Ok; + result |= typechecker_.OnArrayNewElem(var1.index()); + return result; +} +Result SharedValidator::OnArrayGet(const Location& loc, Var var) { + Result result = Result::Ok; + wabt::ArrayType* a = static_cast(moduletypes[var.index()]); + result |= typechecker_.OnArrayGet(var.index(), a->field.type); + return result; +} +Result SharedValidator::OnArrayGetS(const Location& loc, Var var) { + Result result = Result::Ok; + result |= typechecker_.OnArrayGet(var.index(), Type::I32); + return result; +} +Result SharedValidator::OnArrayGetU(const Location& loc, Var var) { + Result result = Result::Ok; + result |= typechecker_.OnArrayGet(var.index(), Type::I32); + return result; +} +Result SharedValidator::OnArraySet(const Location& loc, Var var) { + Result result = Result::Ok; + wabt::ArrayType* a = static_cast(moduletypes[var.index()]); + result |= typechecker_.OnArraySet(var.index(), a->field.type); + return result; +} +Result SharedValidator::OnArrayLen(const Location& loc) { + Result result = Result::Ok; + result |= typechecker_.OnArrayLen(); + return result; +} +Result SharedValidator::OnArrayFill(const Location& loc, Var var) { + Result result = Result::Ok; + wabt::ArrayType* a = static_cast(moduletypes[var.index()]); + result |= + typechecker_.OnArrayFill(Type(Type::RefNull, var.index()), a->field.type); + return result; +} +Result SharedValidator::OnArrayCopy(const Location& loc, Var var, Var var2) { + Result result = Result::Ok; + result |= typechecker_.OnArrayCopy(Type(Type::RefNull, var.index()), + Type(Type::RefNull, var2.index())); + return result; +} +Result SharedValidator::OnArrayInitData(const Location& loc, + Var var, + Var var2) { + Result result = Result::Ok; + result |= typechecker_.OnArrayInitData(Type(Type::RefNull, var.index())); + return result; +} +Result SharedValidator::OnArrayInitElem(const Location& loc, + Var var, + Var var2) { + Result result = Result::Ok; + result |= typechecker_.OnArrayInitData(Type(Type::RefNull, var.index())); + return result; +} +bool SharedValidator::isNumber(const std::string& str) { + for (char const& c : str) { + if (std::isdigit(c) == 0) + return false; + } + return true; +} +Type SharedValidator::ParseVar2RefType(Var var) { + if (var.is_index()) + return Type(var.index()); + std::string name; + Type ans; + if (var.name().substr(0, 7) == "RefNull") { + ans = Type::RefNull; + name = var.name().substr(7); + } else { + ans = Type::Ref; + name = var.name(); + } + if (isNumber(name)) { + ans.type_index_ = std::stoi(name); + } else if (name == "NoFunc") { + ans.type_index_ = Type::NoFunc; + } else if (name == "NoExtern") { + ans.type_index_ = Type::NoExtern; + } else if (name == "None") { + ans.type_index_ = Type::NoneRef; + } else if (name == "Func") { + return Type::FuncRef; + } else if (name == "Extern") { + return Type::ExternRef; + } else if (name == "Any") { + ans.type_index_ = Type::AnyRef; + } else if (name == "Eq") { + ans.type_index_ = Type::Eq; + } else if (name == "I31") { + ans.type_index_ = Type::I31; + } else if (name == "Struct") { + ans.type_index_ = Type::StructRef; + } else if (name == "Array") { + ans.type_index_ = Type::ArrayRef; + } else { + if (moduletypesname3.find(name) != moduletypesname3.end()) { + ans.type_index_ = moduletypesname3[name]; + } + } + return ans; +} +Result SharedValidator::OnRefTest( + const Location& loc, + Var var, + std::unordered_map& typenames) { + Result result = Result::Ok; + moduletypesname3 = typenames; + result |= typechecker_.OnRefTest(ParseVar2RefType(var)); + return result; +} +Result SharedValidator::OnRefCast( + const Location& loc, + Var var, + std::unordered_map& typenames) { + Result result = Result::Ok; + moduletypesname3 = typenames; + result |= typechecker_.OnRefCast(ParseVar2RefType(var)); + return result; +} +Result SharedValidator::OnBrOnCast( + const Location& loc, + Var var1, + Var var2, + Var var3, + std::unordered_map& typenames) { + moduletypesname3 = typenames; + Result result = Result::Ok; + result |= + typechecker_.OnBrOnCast(ParseVar2RefType(var2), ParseVar2RefType(var3)); + return result; +} +Result SharedValidator::OnBrOnCastFail( + const Location& loc, + Var var1, + Var var2, + Var var3, + std::unordered_map& typenames) { + moduletypesname3 = typenames; + Result result = Result::Ok; + result |= typechecker_.OnBrOnCastFail(ParseVar2RefType(var2), + ParseVar2RefType(var3)); + return result; +} +Result SharedValidator::OnAnyConvertExtern(const Location& loc) { + Result result = Result::Ok; + result |= typechecker_.OnAnyConvertExtern(); + return result; +} +Result SharedValidator::OnExternConvertAny(const Location& loc) { + Result result = Result::Ok; + result |= typechecker_.OnExternConvertAny(); + return result; +} +Result SharedValidator::OnRefI31(const Location& loc) { + Result result = Result::Ok; + result |= typechecker_.OnRefI31(); + return result; +} +Result SharedValidator::OnI31GetS(const Location& loc) { + Result result = Result::Ok; + result |= typechecker_.OnI31Get(); + return result; +} +Result SharedValidator::OnI31GetU(const Location& loc) { + Result result = Result::Ok; + result |= typechecker_.OnI31Get(); + return result; +} + Result SharedValidator::OnBlock(const Location& loc, Type sig_type) { Result result = CheckInstr(Opcode::Block, loc); TypeVector param_types, result_types; @@ -979,6 +1232,12 @@ Result SharedValidator::OnNop(const Location& loc) { return result; } +Result SharedValidator::OnRefEq(const Location& loc) { + Result result = CheckInstr(Opcode::RefEq, loc); + result |= typechecker_.OnRefEq(); + return result; +} + Result SharedValidator::OnRefFunc(const Location& loc, Var func_var) { Result result = CheckInstr(Opcode::RefFunc, loc); result |= CheckFuncIndex(func_var); diff --git a/src/tools/wat2wasm.cc b/src/tools/wat2wasm.cc index fedd88a67..54e52dfa7 100644 --- a/src/tools/wat2wasm.cc +++ b/src/tools/wat2wasm.cc @@ -1,19 +1,3 @@ -/* - * Copyright 2016 WebAssembly Community Group participants - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - #include #include #include @@ -134,14 +118,348 @@ int ProgramMain(int argc, char** argv) { std::vector file_data; Result result = ReadFile(s_infile, &file_data); Errors errors; + // 处理filedata 里面的缩写 + for (size_t i = 0; i < file_data.size(); ++i) { + // 前面应该至少有一个空格 + // 后面应该是空格/换行/回车/制表符/) + // anyref + if (file_data[i] == ' ' && file_data[i + 1] == 'a' && + file_data[i + 2] == 'n' && file_data[i + 3] == 'y' && + file_data[i + 4] == 'r' && file_data[i + 5] == 'e' && + file_data[i + 6] == 'f' && + (file_data[i + 7] == ')' || file_data[i + 7] == ' ' || + file_data[i + 7] == '\n' || file_data[i + 7] == '\r' || + file_data[i + 7] == '\t')) { + // 删除原来的anyref + file_data.erase(file_data.begin() + i, file_data.begin() + i + 7); + // 不可以使用赋值,使用insert + file_data.insert(file_data.begin() + i, '('); + file_data.insert(file_data.begin() + i + 1, 'r'); + file_data.insert(file_data.begin() + i + 2, 'e'); + file_data.insert(file_data.begin() + i + 3, 'f'); + file_data.insert(file_data.begin() + i + 4, ' '); + file_data.insert(file_data.begin() + i + 5, 'n'); + file_data.insert(file_data.begin() + i + 6, 'u'); + file_data.insert(file_data.begin() + i + 7, 'l'); + file_data.insert(file_data.begin() + i + 8, 'l'); + file_data.insert(file_data.begin() + i + 9, ' '); + file_data.insert(file_data.begin() + i + 10, 'a'); + file_data.insert(file_data.begin() + i + 11, 'n'); + file_data.insert(file_data.begin() + i + 12, 'y'); + file_data.insert(file_data.begin() + i + 13, ')'); + + i += 13; + } + + // eqref + if (file_data[i] == ' ' && file_data[i + 1] == 'e' && + file_data[i + 2] == 'q' && file_data[i + 3] == 'r' && + file_data[i + 4] == 'e' && file_data[i + 5] == 'f' && + (file_data[i + 6] == ')' || file_data[i + 6] == ' ' || + file_data[i + 6] == '\n' || file_data[i + 6] == '\r' || + file_data[i + 6] == '\t')) { + // 删除原来的structref + file_data.erase(file_data.begin() + i, file_data.begin() + i + 6); + // 不可以使用赋值,使用insert + file_data.insert(file_data.begin() + i, '('); + file_data.insert(file_data.begin() + i + 1, 'r'); + file_data.insert(file_data.begin() + i + 2, 'e'); + file_data.insert(file_data.begin() + i + 3, 'f'); + file_data.insert(file_data.begin() + i + 4, ' '); + file_data.insert(file_data.begin() + i + 5, 'n'); + file_data.insert(file_data.begin() + i + 6, 'u'); + file_data.insert(file_data.begin() + i + 7, 'l'); + file_data.insert(file_data.begin() + i + 8, 'l'); + file_data.insert(file_data.begin() + i + 9, ' '); + file_data.insert(file_data.begin() + i + 10, 'e'); + file_data.insert(file_data.begin() + i + 11, 'q'); + file_data.insert(file_data.begin() + i + 12, ')'); + i += 12; + } + + // i31ref + if (file_data[i] == ' ' && file_data[i + 1] == 'i' && + file_data[i + 2] == '3' && file_data[i + 3] == '1' && + file_data[i + 4] == 'r' && file_data[i + 5] == 'e' && + file_data[i + 6] == 'f' && + (file_data[i + 7] == ')' || file_data[i + 7] == ' ' || + file_data[i + 7] == '\n' || file_data[i + 7] == '\r' || + file_data[i + 7] == '\t')) { + // 删除原来的i31ref + file_data.erase(file_data.begin() + i, file_data.begin() + i + 7); + // 不可以使用赋值,使用insert + file_data.insert(file_data.begin() + i, '('); + file_data.insert(file_data.begin() + i + 1, 'r'); + file_data.insert(file_data.begin() + i + 2, 'e'); + file_data.insert(file_data.begin() + i + 3, 'f'); + file_data.insert(file_data.begin() + i + 4, ' '); + file_data.insert(file_data.begin() + i + 5, 'i'); + file_data.insert(file_data.begin() + i + 6, '3'); + file_data.insert(file_data.begin() + i + 7, '1'); + file_data.insert(file_data.begin() + i + 8, ')'); + i += 8; + } + + // structref + if (file_data[i] == ' ' && file_data[i + 1] == 's' && + file_data[i + 2] == 't' && file_data[i + 3] == 'r' && + file_data[i + 4] == 'u' && file_data[i + 5] == 'c' && + file_data[i + 6] == 't' && file_data[i + 7] == 'r' && + file_data[i + 8] == 'e' && file_data[i + 9] == 'f' && + (file_data[i + 10] == ')' || file_data[i + 10] == ' ' || + file_data[i + 10] == '\n' || file_data[i + 10] == '\r' || + file_data[i + 10] == '\t')) { + // 删除原来的structref + file_data.erase(file_data.begin() + i, file_data.begin() + i + 10); + // 不可以使用赋值,使用insert + file_data.insert(file_data.begin() + i, '('); + file_data.insert(file_data.begin() + i + 1, 'r'); + file_data.insert(file_data.begin() + i + 2, 'e'); + file_data.insert(file_data.begin() + i + 3, 'f'); + file_data.insert(file_data.begin() + i + 4, ' '); + file_data.insert(file_data.begin() + i + 5, 'n'); + file_data.insert(file_data.begin() + i + 6, 'u'); + file_data.insert(file_data.begin() + i + 7, 'l'); + file_data.insert(file_data.begin() + i + 8, 'l'); + file_data.insert(file_data.begin() + i + 9, ' '); + file_data.insert(file_data.begin() + i + 10, 's'); + file_data.insert(file_data.begin() + i + 11, 't'); + file_data.insert(file_data.begin() + i + 12, 'r'); + file_data.insert(file_data.begin() + i + 13, 'u'); + file_data.insert(file_data.begin() + i + 14, 'c'); + file_data.insert(file_data.begin() + i + 15, 't'); + file_data.insert(file_data.begin() + i + 16, ')'); + i += 16; + } + + // arrayref + if (file_data[i] == ' ' && file_data[i + 1] == 'a' && + file_data[i + 2] == 'r' && file_data[i + 3] == 'r' && + file_data[i + 4] == 'a' && file_data[i + 5] == 'y' && + file_data[i + 6] == 'r' && file_data[i + 7] == 'e' && + file_data[i + 8] == 'f' && + (file_data[i + 9] == ')' || file_data[i + 9] == ' ' || + file_data[i + 9] == '\n' || file_data[i + 9] == '\r' || + file_data[i + 9] == '\t')) { + // 删除原来的arrayref + file_data.erase(file_data.begin() + i, file_data.begin() + i + 9); + // 不可以使用赋值,使用insert + file_data.insert(file_data.begin() + i, '('); + file_data.insert(file_data.begin() + i + 1, 'r'); + file_data.insert(file_data.begin() + i + 2, 'e'); + file_data.insert(file_data.begin() + i + 3, 'f'); + file_data.insert(file_data.begin() + i + 4, ' '); + file_data.insert(file_data.begin() + i + 5, 'n'); + file_data.insert(file_data.begin() + i + 6, 'u'); + file_data.insert(file_data.begin() + i + 7, 'l'); + file_data.insert(file_data.begin() + i + 8, 'l'); + file_data.insert(file_data.begin() + i + 9, ' '); + file_data.insert(file_data.begin() + i + 10, 'a'); + file_data.insert(file_data.begin() + i + 11, 'r'); + file_data.insert(file_data.begin() + i + 12, 'r'); + file_data.insert(file_data.begin() + i + 13, 'a'); + file_data.insert(file_data.begin() + i + 14, 'y'); + file_data.insert(file_data.begin() + i + 15, ')'); + i += 15; + } + + // nullref -> (ref null none) + if (file_data[i] == ' ' && file_data[i + 1] == 'n' && + file_data[i + 2] == 'u' && file_data[i + 3] == 'l' && + file_data[i + 4] == 'l' && file_data[i + 5] == 'r' && + file_data[i + 6] == 'e' && file_data[i + 7] == 'f' && + (file_data[i + 8] == ')' || file_data[i + 8] == ' ' || + file_data[i + 8] == '\n' || file_data[i + 8] == '\r' || + file_data[i + 8] == '\t')) { + // 删除原来的nullref + file_data.erase(file_data.begin() + i, file_data.begin() + i + 8); + // 不可以使用赋值,使用insert + file_data.insert(file_data.begin() + i, '('); + file_data.insert(file_data.begin() + i + 1, 'r'); + file_data.insert(file_data.begin() + i + 2, 'e'); + file_data.insert(file_data.begin() + i + 3, 'f'); + file_data.insert(file_data.begin() + i + 4, ' '); + file_data.insert(file_data.begin() + i + 5, 'n'); + file_data.insert(file_data.begin() + i + 6, 'u'); + file_data.insert(file_data.begin() + i + 7, 'l'); + file_data.insert(file_data.begin() + i + 8, 'l'); + file_data.insert(file_data.begin() + i + 9, ' '); + file_data.insert(file_data.begin() + i + 10, 'n'); + file_data.insert(file_data.begin() + i + 11, 'o'); + file_data.insert(file_data.begin() + i + 12, 'n'); + file_data.insert(file_data.begin() + i + 13, 'e'); + file_data.insert(file_data.begin() + i + 14, ')'); + i += 14; + } + // nullfuncref -> (ref null nofunc) + if (file_data[i] == ' ' && file_data[i + 1] == 'n' && + file_data[i + 2] == 'u' && file_data[i + 3] == 'l' && + file_data[i + 4] == 'l' && file_data[i + 5] == 'f' && + file_data[i + 6] == 'u' && file_data[i + 7] == 'n' && + file_data[i + 8] == 'c' && file_data[i + 9] == 'r' && + file_data[i + 10] == 'e' && file_data[i + 11] == 'f' && + (file_data[i + 12] == ')' || file_data[i + 12] == ' ' || + file_data[i + 12] == '\n' || file_data[i + 12] == '\r' || + file_data[i + 12] == '\t')) { + // 删除原来的nullfuncref + file_data.erase(file_data.begin() + i, file_data.begin() + i + 12); + // 不可以使用赋值,使用insert + file_data.insert(file_data.begin() + i, '('); + file_data.insert(file_data.begin() + i + 1, 'r'); + file_data.insert(file_data.begin() + i + 2, 'e'); + file_data.insert(file_data.begin() + i + 3, 'f'); + file_data.insert(file_data.begin() + i + 4, ' '); + file_data.insert(file_data.begin() + i + 5, 'n'); + file_data.insert(file_data.begin() + i + 6, 'u'); + file_data.insert(file_data.begin() + i + 7, 'l'); + file_data.insert(file_data.begin() + i + 8, 'l'); + file_data.insert(file_data.begin() + i + 9, ' '); + file_data.insert(file_data.begin() + i + 10, 'n'); + file_data.insert(file_data.begin() + i + 11, 'o'); + file_data.insert(file_data.begin() + i + 12, 'f'); + file_data.insert(file_data.begin() + i + 13, 'u'); + file_data.insert(file_data.begin() + i + 14, 'n'); + file_data.insert(file_data.begin() + i + 15, 'c'); + file_data.insert(file_data.begin() + i + 16, ')'); + i += 16; + } + // nullexternref -> (ref null noextern) + if (file_data[i] == ' ' && file_data[i + 1] == 'n' && + file_data[i + 2] == 'u' && file_data[i + 3] == 'l' && + file_data[i + 4] == 'l' && file_data[i + 5] == 'e' && + file_data[i + 6] == 'x' && file_data[i + 7] == 't' && + file_data[i + 8] == 'e' && file_data[i + 9] == 'r' && + file_data[i + 10] == 'n' && file_data[i + 11] == 'r' && + file_data[i + 12] == 'e' && file_data[i + 13] == 'f' && + (file_data[i + 14] == ')' || file_data[i + 14] == ' ' || + file_data[i + 14] == '\n' || file_data[i + 14] == '\r' || + file_data[i + 14] == '\t')) { + // 删除原来的nullexternref + file_data.erase(file_data.begin() + i, file_data.begin() + i + 14); + // 不可以使用赋值,使用insert + file_data.insert(file_data.begin() + i, '('); + file_data.insert(file_data.begin() + i + 1, 'r'); + file_data.insert(file_data.begin() + i + 2, 'e'); + file_data.insert(file_data.begin() + i + 3, 'f'); + file_data.insert(file_data.begin() + i + 4, ' '); + file_data.insert(file_data.begin() + i + 5, 'n'); + file_data.insert(file_data.begin() + i + 6, 'u'); + file_data.insert(file_data.begin() + i + 7, 'l'); + file_data.insert(file_data.begin() + i + 8, 'l'); + file_data.insert(file_data.begin() + i + 9, ' '); + file_data.insert(file_data.begin() + i + 10, 'n'); + file_data.insert(file_data.begin() + i + 11, 'o'); + file_data.insert(file_data.begin() + i + 12, 'e'); + file_data.insert(file_data.begin() + i + 13, 'x'); + file_data.insert(file_data.begin() + i + 14, 't'); + file_data.insert(file_data.begin() + i + 15, 'e'); + file_data.insert(file_data.begin() + i + 16, 'r'); + file_data.insert(file_data.begin() + i + 17, 'n'); + file_data.insert(file_data.begin() + i + 18, ')'); + i += 18; + } + } + std::unordered_map moduletypesname; + // 处理类型声明 + size_t type_index = -1; + size_t lparsize = 0; + size_t i = 0, m = file_data.size(); + while (i < m) { + // 处理;; + if (file_data[i] == ';' && file_data[i + 1] == ';') { + while (i < m && file_data[i] != '\n' && file_data[i] != '\r') + i++; + } + if (lparsize == 2) { + // 判断是不是(type) + std::string str; + while (i < m && file_data[i] == ' ') + i++; + while (i < m && file_data[i] != ' ' && file_data[i] != '\n' && + file_data[i] != '\r' && file_data[i] != '\t' && + file_data[i] != '(' && file_data[i] != ')') { + str += file_data[i]; + i++; + } + if (str == "type") { + type_index++; + std::string name; + while (i < m && file_data[i] == ' ') + i++; + if (file_data[i] == '(') { + continue; + } else if (file_data[i] == '$') { + name += file_data[i]; + i++; + while (i < m && file_data[i] != ' ' && file_data[i] != '\n' && + file_data[i] != '\r' && file_data[i] != '\t' && + file_data[i] != '(' && file_data[i] != ')') { + name += file_data[i++]; + } + } + moduletypesname.insert({name, type_index}); + } else if (str == "rec") { + size_t Lpar = 0; + while (i < m) { + while (i < m && file_data[i] == ' ') + i++; + if (Lpar == 1) { + std::string instruction; + while (i < m && file_data[i] == ' ') + i++; + while (i < m && file_data[i] != ' ' && file_data[i] != '\n' && + file_data[i] != '\r' && file_data[i] != '\t' && + file_data[i] != '(' && file_data[i] != ')') { + instruction += file_data[i]; + i++; + } + if (instruction == "type") { + type_index++; + std::string name; + while (i < m && file_data[i] == ' ') + i++; + if (file_data[i] == '(') { + continue; + } else if (file_data[i] == '$') { + name += file_data[i]; + i++; + while (i < m && file_data[i] != ' ' && file_data[i] != '\n' && + file_data[i] != '\r' && file_data[i] != '\t' && + file_data[i] != '(' && file_data[i] != ')') { + name += file_data[i++]; + } + } + moduletypesname.insert({name, type_index}); + } + } + if (file_data[i] == '(') { + Lpar++; + } else if (file_data[i] == ')') { + if (Lpar == 0) { + break; + } else { + Lpar--; + } + } + i++; + } + } + } + if (file_data[i] == '(') + lparsize++; + if (file_data[i] == ')') + lparsize--; + i++; + } std::unique_ptr lexer = WastLexer::CreateBufferLexer( s_infile, file_data.data(), file_data.size(), &errors); if (Failed(result)) { WABT_FATAL("unable to read file: %s\n", s_infile); } - std::unique_ptr module; + std::unique_ptr module = std::make_unique(); WastParseOptions parse_wast_options(s_features); + module->moduletypesname = moduletypesname; result = ParseWatModule(lexer.get(), &module, &errors, &parse_wast_options); if (Succeeded(result) && s_validate) { diff --git a/src/type-checker.cc b/src/type-checker.cc index ff032926b..fff97d9a0 100644 --- a/src/type-checker.cc +++ b/src/type-checker.cc @@ -17,7 +17,8 @@ #include "wabt/type-checker.h" #include - +#include +extern std::vector moduletypes; namespace wabt { namespace { @@ -131,110 +132,161 @@ bool TypeChecker::IsUnreachable() { } void TypeChecker::ResetTypeStackToLabel(Label* label) { - type_stack_.resize(label->type_stack_limit); + type_stack_.resize(label->type_stack_limit); } Result TypeChecker::SetUnreachable() { - Label* label; - CHECK_RESULT(TopLabel(&label)); - label->unreachable = true; - ResetTypeStackToLabel(label); - return Result::Ok; + Label* label; + CHECK_RESULT(TopLabel(&label)); + label->unreachable = true; + ResetTypeStackToLabel(label); + return Result::Ok; } void TypeChecker::PushLabel(LabelType label_type, - const TypeVector& param_types, - const TypeVector& result_types) { - label_stack_.emplace_back(label_type, param_types, result_types, - type_stack_.size()); + const TypeVector& param_types, + const TypeVector& result_types) { + label_stack_.emplace_back(label_type, param_types, result_types, + type_stack_.size()); } Result TypeChecker::PopLabel() { - label_stack_.pop_back(); - return Result::Ok; + label_stack_.pop_back(); + return Result::Ok; } Result TypeChecker::CheckLabelType(Label* label, LabelType label_type) { - return label->label_type == label_type ? Result::Ok : Result::Error; + return label->label_type == label_type ? Result::Ok : Result::Error; } Result TypeChecker::Check2LabelTypes(Label* label, - LabelType label_type1, - LabelType label_type2) { - return label->label_type == label_type1 || label->label_type == label_type2 - ? Result::Ok - : Result::Error; + LabelType label_type1, + LabelType label_type2) { + return label->label_type == label_type1 || label->label_type == label_type2 + ? Result::Ok + : Result::Error; } Result TypeChecker::GetThisFunctionLabel(Label** label) { - return GetLabel(label_stack_.size() - 1, label); + return GetLabel(label_stack_.size() - 1, label); } Result TypeChecker::PeekType(Index depth, Type* out_type) { - Label* label; - CHECK_RESULT(TopLabel(&label)); + Label* label; + CHECK_RESULT(TopLabel(&label)); - if (label->type_stack_limit + depth >= type_stack_.size()) { - *out_type = Type::Any; - return label->unreachable ? Result::Ok : Result::Error; - } - *out_type = type_stack_[type_stack_.size() - depth - 1]; - return Result::Ok; + if (label->type_stack_limit + depth >= type_stack_.size()) { + *out_type = Type::Any; + return label->unreachable ? Result::Ok : Result::Error; + } + *out_type = type_stack_[type_stack_.size() - depth - 1]; + return Result::Ok; } Result TypeChecker::PeekAndCheckType(Index depth, Type expected) { - Type actual = Type::Any; - Result result = PeekType(depth, &actual); - return result | CheckType(actual, expected); + Type actual = Type::Any; + Result result = PeekType(depth, &actual); + return result | CheckType(actual, expected); } Result TypeChecker::DropTypes(size_t drop_count) { - Label* label; - CHECK_RESULT(TopLabel(&label)); - if (label->type_stack_limit + drop_count > type_stack_.size()) { - ResetTypeStackToLabel(label); - return label->unreachable ? Result::Ok : Result::Error; - } - type_stack_.erase(type_stack_.end() - drop_count, type_stack_.end()); - return Result::Ok; + Label* label; + CHECK_RESULT(TopLabel(&label)); + if (label->type_stack_limit + drop_count > type_stack_.size()) { + ResetTypeStackToLabel(label); + return label->unreachable ? Result::Ok : Result::Error; + } + type_stack_.erase(type_stack_.end() - drop_count, type_stack_.end()); + return Result::Ok; } void TypeChecker::PushType(Type type) { - if (type != Type::Void) { - type_stack_.push_back(type); - } + if (type != Type::Void) { + type_stack_.push_back(type); + } } void TypeChecker::PushTypes(const TypeVector& types) { - for (Type type : types) { - PushType(type); - } + for (Type type : types) { + PushType(type); + } } Result TypeChecker::CheckTypeStackEnd(const char* desc) { - Label* label; - CHECK_RESULT(TopLabel(&label)); - Result result = (type_stack_.size() == label->type_stack_limit) - ? Result::Ok - : Result::Error; - PrintStackIfFailedV(result, desc, {}, /*is_end=*/true); - return result; + Label* label; + CHECK_RESULT(TopLabel(&label)); + Result result = (type_stack_.size() == label->type_stack_limit) + ? Result::Ok + : Result::Error; + PrintStackIfFailedV(result, desc, {}, /*is_end=*/true); + return result; +} + +Type UpCastType(Type& type) { + wabt::Index i = type.GetReferenceIndex(); + if (i < 0x3f3f3f3f && moduletypes.size() > i) { + if (moduletypes[i]->kind() == TypeEntryKind::Struct) return Type(Type::Ref, Type::AnyRef); + else if (moduletypes[i]->kind() == TypeEntryKind::Array) return Type(Type::Ref, Type::AnyRef); + else if (moduletypes[i]->kind() == TypeEntryKind::Sub) { + wabt::SubType* subtype = dynamic_cast(moduletypes[i]); + if (subtype->typeEntry->kind() == TypeEntryKind::Struct) + return Type(Type::Ref, Type::AnyRef); + else if (subtype->typeEntry->kind() == TypeEntryKind::Array) + return Type(Type::Ref, Type::AnyRef); + } + } else if (Type(i) == Type::I31) + return Type(Type::Ref, Type::AnyRef); + else if (Type(i) == Type::StructRef) + return Type(Type::Ref, Type::AnyRef); + else if (Type(i) == Type::ArrayRef) + return Type(Type::Ref, Type::AnyRef); + else if (Type(i) == Type::Eq) + return Type(Type::Ref, Type::AnyRef); + else if (Type(i) == Type::NoneRef) + return Type(Type::Ref, Type::AnyRef); + return type; } Result TypeChecker::CheckType(Type actual, Type expected) { - if (expected == Type::Any || actual == Type::Any) { + if (expected == Type::Any || actual == Type::Any) { + return Result::Ok; + } + if (expected == Type::I8 || expected == Type::I16) + return Result::Ok; + if (actual == Type::I8 || actual == Type::I16) + return Result::Ok; + if (expected == Type::Reference && actual == Type::Reference) { + return expected.GetReferenceIndex() == actual.GetReferenceIndex() + ? Result::Ok + : Result::Error; + } + if (actual == Type::FuncRef && (expected == Type(Type::Ref,Type::NoFunc)|| expected == Type(Type::RefNull,Type::NoFunc))) return Result::Ok; + if (expected == Type::FuncRef && (actual == Type(Type::Ref,Type::NoFunc)|| actual == Type(Type::RefNull,Type::NoFunc))) return Result::Ok; + if (actual == Type::ExternRef && (expected == Type(Type::Ref,Type::NoExtern)|| expected == Type(Type::RefNull,Type::NoExtern))) return Result::Ok; + if (expected == Type::ExternRef && (actual == Type(Type::Ref,Type::NoExtern)|| actual == Type(Type::RefNull,Type::NoExtern))) return Result::Ok; + if (actual == Type::FuncRef && expected.IsNewReferenceWithIndex()) { + auto i = expected.GetReferenceIndex(); + if (i < 0x3f3f3f3f && moduletypes.size() < i && + moduletypes[i]->kind() == TypeEntryKind::Func) + return Result::Ok; + } + if (expected == Type::FuncRef && actual.IsNewReferenceWithIndex()) { + auto i = actual.GetReferenceIndex(); + if (i < 0x3f3f3f3f && moduletypes.size() < i && + moduletypes[i]->kind() == TypeEntryKind::Func) + return Result::Ok; + } + if (actual.IsNewReferenceWithIndex()) actual = UpCastType(actual); + if (expected.IsNewReferenceWithIndex()) expected = UpCastType(expected); + if (actual.IsNewReferenceWithIndex()&& expected.IsNewReferenceWithIndex()) { + return expected.GetReferenceIndex() == actual.GetReferenceIndex() + ? Result::Ok + : Result::Error; + } + if (actual != expected) { + return Result::Error; + } return Result::Ok; - } - - if (expected == Type::Reference && actual == Type::Reference) { - return expected.GetReferenceIndex() == actual.GetReferenceIndex() - ? Result::Ok - : Result::Error; - } - if (actual != expected) { - return Result::Error; - } - return Result::Ok; } Result TypeChecker::CheckTypes(const TypeVector& actual, @@ -441,6 +493,159 @@ Result TypeChecker::OnBinary(Opcode opcode) { return CheckOpcode2(opcode); } +Result TypeChecker::OnStructNew(Index index , const TypeVector& typeVector) { + Result result = Result::Ok; + const TypeVector fields = typeVector; + int n = fields.size(); + for (int i = n - 1; i >= 0; i--) { + result |= PopAndCheck1Type(fields[i], "struct.new"); + } + PushType(Type(Type::RefNull, index)); + return result; +} +Result TypeChecker::OnStructNewDefault(Index index) { + PushType(Type(Type::RefNull, index)); + return Result::Ok; +} +Result TypeChecker::OnStructGet(Index index, Type type) { + Result result = PopAndCheck1Type(Type(Type::RefNull, index), "struct.get"); + PushType(type); + return result; +} +Result TypeChecker::OnStructSet(Index index, Type type) { + Result result = Result::Ok; + result |= PopAndCheck1Type(type, "struct.set"); + result |= PopAndCheck1Type(Type(Type::RefNull, index), "struct.set"); + return result; +} + +Result TypeChecker::OnArrayNew(Index index, Type type) { + Result result = PopAndCheck1Type(Type::I32, "array.new"); + result |= PopAndCheck1Type(type, "array.new"); + PushType(Type(Type::Ref, index)); + return Result::Ok; +} +Result TypeChecker::OnArrayNewDefault(Index index) { + Result result = PopAndCheck1Type(Type::I32, "array.new_default"); + PushType(Type(Type::Ref, index)); + return result; +} +Result TypeChecker::OnArrayNewFixed(Index index, Type type, Index size) { + Result result = Result::Ok; + for (Index i = 0; i < size; i++) { + result |= PopAndCheck1Type(type, "array.new_fixed"); + } + PushType(Type(Type::Ref, index)); + return result; +} +Result TypeChecker::OnArrayNewData(Index index) { + Result result = PopAndCheck1Type(Type::I32, "array.new_data"); + result |= PopAndCheck1Type(Type::I32, "array.new_data"); + PushType(Type(Type::Ref, index)); + return result; +} +Result TypeChecker::OnArrayNewElem(Index index) { + Result result = PopAndCheck1Type(Type::I32, "array.new_elem"); + result |= PopAndCheck1Type(Type::I32, "array.new_elem"); + PushType(Type(Type::Ref, index)); + return result; +} +Result TypeChecker::OnArrayGet(Index index, Type type) { + Result result = PopAndCheck1Type(Type::I32, "array.get"); + result |= PopAndCheck1Type(Type(Type::RefNull, index), "array.get"); + PushType(type); + return result; +} +Result TypeChecker::OnArraySet(Index index, Type type) { + Result result = Result::Ok; + result |= PopAndCheck1Type(type, "array.set"); + result |= PopAndCheck1Type(Type::I32, "array.set"); + result |= PopAndCheck1Type(Type(Type::RefNull, index), "array.set"); + return result; +} +Result TypeChecker::OnArrayLen() { + Result result = + PopAndCheck1Type(Type(Type::RefNull, Type::ArrayRef), "array.len"); + PushType(Type::I32); + return result; +} +Result TypeChecker::OnArrayFill(Type type1,Type type2) { + Result result = Result::Ok; + result |= PopAndCheck1Type(Type::I32, "array.fill"); + result |= PopAndCheck1Type(type2, "array.fill"); + result |= PopAndCheck1Type(Type::I32, "array.fill"); + result |= PopAndCheck1Type(type1, "array.fill"); + return result; +} +Result TypeChecker::OnArrayCopy(Type type1,Type type2) { + Result result = Result::Ok; + result |= PopAndCheck1Type(Type::I32, "array.copy"); + result |= PopAndCheck1Type(Type::I32, "array.copy"); + result |= PopAndCheck1Type(type2, "array.copy"); + result |= PopAndCheck1Type(Type::I32, "array.copy"); + result |= PopAndCheck1Type(type1, "array.copy"); + return result; +} +Result TypeChecker::OnArrayInitData(Type type) { + Result result = Result::Ok; + result |= PopAndCheck1Type(Type::I32, "array.init_data"); + result |= PopAndCheck1Type(Type::I32, "array.init_data"); + result |= PopAndCheck1Type(Type::I32, "array.init_data"); + result |= PopAndCheck1Type(type, "array.init_data"); + return result; +} + +Result TypeChecker::OnRefTest(Type type) { + Result result = PopAndCheck1Type(Type(Type::RefNull, Type::AnyRef), "ref.test"); + PushType(Type::I32); + return result; +} +Result TypeChecker::OnRefCast(Type type) { + Result result = PopAndCheck1Type(Type(Type::RefNull, Type::AnyRef), "ref.test"); + PushType(type); + return result; +} +Result TypeChecker::OnBrOnCast(Type type1, Type type2) { + Result result = Result::Ok; + result |= PopAndCheck1Type(type1, "br_on_cast_fail"); + if (type2.isRefNull()) { + PushType(Type(Type::Ref, type1.type_index_)); + } else { + PushType(type1); + } + return result; +} + +Result TypeChecker::OnBrOnCastFail(Type type1, Type type2) { + Result result = Result::Ok; + result |= PopAndCheck1Type(type1, "br_on_cast_fail"); + PushType(type2); + return result; +} +Result TypeChecker::OnAnyConvertExtern() { + Result result = Result::Ok; + result |= PopAndCheck1Type(Type(Type::RefNull,Type::ExternRef), "array.init_elem"); + PushType(Type(Type::RefNull, Type::AnyRef)); + return result; +} +Result TypeChecker::OnExternConvertAny() { + Result result = Result::Ok; + result |= PopAndCheck1Type(Type(Type::RefNull,Type::AnyRef), "array.init_elem"); + PushType(Type(Type::RefNull, Type::ExternRef)); + return result; +} + + +Result TypeChecker::OnRefI31() { + Result result = PopAndCheck1Type(Type::I32, "ref.i31"); + PushType(Type(Type::Ref, Type::I31)); + return result; +} +Result TypeChecker::OnI31Get() { + Result result = PopAndCheck1Type(Type(Type::RefNull, Type::I31), "i31.get"); + PushType(Type::I32); + return result; +} Result TypeChecker::OnBlock(const TypeVector& param_types, const TypeVector& result_types) { Result result = PopAndCheckSignature(param_types, "block"); @@ -777,6 +982,12 @@ Result TypeChecker::OnTableFill(Type elem_type) { return PopAndCheck3Types(Type::I32, elem_type, Type::I32, "table.fill"); } +Result TypeChecker::OnRefEq() { + Result result = DropTypes(2); + PushType(Type::I32); + return result; +} + Result TypeChecker::OnRefFuncExpr(Index func_type, bool force_generic_funcref) { /* * In a const expression, treat ref.func as producing a generic funcref. @@ -785,7 +996,7 @@ Result TypeChecker::OnRefFuncExpr(Index func_type, bool force_generic_funcref) { * examined only the validity of the function index. */ if (features_.function_references_enabled() && !force_generic_funcref) { - PushType(Type(Type::Reference, func_type)); + PushType(Type(Type::Ref, func_type)); } else { PushType(Type::FuncRef); } @@ -793,7 +1004,24 @@ Result TypeChecker::OnRefFuncExpr(Index func_type, bool force_generic_funcref) { } Result TypeChecker::OnRefNullExpr(Type type) { - PushType(type); + if (type == Type::Struct) + PushType(Type(Type::RefNull, Type::StructRef)); + else if (type == Type::Array) + PushType(Type(Type::RefNull, Type::ArrayRef)); + else if (type == Type::I31) + PushType(Type(Type::RefNull, Type::I31)); + else if (type == Type::Eq) + PushType(Type(Type::RefNull, Type::Eq)); + else if (type == Type::Any) + PushType(Type(Type::RefNull, Type::AnyRef)); + else if (type == Type::NoneRef) + PushType(Type(Type::RefNull, Type::NoneRef)); + else if (type == Type::NoExtern) + PushType(Type(Type::RefNull, Type::NoExtern)); + else if (type == Type::NoFunc) + PushType(Type(Type::RefNull, Type::NoFunc)); + else + PushType(type); return Result::Ok; } diff --git a/src/validator.cc b/src/validator.cc index dbf3914de..785c3e2b1 100644 --- a/src/validator.cc +++ b/src/validator.cc @@ -29,6 +29,9 @@ #include "wabt/ir.h" #include "wabt/shared-validator.h" +std::vector moduletypes; +std::unordered_map moduletypesname2; + namespace wabt { namespace { @@ -114,6 +117,35 @@ class Validator : public ExprVisitor::Delegate { Result EndIfExpr(IfExpr*) override; Result OnLoadExpr(LoadExpr*) override; Result OnLocalGetExpr(LocalGetExpr*) override; + Result OnStructNewExpr(StructNewExpr*) override; + Result OnStructNewDefaultExpr(StructNewDefaultExpr*) override; + Result OnStructGetExpr(StructGetExpr*) override; + Result OnStructGetUExpr(StructGetUExpr*) override; + Result OnStructGetSExpr(StructGetSExpr*) override; + Result OnStructSetExpr(StructSetExpr*) override; + Result OnArrayNewExpr(ArrayNewExpr*) override; + Result OnArrayNewDefaultExpr(ArrayNewDefaultExpr*) override; + Result OnArrayNewFixedExpr(ArrayNewFixedExpr*) override; + Result OnArrayNewDataExpr(ArrayNewDataExpr*) override; + Result OnArrayNewElemExpr(ArrayNewElemExpr*) override; + Result OnArrayGetExpr(ArrayGetExpr*) override; + Result OnArrayGetSExpr(ArrayGetSExpr*) override; + Result OnArrayGetUExpr(ArrayGetUExpr*) override; + Result OnArraySetExpr(ArraySetExpr*) override; + Result OnArrayLenExpr(ArrayLenExpr*) override; + Result OnArrayFillExpr(ArrayFillExpr*) override; + Result OnArrayCopyExpr(ArrayCopyExpr*) override; + Result OnArrayInitDataExpr(ArrayInitDataExpr*) override; + Result OnArrayInitElemExpr(ArrayInitElemExpr*) override; + Result OnRefTestExpr(RefTestExpr*) override; + Result OnRefCastExpr(RefCastExpr*) override; + Result OnBrOnCastExpr(BrOnCastExpr*) override; + Result OnBrOnCastFailExpr(BrOnCastFailExpr*) override; + Result OnAnyConvertExternExpr(AnyConvertExternExpr*) override; + Result OnExternConvertAnyExpr(ExternConvertAnyExpr*) override; + Result OnRefI31Expr(RefI31Expr*) override; + Result OnI31GetSExpr(I31GetSExpr*) override; + Result OnI31GetUExpr(I31GetUExpr*) override; Result OnLocalSetExpr(LocalSetExpr*) override; Result OnLocalTeeExpr(LocalTeeExpr*) override; Result BeginLoopExpr(LoopExpr*) override; @@ -132,6 +164,7 @@ class Validator : public ExprVisitor::Delegate { Result OnTableGrowExpr(TableGrowExpr*) override; Result OnTableSizeExpr(TableSizeExpr*) override; Result OnTableFillExpr(TableFillExpr*) override; + Result OnRefEqExpr(RefEqExpr*) override; Result OnRefFuncExpr(RefFuncExpr*) override; Result OnRefNullExpr(RefNullExpr*) override; Result OnRefIsNullExpr(RefIsNullExpr*) override; @@ -392,6 +425,127 @@ Result Validator::OnLocalGetExpr(LocalGetExpr* expr) { return Result::Ok; } +Result Validator::OnStructNewExpr(StructNewExpr* expr) { + result_ |= validator_.OnStructNew(expr->loc, expr->var); + return Result::Ok; +} +Result Validator::OnStructNewDefaultExpr(StructNewDefaultExpr* expr) { + result_ |= validator_.OnStructNewDefault(expr->loc, expr->var); + return Result::Ok; +} +Result Validator::OnStructGetExpr(StructGetExpr* expr) { + result_ |= validator_.OnStructGet(expr->loc, expr->var1, expr->var2); + return Result::Ok; +} +Result Validator::OnStructGetUExpr(StructGetUExpr* expr) { + result_ |= validator_.OnStructGetU(expr->loc, expr->var1, expr->var2); + return Result::Ok; +} +Result Validator::OnStructGetSExpr(StructGetSExpr* expr) { + result_ |= validator_.OnStructGetS(expr->loc, expr->var1, expr->var2); + return Result::Ok; +} +Result Validator::OnStructSetExpr(StructSetExpr* expr) { + result_ |= validator_.OnStructSet(expr->loc, expr->var1, expr->var2); + return Result::Ok; +} + +Result Validator::OnArrayNewExpr(ArrayNewExpr* expr) { + result_ |= validator_.OnArrayNew(expr->loc, expr->var); + return Result::Ok; +} +Result Validator::OnArrayNewDefaultExpr(ArrayNewDefaultExpr* expr) { + result_ |= validator_.OnArrayNewDefault(expr->loc, expr->var); + return Result::Ok; +} +Result Validator::OnArrayNewFixedExpr(ArrayNewFixedExpr* expr) { + result_ |= validator_.OnArrayNewFixed(expr->loc, expr->var1, expr->var2); + return Result::Ok; +} +Result Validator::OnArrayNewDataExpr(ArrayNewDataExpr* expr) { + result_ |= validator_.OnArrayNewData(expr->loc, expr->var1, expr->var2); + return Result::Ok; +} +Result Validator::OnArrayNewElemExpr(ArrayNewElemExpr* expr) { + result_ |= validator_.OnArrayNewElem(expr->loc, expr->var1, expr->var2); + return Result::Ok; +} +Result Validator::OnArrayGetExpr(ArrayGetExpr* expr) { + result_ |= validator_.OnArrayGet(expr->loc, expr->var); + return Result::Ok; +} +Result Validator::OnArrayGetSExpr(ArrayGetSExpr* expr) { + result_ |= validator_.OnArrayGetS(expr->loc, expr->var); + return Result::Ok; +} +Result Validator::OnArrayGetUExpr(ArrayGetUExpr* expr) { + result_ |= validator_.OnArrayGetU(expr->loc, expr->var); + return Result::Ok; +} +Result Validator::OnArraySetExpr(ArraySetExpr* expr) { + result_ |= validator_.OnArraySet(expr->loc, expr->var); + return Result::Ok; +} +Result Validator::OnArrayLenExpr(ArrayLenExpr* expr) { + result_ |= validator_.OnArrayLen(expr->loc); + return Result::Ok; +} +Result Validator::OnArrayFillExpr(ArrayFillExpr* expr) { + result_ |= validator_.OnArrayFill(expr->loc, expr->var); + return Result::Ok; +} +Result Validator::OnArrayCopyExpr(ArrayCopyExpr* expr) { + result_ |= validator_.OnArrayCopy(expr->loc, expr->var1, expr->var2); + return Result::Ok; +} +Result Validator::OnArrayInitDataExpr(ArrayInitDataExpr* expr) { + result_ |= validator_.OnArrayInitData(expr->loc, expr->var1, expr->var2); + return Result::Ok; +} +Result Validator::OnArrayInitElemExpr(ArrayInitElemExpr* expr) { + result_ |= validator_.OnArrayInitElem(expr->loc, expr->var1, expr->var2); + return Result::Ok; +} + +Result Validator::OnRefCastExpr(RefCastExpr* expr) { + result_ |= validator_.OnRefCast(expr->loc, expr->var, moduletypesname2); + return Result::Ok; +} +Result Validator::OnRefTestExpr(RefTestExpr* expr) { + result_ |= validator_.OnRefTest(expr->loc, expr->var, moduletypesname2); + return Result::Ok; +} +Result Validator::OnBrOnCastExpr(BrOnCastExpr* expr) { + result_ |= validator_.OnBrOnCast(expr->loc, expr->var1, expr->var2, + expr->var3, moduletypesname2); + return Result::Ok; +} +Result Validator::OnBrOnCastFailExpr(BrOnCastFailExpr* expr) { + result_ |= validator_.OnBrOnCastFail(expr->loc, expr->var1, expr->var2, + expr->var3, moduletypesname2); + return Result::Ok; +} +Result Validator::OnAnyConvertExternExpr(AnyConvertExternExpr* expr) { + result_ |= validator_.OnAnyConvertExtern(expr->loc); + return Result::Ok; +} +Result Validator::OnExternConvertAnyExpr(ExternConvertAnyExpr* expr) { + result_ |= validator_.OnExternConvertAny(expr->loc); + return Result::Ok; +} +Result Validator::OnRefI31Expr(RefI31Expr* expr) { + result_ |= validator_.OnRefI31(expr->loc); + return Result::Ok; +} +Result Validator::OnI31GetSExpr(I31GetSExpr* expr) { + result_ |= validator_.OnI31GetS(expr->loc); + return Result::Ok; +} +Result Validator::OnI31GetUExpr(I31GetUExpr* expr) { + result_ |= validator_.OnI31GetU(expr->loc); + return Result::Ok; +} + Result Validator::OnLocalSetExpr(LocalSetExpr* expr) { result_ |= validator_.OnLocalSet(expr->loc, expr->var); return Result::Ok; @@ -485,6 +639,11 @@ Result Validator::OnTableFillExpr(TableFillExpr* expr) { return Result::Ok; } +Result Validator::OnRefEqExpr(RefEqExpr* expr) { + result_ |= validator_.OnRefEq(expr->loc); + return Result::Ok; +} + Result Validator::OnRefFuncExpr(RefFuncExpr* expr) { result_ |= validator_.OnRefFunc(expr->loc, expr->var); return Result::Ok; @@ -708,6 +867,123 @@ Result Validator::CheckModule() { TypeMut{array_type->field.type, array_type->field.mutable_}); break; } + + case TypeEntryKind::Sub: { + SubType* sub_type = cast(f->type.get()); + std::string str = sub_type->typeEntry->name; + const TypeEntry* type = sub_type->typeEntry.get(); + switch (type->kind()) { + case TypeEntryKind::Func: { + const FuncType* func_type = cast(type); + result_ |= validator_.OnFuncType( + field.loc, func_type->sig.param_types.size(), + func_type->sig.param_types.data(), + func_type->sig.result_types.size(), + func_type->sig.result_types.data(), + module->GetFuncTypeIndex(func_type->sig)); + break; + } + + case TypeEntryKind::Struct: { + const StructType* struct_type = cast(type); + TypeMutVector type_muts; + for (auto&& field : struct_type->fields) { + type_muts.push_back(TypeMut{field.type, field.mutable_}); + } + result_ |= validator_.OnStructType(field.loc, type_muts.size(), + type_muts.data()); + break; + } + + case TypeEntryKind::Array: { + const ArrayType* array_type = cast(type); + result_ |= validator_.OnArrayType( + field.loc, + TypeMut{array_type->field.type, array_type->field.mutable_}); + break; + } + + default:; + } + break; + } + + case TypeEntryKind::Rec: { + RecType* rec_type = cast(f->type.get()); + for (auto& type : rec_type->fields) { + switch (type->kind()) { + case TypeEntryKind::Func: { + const FuncType* func_type = cast(type.get()); + result_ |= validator_.OnFuncType( + field.loc, func_type->sig.param_types.size(), + func_type->sig.param_types.data(), + func_type->sig.result_types.size(), + func_type->sig.result_types.data(), + module->GetFuncTypeIndex(func_type->sig)); + break; + } + + case TypeEntryKind::Struct: { + StructType* struct_type = cast(type.get()); + TypeMutVector type_muts; + for (auto&& field : struct_type->fields) { + type_muts.push_back(TypeMut{field.type, field.mutable_}); + } + result_ |= validator_.OnStructType(field.loc, type_muts.size(), + type_muts.data()); + break; + } + + case TypeEntryKind::Array: { + ArrayType* array_type = cast(type.get()); + result_ |= validator_.OnArrayType( + field.loc, TypeMut{array_type->field.type, + array_type->field.mutable_}); + break; + } + + case TypeEntryKind::Sub: { + SubType* sub_type = cast(type.get()); + std::string str = sub_type->typeEntry->name; + const TypeEntry* type = sub_type->typeEntry.get(); + switch (type->kind()) { + case TypeEntryKind::Func: { + const FuncType* func_type = cast(type); + result_ |= validator_.OnFuncType( + field.loc, func_type->sig.param_types.size(), + func_type->sig.param_types.data(), + func_type->sig.result_types.size(), + func_type->sig.result_types.data(), + module->GetFuncTypeIndex(func_type->sig)); + break; + } + + case TypeEntryKind::Struct: { + const StructType* struct_type = cast(type); + TypeMutVector type_muts; + for (auto&& field : struct_type->fields) { + type_muts.push_back(TypeMut{field.type, field.mutable_}); + } + result_ |= validator_.OnStructType( + field.loc, type_muts.size(), type_muts.data()); + break; + } + + case TypeEntryKind::Array: { + const ArrayType* array_type = cast(type); + result_ |= validator_.OnArrayType( + field.loc, TypeMut{array_type->field.type, + array_type->field.mutable_}); + break; + } + default:; + } + break; + } + default:; + } + } + } } } } @@ -754,6 +1030,7 @@ Result Validator::CheckModule() { } // Func section. + // 拿到函数类型 然后在type section中找到对应的函数类型 for (const ModuleField& field : module->fields) { if (auto* f = dyn_cast(&field)) { result_ |= validator_.OnFunction( @@ -787,6 +1064,7 @@ Result Validator::CheckModule() { ExprVisitor visitor(this); result_ |= visitor.VisitExprList(const_cast(f->global.init_expr)); + // 初始化语句验证 rec类型没处理 但不影响翻译结果 result_ |= validator_.EndInitExpr(); } } @@ -847,6 +1125,7 @@ Result Validator::CheckModule() { validator_.OnDataCount(module->data_segments.size()); // Code section. + // 函数逻辑 Index func_index = module->num_func_imports; for (const ModuleField& field : module->fields) { if (auto* f = dyn_cast(&field)) { @@ -1070,7 +1349,8 @@ Result ValidateModule(const Module* module, Errors* errors, const ValidateOptions& options) { Validator validator(errors, module, options); - + moduletypes = module->types; + moduletypesname2 = module->moduletypesname; return validator.CheckModule(); } diff --git a/src/wast-lexer.cc b/src/wast-lexer.cc index bc7815892..3365eb8f7 100644 --- a/src/wast-lexer.cc +++ b/src/wast-lexer.cc @@ -1,19 +1,3 @@ -/* - * Copyright 2016 WebAssembly Community Group participants - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - #include "wabt/wast-lexer.h" #include @@ -23,6 +7,8 @@ #include "wabt/lexer-source.h" +#include + #define ERROR(...) Error(GetLocation(), __VA_ARGS__) namespace wabt { @@ -443,14 +429,24 @@ bool WastLexer::IsCharClass(int c, CharClass bit) { // (1 if IsIdChar(c) else 0) // for c in map(chr, range(0, 127)) // ]) + + //一共128个 【0-127】 static const char kCharClasses[257] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, - 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 1, 0, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, - 1, 1, 1, 7, 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, + 1, 0, 0, 1, 1, 0, 1, 1, 1, 13, + + 13, 13, 13,13,13,13,13,13,13,1, + 0, 1, 1, 1, 1, 1, 5, 5, 5, 5, + 5, 5, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 1, 0, 1, 1, 1, 7, 7, + + 7, 7, 7, 7, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 0, 1, 0, 1, }; assert(c >= -1 && c < 256); @@ -597,8 +593,7 @@ Token WastLexer::GetIdChars() { Token WastLexer::GetKeywordToken() { ReadReservedChars(); - TokenInfo* info = - Perfect_Hash::InWordSet(token_start_, cursor_ - token_start_); + TokenInfo* info =Perfect_Hash::InWordSet(token_start_, cursor_ - token_start_); if (!info) { return TextToken(TokenType::Reserved); } diff --git a/src/wast-parser.cc b/src/wast-parser.cc index ad4e2e650..d39eb5ea2 100644 --- a/src/wast-parser.cc +++ b/src/wast-parser.cc @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include "wabt/wast-parser.h" #include "wabt/binary-reader-ir.h" @@ -30,6 +29,8 @@ #define EXPECT(token_type) CHECK_RESULT(Expect(TokenType::token_type)) +std::unordered_map moduletypesname1; + namespace wabt { namespace { @@ -165,6 +166,35 @@ bool IsPlainInstr(TokenType token_type) { case TokenType::CallIndirect: case TokenType::CallRef: case TokenType::LocalGet: + case TokenType::StructNew: + case TokenType::StructNewDefault: + case TokenType::StructGet: + case TokenType::StructGetU: + case TokenType::StructGetS: + case TokenType::StructSet: + case TokenType::ArrayNew: + case TokenType::ArrayNewDefault: + case TokenType::ArrayNewFixed: + case TokenType::ArrayNewData: + case TokenType::ArrayNewElem: + case TokenType::ArrayGet: + case TokenType::ArrayGetS: + case TokenType::ArrayGetU: + case TokenType::ArraySet: + case TokenType::ArrayLen: + case TokenType::ArrayFill: + case TokenType::ArrayCopy: + case TokenType::ArrayInitData: + case TokenType::ArrayInitElem: + case TokenType::RefTest: + case TokenType::RefCast: + case TokenType::BrOnCast: + case TokenType::BrOnCastFail: + case TokenType::AnyConvertExtern: + case TokenType::ExternConvertAny: + case TokenType::RefI31: + case TokenType::I31GetS: + case TokenType::I31GetU: case TokenType::LocalSet: case TokenType::LocalTee: case TokenType::GlobalGet: @@ -193,6 +223,7 @@ bool IsPlainInstr(TokenType token_type) { case TokenType::Throw: case TokenType::Rethrow: case TokenType::RefFunc: + case TokenType::RefEq: case TokenType::RefNull: case TokenType::RefIsNull: case TokenType::AtomicLoad: @@ -229,6 +260,7 @@ bool IsPlainOrBlockInstr(TokenType token_type) { return IsPlainInstr(token_type) || IsBlockInstr(token_type); } +// (关键字 bool IsExpr(TokenTypePair pair) { return pair[0] == TokenType::Lpar && IsPlainOrBlockInstr(pair[1]); } @@ -257,6 +289,7 @@ bool IsModuleField(TokenTypePair pair) { case TokenType::Export: case TokenType::Func: case TokenType::Type: + case TokenType::Rec: case TokenType::Global: case TokenType::Import: case TokenType::Memory: @@ -322,8 +355,11 @@ void ResolveTypeName( const auto name_iterator = bindings.find(index); assert(name_iterator != bindings.cend()); + // 不知道为什么 type_bindings 是空的 + // 2023-11-16 已经正确 const auto type_index = module.type_bindings.FindIndex(name_iterator->second); assert(type_index != kInvalidIndex); + // type = Type(Type::Reference, 0); type = Type(Type::Reference, type_index); } @@ -771,6 +807,140 @@ bool WastParser::ParseBindVarOpt(std::string* name) { return true; } +Result WastParser::ParseVarRef(Var* out_var) { + if (PeekMatch(TokenType::Null)) { + Consume(); + if (PeekMatch(TokenType::Nat)) { + Token token = Consume(); + std::string_view sv = token.literal().text; + uint64_t index = kInvalidIndex; + if (Failed(ParseUint64(sv, &index))) { + // Print an error, but don't fail parsing. + Error(token.loc, "invalid int \"" PRIstringview "\"", + WABT_PRINTF_STRING_VIEW_ARG(sv)); + } + *out_var = Var("RefNull" + std::to_string(index), token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::Var)) { + Token token = Consume(); + std::string str = "RefNull" + std::string(token.text()); + *out_var = Var(std::string_view(str), token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::NoFunc)) { + Token token = Consume(); + *out_var = Var("NoFunc", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::NoExtern)) { + Token token = Consume(); + *out_var = Var("NoExtern", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::None)) { + Token token = Consume(); + *out_var = Var("None", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::Func)) { + Token token = Consume(); + *out_var = Var("RefNullFunc", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::Extern)) { + Token token = Consume(); + *out_var = Var("RefNullExtern", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::Any)) { + Token token = Consume(); + *out_var = Var("RefNullAny", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::Eq)) { + Token token = Consume(); + *out_var = Var("RefNullEq", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::I31)) { + Token token = Consume(); + *out_var = Var("RefNullI31", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::Struct)) { + Token token = Consume(); + *out_var = Var("RefNullStruct", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::Array)) { + Token token = Consume(); + *out_var = Var("RefNullArray", token.loc); + return Result::Ok; + } + } + else if (PeekMatch(TokenType::Nat)) { + Token token = Consume(); + std::string_view sv = token.literal().text; + uint64_t index = kInvalidIndex; + if (Failed(ParseUint64(sv, &index))) { + // Print an error, but don't fail parsing. + Error(token.loc, "invalid int \"" PRIstringview "\"", + WABT_PRINTF_STRING_VIEW_ARG(sv)); + } + *out_var = Var(std::to_string(index), token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::Var)) { + Token token = Consume(); + *out_var = Var(token.text(), token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::NoFunc)) { + Token token = Consume(); + *out_var = Var("NoFunc", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::NoExtern)) { + Token token = Consume(); + *out_var = Var("NoExtern", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::None)) { + Token token = Consume(); + *out_var = Var("None", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::Func)) { + Token token = Consume(); + *out_var = Var("Func", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::Extern)) { + Token token = Consume(); + *out_var = Var("Extern", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::Any)) { + Token token = Consume(); + *out_var = Var("Any", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::Eq)) { + Token token = Consume(); + *out_var = Var("Eq", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::I31)) { + Token token = Consume(); + *out_var = Var("I31", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::Array)) { + Token token = Consume(); + *out_var = Var("Array", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::Struct)) { + Token token = Consume(); + *out_var = Var("Struct", token.loc); + return Result::Ok; + } + else { + return ErrorExpected({"a numeric index", "a name"}, "12 or $foo"); + } + return Result::Ok; +} + Result WastParser::ParseVar(Var* out_var) { WABT_TRACE(ParseVar); if (PeekMatch(TokenType::Nat)) { @@ -782,16 +952,128 @@ Result WastParser::ParseVar(Var* out_var) { Error(token.loc, "invalid int \"" PRIstringview "\"", WABT_PRINTF_STRING_VIEW_ARG(sv)); } - *out_var = Var(index, token.loc); return Result::Ok; } else if (PeekMatch(TokenType::Var)) { Token token = Consume(); *out_var = Var(token.text(), token.loc); return Result::Ok; - } else { + } + else if (PeekMatch(TokenType::Null)) { + Consume(); + if (PeekMatch(TokenType::Nat)) { + Token token = Consume(); + std::string_view sv = token.literal().text; + uint64_t index = kInvalidIndex; + if (Failed(ParseUint64(sv, &index))) { + // Print an error, but don't fail parsing. + Error(token.loc, "invalid int \"" PRIstringview "\"", + WABT_PRINTF_STRING_VIEW_ARG(sv)); + } + //*out_var = Var(index, token.loc); + *out_var = Var("RefNull" + std::to_string(index), token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::Var)) { + Token token = Consume(); + std::string str = "RefNull" + std::string(token.text()); + *out_var = Var(std::string_view(str), token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::NoFunc)) { + Token token = Consume(); + *out_var = Var("NoFunc", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::NoExtern)) { + Token token = Consume(); + *out_var = Var("NoExtern", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::None)) { + Token token = Consume(); + *out_var = Var("None", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::Func)) { + Token token = Consume(); + *out_var = Var("RefNullFunc", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::Extern)) { + Token token = Consume(); + *out_var = Var("RefNullExtern", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::Any)) { + Token token = Consume(); + *out_var = Var("RefNullAny", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::Eq)) { + Token token = Consume(); + *out_var = Var("Eq", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::I31)) { + Token token = Consume(); + *out_var = Var("RefNullI31", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::Struct)) { + Token token = Consume(); + *out_var = Var("RefNullStruct", token.loc); + return Result::Ok; + } else if (PeekMatch(TokenType::Array)) { + Token token = Consume(); + *out_var = Var("RefNullArray", token.loc); + return Result::Ok; + } + } + else if (PeekMatch(TokenType::NoFunc)) { + Token token = Consume(); + *out_var = Var("NoFunc", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::NoExtern)) { + Token token = Consume(); + *out_var = Var("NoExtern", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::None)) { + Token token = Consume(); + *out_var = Var("None", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::Func)) { + Token token = Consume(); + *out_var = Var("Func", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::Extern)) { + Token token = Consume(); + *out_var = Var("Extern", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::Any)) { + Token token = Consume(); + *out_var = Var("Any", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::Eq)) { + Token token = Consume(); + *out_var = Var("Eq", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::I31)) { + Token token = Consume(); + *out_var = Var("I31", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::Struct)) { + Token token = Consume(); + *out_var = Var("Struct", token.loc); + return Result::Ok; + } + else if (PeekMatch(TokenType::Array)) { + Token token = Consume(); + *out_var = Var("Array", token.loc); + return Result::Ok; + } + else { return ErrorExpected({"a numeric index", "a name"}, "12 or $foo"); } + return Result::Ok; } bool WastParser::ParseVarOpt(Var* out_var, Var default_var) { @@ -904,6 +1186,7 @@ bool WastParser::ParseElemExprVarListOpt(ExprListVector* out_list) { return !out_list->empty(); } +// 基本类型 Result WastParser::ParseValueType(Var* out_type) { WABT_TRACE(ParseValueType); @@ -918,7 +1201,7 @@ Result WastParser::ParseValueType(Var* out_type) { if (is_ref_type) { EXPECT(Lpar); EXPECT(Ref); - CHECK_RESULT(ParseVar(out_type)); + CHECK_RESULT(ParseVarRef(out_type)); EXPECT(Rpar); return Result::Ok; } @@ -948,6 +1231,56 @@ Result WastParser::ParseValueType(Var* out_type) { return Result::Ok; } +bool isNumber(const std::string& str) { + for (char const& c : str) { + if (std::isdigit(c) == 0) + return false; + } + return true; +} +Type ParseVar2RefType(Var var) { + if (var.is_index()) + return Type(var.index()); + std::string name; + Type ans; + if (var.name().substr(0, 7) == "RefNull") { + ans = Type::RefNull; + name = var.name().substr(7); + } else { + ans = Type::Ref; + name = var.name(); + } + if (isNumber(name)) { + ans.type_index_ = std::stoi(name); + } else if (name == "NoFunc") { + ans.type_index_ = Type::NoFunc; + } else if (name == "NoExtern") { + ans.type_index_ = Type::NoExtern; + } else if (name == "None") { + ans.type_index_ = Type::NoneRef; + } else if (name == "Any") { + ans.type_index_ = Type::AnyRef; + } else if (name == "Func") { + return Type::FuncRef; + } else if (name == "Extern") { + return Type::ExternRef; + } else if (name == "Eq") { + ans.type_index_ = Type::Eq; + } else if (name == "I31") { + ans.type_index_ = Type::I31; + } else if (name == "Struct") { + ans.type_index_ = Type::StructRef; + } else if (name == "Array") { + ans.type_index_ = Type::ArrayRef; + } else { + if (moduletypesname1.find(name) != moduletypesname1.end()) { + ans.type_index_ = moduletypesname1[name]; + } + } + return ans; +} + +// 处理 基本类型的列表 Result WastParser::ParseValueTypeList( TypeVector* out_type_list, std::unordered_map* type_names) { @@ -963,16 +1296,16 @@ Result WastParser::ParseValueTypeList( if (type.is_index()) { out_type_list->push_back(Type(type.index())); } else { - assert(type.is_name()); - assert(options_->features.function_references_enabled()); - type_names->emplace(out_type_list->size(), type.name()); - out_type_list->push_back(Type(Type::Reference, kInvalidIndex)); + out_type_list->push_back(ParseVar2RefType(type)); + // type_names->emplace(out_type_list->size(), type.name()); + // out_type_list->push_back(Type(Type::Ref, kInvalidIndex)); } } return Result::Ok; } +// 解析引用类型 Result WastParser::ParseRefKind(Type* out_type) { WABT_TRACE(ParseRefKind); if (!IsTokenTypeRefKind(Peek())) { @@ -980,6 +1313,11 @@ Result WastParser::ParseRefKind(Type* out_type) { } Token token = Consume(); + if (token.token_type() == TokenType::Var) { + Var type = Var(token.text(), token.loc); + *out_type = ParseVar2RefType(type); + return Result::Ok; + } Type type = token.type(); if ((type == Type::ExternRef && @@ -996,19 +1334,31 @@ Result WastParser::ParseRefKind(Type* out_type) { Result WastParser::ParseRefType(Type* out_type) { WABT_TRACE(ParseRefType); - if (!PeekMatch(TokenType::ValueType)) { - return ErrorExpected({"funcref", "externref"}); - } + if (PeekMatch(TokenType::Lpar)) { + Var type; + CHECK_RESULT(ParseValueType(&type)); + if (type.is_index()) + *out_type = Type(type.index()); + else { + *out_type = ParseVar2RefType(type); + } + return Result::Ok; + } else { + if (!PeekMatch(TokenType::ValueType)) { + return ErrorExpected({"funcref", "externref"}); + } - Token token = Consume(); - Type type = token.type(); - if (type == Type::ExternRef && - !options_->features.reference_types_enabled()) { - Error(token.loc, "value type not allowed: %s", type.GetName().c_str()); - return Result::Error; - } + Token token = Consume(); + Type type = token.type(); + if (type == Type::ExternRef && + !options_->features.reference_types_enabled()) { + Error(token.loc, "value type not allowed: %s", type.GetName().c_str()); + return Result::Error; + } - *out_type = type; + *out_type = type; + return Result::Ok; + } return Result::Ok; } @@ -1293,6 +1643,11 @@ Result WastParser::ParseModuleFieldList(Module* module) { } } CHECK_RESULT(ResolveFuncTypes(module, errors_)); + // 如果使用的参数名出现问题 + // var name类型的 转成index + // 只能处理local.get $a + // 不能处理函数声明 + // 也能处理(func $g (type $g2)) CHECK_RESULT(ResolveNamesModule(module, errors_)); return Result::Ok; } @@ -1306,6 +1661,7 @@ Result WastParser::ParseModuleField(Module* module) { case TokenType::Export: return ParseExportModuleField(module); case TokenType::Func: return ParseFuncModuleField(module); case TokenType::Type: return ParseTypeModuleField(module); + case TokenType::Rec: return ParseRecModuleField(module); case TokenType::Global: return ParseGlobalModuleField(module); case TokenType::Import: return ParseImportModuleField(module); case TokenType::Memory: return ParseMemoryModuleField(module); @@ -1402,7 +1758,17 @@ Result WastParser::ParseElemModuleField(Module* module) { CHECK_RESULT(ParseOffsetExpr(&field->elem_segment.offset)); } - if (ParseRefTypeOpt(&field->elem_segment.elem_type)) { + if (PeekMatchLpar(TokenType::Ref)) { + Var type; + CHECK_RESULT(ParseValueType(&type)); + if (type.is_index()) + field->elem_segment.elem_type = Type(type.index()); + else { + field->elem_segment.elem_type = ParseVar2RefType(type); + } + ParseElemExprListOpt(&field->elem_segment.elem_exprs); + } + else if (ParseRefTypeOpt(&field->elem_segment.elem_type)) { ParseElemExprListOpt(&field->elem_segment.elem_exprs); } else { field->elem_segment.elem_type = Type::FuncRef; @@ -1495,12 +1861,15 @@ Result WastParser::ParseFuncModuleField(Module* module) { Func& func = field->func; func.loc = GetLocation(); CHECK_RESULT(ParseTypeUseOpt(&func.decl)); + // 处理输入和输出 CHECK_RESULT(ParseFuncSignature(&func.decl.sig, &func.bindings)); + // 处理local输入 TypeVector local_types; CHECK_RESULT(ParseBoundValueTypeList( TokenType::Local, &local_types, &func.bindings, &func.decl.sig.param_type_names, func.GetNumParams())); func.local_types.Set(local_types); + // 处理函数体 CHECK_RESULT(ParseTerminatingInstrList(&func.exprs)); module->AppendField(std::move(field)); } @@ -1511,6 +1880,113 @@ Result WastParser::ParseFuncModuleField(Module* module) { return Result::Ok; } +Result WastParser::ParseSubType(std::unique_ptr& typeEntry) { + std::string name = ""; + ParseBindVarOpt(&name); + EXPECT(Lpar); + Location loc = GetLocation(); + + if (Match(TokenType::Func)) { + auto func_type = std::make_unique(name); + BindingHash bindings; + CHECK_RESULT(ParseFuncSignature(&func_type->sig, &bindings)); + CHECK_RESULT(ErrorIfLpar({"param", "result"})); + typeEntry = std::move(func_type); + } + // struct 部分 + else if (Match(TokenType::Struct)) { + if (!options_->features.gc_enabled()) { + Error(loc, "struct not allowed"); + return Result::Error; + } + auto struct_type = std::make_unique(name); + CHECK_RESULT(ParseFieldList(&struct_type->fields)); + typeEntry = std::move(struct_type); + } + // array 部分 + else if (Match(TokenType::Array)) { + if (!options_->features.gc_enabled()) { + Error(loc, "array type not allowed"); + } + auto array_type = std::make_unique(name); + CHECK_RESULT(ParseField(&array_type->field)); + typeEntry = std::move(array_type); + } else { + return ErrorExpected({"func", "struct", "array"}); + } + + // func 的括号 + EXPECT(Rpar); + return Result::Ok; +} + +Result WastParser::ParseRecModuleField(Module* module) { + EXPECT(Lpar); + auto field = std::make_unique(GetLocation()); + EXPECT(Rec); + std::string name; + ParseBindVarOpt(&name); + auto rec_type = std::make_unique(name); + + while (PeekMatchLpar(TokenType::Type)) { + EXPECT(Lpar); + EXPECT(Type); + + std::string name; + ParseBindVarOpt(&name); + EXPECT(Lpar); + Location loc = GetLocation(); + + if (Match(TokenType::Func)) { + auto func_type = std::make_unique(name); + BindingHash bindings; + CHECK_RESULT(ParseFuncSignature(&func_type->sig, &bindings)); + CHECK_RESULT(ErrorIfLpar({"param", "result"})); + rec_type->fields.push_back(std::move(func_type)); + } else if (Match(TokenType::Struct)) { + if (!options_->features.gc_enabled()) { + Error(loc, "struct not allowed"); + return Result::Error; + } + auto struct_type = std::make_unique(name); + CHECK_RESULT(ParseFieldList(&struct_type->fields)); + // 检查fields的name是否冗余 + int n = struct_type->fields.size(); + for (int i = 0; i < n; i++) { + if (struct_type->fields[i].name == "") + continue; + for (int j = i + 1; j < n; j++) { + if (struct_type->fields[i].name == struct_type->fields[j].name) { + Error(loc, "struct field is duplicate"); + return Result::Error; + } + } + } + rec_type->fields.push_back(std::move(struct_type)); + } else if (Match(TokenType::Array)) { + if (!options_->features.gc_enabled()) { + Error(loc, "array type not allowed"); + } + auto array_type = std::make_unique(name); + CHECK_RESULT(ParseField(&array_type->field)); + rec_type->fields.push_back(std::move(array_type)); + } else if (Match(TokenType::Sub)) { + auto sub_type = std::make_unique(name); + ParseSubType(sub_type->typeEntry); + rec_type->fields.push_back(std::move(sub_type)); + } else { + return ErrorExpected({"func", "struct", "array", "sub"}); + } + EXPECT(Rpar); + EXPECT(Rpar); + } + + EXPECT(Rpar); + field->type = std::move(rec_type); + module->AppendFieldRec(std::move(field)); + return Result::Ok; +} + Result WastParser::ParseTypeModuleField(Module* module) { WABT_TRACE(ParseTypeModuleField); EXPECT(Lpar); @@ -1535,6 +2011,18 @@ Result WastParser::ParseTypeModuleField(Module* module) { } auto struct_type = std::make_unique(name); CHECK_RESULT(ParseFieldList(&struct_type->fields)); + // 检查fields的name是否冗余 + int n = struct_type->fields.size(); + for (int i = 0; i < n; i++) { + if (struct_type->fields[i].name == "") + continue; + for (int j = i + 1; j < n; j++) { + if (struct_type->fields[i].name == struct_type->fields[j].name) { + Error(loc, "struct field is duplicate"); + return Result::Error; + } + } + } field->type = std::move(struct_type); } else if (Match(TokenType::Array)) { if (!options_->features.gc_enabled()) { @@ -1543,16 +2031,25 @@ Result WastParser::ParseTypeModuleField(Module* module) { auto array_type = std::make_unique(name); CHECK_RESULT(ParseField(&array_type->field)); field->type = std::move(array_type); + } else if (Match(TokenType::Sub)) { + auto sub_type = std::make_unique(name); + ParseSubType(sub_type->typeEntry); + field->type = std::move(sub_type); } else { - return ErrorExpected({"func", "struct", "array"}); + return ErrorExpected({"func", "struct", "array", "sub"}); } + // func 的括号 EXPECT(Rpar); + // type 的括号 EXPECT(Rpar); module->AppendField(std::move(field)); return Result::Ok; } +/* + (field ...) +*/ Result WastParser::ParseField(Field* field) { WABT_TRACE(ParseField); auto parse_mut_valuetype = [&]() -> Result { @@ -1561,13 +2058,21 @@ Result WastParser::ParseField(Field* field) { field->mutable_ = true; Var type; CHECK_RESULT(ParseValueType(&type)); - field->type = Type(type.index()); + if (type.is_index()) + field->type = Type(type.index()); + else { + field->type = ParseVar2RefType(type); + } EXPECT(Rpar); } else { field->mutable_ = false; Var type; CHECK_RESULT(ParseValueType(&type)); - field->type = Type(type.index()); + if (type.is_index()) + field->type = Type(type.index()); + else { + field->type = ParseVar2RefType(type); + } } return Result::Ok; }; @@ -1583,12 +2088,88 @@ Result WastParser::ParseField(Field* field) { return Result::Ok; } +Result WastParser::ParseStructField(std::vector& fields) { + auto parse_mut_valuetype = [&]() -> Result { + // TODO: Share with ParseGlobalType? + if (MatchLpar(TokenType::Mut)) { + while (!PeekMatch(TokenType::Rpar)) { + Field* field = new Field(); + field->mutable_ = true; + Var type; + CHECK_RESULT(ParseValueType(&type)); + if (type.is_index()) + field->type = Type(type.index()); + else { + field->type = ParseVar2RefType(type); + } + fields.push_back(field); + } + EXPECT(Rpar); + } else { + while (!PeekMatch(TokenType::Rpar)) { + if (PeekMatchLpar(TokenType::Mut)) { + Consume(); + Consume(); + Field* field = new Field(); + field->mutable_ = true; + Var type; + CHECK_RESULT(ParseValueType(&type)); + if (type.is_index()) + field->type = Type(type.index()); + else { + field->type = ParseVar2RefType(type); + } + fields.push_back(field); + EXPECT(Rpar); + } + else { + Field* field = new Field(); + field->mutable_ = false; + Var type; + CHECK_RESULT(ParseValueType(&type)); + if (type.is_index()) + field->type = Type(type.index()); + else { + field->type = ParseVar2RefType(type); + } + fields.push_back(field); + } + } + } + return Result::Ok; + }; + + if (MatchLpar(TokenType::Field)) { + // 处理field的名字 + std::string name; + ParseBindVarOpt(&name); + CHECK_RESULT(parse_mut_valuetype()); + if (fields.size() >= 1) + fields[0]->name = name; + EXPECT(Rpar); + } else { + CHECK_RESULT(parse_mut_valuetype()); + } + + return Result::Ok; +} + Result WastParser::ParseFieldList(std::vector* fields) { + // 解析field列表 + // (type(struct(field i32 i32))) WABT_TRACE(ParseFieldList); while (PeekMatch(TokenType::ValueType) || PeekMatch(TokenType::Lpar)) { - Field field; - CHECK_RESULT(ParseField(&field)); - fields->push_back(field); + if (PeekMatch(TokenType::ValueType)) { + Field field; + CHECK_RESULT(ParseField(&field)); + fields->push_back(field); + } else { + std::vector field; + CHECK_RESULT(ParseStructField(field)); + for (std::vector::size_type i = 0; i < field.size(); i++) { + fields->push_back(*field[i]); + } + } } return Result::Ok; } @@ -1614,7 +2195,9 @@ Result WastParser::ParseGlobalModuleField(Module* module) { module->AppendField(std::move(field)); } else { auto field = std::make_unique(loc, name); - CHECK_RESULT(ParseGlobalType(&field->global)); + // 处理global的类型 + CHECK_RESULT(ParseGlobalType(&field->global, module)); + // 处理global的初始化 CHECK_RESULT(ParseTerminatingInstrList(&field->global.init_expr)); module->AppendField(std::move(field)); } @@ -1847,11 +2430,21 @@ Result WastParser::ParseExportDesc(Export* export_) { WABT_TRACE(ParseExportDesc); EXPECT(Lpar); switch (Peek()) { - case TokenType::Func: export_->kind = ExternalKind::Func; break; - case TokenType::Table: export_->kind = ExternalKind::Table; break; - case TokenType::Memory: export_->kind = ExternalKind::Memory; break; - case TokenType::Global: export_->kind = ExternalKind::Global; break; - case TokenType::Tag: export_->kind = ExternalKind::Tag; break; + case TokenType::Func: + export_->kind = ExternalKind::Func; + break; + case TokenType::Table: + export_->kind = ExternalKind::Table; + break; + case TokenType::Memory: + export_->kind = ExternalKind::Memory; + break; + case TokenType::Global: + export_->kind = ExternalKind::Global; + break; + case TokenType::Tag: + export_->kind = ExternalKind::Tag; + break; default: return ErrorExpected({"an external kind"}); } @@ -1901,8 +2494,10 @@ Result WastParser::ParseTypeUseOpt(FuncDeclaration* decl) { Result WastParser::ParseFuncSignature(FuncSignature* sig, BindingHash* param_bindings) { WABT_TRACE(ParseFuncSignature); + // 函数输入 CHECK_RESULT(ParseBoundValueTypeList(TokenType::Param, &sig->param_types, param_bindings, &sig->param_type_names)); + // 函数输出 CHECK_RESULT(ParseResultList(&sig->result_types, &sig->result_type_names)); return Result::Ok; } @@ -1915,6 +2510,7 @@ Result WastParser::ParseUnboundFuncSignature(FuncSignature* sig) { return Result::Ok; } +// 处理函数输入 Result WastParser::ParseBoundValueTypeList( TokenType token, TypeVector* types, @@ -1937,7 +2533,7 @@ Result WastParser::ParseBoundValueTypeList( assert(type.is_name()); assert(options_->features.function_references_enabled()); type_names->emplace(binding_index_offset + types->size(), type.name()); - types->push_back(Type(Type::Reference, kInvalidIndex)); + types->push_back(ParseVar2RefType(type)); } } else { CHECK_RESULT(ParseValueTypeList(types, type_names)); @@ -1947,6 +2543,7 @@ Result WastParser::ParseBoundValueTypeList( return Result::Ok; } +// 处理函数输出主要内容 Result WastParser::ParseUnboundValueTypeList( TokenType token, TypeVector* types, @@ -1959,6 +2556,7 @@ Result WastParser::ParseUnboundValueTypeList( return Result::Ok; } +// 处理函数输出 Result WastParser::ParseResultList( TypeVector* result_types, std::unordered_map* type_names) { @@ -1966,13 +2564,17 @@ Result WastParser::ParseResultList( return ParseUnboundValueTypeList(TokenType::Result, result_types, type_names); } +// 处理函数体主要内容 Result WastParser::ParseInstrList(ExprList* exprs) { WABT_TRACE(ParseInstrList); ExprList new_exprs; while (true) { + // 每一次读取一条语句 auto pair = PeekPair(); if (IsInstr(pair)) { + // 是语句 or (语句 都可以识别 if (Succeeded(ParseInstr(&new_exprs))) { + // splice加到exprs的末尾 exprs->splice(exprs->end(), new_exprs); } else { CHECK_RESULT(Synchronize(IsInstr)); @@ -1990,8 +2592,10 @@ Result WastParser::ParseInstrList(ExprList* exprs) { return Result::Ok; } +// 处理函数体 Result WastParser::ParseTerminatingInstrList(ExprList* exprs) { WABT_TRACE(ParseTerminatingInstrList); + // 处理函数体 Result result = ParseInstrList(exprs); // An InstrList often has no further Lpar following it, because it would have // gobbled it up. So if there is a following Lpar it is an error. If we @@ -2003,16 +2607,19 @@ Result WastParser::ParseTerminatingInstrList(ExprList* exprs) { Result WastParser::ParseInstr(ExprList* exprs) { WABT_TRACE(ParseInstr); if (IsPlainInstr(Peek())) { + // 一般进入这里 std::unique_ptr expr; CHECK_RESULT(ParsePlainInstr(&expr)); exprs->push_back(std::move(expr)); return Result::Ok; } else if (IsBlockInstr(Peek())) { + // 循环结构。。。 std::unique_ptr expr; CHECK_RESULT(ParseBlockInstr(&expr)); exprs->push_back(std::move(expr)); return Result::Ok; } else if (PeekMatchExpr()) { + // (i32.add 进入这里 return ParseExpr(exprs); } else { assert(!"ParseInstr should only be called when IsInstr() is true"); @@ -2042,6 +2649,51 @@ Result WastParser::ParsePlainInstrVar(Location loc, return Result::Ok; } +template +Result WastParser::ParsePlainStructGetInstrVar( + Location loc, + std::unique_ptr* out_expr) { + Var var1; + CHECK_RESULT(ParseVar(&var1)); + Var var2; + CHECK_RESULT(ParseVar(&var2)); + out_expr->reset(new T(var1, var2, loc)); + return Result::Ok; +} + +template +Result WastParser::ParsePlainInstrVar2(Location loc, + std::unique_ptr* out_expr) { + Var var1; + CHECK_RESULT(ParseVar(&var1)); + Var var2; + CHECK_RESULT(ParseVar(&var2)); + out_expr->reset(new T(var1, var2, loc)); + return Result::Ok; +} + +template +Result WastParser::ParsePlainInstrVar3(Location loc, + std::unique_ptr* out_expr) { + Var var1; + CHECK_RESULT(ParseVar(&var1)); + Var var2; + CHECK_RESULT(ParseValueType(&var2)); + Var var3; + CHECK_RESULT(ParseValueType(&var3)); + out_expr->reset(new T(var1, var2, var3, loc)); + return Result::Ok; +} + +template +Result WastParser::ParsePlainInstrVarRef(Location loc, + std::unique_ptr* out_expr) { + Var var1; + CHECK_RESULT(ParseValueType(&var1)); + out_expr->reset(new T(var1, loc)); + return Result::Ok; +} + template Result WastParser::ParseMemoryInstrVar(Location loc, std::unique_ptr* out_expr) { @@ -2174,6 +2826,7 @@ Result WastParser::ParseSimdLane(Location loc, uint64_t* lane_idx) { return Result::Ok; } +// 解析简单指令 Result WastParser::ParsePlainInstr(std::unique_ptr* out_expr) { WABT_TRACE(ParsePlainInstr); Location loc = GetLocation(); @@ -2270,6 +2923,132 @@ Result WastParser::ParsePlainInstr(std::unique_ptr* out_expr) { CHECK_RESULT(ParsePlainInstrVar(loc, out_expr)); break; + case TokenType::StructNew: + Consume(); + CHECK_RESULT(ParsePlainInstrVar(loc, out_expr)); + break; + + case TokenType::StructNewDefault: + Consume(); + CHECK_RESULT(ParsePlainInstrVar(loc, out_expr)); + break; + + case TokenType::StructGet: + Consume(); + CHECK_RESULT(ParsePlainStructGetInstrVar(loc, out_expr)); + break; + + case TokenType::StructGetU: + Consume(); + CHECK_RESULT(ParsePlainStructGetInstrVar(loc, out_expr)); + break; + + case TokenType::StructGetS: + Consume(); + CHECK_RESULT(ParsePlainStructGetInstrVar(loc, out_expr)); + break; + + case TokenType::StructSet: + Consume(); + CHECK_RESULT(ParsePlainStructGetInstrVar(loc, out_expr)); + break; + + case TokenType::ArrayNew: + Consume(); + CHECK_RESULT(ParsePlainInstrVar(loc, out_expr)); + break; + + case TokenType::ArrayNewDefault: + Consume(); + CHECK_RESULT(ParsePlainInstrVar(loc, out_expr)); + break; + + case TokenType::ArrayNewFixed: + Consume(); + CHECK_RESULT(ParsePlainInstrVar2(loc, out_expr)); + break; + case TokenType::ArrayNewData: + Consume(); + CHECK_RESULT(ParsePlainInstrVar2(loc, out_expr)); + break; + case TokenType::ArrayNewElem: + Consume(); + CHECK_RESULT(ParsePlainInstrVar2(loc, out_expr)); + break; + case TokenType::ArrayGet: + Consume(); + CHECK_RESULT(ParsePlainInstrVar(loc, out_expr)); + break; + case TokenType::ArrayGetS: + Consume(); + CHECK_RESULT(ParsePlainInstrVar(loc, out_expr)); + break; + case TokenType::ArrayGetU: + Consume(); + CHECK_RESULT(ParsePlainInstrVar(loc, out_expr)); + break; + case TokenType::ArraySet: + Consume(); + CHECK_RESULT(ParsePlainInstrVar(loc, out_expr)); + break; + case TokenType::ArrayLen: + Consume(); + out_expr->reset(new ArrayLenExpr(loc)); + break; + case TokenType::ArrayFill: + Consume(); + CHECK_RESULT(ParsePlainInstrVar(loc, out_expr)); + break; + case TokenType::ArrayCopy: + Consume(); + CHECK_RESULT(ParsePlainInstrVar2(loc, out_expr)); + break; + case TokenType::ArrayInitData: + Consume(); + CHECK_RESULT(ParsePlainInstrVar2(loc, out_expr)); + break; + case TokenType::ArrayInitElem: + Consume(); + CHECK_RESULT(ParsePlainInstrVar2(loc, out_expr)); + break; + +case TokenType::RefCast: + Consume(); + CHECK_RESULT(ParsePlainInstrVarRef(loc, out_expr)); + break; + case TokenType::RefTest: + Consume(); + CHECK_RESULT(ParsePlainInstrVarRef(loc, out_expr)); + break; + case TokenType::BrOnCast: + Consume(); + CHECK_RESULT(ParsePlainInstrVar3(loc, out_expr)); + break; + case TokenType::BrOnCastFail: + Consume(); + CHECK_RESULT(ParsePlainInstrVar3(loc, out_expr)); + break; + case TokenType::AnyConvertExtern: + Consume(); + out_expr->reset(new AnyConvertExternExpr(loc)); + break; + case TokenType::ExternConvertAny: + Consume(); + out_expr->reset(new ExternConvertAnyExpr(loc)); + break; + case TokenType::RefI31: + Consume(); + out_expr->reset(new RefI31Expr(loc)); + break; + case TokenType::I31GetS: + Consume(); + out_expr->reset(new I31GetSExpr(loc)); + break; + case TokenType::I31GetU: + Consume(); + out_expr->reset(new I31GetUExpr(loc)); + break; + case TokenType::LocalSet: Consume(); CHECK_RESULT(ParsePlainInstrVar(loc, out_expr)); @@ -2312,8 +3091,10 @@ Result WastParser::ParsePlainInstr(std::unique_ptr* out_expr) { break; } + // i32.add i32.sub case TokenType::Binary: { Token token = Consume(); + // 检查opcode是否合法 ? 存在? ErrorUnlessOpcodeEnabled(token); out_expr->reset(new BinaryExpr(token.opcode(), loc)); break; @@ -2440,10 +3221,23 @@ Result WastParser::ParsePlainInstr(std::unique_ptr* out_expr) { CHECK_RESULT(ParsePlainInstrVar(loc, out_expr)); break; + case TokenType::RefEq: + Consume(); + out_expr->reset(new RefEqExpr(loc)); + break; + case TokenType::RefNull: { ErrorUnlessOpcodeEnabled(Consume()); Type type; CHECK_RESULT(ParseRefKind(&type)); + if (type == Type::Struct) type = Type(Type::RefNull, Type::StructRef); + else if (type == Type::Array) type = Type(Type::RefNull, Type::ArrayRef); + else if (type == Type::I31) type = Type(Type::RefNull, Type::I31); + else if (type == Type::Eq) type = Type(Type::RefNull, Type::Eq); + else if (type == Type::Any) type = Type(Type::RefNull, Type::AnyRef); + else if (type == Type::NoneRef) type = Type(Type::RefNull, Type::NoneRef); + else if (type == Type::NoExtern) type = Type(Type::RefNull, Type::NoExtern); + else if (type == Type::NoFunc) type = Type(Type::RefNull, Type::NoFunc); out_expr->reset(new RefNullExpr(type, loc)); break; } @@ -2584,12 +3378,32 @@ Result WastParser::ParseSimdV128Const(Const* const_, uint8_t lane_count = 0; bool integer = true; switch (token_type) { - case TokenType::I8X16: { lane_count = 16; break; } - case TokenType::I16X8: { lane_count = 8; break; } - case TokenType::I32X4: { lane_count = 4; break; } - case TokenType::I64X2: { lane_count = 2; break; } - case TokenType::F32X4: { lane_count = 4; integer = false; break; } - case TokenType::F64X2: { lane_count = 2; integer = false; break; } + case TokenType::I8X16: { + lane_count = 16; + break; + } + case TokenType::I16X8: { + lane_count = 8; + break; + } + case TokenType::I32X4: { + lane_count = 4; + break; + } + case TokenType::I64X2: { + lane_count = 2; + break; + } + case TokenType::F32X4: { + lane_count = 4; + integer = false; + break; + } + case TokenType::F64X2: { + lane_count = 2; + integer = false; + break; + } default: { Error(const_->loc, "Unexpected type at start of simd constant. " @@ -3032,6 +3846,7 @@ Result WastParser::ParseBlock(Block* block) { return Result::Ok; } +// 解析指令列表 Result WastParser::ParseExprList(ExprList* exprs) { WABT_TRACE(ParseExprList); ExprList new_exprs; @@ -3045,6 +3860,7 @@ Result WastParser::ParseExprList(ExprList* exprs) { return Result::Ok; } +// 解析表达式 非简单指令 (+keywords Result WastParser::ParseExpr(ExprList* exprs) { WABT_TRACE(ParseExpr); if (!PeekMatch(TokenType::Lpar)) { @@ -3052,13 +3868,17 @@ Result WastParser::ParseExpr(ExprList* exprs) { } if (IsPlainInstr(Peek(1))) { + // 简单指令 Consume(); std::unique_ptr expr; + // 解析简单指令 CHECK_RESULT(ParsePlainInstr(&expr)); + // 解析参数列表 CHECK_RESULT(ParseExprList(exprs)); CHECK_RESULT(ErrorIfLpar({"an expr"})); exprs->push_back(std::move(expr)); } else { + // 复杂指令 Location loc = GetLocation(); switch (Peek(1)) { @@ -3222,19 +4042,28 @@ Result WastParser::ParseCatchExprList(CatchVector* catches) { return Result::Ok; } -Result WastParser::ParseGlobalType(Global* global) { +Result WastParser::ParseGlobalType(Global* global, Module* module) { WABT_TRACE(ParseGlobalType); if (MatchLpar(TokenType::Mut)) { global->mutable_ = true; Var type; CHECK_RESULT(ParseValueType(&type)); - global->type = Type(type.index()); + if (type.is_index()) { + global->type = Type(type.index()); + } else { + global->type = ParseVar2RefType(type); + } + // global->type = Type(type.index()); CHECK_RESULT(ErrorIfLpar({"i32", "i64", "f32", "f64"})); EXPECT(Rpar); } else { Var type; CHECK_RESULT(ParseValueType(&type)); - global->type = Type(type.index()); + if (type.is_index()) { + global->type = Type(type.index()); + } else { + global->type = ParseVar2RefType(type); + } } return Result::Ok; @@ -3691,8 +4520,11 @@ Result ParseWatModule(WastLexer* lexer, WastParseOptions* options) { assert(out_module != nullptr); assert(options != nullptr); + if (*out_module != NULL) + moduletypesname1 = (*out_module)->moduletypesname; WastParser parser(lexer, errors, options); CHECK_RESULT(parser.ParseModule(out_module)); + (*out_module)->moduletypesname = moduletypesname1; return Result::Ok; } diff --git a/src/wat-writer.cc b/src/wat-writer.cc index 88ff60ba5..9ed759431 100644 --- a/src/wat-writer.cc +++ b/src/wat-writer.cc @@ -570,6 +570,36 @@ class WatWriter::ExprVisitorDelegate : public ExprVisitor::Delegate { Result EndIfExpr(IfExpr*) override; Result OnLoadExpr(LoadExpr*) override; Result OnLocalGetExpr(LocalGetExpr*) override; + Result OnStructNewExpr(StructNewExpr*) override; + Result OnStructNewDefaultExpr(StructNewDefaultExpr*) override; + Result OnStructGetExpr(StructGetExpr*) override; + Result OnStructGetUExpr(StructGetUExpr*) override; + Result OnStructGetSExpr(StructGetSExpr*) override; + Result OnStructSetExpr(StructSetExpr*) override; + Result OnArrayNewExpr(ArrayNewExpr*) override; + Result OnArrayNewDefaultExpr(ArrayNewDefaultExpr*) override; + Result OnArrayNewFixedExpr(ArrayNewFixedExpr*) override; + Result OnArrayNewDataExpr(ArrayNewDataExpr*) override; + Result OnArrayNewElemExpr(ArrayNewElemExpr*) override; + Result OnArrayGetExpr(ArrayGetExpr*) override; + Result OnArrayGetUExpr(ArrayGetUExpr*) override; + Result OnArrayGetSExpr(ArrayGetSExpr*) override; + Result OnArraySetExpr(ArraySetExpr*) override; + Result OnArrayLenExpr(ArrayLenExpr*) override; + Result OnArrayFillExpr(ArrayFillExpr*) override; + Result OnArrayCopyExpr(ArrayCopyExpr*) override; + Result OnArrayInitDataExpr(ArrayInitDataExpr*) override; + Result OnArrayInitElemExpr(ArrayInitElemExpr*) override; + + Result OnRefTestExpr(RefTestExpr*) override; + Result OnRefCastExpr(RefCastExpr*) override; + Result OnBrOnCastExpr(BrOnCastExpr*) override; + Result OnBrOnCastFailExpr(BrOnCastFailExpr*) override; + Result OnAnyConvertExternExpr(AnyConvertExternExpr*) override; + Result OnExternConvertAnyExpr(ExternConvertAnyExpr*) override; + Result OnRefI31Expr(RefI31Expr*) override; + Result OnI31GetSExpr(I31GetSExpr*) override; + Result OnI31GetUExpr(I31GetUExpr*) override; Result OnLocalSetExpr(LocalSetExpr*) override; Result OnLocalTeeExpr(LocalTeeExpr*) override; Result BeginLoopExpr(LoopExpr*) override; @@ -588,6 +618,7 @@ class WatWriter::ExprVisitorDelegate : public ExprVisitor::Delegate { Result OnTableGrowExpr(TableGrowExpr*) override; Result OnTableSizeExpr(TableSizeExpr*) override; Result OnTableFillExpr(TableFillExpr*) override; + Result OnRefEqExpr(RefEqExpr*) override; Result OnRefFuncExpr(RefFuncExpr*) override; Result OnRefNullExpr(RefNullExpr*) override; Result OnRefIsNullExpr(RefIsNullExpr*) override; @@ -753,6 +784,59 @@ Result WatWriter::ExprVisitorDelegate::OnLoadExpr(LoadExpr* expr) { writer_->WriteMemoryLoadStoreExpr(expr); return Result::Ok; } +Result WatWriter::ExprVisitorDelegate::OnStructNewExpr(StructNewExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnStructNewDefaultExpr(StructNewDefaultExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnStructGetExpr(StructGetExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnStructGetUExpr(StructGetUExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnStructGetSExpr(StructGetSExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnStructSetExpr(StructSetExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnArrayNewExpr(ArrayNewExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnArrayNewDefaultExpr(ArrayNewDefaultExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnArrayNewFixedExpr(ArrayNewFixedExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnArrayNewDataExpr(ArrayNewDataExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnArrayNewElemExpr(ArrayNewElemExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnArrayGetExpr(ArrayGetExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnArrayGetUExpr(ArrayGetUExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnArrayGetSExpr(ArrayGetSExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnArraySetExpr(ArraySetExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnArrayLenExpr(ArrayLenExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnArrayFillExpr(ArrayFillExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnArrayCopyExpr(ArrayCopyExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnArrayInitDataExpr(ArrayInitDataExpr*) {return Result::Ok;} +Result WatWriter::ExprVisitorDelegate::OnArrayInitElemExpr(ArrayInitElemExpr*) {return Result::Ok;} + +Result WatWriter::ExprVisitorDelegate::OnRefTestExpr(RefTestExpr* expr) { + return Result::Ok; +} +Result WatWriter::ExprVisitorDelegate::OnRefCastExpr(RefCastExpr* expr) { + return Result::Ok; +} +Result WatWriter::ExprVisitorDelegate::OnBrOnCastExpr(BrOnCastExpr*) { + return Result::Ok; +} +Result WatWriter::ExprVisitorDelegate::OnBrOnCastFailExpr(BrOnCastFailExpr*) { + return Result::Ok; +} +Result WatWriter::ExprVisitorDelegate::OnAnyConvertExternExpr(AnyConvertExternExpr* expr) { + writer_->WritePutsSpace(Opcode::AnyConvertExtern_Opcode.GetName()); + return Result::Ok; +} +Result WatWriter::ExprVisitorDelegate::OnExternConvertAnyExpr(ExternConvertAnyExpr* expr) { + writer_->WritePutsSpace(Opcode::ExternConvertAny_Opcode.GetName()); + return Result::Ok; +} +Result WatWriter::ExprVisitorDelegate::OnRefI31Expr(RefI31Expr* expr) { + writer_->WritePutsSpace(Opcode::RefI31_Opcode.GetName()); + return Result::Ok; +} +Result WatWriter::ExprVisitorDelegate::OnI31GetSExpr(I31GetSExpr* expr) { + writer_->WritePutsSpace(Opcode::I31GetS_Opcode.GetName()); + return Result::Ok; +} +Result WatWriter::ExprVisitorDelegate::OnI31GetUExpr(I31GetUExpr* expr) { + writer_->WritePutsSpace(Opcode::I31GetU_Opcode.GetName()); + return Result::Ok; +} Result WatWriter::ExprVisitorDelegate::OnLocalGetExpr(LocalGetExpr* expr) { writer_->WritePutsSpace(Opcode::LocalGet_Opcode.GetName()); @@ -760,6 +844,7 @@ Result WatWriter::ExprVisitorDelegate::OnLocalGetExpr(LocalGetExpr* expr) { return Result::Ok; } + Result WatWriter::ExprVisitorDelegate::OnLocalSetExpr(LocalSetExpr* expr) { writer_->WritePutsSpace(Opcode::LocalSet_Opcode.GetName()); writer_->WriteVar(expr->var, NextChar::Newline); @@ -879,6 +964,11 @@ Result WatWriter::ExprVisitorDelegate::OnTableFillExpr(TableFillExpr* expr) { return Result::Ok; } +Result WatWriter::ExprVisitorDelegate::OnRefEqExpr(RefEqExpr* expr) { + writer_->WritePutsSpace(Opcode::RefEq_Opcode.GetName()); + return Result::Ok; +} + Result WatWriter::ExprVisitorDelegate::OnRefFuncExpr(RefFuncExpr* expr) { writer_->WritePutsSpace(Opcode::RefFunc_Opcode.GetName()); writer_->WriteVar(expr->var, NextChar::Newline); @@ -1594,6 +1684,7 @@ void WatWriter::WriteTypeEntry(const TypeEntry& type) { WriteCloseSpace(); break; } + default:; } WriteCloseNewline(); }