Skip to content

Commit

Permalink
Merge pull request #618 from wasmx/immediates_merge
Browse files Browse the repository at this point in the history
Drop immediates array
  • Loading branch information
chfast authored Nov 6, 2020
2 parents 9abcdfb + 1bb954b commit 7c0562b
Show file tree
Hide file tree
Showing 10 changed files with 263 additions and 366 deletions.
2 changes: 1 addition & 1 deletion circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ jobs:
sanitizers-gcc:
executor: linux-gcc-latest
environment:
CMAKE_BUILD_PARALLEL_LEVEL: 6
CMAKE_BUILD_PARALLEL_LEVEL: 2
# TODO: Enable detect_stack_use_after_return=1 when https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97414 is fixed.
ASAN_OPTIONS: detect_invalid_pointer_pairs=2:check_initialization_order=1
UBSAN_OPTIONS: halt_on_error=1
Expand Down
101 changes: 45 additions & 56 deletions lib/fizzy/execute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ namespace fizzy
{
namespace
{
// code_offset + imm_offset + stack_height
constexpr auto BranchImmediateSize = 3 * sizeof(uint32_t);
// code_offset + stack_drop
constexpr auto BranchImmediateSize = 2 * sizeof(uint32_t);

constexpr uint32_t F32AbsMask = 0x7fffffff;
constexpr uint32_t F32SignMask = ~F32AbsMask;
Expand Down Expand Up @@ -453,15 +453,12 @@ __attribute__((no_sanitize("float-cast-overflow"))) inline constexpr float demot
return static_cast<float>(value);
}

void branch(const Code& code, OperandStack& stack, const uint8_t*& pc, const uint8_t*& immediates,
uint32_t arity) noexcept
void branch(const Code& code, OperandStack& stack, const uint8_t*& pc, uint32_t arity) noexcept
{
const auto code_offset = read<uint32_t>(immediates);
const auto imm_offset = read<uint32_t>(immediates);
const auto stack_drop = read<uint32_t>(immediates);
const auto code_offset = read<uint32_t>(pc);
const auto stack_drop = read<uint32_t>(pc);

pc = code.instructions.data() + code_offset;
immediates = code.immediates.data() + imm_offset;

// When branch is taken, additional stack items must be dropped.
assert(static_cast<int>(stack_drop) >= 0);
Expand Down Expand Up @@ -523,7 +520,6 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
static_cast<size_t>(code.max_stack_height));

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

while (true)
{
Expand All @@ -539,27 +535,20 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
case Instr::if_:
{
if (stack.pop().as<uint32_t>() != 0)
immediates += 2 * sizeof(uint32_t); // Skip the immediates for else instruction.
pc += sizeof(uint32_t); // Skip the immediate for else instruction.
else
{
const auto target_pc = read<uint32_t>(immediates);
const auto target_imm = read<uint32_t>(immediates);

const auto target_pc = read<uint32_t>(pc);
pc = code.instructions.data() + target_pc;
immediates = code.immediates.data() + target_imm;
}
break;
}
case Instr::else_:
{
// We reach else only after executing if block ("then" part),
// so we need to skip else block now.
const auto target_pc = read<uint32_t>(immediates);
const auto target_imm = read<uint32_t>(immediates);

const auto target_pc = read<uint32_t>(pc);
pc = code.instructions.data() + target_pc;
immediates = code.immediates.data() + target_imm;

break;
}
case Instr::end:
Expand All @@ -573,36 +562,36 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
case Instr::br_if:
case Instr::return_:
{
const auto arity = read<uint32_t>(immediates);
const auto arity = read<uint32_t>(pc);

// Check condition for br_if.
if (instruction == Instr::br_if && stack.pop().as<uint32_t>() == 0)
{
immediates += BranchImmediateSize;
pc += BranchImmediateSize;
break;
}

branch(code, stack, pc, immediates, arity);
branch(code, stack, pc, arity);
break;
}
case Instr::br_table:
{
const auto br_table_size = read<uint32_t>(immediates);
const auto arity = read<uint32_t>(immediates);
const auto br_table_size = read<uint32_t>(pc);
const auto arity = read<uint32_t>(pc);

const auto br_table_idx = stack.pop().as<uint32_t>();

const auto label_idx_offset = br_table_idx < br_table_size ?
br_table_idx * BranchImmediateSize :
br_table_size * BranchImmediateSize;
immediates += label_idx_offset;
pc += label_idx_offset;

branch(code, stack, pc, immediates, arity);
branch(code, stack, pc, arity);
break;
}
case Instr::call:
{
const auto called_func_idx = read<uint32_t>(immediates);
const auto called_func_idx = read<uint32_t>(pc);
const auto& called_func_type = instance.module->get_function_type(called_func_idx);

if (!invoke_function(called_func_type, called_func_idx, instance, stack, depth))
Expand All @@ -613,7 +602,7 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
{
assert(instance.table != nullptr);

const auto expected_type_idx = read<uint32_t>(immediates);
const auto expected_type_idx = read<uint32_t>(pc);
assert(expected_type_idx < instance.module->typesec.size());

const auto elem_idx = stack.pop().as<uint32_t>();
Expand Down Expand Up @@ -655,25 +644,25 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
}
case Instr::local_get:
{
const auto idx = read<uint32_t>(immediates);
const auto idx = read<uint32_t>(pc);
stack.push(stack.local(idx));
break;
}
case Instr::local_set:
{
const auto idx = read<uint32_t>(immediates);
const auto idx = read<uint32_t>(pc);
stack.local(idx) = stack.pop();
break;
}
case Instr::local_tee:
{
const auto idx = read<uint32_t>(immediates);
const auto idx = read<uint32_t>(pc);
stack.local(idx) = stack.top();
break;
}
case Instr::global_get:
{
const auto idx = read<uint32_t>(immediates);
const auto idx = read<uint32_t>(pc);
assert(idx < instance.imported_globals.size() + instance.globals.size());
if (idx < instance.imported_globals.size())
{
Expand All @@ -689,7 +678,7 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
}
case Instr::global_set:
{
const auto idx = read<uint32_t>(immediates);
const auto idx = read<uint32_t>(pc);
if (idx < instance.imported_globals.size())
{
assert(instance.imported_globals[idx].type.is_mutable);
Expand All @@ -706,129 +695,129 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
}
case Instr::i32_load:
{
if (!load_from_memory<uint32_t>(*memory, stack, immediates))
if (!load_from_memory<uint32_t>(*memory, stack, pc))
goto trap;
break;
}
case Instr::i64_load:
{
if (!load_from_memory<uint64_t>(*memory, stack, immediates))
if (!load_from_memory<uint64_t>(*memory, stack, pc))
goto trap;
break;
}
case Instr::f32_load:
{
if (!load_from_memory<float>(*memory, stack, immediates))
if (!load_from_memory<float>(*memory, stack, pc))
goto trap;
break;
}
case Instr::f64_load:
{
if (!load_from_memory<double>(*memory, stack, immediates))
if (!load_from_memory<double>(*memory, stack, pc))
goto trap;
break;
}
case Instr::i32_load8_s:
{
if (!load_from_memory<uint32_t, int8_t>(*memory, stack, immediates))
if (!load_from_memory<uint32_t, int8_t>(*memory, stack, pc))
goto trap;
break;
}
case Instr::i32_load8_u:
{
if (!load_from_memory<uint32_t, uint8_t>(*memory, stack, immediates))
if (!load_from_memory<uint32_t, uint8_t>(*memory, stack, pc))
goto trap;
break;
}
case Instr::i32_load16_s:
{
if (!load_from_memory<uint32_t, int16_t>(*memory, stack, immediates))
if (!load_from_memory<uint32_t, int16_t>(*memory, stack, pc))
goto trap;
break;
}
case Instr::i32_load16_u:
{
if (!load_from_memory<uint32_t, uint16_t>(*memory, stack, immediates))
if (!load_from_memory<uint32_t, uint16_t>(*memory, stack, pc))
goto trap;
break;
}
case Instr::i64_load8_s:
{
if (!load_from_memory<uint64_t, int8_t>(*memory, stack, immediates))
if (!load_from_memory<uint64_t, int8_t>(*memory, stack, pc))
goto trap;
break;
}
case Instr::i64_load8_u:
{
if (!load_from_memory<uint64_t, uint8_t>(*memory, stack, immediates))
if (!load_from_memory<uint64_t, uint8_t>(*memory, stack, pc))
goto trap;
break;
}
case Instr::i64_load16_s:
{
if (!load_from_memory<uint64_t, int16_t>(*memory, stack, immediates))
if (!load_from_memory<uint64_t, int16_t>(*memory, stack, pc))
goto trap;
break;
}
case Instr::i64_load16_u:
{
if (!load_from_memory<uint64_t, uint16_t>(*memory, stack, immediates))
if (!load_from_memory<uint64_t, uint16_t>(*memory, stack, pc))
goto trap;
break;
}
case Instr::i64_load32_s:
{
if (!load_from_memory<uint64_t, int32_t>(*memory, stack, immediates))
if (!load_from_memory<uint64_t, int32_t>(*memory, stack, pc))
goto trap;
break;
}
case Instr::i64_load32_u:
{
if (!load_from_memory<uint64_t, uint32_t>(*memory, stack, immediates))
if (!load_from_memory<uint64_t, uint32_t>(*memory, stack, pc))
goto trap;
break;
}
case Instr::i32_store:
{
if (!store_into_memory<uint32_t>(*memory, stack, immediates))
if (!store_into_memory<uint32_t>(*memory, stack, pc))
goto trap;
break;
}
case Instr::i64_store:
{
if (!store_into_memory<uint64_t>(*memory, stack, immediates))
if (!store_into_memory<uint64_t>(*memory, stack, pc))
goto trap;
break;
}
case Instr::f32_store:
{
if (!store_into_memory<float>(*memory, stack, immediates))
if (!store_into_memory<float>(*memory, stack, pc))
goto trap;
break;
}
case Instr::f64_store:
{
if (!store_into_memory<double>(*memory, stack, immediates))
if (!store_into_memory<double>(*memory, stack, pc))
goto trap;
break;
}
case Instr::i32_store8:
case Instr::i64_store8:
{
if (!store_into_memory<uint8_t>(*memory, stack, immediates))
if (!store_into_memory<uint8_t>(*memory, stack, pc))
goto trap;
break;
}
case Instr::i32_store16:
case Instr::i64_store16:
{
if (!store_into_memory<uint16_t>(*memory, stack, immediates))
if (!store_into_memory<uint16_t>(*memory, stack, pc))
goto trap;
break;
}
case Instr::i64_store32:
{
if (!store_into_memory<uint32_t>(*memory, stack, immediates))
if (!store_into_memory<uint32_t>(*memory, stack, pc))
goto trap;
break;
}
Expand Down Expand Up @@ -861,14 +850,14 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
case Instr::i32_const:
case Instr::f32_const:
{
const auto value = read<uint32_t>(immediates);
const auto value = read<uint32_t>(pc);
stack.push(value);
break;
}
case Instr::i64_const:
case Instr::f64_const:
{
const auto value = read<uint64_t>(immediates);
const auto value = read<uint64_t>(pc);
stack.push(value);
break;
}
Expand Down
Loading

0 comments on commit 7c0562b

Please sign in to comment.