diff options
Diffstat (limited to 'src/wast-parser.cc')
-rw-r--r-- | src/wast-parser.cc | 59 |
1 files changed, 55 insertions, 4 deletions
diff --git a/src/wast-parser.cc b/src/wast-parser.cc index 66e83a8c..9b4b231d 100644 --- a/src/wast-parser.cc +++ b/src/wast-parser.cc @@ -139,8 +139,14 @@ bool IsPlainInstr(TokenType token_type) { case TokenType::TableCopy: case TokenType::ElemDrop: case TokenType::TableInit: + case TokenType::TableGet: + case TokenType::TableSet: + case TokenType::TableGrow: + case TokenType::TableSize: case TokenType::Throw: case TokenType::Rethrow: + case TokenType::RefNull: + case TokenType::RefIsNull: case TokenType::AtomicLoad: case TokenType::AtomicStore: case TokenType::AtomicRmw: @@ -605,7 +611,7 @@ bool WastParser::ParseVarListOpt(VarVector* out_var_list) { Result WastParser::ParseValueType(Type* out_type) { WABT_TRACE(ParseValueType); if (!PeekMatch(TokenType::ValueType)) { - return ErrorExpected({"i32", "i64", "f32", "f64", "v128"}); + return ErrorExpected({"i32", "i64", "f32", "f64", "v128", "anyref"}); } *out_type = Consume().type(); @@ -1000,7 +1006,11 @@ Result WastParser::ParseImportModuleField(Module* module) { ParseBindVarOpt(&name); auto import = MakeUnique<TableImport>(name); CHECK_RESULT(ParseLimits(&import->table.elem_limits)); - EXPECT(Funcref); + if (Match(TokenType::Funcref)) { + import->table.elem_type = Type::Anyfunc; + } else { + CHECK_RESULT(ParseValueType(&import->table.elem_type)); + } EXPECT(Rpar); field = MakeUnique<ImportModuleField>(std::move(import), loc); break; @@ -1126,7 +1136,11 @@ Result WastParser::ParseTableModuleField(Module* module) { auto import = MakeUnique<TableImport>(name); CHECK_RESULT(ParseInlineImport(import.get())); CHECK_RESULT(ParseLimits(&import->table.elem_limits)); - EXPECT(Funcref); + if (Match(TokenType::Funcref)) { + import->table.elem_type = Type::Anyfunc; + } else { + CHECK_RESULT(ParseValueType(&import->table.elem_type)); + } auto field = MakeUnique<ImportModuleField>(std::move(import), GetLocation()); module->AppendField(std::move(field)); @@ -1146,12 +1160,17 @@ Result WastParser::ParseTableModuleField(Module* module) { table_field->table.elem_limits.initial = elem_segment.vars.size(); table_field->table.elem_limits.max = elem_segment.vars.size(); table_field->table.elem_limits.has_max = true; + table_field->table.elem_type = Type::Anyfunc; module->AppendField(std::move(table_field)); module->AppendField(std::move(elem_segment_field)); } else { auto field = MakeUnique<TableModuleField>(loc, name); CHECK_RESULT(ParseLimits(&field->table.elem_limits)); - EXPECT(Funcref); + if (Match(TokenType::Funcref)) { + field->table.elem_type = Type::Anyfunc; + } else { + CHECK_RESULT(ParseValueType(&field->table.elem_type)); + } module->AppendField(std::move(field)); } @@ -1403,6 +1422,7 @@ Result WastParser::ParsePlainInstr(std::unique_ptr<Expr>* out_expr) { auto expr = MakeUnique<CallIndirectExpr>(loc); CHECK_RESULT(ParseTypeUseOpt(&expr->decl)); CHECK_RESULT(ParseUnboundFuncSignature(&expr->decl.sig)); + ParseVarOpt(&expr->table, Var(0)); *out_expr = std::move(expr); break; } @@ -1417,6 +1437,7 @@ Result WastParser::ParsePlainInstr(std::unique_ptr<Expr>* out_expr) { auto expr = MakeUnique<ReturnCallIndirectExpr>(loc); CHECK_RESULT(ParseTypeUseOpt(&expr->decl)); CHECK_RESULT(ParseUnboundFuncSignature(&expr->decl.sig)); + ParseVarOpt(&expr->table, Var(0)); *out_expr = std::move(expr); break; } @@ -1530,6 +1551,36 @@ Result WastParser::ParsePlainInstr(std::unique_ptr<Expr>* out_expr) { CHECK_RESULT(ParsePlainInstrVar<TableInitExpr>(loc, out_expr)); break; + case TokenType::TableGet: + ErrorUnlessOpcodeEnabled(Consume()); + CHECK_RESULT(ParsePlainInstrVar<TableGetExpr>(loc, out_expr)); + break; + + case TokenType::TableSet: + ErrorUnlessOpcodeEnabled(Consume()); + CHECK_RESULT(ParsePlainInstrVar<TableSetExpr>(loc, out_expr)); + break; + + case TokenType::TableGrow: + ErrorUnlessOpcodeEnabled(Consume()); + CHECK_RESULT(ParsePlainInstrVar<TableGrowExpr>(loc, out_expr)); + break; + + case TokenType::TableSize: + ErrorUnlessOpcodeEnabled(Consume()); + CHECK_RESULT(ParsePlainInstrVar<TableSizeExpr>(loc, out_expr)); + break; + + case TokenType::RefNull: + ErrorUnlessOpcodeEnabled(Consume()); + out_expr->reset(new RefNullExpr(loc)); + break; + + case TokenType::RefIsNull: + ErrorUnlessOpcodeEnabled(Consume()); + out_expr->reset(new RefIsNullExpr(loc)); + break; + case TokenType::Throw: ErrorUnlessOpcodeEnabled(Consume()); CHECK_RESULT(ParsePlainInstrVar<ThrowExpr>(loc, out_expr)); |