2017-12-14 19:31:01 -08:00
|
|
|
#[macro_use]
|
|
|
|
extern crate serde_derive;
|
2018-02-06 16:06:21 -08:00
|
|
|
extern crate fnv;
|
|
|
|
|
|
|
|
use std::char;
|
|
|
|
use std::hash::{Hash, Hasher};
|
2017-12-14 19:31:01 -08:00
|
|
|
|
2017-12-18 12:39:14 -08:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct Program {
|
|
|
|
pub structs: Vec<Struct>,
|
|
|
|
pub free_functions: Vec<Function>,
|
2018-02-06 07:56:14 -08:00
|
|
|
pub imports: Vec<Import>,
|
2018-02-05 14:24:25 -08:00
|
|
|
pub imported_structs: Vec<ImportStruct>,
|
2018-02-06 16:06:21 -08:00
|
|
|
pub custom_type_names: Vec<CustomTypeName>,
|
2017-12-18 12:39:14 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct Struct {
|
|
|
|
pub name: String,
|
|
|
|
pub functions: Vec<Function>,
|
|
|
|
pub methods: Vec<Method>,
|
|
|
|
}
|
|
|
|
|
2018-02-06 07:56:14 -08:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct Import {
|
|
|
|
pub module: String,
|
2018-02-06 19:04:12 -08:00
|
|
|
pub catch: bool,
|
2018-02-06 07:56:14 -08:00
|
|
|
pub function: Function,
|
|
|
|
}
|
|
|
|
|
2018-02-05 14:24:25 -08:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct ImportStruct {
|
|
|
|
pub module: Option<String>,
|
|
|
|
pub name: String,
|
2018-02-06 07:56:14 -08:00
|
|
|
pub functions: Vec<ImportStructFunction>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct ImportStructFunction {
|
|
|
|
pub method: bool,
|
2018-02-06 15:19:47 -08:00
|
|
|
pub js_new: bool,
|
2018-02-06 19:04:12 -08:00
|
|
|
pub catch: bool,
|
2018-02-06 07:56:14 -08:00
|
|
|
pub function: Function,
|
2018-02-05 14:24:25 -08:00
|
|
|
}
|
|
|
|
|
2017-12-18 12:39:14 -08:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct Method {
|
|
|
|
pub mutable: bool,
|
|
|
|
pub function: Function,
|
|
|
|
}
|
|
|
|
|
2017-12-14 19:31:01 -08:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct Function {
|
|
|
|
pub name: String,
|
|
|
|
pub arguments: Vec<Type>,
|
|
|
|
pub ret: Option<Type>,
|
|
|
|
}
|
|
|
|
|
2018-02-06 16:06:21 -08:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
pub struct CustomTypeName {
|
|
|
|
pub descriptor: char,
|
|
|
|
pub name: String,
|
|
|
|
}
|
|
|
|
|
2018-02-06 07:56:14 -08:00
|
|
|
pub fn free_function(struct_name: &str) -> String {
|
2018-02-06 11:54:40 -08:00
|
|
|
let mut name = format!("__wbg_");
|
2018-02-06 07:56:14 -08:00
|
|
|
name.extend(struct_name
|
|
|
|
.chars()
|
|
|
|
.flat_map(|s| s.to_lowercase()));
|
|
|
|
name.push_str("_free");
|
|
|
|
return name
|
2017-12-18 14:31:01 -08:00
|
|
|
}
|
|
|
|
|
2018-02-06 07:56:14 -08:00
|
|
|
pub fn free_function_export_name(function_name: &str) -> String {
|
|
|
|
function_name.to_string()
|
2017-12-18 14:31:01 -08:00
|
|
|
}
|
|
|
|
|
2018-02-06 07:56:14 -08:00
|
|
|
pub fn struct_function_export_name(struct_: &str, f: &str) -> String {
|
|
|
|
let mut name = struct_
|
|
|
|
.chars()
|
|
|
|
.flat_map(|s| s.to_lowercase())
|
|
|
|
.collect::<String>();
|
|
|
|
name.push_str("_");
|
|
|
|
name.push_str(f);
|
|
|
|
return name
|
2017-12-14 21:55:21 -08:00
|
|
|
}
|
|
|
|
|
2018-02-06 07:56:14 -08:00
|
|
|
pub fn mangled_import_name(struct_: Option<&str>, f: &str) -> String {
|
|
|
|
match struct_ {
|
|
|
|
Some(s) => format!("__wbg_s_{}_{}", s, f),
|
|
|
|
None => format!("__wbg_f_{}", f),
|
2017-12-14 21:55:21 -08:00
|
|
|
}
|
2017-12-14 19:31:01 -08:00
|
|
|
}
|
2018-02-06 07:56:14 -08:00
|
|
|
|
|
|
|
pub type Type = char;
|
|
|
|
|
|
|
|
pub const TYPE_NUMBER: char = '\u{5e}';
|
|
|
|
pub const TYPE_BORROWED_STR: char = '\u{5f}';
|
|
|
|
pub const TYPE_STRING: char = '\u{60}';
|
|
|
|
pub const TYPE_BOOLEAN: char = '\u{61}';
|
|
|
|
pub const TYPE_JS_OWNED: char = '\u{62}';
|
|
|
|
pub const TYPE_JS_REF: char = '\u{63}';
|
|
|
|
|
|
|
|
pub const TYPE_CUSTOM_START: u32 = 0x64;
|
|
|
|
pub const TYPE_CUSTOM_REF_FLAG: u32 = 1;
|
2018-02-06 16:06:21 -08:00
|
|
|
|
|
|
|
pub fn name_to_descriptor(name: &str) -> char {
|
|
|
|
const CHAR_MAX: u32 = 0x10ffff;
|
|
|
|
const CHAR_HOLE_START: u32 = 0xd800;
|
|
|
|
const CHAR_HOLE_END: u32 = 0xe000;
|
|
|
|
let mut h = fnv::FnvHasher::default();
|
|
|
|
name.hash(&mut h);
|
|
|
|
let val = h.finish();
|
|
|
|
let range = (CHAR_MAX - (CHAR_HOLE_END - CHAR_HOLE_START) - TYPE_CUSTOM_START) / 2;
|
|
|
|
let idx = (val % (range as u64)) as u32;
|
|
|
|
let mut ret = TYPE_CUSTOM_START + idx * 2;
|
|
|
|
if CHAR_HOLE_START <= ret && ret < CHAR_HOLE_END {
|
|
|
|
ret += CHAR_HOLE_END - CHAR_HOLE_START;
|
|
|
|
}
|
|
|
|
char::from_u32(ret).unwrap()
|
|
|
|
}
|