added wasmgen init changes

This commit is contained in:
Awal Garg 2018-06-21 05:02:03 +05:30 committed by Fabian
parent d094bdf6ee
commit 6251730fee
5 changed files with 134 additions and 99 deletions

View file

@ -5,7 +5,7 @@
"use strict";
var CORE_FILES =
"const.js config.js log.js lib.js coverage.js cpu.js debug.js codegen.js " +
"const.js config.js log.js lib.js coverage.js cpu.js debug.js " +
"io.js main.js ide.js pci.js floppy.js " +
"memory.js dma.js pit.js vga.js ps2.js pic.js rtc.js uart.js acpi.js apic.js ioapic.js hpet.js " +
"ne2k.js state.js virtio.js bus.js elf.js";

View file

@ -66,6 +66,32 @@ var ASYNC_SAFE = false;
};
};
// Reads len characters at offset from Memory object mem as a JS string
v86util.read_sized_string_from_mem = function read_sized_string_from_mem(mem, offset, len)
{
return String.fromCharCode(...new Uint8Array(mem.buffer, offset, len));
};
//XXX: figure out a better way to handle dylink issue than duplicating above function
v86util.minimal_load_wasm = function minimal_load_wasm(filename, imports, cb)
{
function load_cb(bytes)
{
WebAssembly
.instantiate(bytes, imports)
.then(function({ instance }) {
cb({
memory: imports["env"]["memory"],
exports: instance["exports"],
instance,
imports,
filename,
});
});
}
v86util.load_file(filename, { done: load_cb });
};
/**
* Fetches, compiles, and instantiates a wasm file
* @param {string} filename

View file

@ -259,18 +259,111 @@ function V86Starter(options)
"Infinity": Infinity,
"NaN": NaN,
};
const wasmgen_mem = new WebAssembly.Memory({ initial: 10000 });
const wasmgen_externs = {
"memory": wasmgen_mem,
"log_from_wasm": function(offset, len) {
const str = v86util.read_sized_string_from_mem(wasmgen_mem, offset, len);
dbg_log(str, LOG_CPU);
},
"abort": function() {
dbg_assert(false);
},
};
let wasm_file = DEBUG ? "v86-debug.wasm" : "v86.wasm";
let wasmgen_bin = DEBUG ? "wasmgen-debug.wasm" : "wasmgen.wasm";
if(typeof window === "undefined" && typeof __dirname === "string")
{
wasm_file = __dirname + "/" + wasm_file;
wasmgen_bin = __dirname + "/" + wasmgen_bin;
}
else
{
wasm_file = "build/" + wasm_file;
wasmgen_bin = "build/" + wasmgen_bin;
}
const wasmgen_exports = [
// these are used by C as is
"gen_eqz_i32",
"gen_if_void",
"gen_else",
"gen_loop_void",
"gen_block_void",
"gen_block_end",
"gen_return",
"gen_brtable_and_cases",
"gen_br",
"gen_get_local",
"gen_set_local",
"gen_const_i32",
"gen_unreachable",
"gen_drop",
"gen_increment_mem32",
"gen_increment_variable",
// these are wrapped around without the rs_ prefix by C
"rs_gen_fn0_const",
"rs_gen_fn0_const_ret",
"rs_gen_fn1_const",
"rs_gen_fn1_const_ret",
"rs_gen_fn2_const",
"rs_gen_fn3_const",
"rs_gen_call_fn1_ret",
"rs_gen_call_fn2",
"rs_get_fn_idx",
// these are exported to C with the gen_ prefix attached via JS
"new_buf",
"reset",
"finish",
"get_op_ptr",
"get_op_len",
"include_buffer",
"push_i32",
"push_u32",
"load_aligned_u16",
"load_aligned_i32",
"store_aligned_u16",
"store_aligned_i32",
"add_i32",
"and_i32",
"or_i32",
"shl_i32",
"call_fn",
"call_fn_with_arg",
];
function reexport_wasmgen_functions(wasmgen) {
for(const fn_name of wasmgen_exports)
{
if(fn_name.startsWith("gen_"))
{
// used as is via C
wasm_shared_funcs[`_${fn_name}`] = wasmgen.exports[fn_name];
}
else if(fn_name.startsWith("rs_"))
{
// wrapped around by C
wasm_shared_funcs[`_${fn_name}`] = wasmgen.exports[fn_name.replace("rs_", "")];
}
else
{
// prefix "gen_" attached by JS
wasm_shared_funcs[`_gen_${fn_name}`] = wasmgen.exports[fn_name];
}
}
}
v86util.minimal_load_wasm(wasmgen_bin, { "env": wasmgen_externs }, (wasmgen) => {
reexport_wasmgen_functions(wasmgen);
wasmgen.exports["setup"]();
//XXX: fix indentation break
v86util.load_wasm(
wasm_file,
{ "env": wasm_shared_funcs, "global" : wasm_globals },
@ -281,7 +374,7 @@ function V86Starter(options)
mem8 = new Uint8Array(mem);
wm.instance.exports["__post_instantiate"]();
coverage_logger.init(wm);
emulator = this.v86 = new v86(this.emulator_bus, wm, new Codegen(wm), coverage_logger);
emulator = this.v86 = new v86(this.emulator_bus, wm, wasmgen, coverage_logger);
cpu = emulator.cpu;
// XXX: Leaving unindented to minimize diff; still a part of the cb to load_wasm!
@ -629,6 +722,7 @@ function V86Starter(options)
}
});
});
}
/**

View file

@ -1,94 +0,0 @@
"use strict";
if(typeof module !== "undefined")
{
module.exports = Codegen;
}
/** @constructor */
function Codegen(wm)
{
this.wm = wm;
this.wm.exports["_gen_init"]();
}
Codegen.prototype.reset = function()
{
this.wm.exports["_gen_reset"]();
};
Codegen.OUTPUT_OFFSET = 0x1000;
Codegen.STR_INPUT_OFFSET = 0x301000;
Codegen.prototype.str_input = function(str)
{
if (str.length > 32) {
throw new Error("Max string length for crossing boundary is 32");
}
const view = new Uint8Array(this.wm.memory.buffer, Codegen.STR_INPUT_OFFSET, 32);
for (let i = 0; i < str.length; i++)
{
view[i] = str.charCodeAt(i);
}
};
Codegen.prototype.fn0 = function(fn)
{
this.str_input(fn);
this.wm.exports["_gen_fn0_const"](Codegen.STR_INPUT_OFFSET, fn.length);
};
Codegen.prototype.fn1 = function(fn, arg0)
{
this.str_input(fn);
this.wm.exports["_gen_fn1_const"](Codegen.STR_INPUT_OFFSET, fn.length, arg0);
};
Codegen.prototype.fn2 = function(fn, arg0, arg1)
{
this.str_input(fn);
this.wm.exports["_gen_fn2_const"](Codegen.STR_INPUT_OFFSET, fn.length, arg0, arg1);
};
Codegen.prototype.modrm_fn1 = function(fn, modrm_byte, arg)
{
this.str_input(fn);
this.wm.exports["_gen_modrm_resolve"](modrm_byte);
this.wm.exports["_gen_modrm_fn1"](Codegen.STR_INPUT_OFFSET, fn.length, arg);
};
Codegen.prototype.modrm_fn0 = function(fn, modrm_byte)
{
this.str_input(fn);
this.wm.exports["_gen_modrm_resolve"](modrm_byte);
this.wm.exports["_gen_modrm_fn1"](Codegen.STR_INPUT_OFFSET, fn.length);
};
Codegen.prototype.increment_instruction_pointer = function(n)
{
this.wm.exports["_gen_increment_instruction_pointer"](n);
};
Codegen.prototype.set_previous_eip = function()
{
this.wm.exports["_gen_set_previous_eip"]();
};
Codegen.prototype.finish = function()
{
return this.wm.exports["_gen_finish"]();
};
Codegen.prototype.commit_instruction_body_to_cs = function()
{
return this.wm.exports["_gen_commit_instruction_body_to_cs"]();
};
Codegen.prototype.get_module_code = function()
{
const end = this.wm.exports["_gen_get_final_offset"]() - Codegen.OUTPUT_OFFSET;
// extract wasm module
const output_buffer_view = new Uint8Array(this.wm.memory.buffer, Codegen.OUTPUT_OFFSET, end);
return output_buffer_view;
};

