Skip to content

Commit

Permalink
Move br_table immediate values to the instructions array
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed Oct 22, 2020
1 parent f9c2aba commit 35b4c36
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 33 deletions.
4 changes: 2 additions & 2 deletions lib/fizzy/execute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,8 +596,8 @@ ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args,
}
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>();

Expand Down
7 changes: 4 additions & 3 deletions lib/fizzy/parser_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -634,15 +634,16 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f
if (default_label_idx >= control_stack.size())
throw validation_error{"invalid label index"};

push(code.immediates, static_cast<uint32_t>(label_indices.size()));
code.instructions.push_back(opcode);
push(code.instructions, static_cast<uint32_t>(label_indices.size()));

auto& default_branch_frame = control_stack[default_label_idx];
const auto default_branch_type = get_branch_frame_type(default_branch_frame);

update_branch_stack(frame, default_branch_frame, operand_stack);

// arity is the same for all indices, so we push it once
push(code.immediates, get_branch_arity(default_branch_frame));
push(code.instructions, get_branch_arity(default_branch_frame));

// Remember immediates offset for all br items to fill them at end instruction.
for (const auto idx : label_indices)
Expand All @@ -662,7 +663,7 @@ parser_result<Code> parse_expr(const uint8_t* pos, const uint8_t* end, FuncIdx f

mark_frame_unreachable(frame, operand_stack);

break;
continue;
}

case Instr::return_:
Expand Down
53 changes: 25 additions & 28 deletions test/unittests/parser_expr_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,12 @@ TEST(parser_expr, instr_br_table)

EXPECT_THAT(code.instructions,
ElementsAre(Instr::block, Instr::block, Instr::block, Instr::block, Instr::block,
Instr::local_get, 0, 0, 0, 0, Instr::br_table, Instr::i32_const, 0x41, 0, 0, 0,
Instr::return_, Instr::end, Instr::i32_const, 0x42, 0, 0, 0, Instr::return_, Instr::end,
Instr::i32_const, 0x43, 0, 0, 0, Instr::return_, Instr::end, Instr::i32_const, 0x44, 0,
0, 0, Instr::return_, Instr::end, Instr::i32_const, 0x45, 0, 0, 0, Instr::return_,
Instr::end, Instr::i32_const, 0x46, 0, 0, 0, Instr::end));
Instr::local_get, 0, 0, 0, 0, Instr::br_table, /*label_count:*/ 4, 0, 0, 0,
/*arity:*/ 0, 0, 0, 0, Instr::i32_const, 0x41, 0, 0, 0, Instr::return_, Instr::end,
Instr::i32_const, 0x42, 0, 0, 0, Instr::return_, Instr::end, Instr::i32_const, 0x43, 0,
0, 0, Instr::return_, Instr::end, Instr::i32_const, 0x44, 0, 0, 0, Instr::return_,
Instr::end, Instr::i32_const, 0x45, 0, 0, 0, Instr::return_, Instr::end,
Instr::i32_const, 0x46, 0, 0, 0, Instr::end));

// br_imm_size = 12
// return_imm_size = br_imm_size + arity_size = 16
Expand All @@ -348,27 +349,24 @@ TEST(parser_expr, instr_br_table)
// br_3_offset = br_2_offset + 4 + return_imm_size = 0x98
// br_4_offset = br_3_offset + 4 + return_imm_size = 0xac
const auto expected_br_imm =
"04000000" // label_count
"00000000" // arity

"27000000" // code_offset
"84000000" // imm_offset
"2f000000" // code_offset
"7c000000" // imm_offset
"00000000" // stack_drop

"20000000" // code_offset
"74000000" // imm_offset
"28000000" // code_offset
"6c000000" // imm_offset
"00000000" // stack_drop

"19000000" // code_offset
"64000000" // imm_offset
"21000000" // code_offset
"5c000000" // imm_offset
"00000000" // stack_drop

"12000000" // code_offset
"54000000" // imm_offset
"1a000000" // code_offset
"4c000000" // imm_offset
"00000000" // stack_drop

"2e000000" // code_offset
"94000000" // imm_offset
"36000000" // code_offset
"8c000000" // imm_offset
"00000000"_bytes; // stack_drop

EXPECT_EQ(code.immediates.substr(0, expected_br_imm.size()), expected_br_imm);
Expand All @@ -393,16 +391,14 @@ TEST(parser_expr, instr_br_table_empty_vector)
ASSERT_EQ(module->codesec.size(), 1);
const auto& code = module->codesec[0];

EXPECT_THAT(
code.instructions, ElementsAre(Instr::block, Instr::local_get, 0, 0, 0, 0, Instr::br_table,
Instr::i32_const, 0x63, 0, 0, 0, Instr::return_, Instr::end,
Instr::i32_const, 0x64, 0, 0, 0, Instr::end));
EXPECT_THAT(code.instructions,
ElementsAre(Instr::block, Instr::local_get, 0, 0, 0, 0, Instr::br_table,
/*label_count:*/ 0, 0, 0, 0, /*arity:*/ 0, 0, 0, 0, Instr::i32_const, 0x63, 0, 0, 0,
Instr::return_, Instr::end, Instr::i32_const, 0x64, 0, 0, 0, Instr::end));

const auto expected_br_imm =
"00000000" // label_count
"00000000" // arity
"0e000000" // code_offset
"24000000" // imm_offset
"16000000" // code_offset
"1c000000" // imm_offset
"00000000"_bytes; // stack_drop
EXPECT_EQ(code.immediates.substr(0, expected_br_imm.size()), expected_br_imm);
EXPECT_EQ(code.max_stack_height, 1);
Expand All @@ -417,8 +413,9 @@ TEST(parser_expr, instr_br_table_as_return)

const auto code_bin = i32_const(0) + "0e00000b"_bytes;
const auto [code, _] = parse_expr(code_bin);
EXPECT_THAT(
code.instructions, ElementsAre(Instr::i32_const, 0, 0, 0, 0, Instr::br_table, Instr::end));
EXPECT_THAT(code.instructions,
ElementsAre(Instr::i32_const, 0, 0, 0, 0, Instr::br_table, /*label_count:*/ 0, 0, 0, 0,
/*arity:*/ 0, 0, 0, 0, Instr::end));
EXPECT_EQ(code.max_stack_height, 1);
}

Expand Down

0 comments on commit 35b4c36

Please sign in to comment.