Skip to content

Commit

Permalink
Simplify trap handling
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast authored and axic committed Jul 15, 2020
1 parent 776ce47 commit 30e0cf6
Showing 1 changed file with 36 additions and 126 deletions.
162 changes: 36 additions & 126 deletions lib/fizzy/execute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -616,8 +616,6 @@ execution_result execute(Instance& instance, FuncIdx func_idx, span<const uint64

OperandStack stack(static_cast<size_t>(code.max_stack_height));

bool trap = false;

const Instr* pc = code.instructions.data();
const uint8_t* immediates = code.immediates.data();

Expand All @@ -627,8 +625,7 @@ execution_result execute(Instance& instance, FuncIdx func_idx, span<const uint64
switch (instruction)
{
case Instr::unreachable:
trap = true;
goto end;
goto trap;
case Instr::nop:
case Instr::block:
case Instr::loop:
Expand Down Expand Up @@ -699,10 +696,7 @@ execution_result execute(Instance& instance, FuncIdx func_idx, span<const uint64
const auto& func_type = instance.module.get_function_type(called_func_idx);

if (!invoke_function(func_type, called_func_idx, instance, stack, depth))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::call_indirect:
Expand All @@ -714,32 +708,20 @@ execution_result execute(Instance& instance, FuncIdx func_idx, span<const uint64

const auto elem_idx = stack.pop();
if (elem_idx >= instance.table->size())
{
trap = true;
goto end;
}
goto trap;

const auto called_func = (*instance.table)[elem_idx];
if (!called_func.has_value())
{
trap = true;
goto end;
}
goto trap;

// check actual type against expected type
const auto& actual_type = called_func->type;
const auto& expected_type = instance.module.typesec[expected_type_idx];
if (expected_type != actual_type)
{
trap = true;
goto end;
}
goto trap;

if (!invoke_function(actual_type, called_func->function, instance, stack, depth))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::drop:
Expand Down Expand Up @@ -816,156 +798,105 @@ execution_result execute(Instance& instance, FuncIdx func_idx, span<const uint64
case Instr::i32_load:
{
if (!load_from_memory<uint32_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::i64_load:
{
if (!load_from_memory<uint64_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::i32_load8_s:
{
if (!load_from_memory<uint32_t, int8_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::i32_load8_u:
{
if (!load_from_memory<uint32_t, uint8_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::i32_load16_s:
{
if (!load_from_memory<uint32_t, int16_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::i32_load16_u:
{
if (!load_from_memory<uint32_t, uint16_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::i64_load8_s:
{
if (!load_from_memory<uint64_t, int8_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::i64_load8_u:
{
if (!load_from_memory<uint64_t, uint8_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::i64_load16_s:
{
if (!load_from_memory<uint64_t, int16_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::i64_load16_u:
{
if (!load_from_memory<uint64_t, uint16_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::i64_load32_s:
{
if (!load_from_memory<uint64_t, int32_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::i64_load32_u:
{
if (!load_from_memory<uint64_t, uint32_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::i32_store:
{
if (!store_into_memory<uint32_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::i64_store:
{
if (!store_into_memory<uint64_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::i32_store8:
case Instr::i64_store8:
{
if (!store_into_memory<uint8_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::i32_store16:
case Instr::i64_store16:
{
if (!store_into_memory<uint16_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::i64_store32:
{
if (!store_into_memory<uint32_t>(*memory, stack, immediates))
{
trap = true;
goto end;
}
goto trap;
break;
}
case Instr::memory_size:
Expand Down Expand Up @@ -1155,32 +1086,23 @@ execution_result execute(Instance& instance, FuncIdx func_idx, span<const uint64
auto const rhs = static_cast<int32_t>(stack[0]);
auto const lhs = static_cast<int32_t>(stack[1]);
if (rhs == 0 || (lhs == std::numeric_limits<int32_t>::min() && rhs == -1))
{
trap = true;
goto end;
}
goto trap;
binary_op(stack, std::divides<int32_t>());
break;
}
case Instr::i32_div_u:
{
auto const rhs = static_cast<uint32_t>(stack.top());
if (rhs == 0)
{
trap = true;
goto end;
}
goto trap;
binary_op(stack, std::divides<uint32_t>());
break;
}
case Instr::i32_rem_s:
{
auto const rhs = static_cast<int32_t>(stack.top());
if (rhs == 0)
{
trap = true;
goto end;
}
goto trap;
auto const lhs = static_cast<int32_t>(stack[1]);
if (lhs == std::numeric_limits<int32_t>::min() && rhs == -1)
{
Expand All @@ -1195,10 +1117,7 @@ execution_result execute(Instance& instance, FuncIdx func_idx, span<const uint64
{
auto const rhs = static_cast<uint32_t>(stack.top());
if (rhs == 0)
{
trap = true;
goto end;
}
goto trap;
binary_op(stack, std::modulus<uint32_t>());
break;
}
Expand Down Expand Up @@ -1277,32 +1196,23 @@ execution_result execute(Instance& instance, FuncIdx func_idx, span<const uint64
auto const rhs = static_cast<int64_t>(stack[0]);
auto const lhs = static_cast<int64_t>(stack[1]);
if (rhs == 0 || (lhs == std::numeric_limits<int64_t>::min() && rhs == -1))
{
trap = true;
goto end;
}
goto trap;
binary_op(stack, std::divides<int64_t>());
break;
}
case Instr::i64_div_u:
{
auto const rhs = static_cast<uint64_t>(stack.top());
if (rhs == 0)
{
trap = true;
goto end;
}
goto trap;
binary_op(stack, std::divides<uint64_t>());
break;
}
case Instr::i64_rem_s:
{
auto const rhs = static_cast<int64_t>(stack.top());
if (rhs == 0)
{
trap = true;
goto end;
}
goto trap;
auto const lhs = static_cast<int64_t>(stack[1]);
if (lhs == std::numeric_limits<int64_t>::min() && rhs == -1)
{
Expand All @@ -1317,10 +1227,7 @@ execution_result execute(Instance& instance, FuncIdx func_idx, span<const uint64
{
auto const rhs = static_cast<uint64_t>(stack.top());
if (rhs == 0)
{
trap = true;
goto end;
}
goto trap;
binary_op(stack, std::modulus<uint64_t>());
break;
}
Expand Down Expand Up @@ -1457,8 +1364,11 @@ execution_result execute(Instance& instance, FuncIdx func_idx, span<const uint64

end:
// WebAssembly 1.0 allows at most one return variable.
assert(trap || (pc == &code.instructions[code.instructions.size()] && stack.size() <= 1));
return {trap, {stack.rbegin(), stack.rend()}};
assert(pc == &code.instructions[code.instructions.size()] && stack.size() <= 1);
return {false, {stack.rbegin(), stack.rend()}};

trap:
return {true, {}};
}

std::vector<ExternalFunction> resolve_imported_functions(
Expand Down

0 comments on commit 30e0cf6

Please sign in to comment.