View file

@ -11,10 +11,10 @@ var CPU_LOG_VERBOSE = false;
/** @constructor */
function CPU(bus, wm, codegen, coverage_logger)
function CPU(bus, wm, wasmgen, coverage_logger)
{
this.wm = wm;
this.codegen = codegen;
this.wasmgen = wasmgen;
this.coverage_logger = coverage_logger;
this.wasm_patch(wm);
this.create_jit_imports();
@ -215,6 +215,15 @@ function CPU(bus, wm, codegen, coverage_logger)
//Object.seal(this);
}
CPU.prototype.wasmgen_get_module_code = function()
{
const ptr = this.wasmgen.exports["get_op_ptr"]();
const len = this.wasmgen.exports["get_op_len"]();
const output_buffer_view = new Uint8Array(this.wasmgen.memory.buffer, ptr, len);
return output_buffer_view;
};
CPU.prototype.create_jit_imports = function()
{
// Set this.jit_imports as generated WASM modules will expect
@ -1237,7 +1246,7 @@ CPU.prototype.codegen_finalize = function(wasm_table_index, start, end, first_op
{
dbg_assert(wasm_table_index >= 0 && wasm_table_index < WASM_TABLE_SIZE);
//dbg_log("finalize");
const code = this.codegen.get_module_code();
const code = this.wasmgen_get_module_code();
if(DEBUG)
{