move {set,tee}_new_local to builder

This commit is contained in:
Awal Garg 2018-07-30 12:35:33 +05:30 committed by Fabian
parent 1835ea3844
commit 470246651d
5 changed files with 44 additions and 48 deletions

View file

@ -3,9 +3,9 @@ use jit::JitContext;
use modrm;
use regs;
use tlb::{TLB_GLOBAL, TLB_NO_USER, TLB_READONLY, TLB_VALID};
use wasmgen::module_init;
use wasmgen::module_init::{WasmBuilder, WasmLocal};
use wasmgen::wasm_util::WasmBuf;
use wasmgen::{module_init, wasm_util};
pub fn gen_set_previous_eip_offset_from_eip(builder: &mut WasmBuilder, n: u32) {
let cs = &mut builder.code_section;
@ -184,7 +184,7 @@ pub fn gen_safe_read32(ctx: &mut JitContext) {
//let instruction_body = &mut ctx.builder.instruction_body;
//let cpu = &mut ctx.cpu;
let address_local = wasm_util::tee_new_local(builder);
let address_local = builder.tee_new_local();
// Pseudo: base_on_stack = (uint32_t)address >> 12;
builder.instruction_body.push_i32(12);
@ -198,7 +198,7 @@ pub fn gen_safe_read32(ctx: &mut JitContext) {
builder
.instruction_body
.load_aligned_i32_from_stack(global_pointers::TLB_DATA);
let entry_local = wasm_util::tee_new_local(builder);
let entry_local = builder.tee_new_local();
// Pseudo: bool can_use_fast_path = (entry & 0xFFF & ~TLB_READONLY & ~TLB_GLOBAL & ~(cpl == 3 ? 0 : TLB_NO_USER) == TLB_VALID &&
// (address & 0xFFF) <= (0x1000 - 4));
@ -264,7 +264,7 @@ pub fn gen_safe_write32(ctx: &mut JitContext, address_local: &WasmLocal, value_l
builder
.instruction_body
.load_aligned_i32_from_stack(global_pointers::TLB_DATA);
let entry_local = wasm_util::tee_new_local(builder);
let entry_local = builder.tee_new_local();
// Pseudo: bool can_use_fast_path = (entry & 0xFFF & ~TLB_GLOBAL & ~(cpl == 3 ? 0 : TLB_NO_USER) == TLB_VALID &&
// (address & 0xFFF) <= (0x1000 - 4));
@ -321,7 +321,7 @@ pub fn gen_safe_read16(ctx: &mut JitContext) {
// inline, bailing to safe_read16_slow if necessary
let builder = &mut ctx.builder;
let address_local = wasm_util::tee_new_local(builder);
let address_local = builder.tee_new_local();
// Pseudo: base_on_stack = (uint32_t)address >> 12;
builder.instruction_body.push_i32(12);
@ -335,7 +335,7 @@ pub fn gen_safe_read16(ctx: &mut JitContext) {
builder
.instruction_body
.load_aligned_i32_from_stack(global_pointers::TLB_DATA);
let entry_local = wasm_util::tee_new_local(builder);
let entry_local = builder.tee_new_local();
// Pseudo: bool can_use_fast_path = (entry & 0xFFF & ~TLB_READONLY & ~TLB_GLOBAL & ~(cpl == 3 ? 0 : TLB_NO_USER) == TLB_VALID &&
// (address & 0xFFF) <= (0x1000 - 2));
@ -401,7 +401,7 @@ pub fn gen_safe_write16(ctx: &mut JitContext, address_local: &WasmLocal, value_l
builder
.instruction_body
.load_aligned_i32_from_stack(global_pointers::TLB_DATA);
let entry_local = wasm_util::tee_new_local(builder);
let entry_local = builder.tee_new_local();
// Pseudo: bool can_use_fast_path = (entry & 0xFFF & ~TLB_GLOBAL & ~(cpl == 3 ? 0 : TLB_NO_USER) == TLB_VALID &&
// (address & 0xFFF) <= (0x1000 - 2));
@ -494,7 +494,7 @@ pub fn gen_jmp_rel16(ctx: &mut JitContext, rel16: u16) {
ctx.builder
.instruction_body
.load_aligned_i32(cs_offset_addr);
let local = wasm_util::set_new_local(ctx.builder);
let local = ctx.builder.set_new_local();
// generate:
// *instruction_pointer = cs_offset + ((*instruction_pointer - cs_offset + rel16) & 0xFFFF);
@ -526,7 +526,7 @@ pub fn gen_pop16_ss16(ctx: &mut JitContext) {
ctx.builder
.instruction_body
.load_aligned_i32(global_pointers::get_reg16_offset(regs::SP));
let sp_local = wasm_util::tee_new_local(ctx.builder);
let sp_local = ctx.builder.tee_new_local();
if !ctx.cpu.has_flat_segmentation() {
ctx.builder
@ -557,7 +557,7 @@ pub fn gen_pop16_ss32(ctx: &mut JitContext) {
ctx.builder
.instruction_body
.load_aligned_i32(global_pointers::get_reg32_offset(regs::ESP));
let esp_local = wasm_util::tee_new_local(ctx.builder);
let esp_local = ctx.builder.tee_new_local();
if !ctx.cpu.has_flat_segmentation() {
ctx.builder
@ -596,7 +596,7 @@ pub fn gen_pop32s_ss16(ctx: &mut JitContext) {
ctx.builder
.instruction_body
.load_aligned_i32(global_pointers::get_reg16_offset(regs::SP));
let local_sp = wasm_util::tee_new_local(ctx.builder);
let local_sp = ctx.builder.tee_new_local();
// result = safe_read32s(segment_offsets[SS] + sp) (or just sp if has_flat_segmentation)
if !ctx.cpu.has_flat_segmentation() {
@ -627,7 +627,7 @@ pub fn gen_pop32s_ss32(ctx: &mut JitContext) {
ctx.builder
.instruction_body
.load_aligned_i32(global_pointers::get_reg32_offset(regs::ESP));
let local_esp = wasm_util::tee_new_local(ctx.builder);
let local_esp = ctx.builder.tee_new_local();
// result = safe_read32s(segment_offsets[SS] + esp) (or just esp if has_flat_segmentation)
if !ctx.cpu.has_flat_segmentation() {

View file

@ -10,9 +10,9 @@ use profiler;
use profiler::stat;
use state_flags::CachedStateFlags;
use util::SafeToU16;
use wasmgen::module_init;
use wasmgen::module_init::WasmBuilder;
use wasmgen::wasm_util::WasmBuf;
use wasmgen::{module_init, wasm_util};
pub const WASM_TABLE_SIZE: u32 = 0x10000;
@ -871,14 +871,14 @@ fn jit_generate_module(
builder
.instruction_body
.get_local(&builder.arg_local_initial_state);
let gen_local_state = wasm_util::set_new_local(builder);
let gen_local_state = builder.set_new_local();
// initialise max_iterations
let gen_local_iteration_counter = if JIT_ALWAYS_USE_LOOP_SAFETY || requires_loop_limit {
builder
.instruction_body
.push_i32(JIT_MAX_ITERATIONS_PER_FUNCTION as i32);
Some(wasm_util::set_new_local(builder))
Some(builder.set_new_local())
}
else {
None

View file

@ -11,7 +11,6 @@ use regs::{AX, BP, BX, CX, DI, DX, SI, SP};
use regs::{CS, DS, ES, FS, GS, SS};
use regs::{EAX, EBP, EBX, ECX, EDI, EDX, ESI, ESP};
use wasmgen::module_init::WasmBuilder;
use wasmgen::wasm_util;
use wasmgen::wasm_util::WasmBuf;
pub fn jit_instruction(cpu: &mut CpuContext, builder: &mut WasmBuilder, instr_flags: &mut u32) {
@ -259,13 +258,13 @@ pub fn instr16_89_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
pub fn instr32_89_mem_jit(ctx: &mut JitContext, modrm_byte: u8, r: u32) {
// Pseudo: safe_write32(modrm_resolve(modrm_byte), reg32s[r]);
codegen::gen_modrm_resolve(ctx, modrm_byte);
let address_local = wasm_util::set_new_local(ctx.builder);
let address_local = ctx.builder.set_new_local();
ctx.builder
.instruction_body
.push_i32(global_pointers::get_reg32_offset(r) as i32);
ctx.builder.instruction_body.load_aligned_i32_from_stack(0);
let value_local = wasm_util::set_new_local(ctx.builder);
let value_local = ctx.builder.set_new_local();
codegen::gen_safe_write32(ctx, &address_local, &value_local);
ctx.builder.free_local(address_local);
@ -474,10 +473,10 @@ pub fn instr16_C7_0_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
pub fn instr16_C7_0_mem_jit(ctx: &mut JitContext, modrm_byte: u8) {
codegen::gen_modrm_resolve(ctx, modrm_byte);
let address_local = wasm_util::set_new_local(ctx.builder);
let address_local = ctx.builder.set_new_local();
let imm = ctx.cpu.read_imm16();
ctx.builder.instruction_body.push_i32(imm as i32);
let value_local = wasm_util::set_new_local(ctx.builder);
let value_local = ctx.builder.set_new_local();
codegen::gen_safe_write16(ctx, &address_local, &value_local);
ctx.builder.free_local(address_local);
ctx.builder.free_local(value_local);
@ -494,10 +493,10 @@ pub fn instr32_C7_0_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
pub fn instr32_C7_0_mem_jit(ctx: &mut JitContext, modrm_byte: u8) {
codegen::gen_modrm_resolve(ctx, modrm_byte);
let address_local = wasm_util::set_new_local(ctx.builder);
let address_local = ctx.builder.set_new_local();
let imm = ctx.cpu.read_imm32();
ctx.builder.instruction_body.push_i32(imm as i32);
let value_local = wasm_util::set_new_local(ctx.builder);
let value_local = ctx.builder.set_new_local();
codegen::gen_safe_write32(ctx, &address_local, &value_local);
ctx.builder.free_local(address_local);
ctx.builder.free_local(value_local);

View file

@ -329,13 +329,8 @@ impl WasmBuilder {
self.code_section.append(&mut self.instruction_body);
}
// XXX: This should not be marked pub and not be prefixed with "_",
// but we need to share it with wasm_util so it is pub for now
// Moving set_local and tee_local to builder further complicate
// things. We should be able to fix this by better structuring the
// builder methods and wasm methods in the future.
// Currently only wasm_utils and the tests of this module use it.
pub fn _alloc_local(&mut self) -> WasmLocal {
#[must_use = "local allocated but not used"]
fn alloc_local(&mut self) -> WasmLocal {
match self.free_locals.pop() {
Some(local) => local,
None => {
@ -350,6 +345,22 @@ impl WasmBuilder {
dbg_assert!(local.0 < self.local_count);
self.free_locals.push(local)
}
#[must_use = "local allocated but not used"]
pub fn set_new_local(&mut self) -> WasmLocal {
let local = self.alloc_local();
self.instruction_body.push(op::OP_SETLOCAL);
self.instruction_body.push(local.idx());
local
}
#[must_use = "local allocated but not used"]
pub fn tee_new_local(&mut self) -> WasmLocal {
let local = self.alloc_local();
self.instruction_body.push(op::OP_TEELOCAL);
self.instruction_body.push(local.idx());
local
}
}
#[cfg(test)]
@ -379,7 +390,7 @@ mod tests {
let bar_index = m.get_fn_idx("bar", FN0_TYPE_INDEX);
m.code_section.call_fn(bar_index);
let _ = m._alloc_local(); // for ensuring that reset clears previous locals
let _ = m.alloc_local(); // for ensuring that reset clears previous locals
m.finish();
m.reset();
@ -392,17 +403,17 @@ mod tests {
m.instruction_body.call_fn(foo_index);
m.code_section.push_i32(10);
let local1 = m._alloc_local();
let local1 = m.alloc_local();
m.code_section.tee_local(&local1); // local1 = 10
m.code_section.push_i32(20);
m.code_section.add_i32();
let local2 = m._alloc_local();
let local2 = m.alloc_local();
m.code_section.tee_local(&local2); // local2 = 30
m.free_local(local1);
let local3 = m._alloc_local();
let local3 = m.alloc_local();
assert_eq!(local3.idx(), 0);
m.free_local(local2);

View file

@ -1,5 +1,5 @@
use leb::{write_fixed_leb16_at_idx, write_fixed_leb32_at_idx, write_leb_i32, write_leb_u32};
use wasmgen::module_init::{WasmBuilder, WasmLocal};
use wasmgen::module_init::WasmLocal;
use wasmgen::wasm_opcodes as op;
pub trait WasmBuf {
@ -253,17 +253,3 @@ impl WasmBuf for Vec<u8> {
self.write_leb_u32(byte_offset);
}
}
pub fn set_new_local(builder: &mut WasmBuilder) -> WasmLocal {
let local = builder._alloc_local();
builder.instruction_body.push(op::OP_SETLOCAL);
builder.instruction_body.push(local.idx());
local
}
pub fn tee_new_local(builder: &mut WasmBuilder) -> WasmLocal {
let local = builder._alloc_local();
builder.instruction_body.push(op::OP_TEELOCAL);
builder.instruction_body.push(local.idx());
local
}