LibWasm: Use TRY macro when possible

This removes a lot of the error handling boilerplate, and is more
consistent with the rest of the codebase.
This commit is contained in:
Diego 2024-05-26 18:06:26 -07:00 committed by Ali Mohammad Pur
commit e345d65def
Notes: sideshowbarker 2024-07-16 23:54:15 +09:00
2 changed files with 126 additions and 274 deletions

View file

@ -78,11 +78,8 @@ static auto parse_vector(Stream& stream)
static ParseResult<ByteString> parse_name(Stream& stream) static ParseResult<ByteString> parse_name(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger; ScopeLogger<WASM_BINPARSER_DEBUG> logger;
auto data = parse_vector<u8>(stream); auto data = TRY(parse_vector<u8>(stream));
if (data.is_error()) return ByteString::copy(data);
return data.error();
return ByteString::copy(data.value());
} }
template<typename T> template<typename T>
@ -113,11 +110,9 @@ requires(requires(Stream& stream, Args... args) { T::parse(stream, args...); })
} }
new_stream.unread({ &byte, 1 }); new_stream.unread({ &byte, 1 });
auto parse_result = T::parse(new_stream, args...); auto parse_result = TRY(T::parse(new_stream, args...));
if (parse_result.is_error())
return parse_result.error();
result.values.extend(parse_result.release_value()); result.values.extend(parse_result);
} }
} }
@ -153,10 +148,8 @@ ParseResult<ValueType> ValueType::parse(Stream& stream)
ParseResult<ResultType> ResultType::parse(Stream& stream) ParseResult<ResultType> ResultType::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("ResultType"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("ResultType"sv);
auto types = parse_vector<ValueType>(stream); auto types = TRY(parse_vector<ValueType>(stream));
if (types.is_error()) return ResultType { types };
return types.error();
return ResultType { types.release_value() };
} }
ParseResult<FunctionType> FunctionType::parse(Stream& stream) ParseResult<FunctionType> FunctionType::parse(Stream& stream)
@ -173,14 +166,10 @@ ParseResult<FunctionType> FunctionType::parse(Stream& stream)
return with_eof_check(stream, ParseError::InvalidTag); return with_eof_check(stream, ParseError::InvalidTag);
} }
auto parameters_result = parse_vector<ValueType>(stream); auto parameters_result = TRY(parse_vector<ValueType>(stream));
if (parameters_result.is_error()) auto results_result = TRY(parse_vector<ValueType>(stream));
return parameters_result.error();
auto results_result = parse_vector<ValueType>(stream);
if (results_result.is_error())
return results_result.error();
return FunctionType { parameters_result.release_value(), results_result.release_value() }; return FunctionType { parameters_result, results_result };
} }
ParseResult<Limits> Limits::parse(Stream& stream) ParseResult<Limits> Limits::parse(Stream& stream)
@ -214,32 +203,24 @@ ParseResult<Limits> Limits::parse(Stream& stream)
ParseResult<MemoryType> MemoryType::parse(Stream& stream) ParseResult<MemoryType> MemoryType::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("MemoryType"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("MemoryType"sv);
auto limits_result = Limits::parse(stream); auto limits_result = TRY(Limits::parse(stream));
if (limits_result.is_error()) return MemoryType { limits_result };
return limits_result.error();
return MemoryType { limits_result.release_value() };
} }
ParseResult<TableType> TableType::parse(Stream& stream) ParseResult<TableType> TableType::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("TableType"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("TableType"sv);
auto type_result = ValueType::parse(stream); auto type_result = TRY(ValueType::parse(stream));
if (type_result.is_error()) if (!type_result.is_reference())
return type_result.error();
if (!type_result.value().is_reference())
return with_eof_check(stream, ParseError::InvalidType); return with_eof_check(stream, ParseError::InvalidType);
auto limits_result = Limits::parse(stream); auto limits_result = TRY(Limits::parse(stream));
if (limits_result.is_error()) return TableType { type_result, limits_result };
return limits_result.error();
return TableType { type_result.release_value(), limits_result.release_value() };
} }
ParseResult<GlobalType> GlobalType::parse(Stream& stream) ParseResult<GlobalType> GlobalType::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("GlobalType"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("GlobalType"sv);
auto type_result = ValueType::parse(stream); auto type_result = TRY(ValueType::parse(stream));
if (type_result.is_error())
return type_result.error();
auto mutable_or_error = stream.read_value<u8>(); auto mutable_or_error = stream.read_value<u8>();
if (mutable_or_error.is_error()) if (mutable_or_error.is_error())
@ -250,7 +231,7 @@ ParseResult<GlobalType> GlobalType::parse(Stream& stream)
if (mutable_ > 1) if (mutable_ > 1)
return with_eof_check(stream, ParseError::InvalidTag); return with_eof_check(stream, ParseError::InvalidTag);
return GlobalType { type_result.release_value(), mutable_ == 0x01 }; return GlobalType { type_result, mutable_ == 0x01 };
} }
ParseResult<BlockType> BlockType::parse(Stream& stream) ParseResult<BlockType> BlockType::parse(Stream& stream)
@ -342,57 +323,36 @@ ParseResult<Vector<Instruction>> Instruction::parse(Stream& stream, InstructionP
case Instructions::block.value(): case Instructions::block.value():
case Instructions::loop.value(): case Instructions::loop.value():
case Instructions::if_.value(): { case Instructions::if_.value(): {
auto block_type = BlockType::parse(stream); auto block_type = TRY(BlockType::parse(stream));
if (block_type.is_error()) nested_instructions.append({ move(resulting_instructions), opcode, block_type, {}, {} });
return block_type.error();
nested_instructions.append({ move(resulting_instructions), opcode, block_type.release_value(), {}, {} });
resulting_instructions = {}; resulting_instructions = {};
break; break;
} }
case Instructions::br.value(): case Instructions::br.value():
case Instructions::br_if.value(): { case Instructions::br_if.value(): {
// branches with a single label immediate // branches with a single label immediate
auto index = GenericIndexParser<LabelIndex>::parse(stream); auto index = TRY(GenericIndexParser<LabelIndex>::parse(stream));
if (index.is_error()) resulting_instructions.append(Instruction { opcode, index });
return index.error();
resulting_instructions.append(Instruction { opcode, index.release_value() });
break; break;
} }
case Instructions::br_table.value(): { case Instructions::br_table.value(): {
// br_table label* label // br_table label* label
auto labels = parse_vector<GenericIndexParser<LabelIndex>>(stream); auto labels = TRY(parse_vector<GenericIndexParser<LabelIndex>>(stream));
if (labels.is_error()) auto default_label = TRY(GenericIndexParser<LabelIndex>::parse(stream));
return labels.error(); resulting_instructions.append(Instruction { opcode, TableBranchArgs { labels, default_label } });
auto default_label = GenericIndexParser<LabelIndex>::parse(stream);
if (default_label.is_error())
return default_label.error();
resulting_instructions.append(Instruction { opcode, TableBranchArgs { labels.release_value(), default_label.release_value() } });
break; break;
} }
case Instructions::call.value(): { case Instructions::call.value(): {
// call function // call function
auto function_index = GenericIndexParser<FunctionIndex>::parse(stream); auto function_index = TRY(GenericIndexParser<FunctionIndex>::parse(stream));
if (function_index.is_error()) resulting_instructions.append(Instruction { opcode, function_index });
return function_index.error();
resulting_instructions.append(Instruction { opcode, function_index.release_value() });
break; break;
} }
case Instructions::call_indirect.value(): { case Instructions::call_indirect.value(): {
// call_indirect type table // call_indirect type table
auto type_index = GenericIndexParser<TypeIndex>::parse(stream); auto type_index = TRY(GenericIndexParser<TypeIndex>::parse(stream));
if (type_index.is_error()) auto table_index = TRY(GenericIndexParser<TableIndex>::parse(stream));
return type_index.error(); resulting_instructions.append(Instruction { opcode, IndirectCallArgs { type_index, table_index } });
auto table_index = GenericIndexParser<TableIndex>::parse(stream);
if (table_index.is_error())
return table_index.error();
resulting_instructions.append(Instruction { opcode, IndirectCallArgs { type_index.release_value(), table_index.release_value() } });
break; break;
} }
case Instructions::i32_load.value(): case Instructions::i32_load.value():
@ -445,20 +405,14 @@ ParseResult<Vector<Instruction>> Instruction::parse(Stream& stream, InstructionP
case Instructions::local_get.value(): case Instructions::local_get.value():
case Instructions::local_set.value(): case Instructions::local_set.value():
case Instructions::local_tee.value(): { case Instructions::local_tee.value(): {
auto index = GenericIndexParser<LocalIndex>::parse(stream); auto index = TRY(GenericIndexParser<LocalIndex>::parse(stream));
if (index.is_error()) resulting_instructions.append(Instruction { opcode, index });
return index.error();
resulting_instructions.append(Instruction { opcode, index.release_value() });
break; break;
} }
case Instructions::global_get.value(): case Instructions::global_get.value():
case Instructions::global_set.value(): { case Instructions::global_set.value(): {
auto index = GenericIndexParser<GlobalIndex>::parse(stream); auto index = TRY(GenericIndexParser<GlobalIndex>::parse(stream));
if (index.is_error()) resulting_instructions.append(Instruction { opcode, index });
return index.error();
resulting_instructions.append(Instruction { opcode, index.release_value() });
break; break;
} }
case Instructions::memory_size.value(): case Instructions::memory_size.value():
@ -517,37 +471,26 @@ ParseResult<Vector<Instruction>> Instruction::parse(Stream& stream, InstructionP
} }
case Instructions::table_get.value(): case Instructions::table_get.value():
case Instructions::table_set.value(): { case Instructions::table_set.value(): {
auto index = GenericIndexParser<TableIndex>::parse(stream); auto index = TRY(GenericIndexParser<TableIndex>::parse(stream));
if (index.is_error()) resulting_instructions.append(Instruction { opcode, index });
return index.error();
resulting_instructions.append(Instruction { opcode, index.release_value() });
break; break;
} }
case Instructions::select_typed.value(): { case Instructions::select_typed.value(): {
auto types = parse_vector<ValueType>(stream); auto types = TRY(parse_vector<ValueType>(stream));
if (types.is_error()) resulting_instructions.append(Instruction { opcode, types });
return types.error();
resulting_instructions.append(Instruction { opcode, types.release_value() });
break; break;
} }
case Instructions::ref_null.value(): { case Instructions::ref_null.value(): {
auto type = ValueType::parse(stream); auto type = TRY(ValueType::parse(stream));
if (type.is_error()) if (!type.is_reference())
return type.error();
if (!type.value().is_reference())
return ParseError::InvalidType; return ParseError::InvalidType;
resulting_instructions.append(Instruction { opcode, type.release_value() }); resulting_instructions.append(Instruction { opcode, type });
break; break;
} }
case Instructions::ref_func.value(): { case Instructions::ref_func.value(): {
auto index = GenericIndexParser<FunctionIndex>::parse(stream); auto index = TRY(GenericIndexParser<FunctionIndex>::parse(stream));
if (index.is_error()) resulting_instructions.append(Instruction { opcode, index });
return index.error();
resulting_instructions.append(Instruction { opcode, index.release_value() });
break; break;
} }
case Instructions::ref_is_null.value(): case Instructions::ref_is_null.value():
@ -707,9 +650,7 @@ ParseResult<Vector<Instruction>> Instruction::parse(Stream& stream, InstructionP
resulting_instructions.append(Instruction { full_opcode }); resulting_instructions.append(Instruction { full_opcode });
break; break;
case Instructions::memory_init.value(): { case Instructions::memory_init.value(): {
auto index = GenericIndexParser<DataIndex>::parse(stream); auto index = TRY(GenericIndexParser<DataIndex>::parse(stream));
if (index.is_error())
return index.error();
// Proposal "multi-memory", literal 0x00 is replaced with a memory index. // Proposal "multi-memory", literal 0x00 is replaced with a memory index.
auto memory_index_or_error = stream.read_value<u8>(); auto memory_index_or_error = stream.read_value<u8>();
@ -718,14 +659,12 @@ ParseResult<Vector<Instruction>> Instruction::parse(Stream& stream, InstructionP
auto memory_index = memory_index_or_error.release_value(); auto memory_index = memory_index_or_error.release_value();
resulting_instructions.append(Instruction { full_opcode, MemoryInitArgs { index.release_value(), MemoryIndex(memory_index) } }); resulting_instructions.append(Instruction { full_opcode, MemoryInitArgs { index, MemoryIndex(memory_index) } });
break; break;
} }
case Instructions::data_drop.value(): { case Instructions::data_drop.value(): {
auto index = GenericIndexParser<DataIndex>::parse(stream); auto index = TRY(GenericIndexParser<DataIndex>::parse(stream));
if (index.is_error()) resulting_instructions.append(Instruction { full_opcode, index });
return index.error();
resulting_instructions.append(Instruction { full_opcode, index.release_value() });
break; break;
} }
case Instructions::memory_copy.value(): { case Instructions::memory_copy.value(): {
@ -753,39 +692,27 @@ ParseResult<Vector<Instruction>> Instruction::parse(Stream& stream, InstructionP
break; break;
} }
case Instructions::table_init.value(): { case Instructions::table_init.value(): {
auto element_index = GenericIndexParser<ElementIndex>::parse(stream); auto element_index = TRY(GenericIndexParser<ElementIndex>::parse(stream));
if (element_index.is_error()) auto table_index = TRY(GenericIndexParser<TableIndex>::parse(stream));
return element_index.error(); resulting_instructions.append(Instruction { full_opcode, TableElementArgs { element_index, table_index } });
auto table_index = GenericIndexParser<TableIndex>::parse(stream);
if (table_index.is_error())
return table_index.error();
resulting_instructions.append(Instruction { full_opcode, TableElementArgs { element_index.release_value(), table_index.release_value() } });
break; break;
} }
case Instructions::elem_drop.value(): { case Instructions::elem_drop.value(): {
auto element_index = GenericIndexParser<ElementIndex>::parse(stream); auto element_index = TRY(GenericIndexParser<ElementIndex>::parse(stream));
if (element_index.is_error()) resulting_instructions.append(Instruction { full_opcode, element_index });
return element_index.error();
resulting_instructions.append(Instruction { full_opcode, element_index.release_value() });
break; break;
} }
case Instructions::table_copy.value(): { case Instructions::table_copy.value(): {
auto lhs = GenericIndexParser<TableIndex>::parse(stream); auto lhs = TRY(GenericIndexParser<TableIndex>::parse(stream));
if (lhs.is_error()) auto rhs = TRY(GenericIndexParser<TableIndex>::parse(stream));
return lhs.error(); resulting_instructions.append(Instruction { full_opcode, TableTableArgs { lhs, rhs } });
auto rhs = GenericIndexParser<TableIndex>::parse(stream);
if (rhs.is_error())
return rhs.error();
resulting_instructions.append(Instruction { full_opcode, TableTableArgs { lhs.release_value(), rhs.release_value() } });
break; break;
} }
case Instructions::table_grow.value(): case Instructions::table_grow.value():
case Instructions::table_size.value(): case Instructions::table_size.value():
case Instructions::table_fill.value(): { case Instructions::table_fill.value(): {
auto index = GenericIndexParser<TableIndex>::parse(stream); auto index = TRY(GenericIndexParser<TableIndex>::parse(stream));
if (index.is_error()) resulting_instructions.append(Instruction { full_opcode, index });
return index.error();
resulting_instructions.append(Instruction { full_opcode, index.release_value() });
break; break;
} }
case Instructions::v128_load.value(): case Instructions::v128_load.value():
@ -1119,9 +1046,7 @@ ParseResult<Vector<Instruction>> Instruction::parse(Stream& stream, InstructionP
ParseResult<CustomSection> CustomSection::parse(Stream& stream) ParseResult<CustomSection> CustomSection::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("CustomSection"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("CustomSection"sv);
auto name = parse_name(stream); auto name = TRY(parse_name(stream));
if (name.is_error())
return name.error();
ByteBuffer data_buffer; ByteBuffer data_buffer;
if (data_buffer.try_resize(64).is_error()) if (data_buffer.try_resize(64).is_error())
@ -1139,27 +1064,21 @@ ParseResult<CustomSection> CustomSection::parse(Stream& stream)
return with_eof_check(stream, ParseError::HugeAllocationRequested); return with_eof_check(stream, ParseError::HugeAllocationRequested);
} }
return CustomSection(name.release_value(), move(data_buffer)); return CustomSection(name, move(data_buffer));
} }
ParseResult<TypeSection> TypeSection::parse(Stream& stream) ParseResult<TypeSection> TypeSection::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("TypeSection"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("TypeSection"sv);
auto types = parse_vector<FunctionType>(stream); auto types = TRY(parse_vector<FunctionType>(stream));
if (types.is_error()) return TypeSection { types };
return types.error();
return TypeSection { types.release_value() };
} }
ParseResult<ImportSection::Import> ImportSection::Import::parse(Stream& stream) ParseResult<ImportSection::Import> ImportSection::Import::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("Import"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("Import"sv);
auto module = parse_name(stream); auto module = TRY(parse_name(stream));
if (module.is_error()) auto name = TRY(parse_name(stream));
return module.error();
auto name = parse_name(stream);
if (name.is_error())
return name.error();
auto tag_or_error = stream.read_value<u8>(); auto tag_or_error = stream.read_value<u8>();
if (tag_or_error.is_error()) if (tag_or_error.is_error())
return with_eof_check(stream, ParseError::ExpectedKindTag); return with_eof_check(stream, ParseError::ExpectedKindTag);
@ -1168,10 +1087,8 @@ ParseResult<ImportSection::Import> ImportSection::Import::parse(Stream& stream)
switch (tag) { switch (tag) {
case Constants::extern_function_tag: { case Constants::extern_function_tag: {
auto index = GenericIndexParser<TypeIndex>::parse(stream); auto index = TRY(GenericIndexParser<TypeIndex>::parse(stream));
if (index.is_error()) return Import { module, name, index };
return index.error();
return Import { module.release_value(), name.release_value(), index.release_value() };
} }
case Constants::extern_table_tag: case Constants::extern_table_tag:
return parse_with_type<TableType>(stream, module, name); return parse_with_type<TableType>(stream, module, name);
@ -1187,22 +1104,18 @@ ParseResult<ImportSection::Import> ImportSection::Import::parse(Stream& stream)
ParseResult<ImportSection> ImportSection::parse(Stream& stream) ParseResult<ImportSection> ImportSection::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("ImportSection"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("ImportSection"sv);
auto imports = parse_vector<Import>(stream); auto imports = TRY(parse_vector<Import>(stream));
if (imports.is_error()) return ImportSection { imports };
return imports.error();
return ImportSection { imports.release_value() };
} }
ParseResult<FunctionSection> FunctionSection::parse(Stream& stream) ParseResult<FunctionSection> FunctionSection::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("FunctionSection"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("FunctionSection"sv);
auto indices = parse_vector<u32>(stream); auto indices = TRY(parse_vector<u32>(stream));
if (indices.is_error())
return indices.error();
Vector<TypeIndex> typed_indices; Vector<TypeIndex> typed_indices;
typed_indices.ensure_capacity(indices.value().size()); typed_indices.ensure_capacity(indices.size());
for (auto entry : indices.value()) for (auto entry : indices)
typed_indices.append(entry); typed_indices.append(entry);
return FunctionSection { move(typed_indices) }; return FunctionSection { move(typed_indices) };
@ -1211,37 +1124,29 @@ ParseResult<FunctionSection> FunctionSection::parse(Stream& stream)
ParseResult<TableSection::Table> TableSection::Table::parse(Stream& stream) ParseResult<TableSection::Table> TableSection::Table::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("Table"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("Table"sv);
auto type = TableType::parse(stream); auto type = TRY(TableType::parse(stream));
if (type.is_error()) return Table { type };
return type.error();
return Table { type.release_value() };
} }
ParseResult<TableSection> TableSection::parse(Stream& stream) ParseResult<TableSection> TableSection::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("TableSection"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("TableSection"sv);
auto tables = parse_vector<Table>(stream); auto tables = TRY(parse_vector<Table>(stream));
if (tables.is_error()) return TableSection { tables };
return tables.error();
return TableSection { tables.release_value() };
} }
ParseResult<MemorySection::Memory> MemorySection::Memory::parse(Stream& stream) ParseResult<MemorySection::Memory> MemorySection::Memory::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("Memory"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("Memory"sv);
auto type = MemoryType::parse(stream); auto type = TRY(MemoryType::parse(stream));
if (type.is_error()) return Memory { type };
return type.error();
return Memory { type.release_value() };
} }
ParseResult<MemorySection> MemorySection::parse(Stream& stream) ParseResult<MemorySection> MemorySection::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("MemorySection"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("MemorySection"sv);
auto memories = parse_vector<Memory>(stream); auto memories = TRY(parse_vector<Memory>(stream));
if (memories.is_error()) return MemorySection { memories };
return memories.error();
return MemorySection { memories.release_value() };
} }
ParseResult<Expression> Expression::parse(Stream& stream) ParseResult<Expression> Expression::parse(Stream& stream)
@ -1258,30 +1163,22 @@ ParseResult<Expression> Expression::parse(Stream& stream)
ParseResult<GlobalSection::Global> GlobalSection::Global::parse(Stream& stream) ParseResult<GlobalSection::Global> GlobalSection::Global::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("Global"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("Global"sv);
auto type = GlobalType::parse(stream); auto type = TRY(GlobalType::parse(stream));
if (type.is_error()) auto exprs = TRY(Expression::parse(stream));
return type.error(); return Global { type, exprs };
auto exprs = Expression::parse(stream);
if (exprs.is_error())
return exprs.error();
return Global { type.release_value(), exprs.release_value() };
} }
ParseResult<GlobalSection> GlobalSection::parse(Stream& stream) ParseResult<GlobalSection> GlobalSection::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("GlobalSection"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("GlobalSection"sv);
auto result = parse_vector<Global>(stream); auto result = TRY(parse_vector<Global>(stream));
if (result.is_error()) return GlobalSection { result };
return result.error();
return GlobalSection { result.release_value() };
} }
ParseResult<ExportSection::Export> ExportSection::Export::parse(Stream& stream) ParseResult<ExportSection::Export> ExportSection::Export::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("Export"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("Export"sv);
auto name = parse_name(stream); auto name = TRY(parse_name(stream));
if (name.is_error())
return name.error();
auto tag_or_error = stream.read_value<u8>(); auto tag_or_error = stream.read_value<u8>();
if (tag_or_error.is_error()) if (tag_or_error.is_error())
return with_eof_check(stream, ParseError::ExpectedKindTag); return with_eof_check(stream, ParseError::ExpectedKindTag);
@ -1295,13 +1192,13 @@ ParseResult<ExportSection::Export> ExportSection::Export::parse(Stream& stream)
switch (tag) { switch (tag) {
case Constants::extern_function_tag: case Constants::extern_function_tag:
return Export { name.release_value(), ExportDesc { FunctionIndex { index } } }; return Export { name, ExportDesc { FunctionIndex { index } } };
case Constants::extern_table_tag: case Constants::extern_table_tag:
return Export { name.release_value(), ExportDesc { TableIndex { index } } }; return Export { name, ExportDesc { TableIndex { index } } };
case Constants::extern_memory_tag: case Constants::extern_memory_tag:
return Export { name.release_value(), ExportDesc { MemoryIndex { index } } }; return Export { name, ExportDesc { MemoryIndex { index } } };
case Constants::extern_global_tag: case Constants::extern_global_tag:
return Export { name.release_value(), ExportDesc { GlobalIndex { index } } }; return Export { name, ExportDesc { GlobalIndex { index } } };
default: default:
return with_eof_check(stream, ParseError::InvalidTag); return with_eof_check(stream, ParseError::InvalidTag);
} }
@ -1310,40 +1207,30 @@ ParseResult<ExportSection::Export> ExportSection::Export::parse(Stream& stream)
ParseResult<ExportSection> ExportSection::parse(Stream& stream) ParseResult<ExportSection> ExportSection::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("ExportSection"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("ExportSection"sv);
auto result = parse_vector<Export>(stream); auto result = TRY(parse_vector<Export>(stream));
if (result.is_error()) return ExportSection { result };
return result.error();
return ExportSection { result.release_value() };
} }
ParseResult<StartSection::StartFunction> StartSection::StartFunction::parse(Stream& stream) ParseResult<StartSection::StartFunction> StartSection::StartFunction::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("StartFunction"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("StartFunction"sv);
auto index = GenericIndexParser<FunctionIndex>::parse(stream); auto index = TRY(GenericIndexParser<FunctionIndex>::parse(stream));
if (index.is_error()) return StartFunction { index };
return index.error();
return StartFunction { index.release_value() };
} }
ParseResult<StartSection> StartSection::parse(Stream& stream) ParseResult<StartSection> StartSection::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("StartSection"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("StartSection"sv);
auto result = StartFunction::parse(stream); auto result = TRY(StartFunction::parse(stream));
if (result.is_error()) return StartSection { result };
return result.error();
return StartSection { result.release_value() };
} }
ParseResult<ElementSection::SegmentType0> ElementSection::SegmentType0::parse(Stream& stream) ParseResult<ElementSection::SegmentType0> ElementSection::SegmentType0::parse(Stream& stream)
{ {
auto expression = Expression::parse(stream); auto expression = TRY(Expression::parse(stream));
if (expression.is_error()) auto indices = TRY(parse_vector<GenericIndexParser<FunctionIndex>>(stream));
return expression.error();
auto indices = parse_vector<GenericIndexParser<FunctionIndex>>(stream);
if (indices.is_error())
return indices.error();
return SegmentType0 { indices.release_value(), Active { 0, expression.release_value() } }; return SegmentType0 { indices, Active { 0, expression } };
} }
ParseResult<ElementSection::SegmentType1> ElementSection::SegmentType1::parse(Stream& stream) ParseResult<ElementSection::SegmentType1> ElementSection::SegmentType1::parse(Stream& stream)
@ -1355,11 +1242,9 @@ ParseResult<ElementSection::SegmentType1> ElementSection::SegmentType1::parse(St
auto kind = kind_or_error.release_value(); auto kind = kind_or_error.release_value();
if (kind != 0) if (kind != 0)
return ParseError::InvalidTag; return ParseError::InvalidTag;
auto indices = parse_vector<GenericIndexParser<FunctionIndex>>(stream); auto indices = TRY(parse_vector<GenericIndexParser<FunctionIndex>>(stream));
if (indices.is_error())
return indices.error();
return SegmentType1 { indices.release_value() }; return SegmentType1 { indices };
} }
ParseResult<ElementSection::SegmentType2> ElementSection::SegmentType2::parse(Stream& stream) ParseResult<ElementSection::SegmentType2> ElementSection::SegmentType2::parse(Stream& stream)
@ -1378,19 +1263,15 @@ ParseResult<ElementSection::SegmentType3> ElementSection::SegmentType3::parse(St
ParseResult<ElementSection::SegmentType4> ElementSection::SegmentType4::parse(Stream& stream) ParseResult<ElementSection::SegmentType4> ElementSection::SegmentType4::parse(Stream& stream)
{ {
auto expression = Expression::parse(stream); auto expression = TRY(Expression::parse(stream));
if (expression.is_error()) auto initializers = TRY(parse_vector<Expression>(stream));
return expression.error();
auto initializers = parse_vector<Expression>(stream);
if (initializers.is_error())
return initializers.error();
return SegmentType4 { return SegmentType4 {
.mode = Active { .mode = Active {
.index = 0, .index = 0,
.expression = expression.release_value(), .expression = expression,
}, },
.initializer = initializers.release_value(), .initializer = initializers,
}; };
} }
@ -1487,10 +1368,8 @@ ParseResult<ElementSection::Element> ElementSection::Element::parse(Stream& stre
ParseResult<ElementSection> ElementSection::parse(Stream& stream) ParseResult<ElementSection> ElementSection::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("ElementSection"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("ElementSection"sv);
auto result = parse_vector<Element>(stream); auto result = TRY(parse_vector<Element>(stream));
if (result.is_error()) return ElementSection { result };
return result.error();
return ElementSection { result.release_value() };
} }
ParseResult<Locals> Locals::parse(Stream& stream) ParseResult<Locals> Locals::parse(Stream& stream)
@ -1504,23 +1383,17 @@ ParseResult<Locals> Locals::parse(Stream& stream)
if (count > Constants::max_allowed_function_locals_per_type) if (count > Constants::max_allowed_function_locals_per_type)
return with_eof_check(stream, ParseError::HugeAllocationRequested); return with_eof_check(stream, ParseError::HugeAllocationRequested);
auto type = ValueType::parse(stream); auto type = TRY(ValueType::parse(stream));
if (type.is_error())
return type.error();
return Locals { static_cast<u32>(count), type.release_value() }; return Locals { static_cast<u32>(count), type };
} }
ParseResult<CodeSection::Func> CodeSection::Func::parse(Stream& stream) ParseResult<CodeSection::Func> CodeSection::Func::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("Func"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("Func"sv);
auto locals = parse_vector<Locals>(stream); auto locals = TRY(parse_vector<Locals>(stream));
if (locals.is_error()) auto body = TRY(Expression::parse(stream));
return locals.error(); return Func { locals, body };
auto body = Expression::parse(stream);
if (body.is_error())
return body.error();
return Func { locals.release_value(), body.release_value() };
} }
ParseResult<CodeSection::Code> CodeSection::Code::parse(Stream& stream) ParseResult<CodeSection::Code> CodeSection::Code::parse(Stream& stream)
@ -1533,20 +1406,16 @@ ParseResult<CodeSection::Code> CodeSection::Code::parse(Stream& stream)
auto constrained_stream = ConstrainedStream { MaybeOwned<Stream>(stream), size }; auto constrained_stream = ConstrainedStream { MaybeOwned<Stream>(stream), size };
auto func = Func::parse(constrained_stream); auto func = TRY(Func::parse(constrained_stream));
if (func.is_error())
return func.error();
return Code { static_cast<u32>(size), func.release_value() }; return Code { static_cast<u32>(size), func };
} }
ParseResult<CodeSection> CodeSection::parse(Stream& stream) ParseResult<CodeSection> CodeSection::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("CodeSection"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("CodeSection"sv);
auto result = parse_vector<Code>(stream); auto result = TRY(parse_vector<Code>(stream));
if (result.is_error()) return CodeSection { result };
return result.error();
return CodeSection { result.release_value() };
} }
ParseResult<DataSection::Data> DataSection::Data::parse(Stream& stream) ParseResult<DataSection::Data> DataSection::Data::parse(Stream& stream)
@ -1562,31 +1431,19 @@ ParseResult<DataSection::Data> DataSection::Data::parse(Stream& stream)
return with_eof_check(stream, ParseError::InvalidTag); return with_eof_check(stream, ParseError::InvalidTag);
if (tag == 0x00) { if (tag == 0x00) {
auto expr = Expression::parse(stream); auto expr = TRY(Expression::parse(stream));
if (expr.is_error()) auto init = TRY(parse_vector<u8>(stream));
return expr.error(); return Data { Active { init, { 0 }, expr } };
auto init = parse_vector<u8>(stream);
if (init.is_error())
return init.error();
return Data { Active { init.release_value(), { 0 }, expr.release_value() } };
} }
if (tag == 0x01) { if (tag == 0x01) {
auto init = parse_vector<u8>(stream); auto init = TRY(parse_vector<u8>(stream));
if (init.is_error()) return Data { Passive { init } };
return init.error();
return Data { Passive { init.release_value() } };
} }
if (tag == 0x02) { if (tag == 0x02) {
auto index = GenericIndexParser<MemoryIndex>::parse(stream); auto index = TRY(GenericIndexParser<MemoryIndex>::parse(stream));
if (index.is_error()) auto expr = TRY(Expression::parse(stream));
return index.error(); auto init = TRY(parse_vector<u8>(stream));
auto expr = Expression::parse(stream); return Data { Active { init, index, expr } };
if (expr.is_error())
return expr.error();
auto init = parse_vector<u8>(stream);
if (init.is_error())
return init.error();
return Data { Active { init.release_value(), index.release_value(), expr.release_value() } };
} }
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
@ -1594,11 +1451,8 @@ ParseResult<DataSection::Data> DataSection::Data::parse(Stream& stream)
ParseResult<DataSection> DataSection::parse(Stream& stream) ParseResult<DataSection> DataSection::parse(Stream& stream)
{ {
ScopeLogger<WASM_BINPARSER_DEBUG> logger("DataSection"sv); ScopeLogger<WASM_BINPARSER_DEBUG> logger("DataSection"sv);
auto data = parse_vector<Data>(stream); auto data = TRY(parse_vector<Data>(stream));
if (data.is_error()) return DataSection { data };
return data.error();
return DataSection { data.release_value() };
} }
ParseResult<DataCountSection> DataCountSection::parse([[maybe_unused]] Stream& stream) ParseResult<DataCountSection> DataCountSection::parse([[maybe_unused]] Stream& stream)

View file

@ -557,10 +557,8 @@ public:
template<typename T> template<typename T>
static ParseResult<Import> parse_with_type(auto&& stream, auto&& module, auto&& name) static ParseResult<Import> parse_with_type(auto&& stream, auto&& module, auto&& name)
{ {
auto result = T::parse(stream); auto result = TRY(T::parse(stream));
if (result.is_error()) return Import { module, name, result };
return result.error();
return Import { module.release_value(), name.release_value(), result.release_value() };
} }
ByteString m_module; ByteString m_module;