minor fixes

This commit is contained in:
Awal Garg 2018-06-30 07:09:28 +05:30 committed by Fabian
parent e462e0aaf1
commit 853bf477cc
11 changed files with 126 additions and 125 deletions

2
.cargo/config Normal file
View file

@ -0,0 +1,2 @@
[build]
target-dir = "build"

3
.travis-run-jshint.sh Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -e
make jshint

View file

@ -1,3 +0,0 @@
#!/usr/bin/env bash
set -e
make jshint rustfmt clang-tidy

View file

@ -3,7 +3,7 @@ name = "v86oxide"
version = "0.1.0"
publish = false
[dependencies]
[dev-dependencies]
quickcheck = "0.6.2"
[lib]
@ -18,4 +18,3 @@ panic = "abort"
lto = true
incremental = false
panic = "abort"

View file

@ -106,7 +106,6 @@ CC_FLAGS=\
CARGO_FLAGS=\
--target wasm32-unknown-unknown \
--target-dir build/ \
-- -Clink-args="--import-memory"
CORE_FILES=const.js config.js io.js main.js lib.js coverage.js ide.js pci.js floppy.js \
@ -319,7 +318,7 @@ devices-test: all-debug
./tests/devices/virtio_9p.js
rust-test:
env RUST_BACKTRACE=full RUST_TEST_THREADS=1 cargo test --target-dir build -- --nocapture
env RUST_BACKTRACE=full RUST_TEST_THREADS=1 cargo test -- --nocapture
./tests/rust/verify-wasmgen-dummy-output.js
covreport:

View file

@ -14,4 +14,3 @@ RUN \
rustup toolchain install nightly && \
rustup target add wasm32-unknown-unknown --toolchain nightly && \
rustup component add rustfmt-preview --toolchain nightly

View file

@ -9,4 +9,3 @@ mod dbg;
mod util;
pub mod wasmgen;

View file

