summaryrefslogtreecommitdiff
path: root/src/wast-parser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/wast-parser.cc')
-rw-r--r--src/wast-parser.cc59
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));