Skip to content

Instantly share code, notes, and snippets.

@gumb0
Last active October 23, 2020 14:36
Show Gist options
  • Save gumb0/a25cfa01dffe962770632e1c997e4408 to your computer and use it in GitHub Desktop.
Save gumb0/a25cfa01dffe962770632e1c997e4408 to your computer and use it in GitHub Desktop.
Injecting metering in Fizzy's parser
// ControlFrame new members:
struct ControlFrame
{
// ...
int gas;
size_t metering_immediate_offset;
};
void insert_metering_statement()
{
code.instructions.emplace_back(Instr::i32_const);
code.immediates.emplace_back(0); // cost immediate to be updated later
code.instructions.emplace_bac(Instr::call);
code.immdeidates.emplace_back(MeterFunctionIndex);
}
void update_metering_immediate(offset, cost)
{
store(code.immediates.data() + offset, cost)
}
// Parser loop changes
// for each instruction, before switch:
if (!frame.unreachable)
frame.gas += gas_table[instr];
// This is currently below the switch, it will have to be moved to before,
// with adjusting offsets of jumps inside the switch
code.instructions.emplace_back(instr);
// Or without moving we could raise a flag inside the switch that would indicate,
// that metering statement needs to be inserted after current instruction
switch(instr)
{
case loop:
case block:
case if:
case else:
if (!frame.unreachable)
update_metering_immediate(frame.metering_immediate_offset, frame.gas);
push control frame: gas = 0, metering_immediate_offset = immediates.size()
insert_metering_statement();
case br:
case br_table:
case return:
case unreachable:
if (!frame.unreachable)
update_metering_immediate(frame.metering_immediate_offset, frame.gas);
mark_frame_unreachable();
case br_if:
if (!frame.unreachable)
update_metering_immediate(frame.metering_immediate_offset, frame.gas);
frame.gas = 0;
frame.metering_immediate_offset = immediates.size();
insert_metering_statement();
case end:
if (!frame.unreachable)
update_metering_immediate(frame.metering_immediate_offset, frame.gas);
pop control frame
if (!control_stack.empty())
insert_metering_statement();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment