fix commit_instruction_body_to_cs
This commit is contained in:
parent
03f0da9525
commit
95a65153f4
2
Makefile
2
Makefile
|
@ -108,7 +108,7 @@ CORE_FILES=const.js config.js io.js main.js lib.js coverage.js ide.js pci.js flo
|
||||||
memory.js dma.js pit.js vga.js ps2.js pic.js rtc.js uart.js hpet.js acpi.js apic.js ioapic.js \
|
memory.js dma.js pit.js vga.js ps2.js pic.js rtc.js uart.js hpet.js acpi.js apic.js ioapic.js \
|
||||||
state.js ne2k.js virtio.js bus.js log.js \
|
state.js ne2k.js virtio.js bus.js log.js \
|
||||||
cpu.js debug.js \
|
cpu.js debug.js \
|
||||||
elf.js codegen.js
|
elf.js
|
||||||
LIB_FILES=9p.js filesystem.js jor1k.js marshall.js utf8.js
|
LIB_FILES=9p.js filesystem.js jor1k.js marshall.js utf8.js
|
||||||
BROWSER_FILES=screen.js \
|
BROWSER_FILES=screen.js \
|
||||||
keyboard.js mouse.js serial.js \
|
keyboard.js mouse.js serial.js \
|
||||||
|
|
|
@ -287,7 +287,9 @@ function V86Starter(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
const wasmgen_exports = [
|
const wasmgen_exports = [
|
||||||
"new_buf",
|
"get_cs",
|
||||||
|
"get_instruction_body",
|
||||||
|
"commit_instruction_body_to_cs",
|
||||||
"finish",
|
"finish",
|
||||||
"reset",
|
"reset",
|
||||||
"get_fn_idx",
|
"get_fn_idx",
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "../const.h"
|
#include "../const.h"
|
||||||
#include "../cpu.h"
|
#include "../cpu.h"
|
||||||
|
#include "../log.h"
|
||||||
#include "../global_pointers.h"
|
#include "../global_pointers.h"
|
||||||
#include "wasmgen.h"
|
#include "wasmgen.h"
|
||||||
#include "codegen.h"
|
#include "codegen.h"
|
||||||
|
@ -16,8 +17,8 @@ PackedStr pack_str(char const* fn_name, uint8_t fn_len);
|
||||||
void gen_reset(void)
|
void gen_reset(void)
|
||||||
{
|
{
|
||||||
wg_reset();
|
wg_reset();
|
||||||
cs = wg_new_buf();
|
cs = wg_get_cs();
|
||||||
instruction_body = wg_new_buf();
|
instruction_body = wg_get_instruction_body();
|
||||||
add_get_seg_import();
|
add_get_seg_import();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,9 +713,3 @@ void gen_modrm_fn0(char const* fn, uint8_t fn_len)
|
||||||
wg_call_fn(instruction_body, fn_idx);
|
wg_call_fn(instruction_body, fn_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_commit_instruction_body_to_cs(void)
|
|
||||||
{
|
|
||||||
wg_include_buffer(cs);
|
|
||||||
wg_include_buffer(instruction_body);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,5 @@ void gen_increment_instruction_pointer(int32_t);
|
||||||
|
|
||||||
void gen_increment_timestamp_counter(uint32_t);
|
void gen_increment_timestamp_counter(uint32_t);
|
||||||
|
|
||||||
void gen_commit_instruction_body_to_cs(void);
|
|
||||||
void gen_clear_prefixes(void);
|
void gen_clear_prefixes(void);
|
||||||
void gen_add_prefix_bits(int32_t);
|
void gen_add_prefix_bits(int32_t);
|
||||||
|
|
|
@ -9,7 +9,9 @@ typedef struct PackedStr {
|
||||||
|
|
||||||
#define PSTR_TY uint64_t, uint64_t
|
#define PSTR_TY uint64_t, uint64_t
|
||||||
|
|
||||||
extern uint8_t* wg_new_buf(void);
|
extern uint8_t* wg_get_cs(void);
|
||||||
|
extern uint8_t* wg_get_instruction_body(void);
|
||||||
|
extern void wg_commit_instruction_body_to_cs(void);
|
||||||
extern void wg_finish(uint8_t no_of_locals_i32);
|
extern void wg_finish(uint8_t no_of_locals_i32);
|
||||||
extern void wg_reset(void);
|
extern void wg_reset(void);
|
||||||
extern uint16_t wg_get_fn_idx(PSTR_TY, uint8_t fn_type);
|
extern uint16_t wg_get_fn_idx(PSTR_TY, uint8_t fn_type);
|
||||||
|
|
|
@ -881,7 +881,7 @@ static void jit_generate_basic_block(int32_t start_addr, int32_t stop_addr)
|
||||||
|
|
||||||
// eip += eip_delta + len(jump) so instruction logic uses the correct eip
|
// eip += eip_delta + len(jump) so instruction logic uses the correct eip
|
||||||
gen_increment_instruction_pointer(eip_delta + instruction_length);
|
gen_increment_instruction_pointer(eip_delta + instruction_length);
|
||||||
gen_commit_instruction_body_to_cs();
|
wg_commit_instruction_body_to_cs();
|
||||||
|
|
||||||
eip_delta = 0;
|
eip_delta = 0;
|
||||||
}
|
}
|
||||||
|
@ -891,7 +891,7 @@ static void jit_generate_basic_block(int32_t start_addr, int32_t stop_addr)
|
||||||
|
|
||||||
// prev_ip = eip + eip_delta, so that previous_ip points to the start of this instruction
|
// prev_ip = eip + eip_delta, so that previous_ip points to the start of this instruction
|
||||||
gen_set_previous_eip_offset_from_eip(eip_delta);
|
gen_set_previous_eip_offset_from_eip(eip_delta);
|
||||||
gen_commit_instruction_body_to_cs();
|
wg_commit_instruction_body_to_cs();
|
||||||
|
|
||||||
// Leave this instruction's length to be updated in the next batch, whatever it may be
|
// Leave this instruction's length to be updated in the next batch, whatever it may be
|
||||||
eip_delta += instruction_length;
|
eip_delta += instruction_length;
|
||||||
|
@ -907,7 +907,7 @@ static void jit_generate_basic_block(int32_t start_addr, int32_t stop_addr)
|
||||||
UNUSED(eip_delta);
|
UNUSED(eip_delta);
|
||||||
gen_set_previous_eip();
|
gen_set_previous_eip();
|
||||||
gen_increment_instruction_pointer(instruction_length);
|
gen_increment_instruction_pointer(instruction_length);
|
||||||
gen_commit_instruction_body_to_cs();
|
wg_commit_instruction_body_to_cs();
|
||||||
#endif
|
#endif
|
||||||
end_addr = *instruction_pointer;
|
end_addr = *instruction_pointer;
|
||||||
len++;
|
len++;
|
||||||
|
@ -930,7 +930,7 @@ static void jit_generate_basic_block(int32_t start_addr, int32_t stop_addr)
|
||||||
// When the block ends in a non-jump instruction, we may have uncommitted updates still
|
// When the block ends in a non-jump instruction, we may have uncommitted updates still
|
||||||
if(eip_delta > 0)
|
if(eip_delta > 0)
|
||||||
{
|
{
|
||||||
gen_commit_instruction_body_to_cs();
|
wg_commit_instruction_body_to_cs();
|
||||||
gen_increment_instruction_pointer(eip_delta);
|
gen_increment_instruction_pointer(eip_delta);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1574,9 +1574,9 @@ static void jit_generate(uint32_t phys_addr)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gen_commit_instruction_body_to_cs();
|
wg_commit_instruction_body_to_cs();
|
||||||
jit_generate_basic_block(block.addr, next_block_start);
|
jit_generate_basic_block(block.addr, next_block_start);
|
||||||
gen_commit_instruction_body_to_cs();
|
wg_commit_instruction_body_to_cs();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool invalid_connection_to_next_block = next_block_start != *instruction_pointer;
|
bool invalid_connection_to_next_block = next_block_start != *instruction_pointer;
|
||||||
|
@ -1670,7 +1670,7 @@ static void jit_generate(uint32_t phys_addr)
|
||||||
|
|
||||||
wg_block_end(instruction_body); // loop
|
wg_block_end(instruction_body); // loop
|
||||||
|
|
||||||
gen_commit_instruction_body_to_cs();
|
wg_commit_instruction_body_to_cs();
|
||||||
wg_finish(GEN_NO_OF_LOCALS);
|
wg_finish(GEN_NO_OF_LOCALS);
|
||||||
|
|
||||||
cached_state_flags state_flags = pack_current_state_flags();
|
cached_state_flags state_flags = pack_current_state_flags();
|
||||||
|
|
|
@ -3,9 +3,13 @@ use ::util::PackedStr;
|
||||||
pub use ::module_init::{ setup, get_module };
|
pub use ::module_init::{ setup, get_module };
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn new_buf() -> *mut Vec<u8> {
|
pub fn get_cs() -> *mut Vec<u8> {
|
||||||
let b = Box::new(Vec::with_capacity(256));
|
&mut get_module().cs
|
||||||
Box::into_raw(b)
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn get_instruction_body() -> *mut Vec<u8> {
|
||||||
|
&mut get_module().instruction_body
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -26,12 +30,6 @@ pub fn get_fn_idx(fn_name: PackedStr, type_idx: u8) -> u16 {
|
||||||
m.get_fn_index(fn_name, type_idx)
|
m.get_fn_index(fn_name, type_idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub fn include_buffer(buf: *mut Vec<u8>) {
|
|
||||||
let m = get_module();
|
|
||||||
m.include_buffer(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn get_op_ptr() -> *const u8 {
|
pub fn get_op_ptr() -> *const u8 {
|
||||||
let m = get_module();
|
let m = get_module();
|
||||||
|
@ -44,6 +42,12 @@ pub fn get_op_len() -> usize {
|
||||||
m.get_op_len()
|
m.get_op_len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn commit_instruction_body_to_cs() {
|
||||||
|
let m = get_module();
|
||||||
|
m.commit_instruction_body_cs();
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
|
@ -56,23 +60,20 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn c_api_test() {
|
fn c_api_test() {
|
||||||
setup();
|
setup();
|
||||||
let buf1 = unsafe { new_buf().as_mut().expect("get buf1") };
|
let cs = &mut get_module().cs;
|
||||||
let buf2 = unsafe { new_buf().as_mut().expect("get buf2") };
|
let instruction_body = &mut get_module().instruction_body;
|
||||||
|
|
||||||
wg_fn0_const_ret(buf1, pack_str("foo"));
|
wg_fn0_const_ret(cs, pack_str("foo"));
|
||||||
wg_fn0_const_ret(buf1, pack_str("bar"));
|
wg_fn0_const_ret(cs, pack_str("bar"));
|
||||||
|
|
||||||
include_buffer(buf1);
|
|
||||||
|
|
||||||
finish(2);
|
finish(2);
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
wg_push_i32(buf1, 2);
|
wg_push_i32(cs, 2);
|
||||||
wg_call_fn1_ret(buf2, pack_str("baz"));
|
wg_call_fn1_ret(instruction_body, pack_str("baz"));
|
||||||
wg_drop(buf2);
|
wg_drop(instruction_body);
|
||||||
|
|
||||||
include_buffer(buf1);
|
commit_instruction_body_to_cs();
|
||||||
include_buffer(buf2);
|
|
||||||
|
|
||||||
finish(1);
|
finish(1);
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,8 @@ pub fn get_module<'a>() -> &'a mut WasmBuilder {
|
||||||
|
|
||||||
pub struct WasmBuilder {
|
pub struct WasmBuilder {
|
||||||
pub op: Vec<u8>,
|
pub op: Vec<u8>,
|
||||||
pub buffers: Vec<*mut Vec<u8>>,
|
pub cs: Vec<u8>,
|
||||||
|
pub instruction_body: Vec<u8>,
|
||||||
|
|
||||||
idx_import_table_size: usize, // for rewriting once finished
|
idx_import_table_size: usize, // for rewriting once finished
|
||||||
idx_import_count: usize, // for rewriting once finished
|
idx_import_count: usize, // for rewriting once finished
|
||||||
|
@ -52,7 +53,8 @@ impl WasmBuilder {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
WasmBuilder {
|
WasmBuilder {
|
||||||
op: Vec::with_capacity(256),
|
op: Vec::with_capacity(256),
|
||||||
buffers: Vec::with_capacity(64),
|
cs: Vec::with_capacity(256),
|
||||||
|
instruction_body: Vec::with_capacity(256),
|
||||||
|
|
||||||
idx_import_table_size: 0,
|
idx_import_table_size: 0,
|
||||||
idx_import_count: 0,
|
idx_import_count: 0,
|
||||||
|
@ -82,11 +84,8 @@ impl WasmBuilder {
|
||||||
self.op.drain(self.initial_static_size..);
|
self.op.drain(self.initial_static_size..);
|
||||||
self.set_import_table_size(2);
|
self.set_import_table_size(2);
|
||||||
self.set_import_count(0);
|
self.set_import_count(0);
|
||||||
self.buffers.drain(..);
|
self.cs.drain(..);
|
||||||
}
|
self.instruction_body.drain(..);
|
||||||
|
|
||||||
pub fn include_buffer(&mut self, buf: *mut Vec<u8>) {
|
|
||||||
self.buffers.push(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finish(&mut self, no_of_locals_i32: u8) -> usize {
|
pub fn finish(&mut self, no_of_locals_i32: u8) -> usize {
|
||||||
|
@ -111,9 +110,7 @@ impl WasmBuilder {
|
||||||
self.op.push(1); // count of local blocks
|
self.op.push(1); // count of local blocks
|
||||||
self.op.push(no_of_locals_i32); self.op.push(TYPE_I32);
|
self.op.push(no_of_locals_i32); self.op.push(TYPE_I32);
|
||||||
|
|
||||||
for buf_ptr in &mut self.buffers {
|
self.op.append(&mut self.cs);
|
||||||
self.op.append(unsafe { buf_ptr.as_mut().expect("unloading buffer") });
|
|
||||||
}
|
|
||||||
|
|
||||||
self.op.push(OP_END);
|
self.op.push(OP_END);
|
||||||
|
|
||||||
|
@ -320,6 +317,10 @@ impl WasmBuilder {
|
||||||
self.op.len()
|
self.op.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn commit_instruction_body_cs(&mut self) {
|
||||||
|
self.cs.append(&mut self.instruction_body);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Reference in a new issue