-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Switch wasm emission to a custom encoder
This commit moves emission of the wasm module away from the `parity-wasm` crate to instead using custom code within this crate. Similar to parsing with `wasmparser`, this is motivated twofold: * First, we want the ability to record binary offsets of where functions and instructions are located. This allows us encode dwarf debug information eventually. * Second, this avoids a "lowering to a different IR" problem where we will be able to implement more efficient emission than if we go to parity-wasm first. Ideally this would all be separated to an external crate and/or maybe even sharing `wasmparser` types or something like that, but for now it should be relatively easy enough to inline it and with the spec tests we can have a pretty high degree of confidence it's not full of bugs at least. Some other changes included here are: * Functions are now serialized in parallel * The handling of mapping a local id to an index is now done in a per-function fashion rather than through `IdsToIndices`. This way the maps can be built in parallel and then aggregated at the end into the one global map serially.
- Loading branch information
1 parent
c5a2a5f
commit 8ec9613
Showing
23 changed files
with
1,071 additions
and
821 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// A small example which is primarily used to help benchmark walrus right now. | ||
|
||
fn main() { | ||
env_logger::init(); | ||
let a = std::env::args().nth(1).unwrap(); | ||
let m = walrus::module::Module::from_file(&a).unwrap(); | ||
m.emit_wasm().unwrap(); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
pub const MAX_U32_LENGTH: usize = 5; | ||
|
||
#[derive(Debug)] | ||
pub struct Encoder<'a> { | ||
dst: &'a mut Vec<u8>, | ||
} | ||
|
||
impl<'data> Encoder<'data> { | ||
pub fn new(dst: &'data mut Vec<u8>) -> Encoder<'data> { | ||
Encoder { dst } | ||
} | ||
|
||
pub fn byte(&mut self, byte: u8) { | ||
self.dst.push(byte); | ||
} | ||
|
||
pub fn bytes(&mut self, bytes: &[u8]) { | ||
self.usize(bytes.len()); | ||
self.raw(bytes); | ||
} | ||
|
||
pub fn str(&mut self, data: &str) { | ||
self.bytes(data.as_bytes()) | ||
} | ||
|
||
pub fn usize(&mut self, amt: usize) { | ||
assert!(amt <= u32::max_value() as usize); | ||
self.u32(amt as u32) | ||
} | ||
|
||
pub fn u32(&mut self, mut amt: u32) { | ||
while amt >= (1 << 7) { | ||
self.byte((amt as u8) & 0x7f | 0x80); | ||
amt >>= 7; | ||
} | ||
self.byte(amt as u8); | ||
} | ||
|
||
pub fn i32(&mut self, val: i32) { | ||
self.i64(val as i64); | ||
} | ||
|
||
pub fn i64(&mut self, mut val: i64) { | ||
let mut done = false; | ||
while !done { | ||
let mut byte = (val as i8) & 0x7f; | ||
val >>= 7; | ||
if (val == 0 && (byte & 0x40 == 0)) || (val == -1 && (byte & 0x40 != 0)) { | ||
done = true; | ||
} else { | ||
byte |= 0x80u8 as i8; | ||
} | ||
self.byte(byte as u8); | ||
} | ||
} | ||
|
||
pub fn f32(&mut self, val: f32) { | ||
let bits = val.to_bits(); | ||
for i in 0..4 { | ||
self.byte((bits >> (i * 8)) as u8); | ||
} | ||
} | ||
|
||
pub fn f64(&mut self, val: f64) { | ||
let bits = val.to_bits(); | ||
for i in 0..8 { | ||
self.byte((bits >> (i * 8)) as u8); | ||
} | ||
} | ||
|
||
pub fn raw(&mut self, raw: &[u8]) { | ||
self.dst.extend_from_slice(raw); | ||
} | ||
|
||
/// Reserves `bytes` bytes of space, returning the position at which the | ||
/// reservation starts | ||
pub fn reserve(&mut self, bytes: usize) -> usize { | ||
let start = self.dst.len(); | ||
for _ in 0..bytes { | ||
self.byte(0); | ||
} | ||
return start; | ||
} | ||
|
||
/// Reserves space to write a uleb128 `u32`, returning the postition at | ||
/// hwich it can be written. | ||
pub fn reserve_u32(&mut self) -> usize { | ||
self.reserve(MAX_U32_LENGTH) | ||
} | ||
|
||
pub fn pos(&self) -> usize { | ||
self.dst.len() | ||
} | ||
|
||
pub fn u32_at(&mut self, pos: usize, mut amt: u32) { | ||
for i in 0..MAX_U32_LENGTH { | ||
let flag = if i == MAX_U32_LENGTH - 1 { 0 } else { 0x80 }; | ||
self.dst[pos + i] = (amt as u8) & 0x7f | flag; | ||
amt >>= 7; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.