Make all instructions non-faulting; handle faulting case in gen_safe_{read,write} (#44)
This commit is contained in:
parent
60d4a28e2c
commit
d4d7d236d5
|
@ -236,8 +236,29 @@ fn gen_safe_read(ctx: &mut JitContext, bits: BitSize) {
|
|||
}
|
||||
|
||||
// Pseudo:
|
||||
// else { leave_on_stack(safe_read*_slow(address)); if(page_fault) return }
|
||||
// else {
|
||||
// *previous_ip = *instruction_pointer & ~0xFFF | start_of_instruction;
|
||||
// leave_on_stack(safe_read*_slow(address));
|
||||
// if(page_fault) return;
|
||||
// }
|
||||
builder.instruction_body.else_();
|
||||
|
||||
builder
|
||||
.instruction_body
|
||||
.push_i32(global_pointers::PREVIOUS_IP as i32);
|
||||
|
||||
builder
|
||||
.instruction_body
|
||||
.load_aligned_i32(global_pointers::INSTRUCTION_POINTER);
|
||||
builder.instruction_body.push_i32(!0xFFF);
|
||||
builder.instruction_body.and_i32();
|
||||
builder
|
||||
.instruction_body
|
||||
.push_i32(ctx.start_of_current_instruction as i32 & 0xFFF);
|
||||
builder.instruction_body.or_i32();
|
||||
|
||||
builder.instruction_body.store_aligned_i32();
|
||||
|
||||
builder.instruction_body.get_local(&address_local);
|
||||
match bits {
|
||||
BitSize::WORD => {
|
||||
|
@ -341,8 +362,29 @@ fn gen_safe_write(
|
|||
}
|
||||
|
||||
// Pseudo:
|
||||
// else { safe_write*_slow(address, value); if(page_fault) return; }
|
||||
// else {
|
||||
// *previous_ip = *instruction_pointer & ~0xFFF | start_of_instruction;
|
||||
// safe_write*_slow(address, value);
|
||||
// if(page_fault) return;
|
||||
// }
|
||||
builder.instruction_body.else_();
|
||||
|
||||
builder
|
||||
.instruction_body
|
||||
.push_i32(global_pointers::PREVIOUS_IP as i32);
|
||||
|
||||
builder
|
||||
.instruction_body
|
||||
.load_aligned_i32(global_pointers::INSTRUCTION_POINTER);
|
||||
builder.instruction_body.push_i32(!0xFFF);
|
||||
builder.instruction_body.and_i32();
|
||||
builder
|
||||
.instruction_body
|
||||
.push_i32(ctx.start_of_current_instruction as i32 & 0xFFF);
|
||||
builder.instruction_body.or_i32();
|
||||
|
||||
builder.instruction_body.store_aligned_i32();
|
||||
|
||||
builder.instruction_body.get_local(&address_local);
|
||||
builder.instruction_body.get_local(&value_local);
|
||||
match bits {
|
||||
|
|
|
@ -19,7 +19,6 @@ pub const WASM_TABLE_SIZE: u32 = 0x10000;
|
|||
pub const HASH_PRIME: u32 = 6151;
|
||||
|
||||
pub const CHECK_JIT_CACHE_ARRAY_INVARIANTS: bool = false;
|
||||
pub const ENABLE_JIT_NONFAULTING_OPTIMZATION: bool = true;
|
||||
|
||||
pub const JIT_MAX_ITERATIONS_PER_FUNCTION: u32 = 10000;
|
||||
|
||||
|
@ -380,6 +379,7 @@ impl cached_code {
|
|||
pub struct JitContext<'a> {
|
||||
pub cpu: &'a mut CpuContext,
|
||||
pub builder: &'a mut WasmBuilder,
|
||||
pub start_of_current_instruction: u32,
|
||||
}
|
||||
|
||||
pub const JIT_INSTR_BLOCK_BOUNDARY_FLAG: u32 = 1 << 0;
|
||||
|
@ -643,16 +643,14 @@ fn jit_find_basic_blocks(
|
|||
}
|
||||
}
|
||||
|
||||
let mut basic_blocks: Vec<BasicBlock> =
|
||||
basic_blocks.into_iter().map(|(_, block)| block).collect();
|
||||
|
||||
basic_blocks.sort_by_key(|block| block.addr);
|
||||
let basic_blocks: Vec<BasicBlock> = basic_blocks.into_iter().map(|(_, block)| block).collect();
|
||||
|
||||
for i in 0..basic_blocks.len() - 1 {
|
||||
let next_block_addr = basic_blocks[i + 1].addr;
|
||||
let next_block_end_addr = basic_blocks[i + 1].end_addr;
|
||||
let next_block_is_entry = basic_blocks[i + 1].is_entry_block;
|
||||
let block = &basic_blocks[i];
|
||||
dbg_assert!(block.addr < next_block_addr);
|
||||
if next_block_addr < block.end_addr {
|
||||
dbg_log!(
|
||||
"Overlapping first=[from={:x} to={:x} is_entry={}] second=[from={:x} to={:x} is_entry={}]",
|
||||
|
@ -1045,6 +1043,7 @@ fn jit_generate_module(
|
|||
let ctx = &mut JitContext {
|
||||
cpu: &mut cpu.clone(),
|
||||
builder,
|
||||
start_of_current_instruction: 0,
|
||||
};
|
||||
codegen::gen_fn1_const(ctx, "jmp_rel16", jump_offset as u32);
|
||||
}
|
||||
|
@ -1108,11 +1107,7 @@ fn jit_generate_basic_block(
|
|||
last_instruction_addr: u32,
|
||||
stop_addr: u32,
|
||||
) {
|
||||
let mut len = 0;
|
||||
|
||||
let mut end_addr;
|
||||
let mut was_block_boundary;
|
||||
let mut eip_delta = 0;
|
||||
let mut count = 0;
|
||||
|
||||
// First iteration of do-while assumes the caller confirms this condition
|
||||
dbg_assert!(!is_near_end_of_page(start_addr));
|
||||
|
@ -1123,6 +1118,19 @@ fn jit_generate_basic_block(
|
|||
if false {
|
||||
::opstats::gen_opstats(builder, cpu::read32(cpu.eip));
|
||||
}
|
||||
|
||||
if cpu.eip == last_instruction_addr {
|
||||
// Before the last instruction:
|
||||
// - Set eip to *after* the instruction
|
||||
// - Set previous_eip to *before* the instruction
|
||||
builder.commit_instruction_body_to_cs();
|
||||
codegen::gen_set_previous_eip_offset_from_eip(
|
||||
builder,
|
||||
last_instruction_addr - start_addr,
|
||||
);
|
||||
codegen::gen_increment_instruction_pointer(builder, stop_addr - start_addr);
|
||||
}
|
||||
|
||||
let start_eip = cpu.eip;
|
||||
let mut instruction_flags = 0;
|
||||
jit_instructions::jit_instruction(&mut cpu, builder, &mut instruction_flags);
|
||||
|
@ -1141,55 +1149,18 @@ fn jit_generate_basic_block(
|
|||
}
|
||||
|
||||
let instruction_length = end_eip - start_eip;
|
||||
was_block_boundary = instruction_flags & JIT_INSTR_BLOCK_BOUNDARY_FLAG != 0;
|
||||
let was_block_boundary = instruction_flags & JIT_INSTR_BLOCK_BOUNDARY_FLAG != 0;
|
||||
|
||||
dbg_assert!((end_eip == stop_addr) == (start_eip == last_instruction_addr));
|
||||
|
||||
dbg_assert!(instruction_length < MAX_INSTRUCTION_LENGTH);
|
||||
|
||||
if ENABLE_JIT_NONFAULTING_OPTIMZATION {
|
||||
// There are a few conditions to keep in mind to optimize the update of previous_ip and
|
||||
// instruction_pointer:
|
||||
// - previous_ip MUST be updated just before a faulting instruction
|
||||
// - instruction_pointer MUST be updated before jump instructions (since they use the EIP
|
||||
// value for instruction logic)
|
||||
// - Nonfaulting instructions don't need either to be updated
|
||||
if was_block_boundary {
|
||||
// prev_ip = eip + eip_delta, so that previous_ip points to the start of this instruction
|
||||
codegen::gen_set_previous_eip_offset_from_eip(builder, eip_delta);
|
||||
|
||||
// eip += eip_delta + len(jump) so instruction logic uses the correct eip
|
||||
codegen::gen_increment_instruction_pointer(builder, eip_delta + instruction_length);
|
||||
builder.commit_instruction_body_to_cs();
|
||||
|
||||
eip_delta = 0;
|
||||
}
|
||||
else if instruction_flags & JIT_INSTR_NONFAULTING_FLAG == 0 {
|
||||
// Faulting instruction
|
||||
|
||||
// prev_ip = eip + eip_delta, so that previous_ip points to the start of this instruction
|
||||
codegen::gen_set_previous_eip_offset_from_eip(builder, eip_delta);
|
||||
builder.commit_instruction_body_to_cs();
|
||||
|
||||
// Leave this instruction's length to be updated in the next batch, whatever it may be
|
||||
eip_delta += instruction_length;
|
||||
}
|
||||
else {
|
||||
// Non-faulting, so we skip setting previous_ip and simply queue the instruction length
|
||||
// for whenever eip is updated next
|
||||
profiler::stat_increment(stat::S_NONFAULTING_OPTIMIZATION);
|
||||
eip_delta += instruction_length;
|
||||
}
|
||||
}
|
||||
else {
|
||||
codegen::gen_set_previous_eip(builder);
|
||||
codegen::gen_increment_instruction_pointer(builder, instruction_length);
|
||||
builder.commit_instruction_body_to_cs();
|
||||
}
|
||||
end_addr = cpu.eip;
|
||||
len += 1;
|
||||
let end_addr = cpu.eip;
|
||||
count += 1;
|
||||
|
||||
if end_addr == stop_addr {
|
||||
// no page was crossed
|
||||
dbg_assert!(Page::page_of(end_addr) == Page::page_of(start_addr));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1201,18 +1172,7 @@ fn jit_generate_basic_block(
|
|||
}
|
||||
}
|
||||
|
||||
if ENABLE_JIT_NONFAULTING_OPTIMZATION {
|
||||
// When the block ends in a non-jump instruction, we may have uncommitted updates still
|
||||
if eip_delta > 0 {
|
||||
builder.commit_instruction_body_to_cs();
|
||||
codegen::gen_increment_instruction_pointer(builder, eip_delta);
|
||||
}
|
||||
}
|
||||
|
||||
codegen::gen_increment_timestamp_counter(builder, len);
|
||||
|
||||
// no page was crossed
|
||||
dbg_assert!(Page::page_of(end_addr) == Page::page_of(start_addr));
|
||||
codegen::gen_increment_timestamp_counter(builder, count);
|
||||
}
|
||||
|
||||
pub fn jit_increase_hotness_and_maybe_compile(
|
||||
|
|
|
@ -16,7 +16,12 @@ use wasmgen::wasm_util::WasmBuf;
|
|||
|
||||
pub fn jit_instruction(cpu: &mut CpuContext, builder: &mut WasmBuilder, instr_flags: &mut u32) {
|
||||
cpu.prefixes = 0;
|
||||
let ctx = &mut JitContext { cpu, builder };
|
||||
let start_of_current_instruction = cpu.eip;
|
||||
let ctx = &mut JitContext {
|
||||
cpu,
|
||||
builder,
|
||||
start_of_current_instruction,
|
||||
};
|
||||
::gen::jit::jit(
|
||||
ctx.cpu.read_imm8() as u32 | (ctx.cpu.osize_32() as u32) << 8,
|
||||
ctx,
|
||||
|
|
|
@ -33,6 +33,12 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 5)))
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 1)))
|
||||
(set_local $l0
|
||||
(i32.sub
|
||||
(i32.load
|
||||
|
@ -75,6 +81,14 @@
|
|||
(get_local $l2))
|
||||
(get_local $l0)))
|
||||
(else
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.or
|
||||
(i32.and
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const -4096))
|
||||
(i32.const 0)))
|
||||
(call $e.safe_write32_slow_jit
|
||||
(get_local $l2)
|
||||
(get_local $l0))
|
||||
|
@ -92,12 +106,6 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 1)))
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 1)))
|
||||
(set_local $p0
|
||||
(i32.const 2))
|
||||
(br $L0))
|
||||
|
@ -111,14 +119,15 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 1)))
|
||||
(call $e.instr_F4)
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 1)))
|
||||
(call $e.instr_F4)
|
||||
(return))
|
||||
(call $e.instr32_40)
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.add
|
||||
|
@ -131,7 +140,12 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 2)))
|
||||
(call $e.instr32_40)
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 2)))
|
||||
(i32.const 556)
|
||||
(i32.load
|
||||
(i32.const 740))
|
||||
|
@ -167,6 +181,14 @@
|
|||
(i32.const -4096))
|
||||
(get_local $l1))))
|
||||
(else
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.or
|
||||
(i32.and
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const -4096))
|
||||
(i32.const 7)))
|
||||
(call $e.safe_read32s_slow_jit
|
||||
(get_local $l1))
|
||||
(if $I8
|
||||
|
@ -181,11 +203,5 @@
|
|||
(i32.const 4)))
|
||||
(i32.add)
|
||||
(i32.store)
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 2)))
|
||||
(return))
|
||||
(unreachable))))
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
(block $B4
|
||||
(br_table $B4 $B3 $B2 $B1
|
||||
(get_local $p0)))
|
||||
(call $e.instr32_43)
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.add
|
||||
|
@ -35,16 +36,15 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 4)))
|
||||
(call $e.instr32_43)
|
||||
(call $e.instr32_83_7_reg
|
||||
(i32.const 0)
|
||||
(i32.const 10))
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 2)))
|
||||
(call $e.instr32_83_7_reg
|
||||
(i32.const 0)
|
||||
(i32.const 10))
|
||||
(return))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
|
@ -87,12 +87,12 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 1)))
|
||||
(call $e.instr_F4)
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 1)))
|
||||
(call $e.instr_F4)
|
||||
(return))
|
||||
(unreachable))))
|
||||
|
|
|
@ -35,15 +35,15 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 3)))
|
||||
(call $e.instr32_83_7_reg
|
||||
(i32.const 0)
|
||||
(i32.const 5))
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 1)))
|
||||
(call $e.instr32_83_7_reg
|
||||
(i32.const 0)
|
||||
(i32.const 5))
|
||||
(return))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
|
@ -76,7 +76,10 @@
|
|||
(set_local $p0
|
||||
(i32.const 2))))
|
||||
(br $L0))
|
||||
(call $e.instr32_41)
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.load
|
||||
(i32.const 556)))
|
||||
(i32.store
|
||||
(i32.const 556)
|
||||
(i32.add
|
||||
|
@ -89,9 +92,11 @@
|
|||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 1)))
|
||||
(call $e.instr32_41)
|
||||
(set_local $p0
|
||||
(i32.const 3))
|
||||
(br $L0))
|
||||
(call $e.instr32_43)
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.add
|
||||
|
@ -104,13 +109,12 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 2)))
|
||||
(call $e.instr32_43)
|
||||
(call $e.instr_F4)
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 2)))
|
||||
(call $e.instr_F4)
|
||||
(return))
|
||||
(unreachable))))
|
||||
|
|
|
@ -30,18 +30,18 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 2)))
|
||||
(call $e.instr32_FF_2_mem
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 4))
|
||||
(call $e.get_seg
|
||||
(i32.const 3))))
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 1)))
|
||||
(call $e.instr32_FF_2_mem
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 4))
|
||||
(call $e.get_seg
|
||||
(i32.const 3))))
|
||||
(return))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
|
@ -53,12 +53,12 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 1)))
|
||||
(call $e.instr_F4)
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 1)))
|
||||
(call $e.instr_F4)
|
||||
(return))
|
||||
(unreachable))))
|
||||
|
|
|
@ -21,12 +21,6 @@
|
|||
(block $B2
|
||||
(br_table $B2 $B1
|
||||
(get_local $p0)))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 3)))
|
||||
(call $e.instr16_B8
|
||||
(i32.const 51966))
|
||||
(i32.store16
|
||||
|
@ -61,6 +55,14 @@
|
|||
(i32.const -4096))
|
||||
(get_local $l0))))
|
||||
(else
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.or
|
||||
(i32.and
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const -4096))
|
||||
(i32.const 3)))
|
||||
(call $e.safe_read16_slow_jit
|
||||
(get_local $l0))
|
||||
(if $I4
|
||||
|
@ -68,12 +70,6 @@
|
|||
(i32.const 540))
|
||||
(then
|
||||
(return))))))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 7)))
|
||||
(i32.store16
|
||||
(i32.const 12)
|
||||
(if $I5 (result i32)
|
||||
|
@ -106,6 +102,14 @@
|
|||
(i32.const -4096))
|
||||
(get_local $l1))))
|
||||
(else
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.or
|
||||
(i32.and
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const -4096))
|
||||
(i32.const 7)))
|
||||
(call $e.safe_read16_slow_jit
|
||||
(get_local $l1))
|
||||
(if $I6
|
||||
|
@ -113,12 +117,6 @@
|
|||
(i32.const 540))
|
||||
(then
|
||||
(return))))))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 19)))
|
||||
(i32.store16
|
||||
(i32.const 32)
|
||||
(i32.const 36))
|
||||
|
@ -166,6 +164,14 @@
|
|||
(get_local $l0))
|
||||
(get_local $l1)))
|
||||
(else
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.or
|
||||
(i32.and
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const -4096))
|
||||
(i32.const 19)))
|
||||
(call $e.safe_write16_slow_jit
|
||||
(get_local $l0)
|
||||
(get_local $l1))
|
||||
|
@ -174,12 +180,6 @@
|
|||
(i32.const 540))
|
||||
(then
|
||||
(return)))))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 21)))
|
||||
(set_local $l1
|
||||
(i32.add
|
||||
(i32.and
|
||||
|
@ -221,6 +221,14 @@
|
|||
(get_local $l1))
|
||||
(get_local $l0)))
|
||||
(else
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.or
|
||||
(i32.and
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const -4096))
|
||||
(i32.const 21)))
|
||||
(call $e.safe_write16_slow_jit
|
||||
(get_local $l1)
|
||||
(get_local $l0))
|
||||
|
@ -229,18 +237,6 @@
|
|||
(i32.const 540))
|
||||
(then
|
||||
(return)))))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 31)))
|
||||
(i32.store
|
||||
(i32.const 556)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 32)))
|
||||
(i32.store16
|
||||
(i32.const 8)
|
||||
(i32.load16_u
|
||||
|
@ -257,12 +253,24 @@
|
|||
(i32.const 4)
|
||||
(i32.load16_u
|
||||
(i32.const 8)))
|
||||
(call $e.instr_F4)
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 31)))
|
||||
(i32.store
|
||||
(i32.const 556)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 32)))
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 12)))
|
||||
(call $e.instr_F4)
|
||||
(return))
|
||||
(unreachable))))
|
||||
|
|
|
@ -20,10 +20,6 @@
|
|||
(block $B2
|
||||
(br_table $B2 $B1
|
||||
(get_local $p0)))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.load
|
||||
(i32.const 556)))
|
||||
(set_local $l0
|
||||
(i32.add
|
||||
(i32.add
|
||||
|
@ -62,6 +58,14 @@
|
|||
(get_local $l0))
|
||||
(get_local $l1)))
|
||||
(else
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.or
|
||||
(i32.and
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const -4096))
|
||||
(i32.const 0)))
|
||||
(call $e.safe_write32_slow_jit
|
||||
(get_local $l0)
|
||||
(get_local $l1))
|
||||
|
@ -70,12 +74,6 @@
|
|||
(i32.const 540))
|
||||
(then
|
||||
(return)))))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 6)))
|
||||
(set_local $l1
|
||||
(i32.add
|
||||
(i32.add
|
||||
|
@ -114,6 +112,14 @@
|
|||
(get_local $l1))
|
||||
(get_local $l0)))
|
||||
(else
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.or
|
||||
(i32.and
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const -4096))
|
||||
(i32.const 6)))
|
||||
(call $e.safe_write32_slow_jit
|
||||
(get_local $l1)
|
||||
(get_local $l0))
|
||||
|
@ -122,12 +128,6 @@
|
|||
(i32.const 540))
|
||||
(then
|
||||
(return)))))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 12)))
|
||||
(i32.store
|
||||
(i32.const 28)
|
||||
(if $I7 (result i32)
|
||||
|
@ -163,6 +163,14 @@
|
|||
(i32.const -4096))
|
||||
(get_local $l0))))
|
||||
(else
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.or
|
||||
(i32.and
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const -4096))
|
||||
(i32.const 12)))
|
||||
(call $e.safe_read32s_slow_jit
|
||||
(get_local $l0))
|
||||
(if $I8
|
||||
|
@ -170,12 +178,6 @@
|
|||
(i32.const 540))
|
||||
(then
|
||||
(return))))))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 18)))
|
||||
(i32.store
|
||||
(i32.const 32)
|
||||
(if $I9 (result i32)
|
||||
|
@ -211,6 +213,14 @@
|
|||
(i32.const -4096))
|
||||
(get_local $l1))))
|
||||
(else
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.or
|
||||
(i32.and
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const -4096))
|
||||
(i32.const 18)))
|
||||
(call $e.safe_read32s_slow_jit
|
||||
(get_local $l1))
|
||||
(if $I10
|
||||
|
@ -230,12 +240,12 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 25)))
|
||||
(call $e.instr_F4)
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 5)))
|
||||
(call $e.instr_F4)
|
||||
(return))
|
||||
(unreachable))))
|
||||
|
|
|
@ -22,18 +22,6 @@
|
|||
(block $B2
|
||||
(br_table $B2 $B1
|
||||
(get_local $p0)))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 28)))
|
||||
(i32.store
|
||||
(i32.const 556)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 29)))
|
||||
(call $e.instr32_B8
|
||||
(i32.const -889270259))
|
||||
(call $e.instr32_B9
|
||||
|
@ -58,12 +46,24 @@
|
|||
(i32.const 4)
|
||||
(i32.load
|
||||
(i32.const 8)))
|
||||
(call $e.instr_F4)
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 28)))
|
||||
(i32.store
|
||||
(i32.const 556)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 29)))
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 9)))
|
||||
(call $e.instr_F4)
|
||||
(return))
|
||||
(unreachable))))
|
||||
|
|
|
@ -19,10 +19,6 @@
|
|||
(block $B2
|
||||
(br_table $B2 $B1
|
||||
(get_local $p0)))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.load
|
||||
(i32.const 556)))
|
||||
(i32.const 4)
|
||||
(if $I3 (result i32)
|
||||
(i32.and
|
||||
|
@ -56,6 +52,14 @@
|
|||
(i32.const -4096))
|
||||
(get_local $l1))))
|
||||
(else
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.or
|
||||
(i32.and
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const -4096))
|
||||
(i32.const 0)))
|
||||
(call $e.safe_read32s_slow_jit
|
||||
(get_local $l1))
|
||||
(if $I4
|
||||
|
@ -81,12 +85,12 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 2)))
|
||||
(call $e.instr_F4)
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 2)))
|
||||
(call $e.instr_F4)
|
||||
(return))
|
||||
(unreachable))))
|
||||
|
|
|
@ -19,10 +19,6 @@
|
|||
(block $B2
|
||||
(br_table $B2 $B1
|
||||
(get_local $p0)))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.load
|
||||
(i32.const 556)))
|
||||
(set_local $l0
|
||||
(i32.load
|
||||
(i32.const 4)))
|
||||
|
@ -62,6 +58,14 @@
|
|||
(get_local $l2))
|
||||
(get_local $l0)))
|
||||
(else
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.or
|
||||
(i32.and
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const -4096))
|
||||
(i32.const 0)))
|
||||
(call $e.safe_write32_slow_jit
|
||||
(get_local $l2)
|
||||
(get_local $l0))
|
||||
|
@ -85,12 +89,12 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 2)))
|
||||
(call $e.instr_F4)
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 2)))
|
||||
(call $e.instr_F4)
|
||||
(return))
|
||||
(unreachable))))
|
||||
|
|
|
@ -31,6 +31,12 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 2)))
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 1)))
|
||||
(if $I4
|
||||
(i32.and
|
||||
(i32.load
|
||||
|
@ -41,12 +47,6 @@
|
|||
(return)))
|
||||
(call $e.instr_DE_0_reg
|
||||
(i32.const 1))
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 1)))
|
||||
(return))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
|
@ -58,12 +58,12 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 1)))
|
||||
(call $e.instr_F4)
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 1)))
|
||||
(call $e.instr_F4)
|
||||
(return))
|
||||
(unreachable))))
|
||||
|
|
|
@ -31,6 +31,12 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 4)))
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 1)))
|
||||
(i32.store
|
||||
(i32.const 648)
|
||||
(i32.or
|
||||
|
@ -51,12 +57,6 @@
|
|||
(i32.store
|
||||
(i32.const 648)
|
||||
(i32.const 0))
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 1)))
|
||||
(return))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
|
@ -68,12 +68,12 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 1)))
|
||||
(call $e.instr_F4)
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 1)))
|
||||
(call $e.instr_F4)
|
||||
(return))
|
||||
(unreachable))))
|
||||
|
|
|
@ -34,15 +34,15 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 3)))
|
||||
(call $e.instr32_83_7_reg
|
||||
(i32.const 0)
|
||||
(i32.const 10))
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 1)))
|
||||
(call $e.instr32_83_7_reg
|
||||
(i32.const 0)
|
||||
(i32.const 10))
|
||||
(return))
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
|
@ -75,6 +75,7 @@
|
|||
(set_local $p0
|
||||
(i32.const 2))))
|
||||
(br $L0))
|
||||
(call $e.instr32_43)
|
||||
(i32.store
|
||||
(i32.const 560)
|
||||
(i32.add
|
||||
|
@ -87,19 +88,18 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 3)))
|
||||
(call $e.instr32_43)
|
||||
(i32.store
|
||||
(i32.const 556)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const -8)))
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 2)))
|
||||
(i32.store
|
||||
(i32.const 556)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const -8)))
|
||||
(set_local $p0
|
||||
(i32.const 0))
|
||||
(br $L0))
|
||||
|
@ -113,12 +113,12 @@
|
|||
(i32.load
|
||||
(i32.const 556))
|
||||
(i32.const 1)))
|
||||
(call $e.instr_F4)
|
||||
(i32.store
|
||||
(i32.const 664)
|
||||
(i32.add
|
||||
(i32.load
|
||||
(i32.const 664))
|
||||
(i32.const 1)))
|
||||
(call $e.instr_F4)
|
||||
(return))
|
||||
(unreachable))))
|
||||
|
|
Loading…
Reference in a new issue