added wasmgen init changes
This commit is contained in:
parent
d094bdf6ee
commit
6251730fee
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
|||
}
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
};
|
15
src/cpu.js
15
src/cpu.js
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue