summaryrefslogtreecommitdiff
path: root/src/wast-parser.cc
diff options
context:
space:
mode:
authorBen Smith <binjimin@gmail.com>2019-02-25 00:12:19 -0800
committerGitHub <noreply@github.com>2019-02-25 00:12:19 -0800
commit93640e2a4ef8559c412f9860aa8ed1497d756abc (patch)
treee66216d6841668c8c1671450e22db6fbdc531022 /src/wast-parser.cc
parent8096983bb0b8fa2f0ab3486dad76e9f7c50eb381 (diff)
downloadwabt-93640e2a4ef8559c412f9860aa8ed1497d756abc.tar.gz
wabt-93640e2a4ef8559c412f9860aa8ed1497d756abc.tar.bz2
wabt-93640e2a4ef8559c412f9860aa8ed1497d756abc.zip
Rename anyfunc -> funcref; parse reference types (#1026)
Also: * Add feature limits on using v128 and anyref types (requires --enable-simd and --enable-reference-types respectively). * Separate out ParseValueType (used for params, locals, global types) from ParseRefType (used for table types).
Diffstat (limited to 'src/wast-parser.cc')
-rw-r--r--src/wast-parser.cc64
1 files changed, 46 insertions, 18 deletions
diff --git a/src/wast-parser.cc b/src/wast-parser.cc
index 9b4b231d..11c2947a 100644
--- a/src/wast-parser.cc
+++ b/src/wast-parser.cc
@@ -614,7 +614,27 @@ Result WastParser::ParseValueType(Type* out_type) {
return ErrorExpected({"i32", "i64", "f32", "f64", "v128", "anyref"});
}
- *out_type = Consume().type();
+ Token token = Consume();
+ Type type = token.type();
+ bool is_enabled;
+ switch (type) {
+ case Type::V128:
+ is_enabled = options_->features.simd_enabled();
+ break;
+ case Type::Anyref:
+ is_enabled = options_->features.reference_types_enabled();
+ break;
+ default:
+ is_enabled = true;
+ break;
+ }
+
+ if (!is_enabled) {
+ Error(token.loc, "value type not allowed: %s", GetTypeName(type));
+ return Result::Error;
+ }
+
+ *out_type = type;
return Result::Ok;
}
@@ -626,6 +646,23 @@ Result WastParser::ParseValueTypeList(TypeVector* out_type_list) {
return Result::Ok;
}
+Result WastParser::ParseRefType(Type* out_type) {
+ WABT_TRACE(ParseRefType);
+ if (!PeekMatch(TokenType::ValueType)) {
+ return ErrorExpected({"anyref", "funcref"});
+ }
+
+ Token token = Consume();
+ Type type = token.type();
+ if (type == Type::Anyref && !options_->features.reference_types_enabled()) {
+ Error(token.loc, "value type not allowed: %s", GetTypeName(type));
+ return Result::Error;
+ }
+
+ *out_type = type;
+ return Result::Ok;
+}
+
Result WastParser::ParseQuotedText(std::string* text) {
WABT_TRACE(ParseQuotedText);
if (!PeekMatch(TokenType::Text)) {
@@ -1006,11 +1043,7 @@ Result WastParser::ParseImportModuleField(Module* module) {
ParseBindVarOpt(&name);
auto import = MakeUnique<TableImport>(name);
CHECK_RESULT(ParseLimits(&import->table.elem_limits));
- if (Match(TokenType::Funcref)) {
- import->table.elem_type = Type::Anyfunc;
- } else {
- CHECK_RESULT(ParseValueType(&import->table.elem_type));
- }
+ CHECK_RESULT(ParseRefType(&import->table.elem_type));
EXPECT(Rpar);
field = MakeUnique<ImportModuleField>(std::move(import), loc);
break;
@@ -1136,15 +1169,14 @@ Result WastParser::ParseTableModuleField(Module* module) {
auto import = MakeUnique<TableImport>(name);
CHECK_RESULT(ParseInlineImport(import.get()));
CHECK_RESULT(ParseLimits(&import->table.elem_limits));
- if (Match(TokenType::Funcref)) {
- import->table.elem_type = Type::Anyfunc;
- } else {
- CHECK_RESULT(ParseValueType(&import->table.elem_type));
- }
+ CHECK_RESULT(ParseRefType(&import->table.elem_type));
auto field =
MakeUnique<ImportModuleField>(std::move(import), GetLocation());
module->AppendField(std::move(field));
- } else if (Match(TokenType::Funcref)) {
+ } else if (PeekMatch(TokenType::ValueType)) {
+ Type elem_type;
+ CHECK_RESULT(ParseRefType(&elem_type));
+
EXPECT(Lpar);
EXPECT(Elem);
@@ -1160,17 +1192,13 @@ 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;
+ table_field->table.elem_type = elem_type;
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));
- if (Match(TokenType::Funcref)) {
- field->table.elem_type = Type::Anyfunc;
- } else {
- CHECK_RESULT(ParseValueType(&field->table.elem_type));
- }
+ CHECK_RESULT(ParseRefType(&field->table.elem_type));
module->AppendField(std::move(field));
}