mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-12 12:32:21 +00:00
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:
parent
0eeae7ff24
commit
e345d65def
Notes:
sideshowbarker
2024-07-16 23:54:15 +09:00
Author: https://github.com/dzfrias
Commit: e345d65def
Pull-request: https://github.com/SerenityOS/serenity/pull/24457
2 changed files with 126 additions and 274 deletions
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue