diff options
author | Ben Smith <binji@chromium.org> | 2020-03-09 11:45:17 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-09 11:45:17 -0700 |
commit | f649b7ca9af02ff3213d8c2b135eaef9d87f5e0d (patch) | |
tree | 41ee03ea4b45fcf9ba2e1347c6f41400c89e53dd /src/wast-parser.cc | |
parent | bec78eafbc203d81b9a6d1ce81f5a80dd7bf692a (diff) | |
download | wabt-f649b7ca9af02ff3213d8c2b135eaef9d87f5e0d.tar.gz wabt-f649b7ca9af02ff3213d8c2b135eaef9d87f5e0d.tar.bz2 wabt-f649b7ca9af02ff3213d8c2b135eaef9d87f5e0d.zip |
Initial pass parsing/reading struct (#1352)
This parses just the format `(struct)` as a new type. I added a test for
this using `wat2wasm`, but that requires a rudimentary binary format.
The test runner automatically attempts to rountrip all wat2wasm tests,
so this required implementing the wat writing and binary reading too.
Here's a summary of the changes:
* binary-reader:h: Rename `BinaryReader::OnType` callbacks to `OnFuncType`
* binary-reader.h: Add `BinaryReader::OnStructType`
* binary-reader.cc: Use a switch after reading the type form to
determine whether we're reading a function or struct.
* tokens.def: Add new `TokenType::Struct`
* lexer-keywords.txt: Add new `struct` keyword
* type.h: Add `Type::Struct` type form
* wast-parser.cc: Parse `(struct)` in text format
* wat-writer.cc: Write Func or Struct type forms
Diffstat (limited to 'src/wast-parser.cc')
-rw-r--r-- | src/wast-parser.cc | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/src/wast-parser.cc b/src/wast-parser.cc index 6c9ca6ef..71d37ffe 100644 --- a/src/wast-parser.cc +++ b/src/wast-parser.cc @@ -261,7 +261,9 @@ void ResolveImplicitlyDefinedFunctionType(const Location& loc, Index func_type_index = module->GetFuncTypeIndex(decl.sig); if (func_type_index == kInvalidIndex) { auto func_type_field = MakeUnique<TypeModuleField>(loc); - cast<FuncType>(func_type_field->type.get())->sig = decl.sig; + auto func_type = MakeUnique<FuncType>(); + func_type->sig = decl.sig; + func_type_field->type = std::move(func_type); module->AppendField(std::move(func_type_field)); } } @@ -1182,16 +1184,34 @@ Result WastParser::ParseTypeModuleField(Module* module) { WABT_TRACE(ParseTypeModuleField); EXPECT(Lpar); auto field = MakeUnique<TypeModuleField>(GetLocation()); - FuncType& func_type = *cast<FuncType>(field->type.get()); EXPECT(Type); - ParseBindVarOpt(&func_type.name); + + std::string name; + ParseBindVarOpt(&name); EXPECT(Lpar); - EXPECT(Func); - BindingHash bindings; - CHECK_RESULT(ParseFuncSignature(&func_type.sig, &bindings)); - CHECK_RESULT(ErrorIfLpar({"param", "result"})); - EXPECT(Rpar); - EXPECT(Rpar); + Location loc = GetLocation(); + + if (Match(TokenType::Func)) { + auto func_type = MakeUnique<FuncType>(name); + BindingHash bindings; + CHECK_RESULT(ParseFuncSignature(&func_type->sig, &bindings)); + CHECK_RESULT(ErrorIfLpar({"param", "result"})); + EXPECT(Rpar); + EXPECT(Rpar); + field->type = 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 = MakeUnique<StructType>(name); + EXPECT(Rpar); + EXPECT(Rpar); + field->type = std::move(struct_type); + } else { + return ErrorExpected({"func", "struct"}); + } + module->AppendField(std::move(field)); return Result::Ok; } |