@ -165,6 +165,7 @@ pub fn _log_to_js_console<T: ToString>(s: T) {
#[cfg(test)]
mod tests {
use ::util::*;
use quickcheck::TestResult;
#[test]
fn packed_strs() {
@ -176,10 +177,13 @@ mod tests {
}
quickcheck! {
fn prop(xs: Vec<u8>) -> bool {
if xs.len() > 24 || xs.contains(&0) { return true; }
let xs = String::from_utf8(xs).expect("get string");
xs == unpack_str(pack_str(&xs))
fn prop(xs: Vec<u8>) -> TestResult {
if xs.len() > 24 || xs.contains(&0) { return TestResult::discard(); }
let xs = match String::from_utf8(xs) {
Ok(x) => x,
Err(_) => { return TestResult::discard(); },
};
TestResult::from_bool(xs == unpack_str(pack_str(&xs)))
}
}

View file

@ -5,7 +5,7 @@ use wasmgen::module_init::get_module;
#[no_mangle]
pub fn wg_get_code_section() -> *mut Vec<u8> {
&mut get_module().cs
&mut get_module().code_section
}
#[no_mangle]
@ -63,7 +63,7 @@ mod tests {
fn c_api_test() {
wg_setup();
let m = get_module();
let cs = &mut get_module().cs;
let cs = &mut get_module().code_section;
let instruction_body = &mut get_module().instruction_body;
wg_call_fn(cs, m.get_fn_idx(pack_str("foo"), FN0_TYPE_INDEX));
@ -85,7 +85,7 @@ mod tests {
dbg_log!("op_ptr: {:?}, op_len: {:?}", op_ptr, op_len);
let mut f = File::create("build/wg_dummy_output.wasm").expect("creating wg_dummy_output.wasm");
f.write_all(&get_module().op).expect("write wg_dummy_output.wasm");
f.write_all(&get_module().output).expect("write wg_dummy_output.wasm");
}
}

View file

@ -46,8 +46,8 @@ pub fn get_module<'a>() -> &'a mut WasmBuilder {
}
pub struct WasmBuilder {
pub op: Vec<u8>,
pub cs: Vec<u8>,
pub output: Vec<u8>,
pub code_section: Vec<u8>,
pub instruction_body: Vec<u8>,
idx_import_table_size: usize, // for rewriting once finished
@ -63,8 +63,8 @@ pub struct WasmBuilder {
impl WasmBuilder {
pub fn new() -> Self {
WasmBuilder {
op: Vec::with_capacity(256),
cs: Vec::with_capacity(256),
output: Vec::with_capacity(256),
code_section: Vec::with_capacity(256),
instruction_body: Vec::with_capacity(256),
idx_import_table_size: 0,
@ -79,23 +79,23 @@ impl WasmBuilder {
}
pub fn init(&mut self) {
self.op.extend("\0asm".as_bytes());
self.output.extend("\0asm".as_bytes());
// wasm version in leb128, 4 bytes
self.op.push(op::WASM_VERSION); self.op.push(0); self.op.push(0); self.op.push(0);
self.output.push(op::WASM_VERSION); self.output.push(0); self.output.push(0); self.output.push(0);
self.write_type_section();
self.write_import_section_preamble();
// store state of current pointers etc. so we can reset them later
self.initial_static_size = self.op.len();
self.initial_static_size = self.output.len();
}
pub fn reset(&mut self) {
self.op.drain(self.initial_static_size..);
self.output.drain(self.initial_static_size..);
self.set_import_table_size(2);
self.set_import_count(0);
self.cs.clear();
self.code_section.clear();
self.instruction_body.clear();
}
@ -105,96 +105,96 @@ impl WasmBuilder {
self.write_export_section();
// write code section preamble
self.op.push(op::SC_CODE);
self.output.push(op::SC_CODE);
let idx_code_section_size = self.op.len(); // we will write to this location later
self.op.push(0); self.op.push(0); // write temp val for now using 4 bytes
self.op.push(0); self.op.push(0);
let idx_code_section_size = self.output.len(); // we will write to this location later
self.output.push(0); self.output.push(0); // write temp val for now using 4 bytes
self.output.push(0); self.output.push(0);
self.op.push(1); // number of function bodies: just 1
self.output.push(1); // number of function bodies: just 1
// same as above but for body size of the function
let idx_fn_body_size = self.op.len();
self.op.push(0); self.op.push(0);
self.op.push(0); self.op.push(0);
let idx_fn_body_size = self.output.len();
self.output.push(0); self.output.push(0);
self.output.push(0); self.output.push(0);
self.op.push(1); // count of local blocks
self.output.push(1); // count of local blocks
dbg_assert!(no_of_locals_i32 < 128);
self.op.push(no_of_locals_i32); self.op.push(op::TYPE_I32);
self.output.push(no_of_locals_i32); self.output.push(op::TYPE_I32);
self.op.append(&mut self.cs);
self.output.append(&mut self.code_section);
self.op.push(op::OP_END);
self.output.push(op::OP_END);
// write the actual sizes to the pointer locations stored above. We subtract 4 from the actual
// value because the ptr itself points to four bytes
let fn_body_size = (self.op.len() - idx_fn_body_size - 4) as u32;
write_fixed_leb32_at_idx(&mut self.op, idx_fn_body_size, fn_body_size);
let fn_body_size = (self.output.len() - idx_fn_body_size - 4) as u32;
write_fixed_leb32_at_idx(&mut self.output, idx_fn_body_size, fn_body_size);
let code_section_size = (self.op.len() - idx_code_section_size - 4) as u32;
write_fixed_leb32_at_idx(&mut self.op, idx_code_section_size, code_section_size);
let code_section_size = (self.output.len() - idx_code_section_size - 4) as u32;
write_fixed_leb32_at_idx(&mut self.output, idx_code_section_size, code_section_size);
self.op.len()
self.output.len()
}
pub fn write_type_section(&mut self) {
self.op.push(op::SC_TYPE);
self.output.push(op::SC_TYPE);
let idx_section_size = self.op.len();
self.op.push(0);
let idx_section_size = self.output.len();
self.output.push(0);
self.op.push(NR_FN_TYPE_INDEXES); // number of type descriptors
self.output.push(NR_FN_TYPE_INDEXES); // number of type descriptors
// FN0
self.op.push(op::TYPE_FUNC);
self.op.push(0); // no args
self.op.push(0); // no return val
self.output.push(op::TYPE_FUNC);
self.output.push(0); // no args
self.output.push(0); // no return val
// FN1
self.op.push(op::TYPE_FUNC);
self.op.push(1);
self.op.push(op::TYPE_I32);
self.op.push(0);
self.output.push(op::TYPE_FUNC);
self.output.push(1);
self.output.push(op::TYPE_I32);
self.output.push(0);
// FN2
self.op.push(op::TYPE_FUNC);
self.op.push(2);
self.op.push(op::TYPE_I32);
self.op.push(op::TYPE_I32);
self.op.push(0);
self.output.push(op::TYPE_FUNC);
self.output.push(2);
self.output.push(op::TYPE_I32);
self.output.push(op::TYPE_I32);
self.output.push(0);
// FN3
self.op.push(op::TYPE_FUNC);
self.op.push(3);
self.op.push(op::TYPE_I32);
self.op.push(op::TYPE_I32);
self.op.push(op::TYPE_I32);
self.op.push(0);
self.output.push(op::TYPE_FUNC);
self.output.push(3);
self.output.push(op::TYPE_I32);
self.output.push(op::TYPE_I32);
self.output.push(op::TYPE_I32);
self.output.push(0);
// FN0_RET
self.op.push(op::TYPE_FUNC);
self.op.push(0);
self.op.push(1);
self.op.push(op::TYPE_I32);
self.output.push(op::TYPE_FUNC);
self.output.push(0);
self.output.push(1);
self.output.push(op::TYPE_I32);
// FN1_RET
self.op.push(op::TYPE_FUNC);
self.op.push(1);
self.op.push(op::TYPE_I32);
self.op.push(1);
self.op.push(op::TYPE_I32);
self.output.push(op::TYPE_FUNC);
self.output.push(1);
self.output.push(op::TYPE_I32);
self.output.push(1);
self.output.push(op::TYPE_I32);
// FN2_RET
self.op.push(op::TYPE_FUNC);
self.op.push(2);
self.op.push(op::TYPE_I32);
self.op.push(op::TYPE_I32);
self.op.push(1);
self.op.push(op::TYPE_I32);
self.output.push(op::TYPE_FUNC);
self.output.push(2);
self.output.push(op::TYPE_I32);
self.output.push(op::TYPE_I32);
self.output.push(1);
self.output.push(op::TYPE_I32);
let new_len = self.op.len();
let new_len = self.output.len();
let size = (new_len - 1) - idx_section_size;
self.op[idx_section_size] = size.safe_to_u8();
self.output[idx_section_size] = size.safe_to_u8();
}
/// Goes over the import block to find index of an import entry by function name
@ -204,9 +204,9 @@ impl WasmBuilder {
for i in 0..self.import_count {
offset += 1; // skip length of module name
offset += 1; // skip module name itself
let len = self.op[offset] as usize;
let len = self.output[offset] as usize;
offset += 1;
let name = self.op.get(offset..(offset + len)).expect("get function name");
let name = self.output.get(offset..(offset + len)).expect("get function name");
if name == fn_name.as_bytes() {
return Some(i);
}
@ -221,39 +221,39 @@ impl WasmBuilder {
dbg_assert!(count < 0x4000);
self.import_count = count;
let idx_import_count = self.idx_import_count;
write_fixed_leb16_at_idx(&mut self.op, idx_import_count, count);
write_fixed_leb16_at_idx(&mut self.output, idx_import_count, count);
}
pub fn set_import_table_size(&mut self, size: usize) {
dbg_assert!(size < 0x4000);
self.import_table_size = size;
let idx_import_table_size = self.idx_import_table_size;
write_fixed_leb16_at_idx(&mut self.op, idx_import_table_size, size.safe_to_u16());
write_fixed_leb16_at_idx(&mut self.output, idx_import_table_size, size.safe_to_u16());
}
pub fn write_import_section_preamble(&mut self) {
self.op.push(op::SC_IMPORT);
self.output.push(op::SC_IMPORT);
self.idx_import_table_size = self.op.len();
self.op.push(1 | 0b10000000); self.op.push(2); // 2 in 2 byte leb
self.idx_import_table_size = self.output.len();
self.output.push(1 | 0b10000000); self.output.push(2); // 2 in 2 byte leb
self.idx_import_count = self.op.len();
self.op.push(1 | 0b10000000); self.op.push(0); // 0 in 2 byte leb
self.idx_import_count = self.output.len();
self.output.push(1 | 0b10000000); self.output.push(0); // 0 in 2 byte leb
// here after starts the actual list of imports
self.idx_import_entries = self.op.len();
self.idx_import_entries = self.output.len();
}
pub fn write_memory_import(&mut self) {
self.op.push(1);
self.op.push('e' as u8);
self.op.push(1);
self.op.push('m' as u8);
self.output.push(1);
self.output.push('e' as u8);
self.output.push(1);
self.output.push('m' as u8);
self.op.push(op::EXT_MEMORY);
self.output.push(op::EXT_MEMORY);
self.op.push(0); // memory flag, 0 for no maximum memory limit present
write_leb_u32(&mut self.op, 256); // initial memory length of 256 pages, takes 2 bytes in leb128
self.output.push(0); // memory flag, 0 for no maximum memory limit present
write_leb_u32(&mut self.output, 256); // initial memory length of 256 pages, takes 2 bytes in leb128
let new_import_count = self.import_count + 1;
self.set_import_count(new_import_count);
@ -263,13 +263,13 @@ impl WasmBuilder {
}
pub fn write_import_entry(&mut self, fn_name: PackedStr, type_index: u8) -> u16 {
self.op.push(1); // length of module name
self.op.push('e' as u8); // module name
self.output.push(1); // length of module name
self.output.push('e' as u8); // module name
let fn_name = unpack_str(fn_name);
self.op.push(fn_name.len().safe_to_u8());
self.op.extend(fn_name.as_bytes());
self.op.push(op::EXT_FUNCTION);
self.op.push(type_index);
self.output.push(fn_name.len().safe_to_u8());
self.output.extend(fn_name.as_bytes());
self.output.push(op::EXT_FUNCTION);
self.output.push(type_index);
let new_import_count = self.import_count + 1;
self.set_import_count(new_import_count);
@ -281,29 +281,29 @@ impl WasmBuilder {
}
pub fn write_function_section(&mut self, count: u8) {
self.op.push(op::SC_FUNCTION);
self.op.push(1 + count); // length of this section
self.op.push(count); // count of signature indices
self.output.push(op::SC_FUNCTION);
self.output.push(1 + count); // length of this section
self.output.push(count); // count of signature indices
for _ in 0..count {
self.op.push(FN1_TYPE_INDEX);
self.output.push(FN1_TYPE_INDEX);
}
}
pub fn write_export_section(&mut self) {
self.op.push(op::SC_EXPORT);
self.op.push(1 + 1 + 1 + 1 + 2); // size of this section
self.op.push(1); // count of table: just one function exported
self.output.push(op::SC_EXPORT);
self.output.push(1 + 1 + 1 + 1 + 2); // size of this section
self.output.push(1); // count of table: just one function exported
self.op.push(1); // length of exported function name
self.op.push('f' as u8); // function name
self.op.push(op::EXT_FUNCTION);
self.output.push(1); // length of exported function name
self.output.push('f' as u8); // function name
self.output.push(op::EXT_FUNCTION);
// index of the exported function
// function space starts with imports. index of last import is import count - 1
// the last import however is a memory, so we subtract one from that
let next_op_idx = self.op.len();
self.op.push(0); self.op.push(0); // add 2 bytes for writing 16 byte val
write_fixed_leb16_at_idx(&mut self.op, next_op_idx, self.import_count - 1);
let next_op_idx = self.output.len();
self.output.push(0); self.output.push(0); // add 2 bytes for writing 16 byte val
write_fixed_leb16_at_idx(&mut self.output, next_op_idx, self.import_count - 1);
}
pub fn get_fn_idx(&mut self, fn_name: PackedStr, type_index: u8) -> u16 {
@ -319,15 +319,15 @@ impl WasmBuilder {
}
pub fn get_op_ptr(&self) -> *const u8 {
self.op.as_ptr()
self.output.as_ptr()
}
pub fn get_op_len(&self) -> usize {
self.op.len()
self.output.len()
}
pub fn commit_instruction_body_cs(&mut self) {
self.cs.append(&mut self.instruction_body);
self.code_section.append(&mut self.instruction_body);
}
}

View file

@ -3,10 +3,10 @@
process.on("unhandledRejection", exn => { throw exn; });
const fs = require('fs');
const path = require('path');
const fs = require("fs");
const path = require("path");
const DUMMY_MODULE_PATH = path.resolve(__dirname, '../../build/wg_dummy_output.wasm');
const DUMMY_MODULE_PATH = path.resolve(__dirname, "../../build/wg_dummy_output.wasm");
const dummy_module = fs.readFileSync(DUMMY_MODULE_PATH);
const wm = new WebAssembly.Module(dummy_module);
@ -26,9 +26,8 @@ function foo(arg) {
foo_recd_arg = arg;
}
const i = new WebAssembly.Instance(wm, { 'e': { m: mem, baz, foo } });
const i = new WebAssembly.Instance(wm, { "e": { m: mem, baz, foo } });
i.exports.f();
console.assert(baz_recd_arg === 2, `baz returned: "${baz_recd_arg}"`);
console.assert(foo_recd_arg === 456, `foo returned: "${foo_recd_arg}"`);