mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-18 15:31:25 +00:00
Change schemes for encoding custom type names
Store JSON a utf-32, map hashes of names to a `char` and store that name in the map, and then do a reverse mapping when generating JS
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
use std::collections::HashSet;
|
||||
use std::char;
|
||||
use std::collections::{HashSet, HashMap};
|
||||
|
||||
use shared;
|
||||
use parity_wasm::elements::*;
|
||||
@ -14,6 +15,7 @@ pub struct Context<'a> {
|
||||
pub config: &'a Bindgen,
|
||||
pub module: &'a mut Module,
|
||||
pub imports_to_rewrite: HashSet<String>,
|
||||
pub custom_type_names: HashMap<char, String>,
|
||||
}
|
||||
|
||||
pub struct SubContext<'a, 'b: 'a> {
|
||||
@ -22,6 +24,18 @@ pub struct SubContext<'a, 'b: 'a> {
|
||||
}
|
||||
|
||||
impl<'a> Context<'a> {
|
||||
pub fn add_custom_type_names(&mut self, program: &shared::Program) {
|
||||
for custom in program.custom_type_names.iter() {
|
||||
assert!(self.custom_type_names.insert(custom.descriptor,
|
||||
custom.name.clone()).is_none());
|
||||
let val = custom.descriptor as u32;
|
||||
assert!(val & 1 == 0);
|
||||
let descriptor = char::from_u32(val | 1).unwrap();
|
||||
assert!(self.custom_type_names.insert(descriptor,
|
||||
custom.name.clone()).is_none());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn finalize(&mut self, module_name: &str) -> (String, String) {
|
||||
{
|
||||
let mut bind = |name: &str, f: &Fn(&mut Self) -> String| {
|
||||
@ -756,9 +770,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
pass(&format!("idx{}", i));
|
||||
}
|
||||
custom if (custom as u32) & shared::TYPE_CUSTOM_REF_FLAG != 0 => {
|
||||
let custom = ((custom as u32) & !shared::TYPE_CUSTOM_REF_FLAG) -
|
||||
shared::TYPE_CUSTOM_START;
|
||||
let s = &self.program.custom_type_names[custom as usize / 2];
|
||||
let s = self.cx.custom_type_names[&custom].clone();
|
||||
dst_ts.push_str(&format!(": {}", s));
|
||||
if self.cx.config.debug {
|
||||
self.cx.expose_assert_class();
|
||||
@ -769,8 +781,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
pass(&format!("{}.ptr", name));
|
||||
}
|
||||
custom => {
|
||||
let custom = (custom as u32) - shared::TYPE_CUSTOM_START;
|
||||
let s = &self.program.custom_type_names[custom as usize / 2];
|
||||
let s = self.cx.custom_type_names[&custom].clone();
|
||||
dst_ts.push_str(&format!(": {}", s));
|
||||
if self.cx.config.debug {
|
||||
self.cx.expose_assert_class();
|
||||
@ -823,9 +834,8 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
Some(&shared::TYPE_JS_REF) |
|
||||
Some(&shared::TYPE_BORROWED_STR) => panic!(),
|
||||
Some(&t) if (t as u32) & shared::TYPE_CUSTOM_REF_FLAG != 0 => panic!(),
|
||||
Some(&custom) => {
|
||||
let custom = (custom as u32) - shared::TYPE_CUSTOM_START;
|
||||
let name = &self.program.custom_type_names[custom as usize / 2];
|
||||
Some(custom) => {
|
||||
let name = &self.cx.custom_type_names[custom];
|
||||
dst_ts.push_str(": ");
|
||||
dst_ts.push_str(name);
|
||||
if self.cx.config.debug {
|
||||
|
@ -5,9 +5,11 @@ extern crate wasm_bindgen_shared as shared;
|
||||
extern crate serde_json;
|
||||
extern crate wasm_gc;
|
||||
|
||||
use std::char;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::slice;
|
||||
|
||||
use failure::Error;
|
||||
use parity_wasm::elements::*;
|
||||
@ -75,9 +77,13 @@ impl Bindgen {
|
||||
exposed_globals: Default::default(),
|
||||
required_internal_exports: Default::default(),
|
||||
imports_to_rewrite: Default::default(),
|
||||
custom_type_names: Default::default(),
|
||||
config: &self,
|
||||
module: &mut module,
|
||||
};
|
||||
for program in programs.iter() {
|
||||
cx.add_custom_type_names(program);
|
||||
}
|
||||
for program in programs.iter() {
|
||||
js::SubContext {
|
||||
program,
|
||||
@ -126,14 +132,34 @@ fn extract_programs(module: &mut Module) -> Vec<shared::Program> {
|
||||
None => return ret,
|
||||
};
|
||||
|
||||
'outer:
|
||||
for i in (0..data.entries().len()).rev() {
|
||||
{
|
||||
let value = data.entries()[i].value();
|
||||
if !value.starts_with(b"wbg:") {
|
||||
continue
|
||||
let mut value = bytes_to_u32(data.entries()[i].value());
|
||||
loop {
|
||||
match value.iter().position(|i| i.0 == (b'w' as u32)) {
|
||||
Some(i) => value = &value[i + 1..],
|
||||
None => continue 'outer,
|
||||
}
|
||||
match value.iter().position(|i| i.0 == (b'b' as u32)) {
|
||||
Some(i) => value = &value[i + 1..],
|
||||
None => continue 'outer,
|
||||
}
|
||||
match value.iter().position(|i| i.0 == (b'g' as u32)) {
|
||||
Some(i) => value = &value[i + 1..],
|
||||
None => continue 'outer,
|
||||
}
|
||||
match value.iter().position(|i| i.0 == (b':' as u32)) {
|
||||
Some(i) => value = &value[i + 1..],
|
||||
None => continue 'outer,
|
||||
}
|
||||
break
|
||||
}
|
||||
let json = &value[4..];
|
||||
let p = match serde_json::from_slice(json) {
|
||||
// TODO: shouldn't take the rest of the value
|
||||
let json = value.iter()
|
||||
.map(|i| char::from_u32(i.0).unwrap())
|
||||
.collect::<String>();
|
||||
let p = match serde_json::from_str(&json) {
|
||||
Ok(f) => f,
|
||||
Err(e) => {
|
||||
panic!("failed to decode what looked like wasm-bindgen data: {}", e)
|
||||
@ -145,3 +171,12 @@ fn extract_programs(module: &mut Module) -> Vec<shared::Program> {
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
struct Unaligned(u32);
|
||||
|
||||
fn bytes_to_u32(a: &[u8]) -> &[Unaligned] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(a.as_ptr() as *const Unaligned, a.len() / 4)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user