2019-01-29 23:08:03 -06:00
#[ macro_use ]
2019-01-22 13:02:06 -06:00
extern crate wasmer_runtime_core ;
2019-01-10 21:37:59 -08:00
2019-02-10 15:24:04 -07:00
use lazy_static ::lazy_static ;
2019-01-23 23:49:34 -06:00
use std ::cell ::UnsafeCell ;
2019-02-09 13:31:28 -08:00
use std ::{ f64 , ffi ::c_void } ;
2019-01-22 13:02:06 -06:00
use wasmer_runtime_core ::{
2019-01-30 19:19:53 -06:00
error ::CallResult ,
2019-02-09 13:31:28 -08:00
export ::Export ,
2019-01-29 20:00:08 -06:00
func ,
global ::Global ,
2019-02-09 13:31:28 -08:00
import ::ImportObject ,
2019-01-29 20:00:08 -06:00
imports ,
2019-02-05 10:35:15 -08:00
memory ::Memory ,
2019-02-10 15:24:04 -07:00
module ::ImportName ,
2019-01-29 20:00:08 -06:00
table ::Table ,
2019-02-10 15:24:04 -07:00
types ::{ ElementType , FuncSig , MemoryDescriptor , TableDescriptor , Type , Value } ,
2019-01-29 23:08:03 -06:00
units ::Pages ,
2019-01-30 19:19:53 -06:00
vm ::Ctx ,
2019-02-10 15:24:04 -07:00
Func , Instance , IsExport , Module ,
2019-01-11 17:10:21 +01:00
} ;
2019-01-17 23:55:44 -06:00
2019-01-21 16:42:20 -08:00
#[ macro_use ]
mod macros ;
2019-01-17 23:55:44 -06:00
//#[cfg(test)]
mod file_descriptor ;
pub mod stdio ;
2018-11-13 19:19:23 -08:00
2018-11-20 20:11:58 +01:00
// EMSCRIPTEN APIS
2019-03-26 14:37:47 -07:00
mod bitwise ;
2019-02-20 14:05:12 -08:00
mod emscripten_target ;
2018-11-21 15:10:03 -08:00
mod env ;
2018-11-26 20:29:26 -08:00
mod errno ;
2018-12-18 09:43:59 -08:00
mod exception ;
2019-03-01 10:59:52 -08:00
mod exec ;
2019-03-01 11:24:14 -08:00
mod exit ;
2018-11-21 20:59:23 -08:00
mod io ;
2018-12-18 17:21:12 -08:00
mod jmp ;
2019-01-26 17:02:51 -06:00
mod linking ;
2018-11-26 20:29:26 -08:00
mod lock ;
2018-12-13 19:28:30 +01:00
mod math ;
2018-12-18 09:43:59 -08:00
mod memory ;
2018-11-20 20:11:58 +01:00
mod process ;
2018-11-28 13:25:56 -08:00
mod signal ;
2018-11-26 20:29:26 -08:00
mod storage ;
2018-11-21 15:10:03 -08:00
mod syscalls ;
2018-11-26 20:29:26 -08:00
mod time ;
2018-11-21 20:59:23 -08:00
mod utils ;
2018-11-23 00:13:01 -05:00
mod varargs ;
2018-11-20 20:11:58 +01:00
2019-02-08 10:55:32 -08:00
pub use self ::storage ::{ align_memory , static_alloc } ;
2019-01-25 19:55:33 -06:00
pub use self ::utils ::{
2019-01-25 20:12:36 -06:00
allocate_cstr_on_stack , allocate_on_stack , get_emscripten_memory_size ,
get_emscripten_table_size , is_emscripten_module ,
2019-01-25 19:55:33 -06:00
} ;
2018-11-13 19:19:23 -08:00
2018-11-25 23:56:21 -05:00
// TODO: Magic number - how is this calculated?
2018-12-08 00:19:55 -06:00
const TOTAL_STACK : u32 = 5_242_880 ;
2018-12-07 03:10:26 +01:00
// TODO: make this variable
2018-12-08 00:19:55 -06:00
const STATIC_BUMP : u32 = 215_536 ;
2018-11-25 23:56:21 -05:00
2019-02-10 15:24:04 -07:00
lazy_static! {
static ref OLD_ABORT_ON_CANNOT_GROW_MEMORY_SIG : FuncSig =
{ FuncSig ::new ( vec! [ ] , vec! [ Type ::I32 ] ) } ;
}
2019-01-23 12:43:41 -08:00
// The address globals begin at. Very low in memory, for code size and optimization opportunities.
// Above 0 is static memory, starting with globals.
// Then the stack.
// Then 'dynamic' memory for sbrk.
const GLOBAL_BASE : u32 = 1024 ;
2019-02-08 10:55:32 -08:00
const STATIC_BASE : u32 = GLOBAL_BASE ;
2019-01-23 12:43:41 -08:00
2019-02-02 15:28:50 -08:00
pub struct EmscriptenData < ' a > {
pub malloc : Func < ' a , u32 , u32 > ,
pub free : Func < ' a , u32 > ,
2019-02-05 23:24:07 -06:00
pub memalign : Option < Func < ' a , ( u32 , u32 ) , u32 > > ,
2019-02-02 15:28:50 -08:00
pub memset : Func < ' a , ( u32 , u32 , u32 ) , u32 > ,
pub stack_alloc : Func < ' a , u32 , u32 > ,
2019-02-07 10:45:48 -08:00
pub jumps : Vec < UnsafeCell < [ u32 ; 27 ] > > ,
2019-02-20 14:05:12 -08:00
pub dyn_call_i : Option < Func < ' a , i32 , i32 > > ,
pub dyn_call_ii : Option < Func < ' a , ( i32 , i32 ) , i32 > > ,
pub dyn_call_iii : Option < Func < ' a , ( i32 , i32 , i32 ) , i32 > > ,
pub dyn_call_iiii : Option < Func < ' a , ( i32 , i32 , i32 , i32 ) , i32 > > ,
pub dyn_call_v : Option < Func < ' a , ( i32 ) > > ,
pub dyn_call_vi : Option < Func < ' a , ( i32 , i32 ) > > ,
pub dyn_call_vii : Option < Func < ' a , ( i32 , i32 , i32 ) > > ,
pub dyn_call_viii : Option < Func < ' a , ( i32 , i32 , i32 , i32 ) > > ,
pub dyn_call_viiii : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 ) > > ,
2019-02-22 10:42:38 -08:00
// round 2
pub dyn_call_dii : Option < Func < ' a , ( i32 , i32 , i32 ) , f64 > > ,
pub dyn_call_diiii : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 ) , f64 > > ,
pub dyn_call_iiiii : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 ) , i32 > > ,
pub dyn_call_iiiiii : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 ) , i32 > > ,
2019-03-20 15:13:00 -07:00
pub dyn_call_iiiiiii : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 , i32 ) , i32 > > ,
2019-03-21 17:18:25 -07:00
pub dyn_call_iiiiiiii : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 ) , i32 > > ,
2019-03-21 17:20:13 -07:00
pub dyn_call_iiiiiiiiii :
Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 ) , i32 > > ,
2019-02-22 10:42:38 -08:00
pub dyn_call_vd : Option < Func < ' a , ( i32 , f64 ) > > ,
pub dyn_call_viiiii : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 ) > > ,
pub dyn_call_viiiiii : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 , i32 ) > > ,
pub dyn_call_viiiiiii : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 ) > > ,
pub dyn_call_viiiiiiii : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 ) > > ,
pub dyn_call_viiiiiiiii : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 ) > > ,
pub dyn_call_iiji : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 ) , i32 > > ,
pub dyn_call_j : Option < Func < ' a , i32 , i32 > > ,
pub dyn_call_ji : Option < Func < ' a , ( i32 , i32 ) , i32 > > ,
pub dyn_call_jij : Option < Func < ' a , ( i32 , i32 , i32 , i32 ) , i32 > > ,
pub dyn_call_jjj : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 ) , i32 > > ,
pub dyn_call_viiij : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 ) > > ,
pub dyn_call_viiijiiii : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 ) > > ,
pub dyn_call_viiijiiiiii :
Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 ) > > ,
pub dyn_call_viij : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 ) > > ,
pub dyn_call_viiji : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 ) > > ,
pub dyn_call_viijiii : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 , i32 , i32 ) > > ,
pub dyn_call_viijj : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 , i32 ) > > ,
pub dyn_call_vij : Option < Func < ' a , ( i32 , i32 , i32 , i32 ) > > ,
pub dyn_call_viji : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 ) > > ,
pub dyn_call_vijiii : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 , i32 ) > > ,
pub dyn_call_vijj : Option < Func < ' a , ( i32 , i32 , i32 , i32 , i32 , i32 ) > > ,
2019-03-20 15:13:00 -07:00
pub dyn_call_viidii : Option < Func < ' a , ( i32 , i32 , i32 , f64 , i32 , i32 ) > > ,
2019-01-23 23:49:34 -06:00
}
2019-02-02 15:28:50 -08:00
impl < ' a > EmscriptenData < ' a > {
pub fn new ( instance : & ' a mut Instance ) -> EmscriptenData < ' a > {
let malloc = instance . func ( " _malloc " ) . unwrap ( ) ;
let free = instance . func ( " _free " ) . unwrap ( ) ;
2019-02-05 23:24:07 -06:00
let memalign = if let Ok ( func ) = instance . func ( " _memalign " ) {
Some ( func )
} else {
None
} ;
2019-02-02 15:28:50 -08:00
let memset = instance . func ( " _memset " ) . unwrap ( ) ;
let stack_alloc = instance . func ( " stackAlloc " ) . unwrap ( ) ;
2019-02-20 14:05:12 -08:00
let dyn_call_i = instance . func ( " dynCall_i " ) . ok ( ) ;
let dyn_call_ii = instance . func ( " dynCall_ii " ) . ok ( ) ;
let dyn_call_iii = instance . func ( " dynCall_iii " ) . ok ( ) ;
let dyn_call_iiii = instance . func ( " dynCall_iiii " ) . ok ( ) ;
let dyn_call_v = instance . func ( " dynCall_v " ) . ok ( ) ;
let dyn_call_vi = instance . func ( " dynCall_vi " ) . ok ( ) ;
let dyn_call_vii = instance . func ( " dynCall_vii " ) . ok ( ) ;
let dyn_call_viii = instance . func ( " dynCall_viii " ) . ok ( ) ;
let dyn_call_viiii = instance . func ( " dynCall_viiii " ) . ok ( ) ;
2019-02-22 10:42:38 -08:00
// round 2
let dyn_call_dii = instance . func ( " dynCall_dii " ) . ok ( ) ;
let dyn_call_diiii = instance . func ( " dynCall_diiii " ) . ok ( ) ;
let dyn_call_iiiii = instance . func ( " dynCall_iiiii " ) . ok ( ) ;
let dyn_call_iiiiii = instance . func ( " dynCall_iiiiii " ) . ok ( ) ;
2019-03-20 15:13:00 -07:00
let dyn_call_iiiiiii = instance . func ( " dynCall_iiiiiii " ) . ok ( ) ;
2019-03-21 17:18:25 -07:00
let dyn_call_iiiiiiii = instance . func ( " dynCall_iiiiiiii " ) . ok ( ) ;
let dyn_call_iiiiiiiiii = instance . func ( " dynCall_iiiiiiiiii " ) . ok ( ) ;
2019-02-22 10:42:38 -08:00
let dyn_call_vd = instance . func ( " dynCall_vd " ) . ok ( ) ;
let dyn_call_viiiii = instance . func ( " dynCall_viiiii " ) . ok ( ) ;
let dyn_call_viiiiii = instance . func ( " dynCall_viiiiii " ) . ok ( ) ;
let dyn_call_viiiiiii = instance . func ( " dynCall_viiiiiii " ) . ok ( ) ;
let dyn_call_viiiiiiii = instance . func ( " dynCall_viiiiiiii " ) . ok ( ) ;
let dyn_call_viiiiiiiii = instance . func ( " dynCall_viiiiiiiii " ) . ok ( ) ;
let dyn_call_iiji = instance . func ( " dynCall_iiji " ) . ok ( ) ;
let dyn_call_j = instance . func ( " dynCall_j " ) . ok ( ) ;
let dyn_call_ji = instance . func ( " dynCall_ji " ) . ok ( ) ;
let dyn_call_jij = instance . func ( " dynCall_jij " ) . ok ( ) ;
let dyn_call_jjj = instance . func ( " dynCall_jjj " ) . ok ( ) ;
let dyn_call_viiij = instance . func ( " dynCall_viiij " ) . ok ( ) ;
let dyn_call_viiijiiii = instance . func ( " dynCall_viiijiiii " ) . ok ( ) ;
let dyn_call_viiijiiiiii = instance . func ( " dynCall_viiijiiiiii " ) . ok ( ) ;
let dyn_call_viij = instance . func ( " dynCall_viij " ) . ok ( ) ;
let dyn_call_viiji = instance . func ( " dynCall_viiji " ) . ok ( ) ;
let dyn_call_viijiii = instance . func ( " dynCall_viijiii " ) . ok ( ) ;
let dyn_call_viijj = instance . func ( " dynCall_viijj " ) . ok ( ) ;
let dyn_call_vij = instance . func ( " dynCall_vij " ) . ok ( ) ;
let dyn_call_viji = instance . func ( " dynCall_viji " ) . ok ( ) ;
let dyn_call_vijiii = instance . func ( " dynCall_vijiii " ) . ok ( ) ;
let dyn_call_vijj = instance . func ( " dynCall_vijj " ) . ok ( ) ;
2019-03-20 15:13:00 -07:00
let dyn_call_viidii = instance . func ( " dynCall_viidii " ) . ok ( ) ;
2019-02-22 10:42:38 -08:00
2019-02-02 15:28:50 -08:00
EmscriptenData {
malloc ,
free ,
memalign ,
memset ,
stack_alloc ,
jumps : Vec ::new ( ) ,
2019-02-20 14:05:12 -08:00
dyn_call_i ,
dyn_call_ii ,
dyn_call_iii ,
dyn_call_iiii ,
dyn_call_v ,
dyn_call_vi ,
dyn_call_vii ,
dyn_call_viii ,
dyn_call_viiii ,
2019-02-22 10:42:38 -08:00
// round 2
dyn_call_dii ,
dyn_call_diiii ,
dyn_call_iiiii ,
dyn_call_iiiiii ,
2019-03-20 15:13:00 -07:00
dyn_call_iiiiiii ,
2019-03-21 17:18:25 -07:00
dyn_call_iiiiiiii ,
dyn_call_iiiiiiiiii ,
2019-02-22 10:42:38 -08:00
dyn_call_vd ,
dyn_call_viiiii ,
dyn_call_viiiiii ,
dyn_call_viiiiiii ,
dyn_call_viiiiiiii ,
dyn_call_viiiiiiiii ,
dyn_call_iiji ,
dyn_call_j ,
dyn_call_ji ,
dyn_call_jij ,
dyn_call_jjj ,
dyn_call_viiij ,
dyn_call_viiijiiii ,
dyn_call_viiijiiiiii ,
dyn_call_viij ,
dyn_call_viiji ,
dyn_call_viijiii ,
dyn_call_viijj ,
dyn_call_vij ,
dyn_call_viji ,
dyn_call_vijiii ,
dyn_call_vijj ,
2019-03-20 15:13:00 -07:00
dyn_call_viidii ,
2019-01-23 23:49:34 -06:00
}
}
}
2019-01-06 15:21:06 -06:00
2019-01-23 18:47:34 -06:00
pub fn run_emscripten_instance (
2019-01-24 00:00:38 -06:00
_module : & Module ,
2019-01-23 18:47:34 -06:00
instance : & mut Instance ,
2019-01-26 14:17:17 -06:00
path : & str ,
2019-01-23 18:47:34 -06:00
args : Vec < & str > ,
) -> CallResult < ( ) > {
2019-01-23 23:49:34 -06:00
let mut data = EmscriptenData ::new ( instance ) ;
let data_ptr = & mut data as * mut _ as * mut c_void ;
2019-01-29 23:08:03 -06:00
instance . context_mut ( ) . data = data_ptr ;
2019-01-23 18:47:34 -06:00
2019-02-06 00:11:31 -06:00
if let Ok ( _func ) = instance . dyn_func ( " ___emscripten_environ_constructor " ) {
instance . call ( " ___emscripten_environ_constructor " , & [ ] ) ? ;
}
2019-02-07 11:37:15 -08:00
// println!("running emscripten instance");
2019-02-07 10:45:48 -08:00
2019-02-02 15:28:50 -08:00
let main_func = instance . dyn_func ( " _main " ) ? ;
2019-01-29 23:08:03 -06:00
let num_params = main_func . signature ( ) . params ( ) . len ( ) ;
2019-01-27 19:06:03 -06:00
let _result = match num_params {
2019-01-26 14:17:17 -06:00
2 = > {
2019-02-09 13:58:05 -08:00
let ( argc , argv ) = store_module_arguments ( instance . context_mut ( ) , path , args ) ;
2019-01-26 14:17:17 -06:00
instance . call ( " _main " , & [ Value ::I32 ( argc as i32 ) , Value ::I32 ( argv as i32 ) ] ) ? ;
}
0 = > {
instance . call ( " _main " , & [ ] ) ? ;
}
_ = > panic! (
" The emscripten main function has received an incorrect number of params {} " ,
num_params
) ,
} ;
2019-01-23 18:47:34 -06:00
// TODO atinit and atexit for emscripten
2019-02-02 15:28:50 -08:00
// println!("{:?}", data);
2019-01-23 18:47:34 -06:00
Ok ( ( ) )
}
2019-02-09 13:58:05 -08:00
fn store_module_arguments ( ctx : & mut Ctx , path : & str , args : Vec < & str > ) -> ( u32 , u32 ) {
2019-01-27 12:18:58 -06:00
let argc = args . len ( ) + 1 ;
let mut args_slice = vec! [ 0 ; argc ] ;
2019-02-09 13:58:05 -08:00
args_slice [ 0 ] = unsafe { allocate_cstr_on_stack ( ctx , path ) . 0 } ;
2019-01-27 12:18:58 -06:00
for ( slot , arg ) in args_slice [ 1 .. argc ] . iter_mut ( ) . zip ( args . iter ( ) ) {
2019-02-09 13:58:05 -08:00
* slot = unsafe { allocate_cstr_on_stack ( ctx , & arg ) . 0 } ;
2019-01-27 12:18:58 -06:00
}
let ( argv_offset , argv_slice ) : ( _ , & mut [ u32 ] ) =
2019-02-09 13:58:05 -08:00
unsafe { allocate_on_stack ( ctx , ( ( argc + 1 ) * 4 ) as u32 ) } ;
2019-01-27 12:18:58 -06:00
assert! ( ! argv_slice . is_empty ( ) ) ;
for ( slot , arg ) in argv_slice [ 0 .. argc ] . iter_mut ( ) . zip ( args_slice . iter ( ) ) {
* slot = * arg
}
argv_slice [ argc ] = 0 ;
( argc as u32 , argv_offset )
}
2019-01-26 14:17:17 -06:00
2019-02-08 10:55:32 -08:00
pub fn emscripten_set_up_memory ( memory : & Memory , globals : & EmscriptenGlobalsData ) {
let dynamictop_ptr = globals . dynamictop_ptr ;
let stack_max = globals . stack_max ;
2019-01-11 20:47:41 +01:00
2019-02-08 10:55:32 -08:00
let dynamic_base = align_memory ( stack_max ) ;
2018-11-26 11:15:29 -08:00
2019-02-08 10:55:32 -08:00
memory . view ::< u32 > ( ) [ ( dynamictop_ptr / 4 ) as usize ] . set ( dynamic_base ) ;
2019-01-17 23:10:29 +01:00
}
2019-01-24 16:24:41 -08:00
pub struct EmscriptenGlobalsData {
2019-01-24 23:58:54 -06:00
abort : u64 ,
2019-01-24 16:24:41 -08:00
// Env namespace
2019-02-08 10:55:32 -08:00
stacktop : u32 ,
stack_max : u32 ,
dynamictop_ptr : u32 ,
memory_base : u32 ,
table_base : u32 ,
temp_double_ptr : u32 ,
2019-02-10 15:24:04 -07:00
use_old_abort_on_cannot_grow_memory : bool ,
2019-01-24 16:24:41 -08:00
}
pub struct EmscriptenGlobals {
// The emscripten data
pub data : EmscriptenGlobalsData ,
2019-01-23 12:25:56 -08:00
// The emscripten memory
2019-01-29 23:08:03 -06:00
pub memory : Memory ,
pub table : Table ,
pub memory_min : Pages ,
pub memory_max : Option < Pages > ,
2019-03-26 18:59:39 -07:00
pub null_func_names : Vec < String > ,
2019-01-11 17:10:21 +01:00
}
2019-01-24 16:46:16 -08:00
impl EmscriptenGlobals {
2019-02-08 10:55:32 -08:00
pub fn new ( module : & Module /* , static_bump: u32 */ ) -> Self {
2019-02-10 15:24:04 -07:00
let mut use_old_abort_on_cannot_grow_memory = false ;
for (
index ,
ImportName {
namespace_index ,
name_index ,
} ,
2019-02-20 16:41:41 -08:00
) in & module . info ( ) . imported_functions
2019-02-10 15:24:04 -07:00
{
2019-02-20 16:41:41 -08:00
let namespace = module . info ( ) . namespace_table . get ( * namespace_index ) ;
let name = module . info ( ) . name_table . get ( * name_index ) ;
2019-02-10 15:24:04 -07:00
if name = = " abortOnCannotGrowMemory " & & namespace = = " env " {
2019-02-20 16:41:41 -08:00
let sig_index = module . info ( ) . func_assoc [ index . convert_up ( module . info ( ) ) ] ;
let expected_sig = & module . info ( ) . signatures [ sig_index ] ;
2019-03-03 15:18:16 -06:00
if * expected_sig = = * OLD_ABORT_ON_CANNOT_GROW_MEMORY_SIG {
2019-02-10 15:24:04 -07:00
use_old_abort_on_cannot_grow_memory = true ;
}
break ;
}
}
2019-01-28 14:31:03 -08:00
let ( table_min , table_max ) = get_emscripten_table_size ( & module ) ;
let ( memory_min , memory_max ) = get_emscripten_memory_size ( & module ) ;
2019-01-23 12:34:56 -08:00
// Memory initialization
2019-01-29 23:08:03 -06:00
let memory_type = MemoryDescriptor {
minimum : memory_min ,
maximum : memory_max ,
2019-01-23 12:25:56 -08:00
shared : false ,
} ;
2019-02-08 10:55:32 -08:00
let memory = Memory ::new ( memory_type ) . unwrap ( ) ;
2019-01-23 12:25:56 -08:00
2019-01-29 23:08:03 -06:00
let table_type = TableDescriptor {
element : ElementType ::Anyfunc ,
minimum : table_min ,
maximum : table_max ,
2019-01-23 12:34:56 -08:00
} ;
2019-03-12 22:00:33 +01:00
let table = Table ::new ( table_type ) . unwrap ( ) ;
2019-01-23 12:34:56 -08:00
2019-02-08 10:55:32 -08:00
let data = {
let static_bump = STATIC_BUMP ;
2019-03-12 22:00:33 +01:00
let mut static_top = STATIC_BASE + static_bump ;
2019-02-08 10:55:32 -08:00
let memory_base = STATIC_BASE ;
let table_base = 0 ;
2019-03-12 22:00:33 +01:00
let temp_double_ptr = static_top ;
static_top + = 16 ;
2019-02-08 10:55:32 -08:00
2019-03-12 22:00:33 +01:00
let dynamictop_ptr = static_alloc ( & mut static_top , 4 ) ;
2019-02-08 10:55:32 -08:00
2019-03-12 22:00:33 +01:00
let stacktop = align_memory ( static_top ) ;
2019-02-08 10:55:32 -08:00
let stack_max = stacktop + TOTAL_STACK ;
EmscriptenGlobalsData {
abort : 0 ,
stacktop ,
stack_max ,
dynamictop_ptr ,
memory_base ,
table_base ,
temp_double_ptr ,
2019-02-10 15:24:04 -07:00
use_old_abort_on_cannot_grow_memory ,
2019-02-08 10:55:32 -08:00
}
2019-01-24 16:24:41 -08:00
} ;
2019-01-17 19:55:25 +01:00
2019-02-08 10:55:32 -08:00
emscripten_set_up_memory ( & memory , & data ) ;
2019-03-26 18:59:39 -07:00
let mut null_func_names = vec! [ ] ;
for (
_ ,
ImportName {
namespace_index ,
name_index ,
} ,
) in & module . info ( ) . imported_functions
2019-03-26 19:00:39 -07:00
{
let namespace = module . info ( ) . namespace_table . get ( * namespace_index ) ;
let name = module . info ( ) . name_table . get ( * name_index ) ;
if namespace = = " env " & & name . starts_with ( " nullFunc_ " ) {
null_func_names . push ( name . to_string ( ) )
2019-03-26 18:59:39 -07:00
}
2019-03-26 19:00:39 -07:00
}
2019-03-26 18:59:39 -07:00
2019-01-30 19:19:53 -06:00
Self {
data ,
memory ,
table ,
memory_min ,
memory_max ,
2019-03-26 18:59:39 -07:00
null_func_names ,
2019-01-30 19:19:53 -06:00
}
2019-01-11 17:10:21 +01:00
}
}
2019-01-23 12:25:56 -08:00
pub fn generate_emscripten_env ( globals : & mut EmscriptenGlobals ) -> ImportObject {
2019-02-10 15:24:04 -07:00
let abort_on_cannot_grow_memory_export = if globals . data . use_old_abort_on_cannot_grow_memory {
func! ( crate ::memory ::abort_on_cannot_grow_memory_old ) . to_export ( )
} else {
func! ( crate ::memory ::abort_on_cannot_grow_memory ) . to_export ( )
} ;
2019-03-26 20:07:00 -07:00
let mut env_ns = namespace! {
2019-03-26 19:00:39 -07:00
" memory " = > Export ::Memory ( globals . memory . clone ( ) ) ,
" table " = > Export ::Table ( globals . table . clone ( ) ) ,
// Globals
" STACKTOP " = > Global ::new ( Value ::I32 ( globals . data . stacktop as i32 ) ) ,
" STACK_MAX " = > Global ::new ( Value ::I32 ( globals . data . stack_max as i32 ) ) ,
" DYNAMICTOP_PTR " = > Global ::new ( Value ::I32 ( globals . data . dynamictop_ptr as i32 ) ) ,
" tableBase " = > Global ::new ( Value ::I32 ( globals . data . table_base as i32 ) ) ,
" __table_base " = > Global ::new ( Value ::I32 ( globals . data . table_base as i32 ) ) ,
" ABORT " = > Global ::new ( Value ::I32 ( globals . data . abort as i32 ) ) ,
" memoryBase " = > Global ::new ( Value ::I32 ( globals . data . memory_base as i32 ) ) ,
" __memory_base " = > Global ::new ( Value ::I32 ( globals . data . memory_base as i32 ) ) ,
" tempDoublePtr " = > Global ::new ( Value ::I32 ( globals . data . temp_double_ptr as i32 ) ) ,
// IO
" printf " = > func! ( crate ::io ::printf ) ,
" putchar " = > func! ( crate ::io ::putchar ) ,
" ___lock " = > func! ( crate ::lock ::___lock ) ,
" ___unlock " = > func! ( crate ::lock ::___unlock ) ,
" ___wait " = > func! ( crate ::lock ::___wait ) ,
" _flock " = > func! ( crate ::lock ::_flock ) ,
" _chroot " = > func! ( crate ::io ::chroot ) ,
" _getprotobyname " = > func! ( crate ::io ::getprotobyname ) ,
" _getprotobynumber " = > func! ( crate ::io ::getprotobynumber ) ,
" _getpwuid " = > func! ( crate ::io ::getpwuid ) ,
" _sigdelset " = > func! ( crate ::io ::sigdelset ) ,
" _sigfillset " = > func! ( crate ::io ::sigfillset ) ,
" _tzset " = > func! ( crate ::io ::tzset ) ,
" _strptime " = > func! ( crate ::io ::strptime ) ,
// exec
" _execvp " = > func! ( crate ::exec ::execvp ) ,
" _execl " = > func! ( crate ::exec ::execl ) ,
" _execle " = > func! ( crate ::exec ::execle ) ,
// exit
" __exit " = > func! ( crate ::exit ::exit ) ,
// Env
" ___assert_fail " = > func! ( crate ::env ::___assert_fail ) ,
" _getenv " = > func! ( crate ::env ::_getenv ) ,
" _setenv " = > func! ( crate ::env ::_setenv ) ,
" _putenv " = > func! ( crate ::env ::_putenv ) ,
" _unsetenv " = > func! ( crate ::env ::_unsetenv ) ,
" _getpwnam " = > func! ( crate ::env ::_getpwnam ) ,
" _getgrnam " = > func! ( crate ::env ::_getgrnam ) ,
" ___buildEnvironment " = > func! ( crate ::env ::___build_environment ) ,
" ___setErrNo " = > func! ( crate ::errno ::___seterrno ) ,
" _getpagesize " = > func! ( crate ::env ::_getpagesize ) ,
" _sysconf " = > func! ( crate ::env ::_sysconf ) ,
" _getaddrinfo " = > func! ( crate ::env ::_getaddrinfo ) ,
// Syscalls
" ___syscall1 " = > func! ( crate ::syscalls ::___syscall1 ) ,
" ___syscall3 " = > func! ( crate ::syscalls ::___syscall3 ) ,
" ___syscall4 " = > func! ( crate ::syscalls ::___syscall4 ) ,
" ___syscall5 " = > func! ( crate ::syscalls ::___syscall5 ) ,
" ___syscall6 " = > func! ( crate ::syscalls ::___syscall6 ) ,
" ___syscall9 " = > func! ( crate ::syscalls ::___syscall9 ) ,
" ___syscall10 " = > func! ( crate ::syscalls ::___syscall10 ) ,
" ___syscall12 " = > func! ( crate ::syscalls ::___syscall12 ) ,
" ___syscall15 " = > func! ( crate ::syscalls ::___syscall15 ) ,
" ___syscall20 " = > func! ( crate ::syscalls ::___syscall20 ) ,
" ___syscall33 " = > func! ( crate ::syscalls ::___syscall33 ) ,
" ___syscall34 " = > func! ( crate ::syscalls ::___syscall34 ) ,
" ___syscall39 " = > func! ( crate ::syscalls ::___syscall39 ) ,
" ___syscall38 " = > func! ( crate ::syscalls ::___syscall38 ) ,
" ___syscall40 " = > func! ( crate ::syscalls ::___syscall40 ) ,
" ___syscall41 " = > func! ( crate ::syscalls ::___syscall41 ) ,
" ___syscall42 " = > func! ( crate ::syscalls ::___syscall42 ) ,
" ___syscall54 " = > func! ( crate ::syscalls ::___syscall54 ) ,
" ___syscall57 " = > func! ( crate ::syscalls ::___syscall57 ) ,
" ___syscall60 " = > func! ( crate ::syscalls ::___syscall60 ) ,
" ___syscall63 " = > func! ( crate ::syscalls ::___syscall63 ) ,
" ___syscall64 " = > func! ( crate ::syscalls ::___syscall64 ) ,
" ___syscall66 " = > func! ( crate ::syscalls ::___syscall66 ) ,
" ___syscall75 " = > func! ( crate ::syscalls ::___syscall75 ) ,
" ___syscall77 " = > func! ( crate ::syscalls ::___syscall77 ) ,
" ___syscall83 " = > func! ( crate ::syscalls ::___syscall83 ) ,
" ___syscall85 " = > func! ( crate ::syscalls ::___syscall85 ) ,
" ___syscall91 " = > func! ( crate ::syscalls ::___syscall191 ) ,
" ___syscall94 " = > func! ( crate ::syscalls ::___syscall194 ) ,
" ___syscall97 " = > func! ( crate ::syscalls ::___syscall97 ) ,
" ___syscall102 " = > func! ( crate ::syscalls ::___syscall102 ) ,
" ___syscall110 " = > func! ( crate ::syscalls ::___syscall110 ) ,
" ___syscall114 " = > func! ( crate ::syscalls ::___syscall114 ) ,
" ___syscall118 " = > func! ( crate ::syscalls ::___syscall118 ) ,
" ___syscall122 " = > func! ( crate ::syscalls ::___syscall122 ) ,
" ___syscall140 " = > func! ( crate ::syscalls ::___syscall140 ) ,
" ___syscall142 " = > func! ( crate ::syscalls ::___syscall142 ) ,
" ___syscall145 " = > func! ( crate ::syscalls ::___syscall145 ) ,
" ___syscall146 " = > func! ( crate ::syscalls ::___syscall146 ) ,
" ___syscall148 " = > func! ( crate ::syscalls ::___syscall148 ) ,
" ___syscall168 " = > func! ( crate ::syscalls ::___syscall168 ) ,
" ___syscall180 " = > func! ( crate ::syscalls ::___syscall180 ) ,
" ___syscall181 " = > func! ( crate ::syscalls ::___syscall181 ) ,
" ___syscall183 " = > func! ( crate ::syscalls ::___syscall183 ) ,
" ___syscall191 " = > func! ( crate ::syscalls ::___syscall191 ) ,
" ___syscall192 " = > func! ( crate ::syscalls ::___syscall192 ) ,
" ___syscall194 " = > func! ( crate ::syscalls ::___syscall194 ) ,
" ___syscall195 " = > func! ( crate ::syscalls ::___syscall195 ) ,
" ___syscall196 " = > func! ( crate ::syscalls ::___syscall196 ) ,
" ___syscall197 " = > func! ( crate ::syscalls ::___syscall197 ) ,
" ___syscall198 " = > func! ( crate ::syscalls ::___syscall198 ) ,
" ___syscall199 " = > func! ( crate ::syscalls ::___syscall199 ) ,
" ___syscall200 " = > func! ( crate ::syscalls ::___syscall200 ) ,
" ___syscall201 " = > func! ( crate ::syscalls ::___syscall201 ) ,
" ___syscall202 " = > func! ( crate ::syscalls ::___syscall202 ) ,
" ___syscall205 " = > func! ( crate ::syscalls ::___syscall205 ) ,
" ___syscall207 " = > func! ( crate ::syscalls ::___syscall207 ) ,
" ___syscall212 " = > func! ( crate ::syscalls ::___syscall212 ) ,
" ___syscall219 " = > func! ( crate ::syscalls ::___syscall219 ) ,
" ___syscall220 " = > func! ( crate ::syscalls ::___syscall220 ) ,
" ___syscall221 " = > func! ( crate ::syscalls ::___syscall221 ) ,
" ___syscall268 " = > func! ( crate ::syscalls ::___syscall268 ) ,
" ___syscall272 " = > func! ( crate ::syscalls ::___syscall272 ) ,
" ___syscall295 " = > func! ( crate ::syscalls ::___syscall295 ) ,
" ___syscall300 " = > func! ( crate ::syscalls ::___syscall300 ) ,
" ___syscall324 " = > func! ( crate ::syscalls ::___syscall324 ) ,
" ___syscall330 " = > func! ( crate ::syscalls ::___syscall330 ) ,
" ___syscall334 " = > func! ( crate ::syscalls ::___syscall334 ) ,
" ___syscall340 " = > func! ( crate ::syscalls ::___syscall340 ) ,
// Process
" abort " = > func! ( crate ::process ::em_abort ) ,
" _abort " = > func! ( crate ::process ::_abort ) ,
" abortStackOverflow " = > func! ( crate ::process ::abort_stack_overflow ) ,
" _llvm_trap " = > func! ( crate ::process ::_llvm_trap ) ,
" _fork " = > func! ( crate ::process ::_fork ) ,
" _exit " = > func! ( crate ::process ::_exit ) ,
" _system " = > func! ( crate ::process ::_system ) ,
" _popen " = > func! ( crate ::process ::_popen ) ,
" _endgrent " = > func! ( crate ::process ::_endgrent ) ,
" _execve " = > func! ( crate ::process ::_execve ) ,
" _kill " = > func! ( crate ::process ::_kill ) ,
" _llvm_stackrestore " = > func! ( crate ::process ::_llvm_stackrestore ) ,
" _llvm_stacksave " = > func! ( crate ::process ::_llvm_stacksave ) ,
" _raise " = > func! ( crate ::process ::_raise ) ,
" _sem_init " = > func! ( crate ::process ::_sem_init ) ,
" _sem_post " = > func! ( crate ::process ::_sem_post ) ,
" _sem_wait " = > func! ( crate ::process ::_sem_wait ) ,
" _getgrent " = > func! ( crate ::process ::_getgrent ) ,
" _sched_yield " = > func! ( crate ::process ::_sched_yield ) ,
" _setgrent " = > func! ( crate ::process ::_setgrent ) ,
" _setgroups " = > func! ( crate ::process ::_setgroups ) ,
" _setitimer " = > func! ( crate ::process ::_setitimer ) ,
" _usleep " = > func! ( crate ::process ::_usleep ) ,
" _nanosleep " = > func! ( crate ::process ::_nanosleep ) ,
" _utimes " = > func! ( crate ::process ::_utimes ) ,
" _waitpid " = > func! ( crate ::process ::_waitpid ) ,
// Signal
" _sigemptyset " = > func! ( crate ::signal ::_sigemptyset ) ,
" _sigaddset " = > func! ( crate ::signal ::_sigaddset ) ,
" _sigprocmask " = > func! ( crate ::signal ::_sigprocmask ) ,
" _sigaction " = > func! ( crate ::signal ::_sigaction ) ,
" _signal " = > func! ( crate ::signal ::_signal ) ,
" _sigsuspend " = > func! ( crate ::signal ::_sigsuspend ) ,
// Memory
" abortOnCannotGrowMemory " = > abort_on_cannot_grow_memory_export ,
" _emscripten_memcpy_big " = > func! ( crate ::memory ::_emscripten_memcpy_big ) ,
" _emscripten_get_heap_size " = > func! ( crate ::memory ::_emscripten_get_heap_size ) ,
" _emscripten_resize_heap " = > func! ( crate ::memory ::_emscripten_resize_heap ) ,
" enlargeMemory " = > func! ( crate ::memory ::enlarge_memory ) ,
" getTotalMemory " = > func! ( crate ::memory ::get_total_memory ) ,
" ___map_file " = > func! ( crate ::memory ::___map_file ) ,
// Exception
" ___cxa_allocate_exception " = > func! ( crate ::exception ::___cxa_allocate_exception ) ,
" ___cxa_throw " = > func! ( crate ::exception ::___cxa_throw ) ,
// Time
" _gettimeofday " = > func! ( crate ::time ::_gettimeofday ) ,
" _clock_gettime " = > func! ( crate ::time ::_clock_gettime ) ,
" ___clock_gettime " = > func! ( crate ::time ::_clock_gettime ) ,
" _clock " = > func! ( crate ::time ::_clock ) ,
" _difftime " = > func! ( crate ::time ::_difftime ) ,
" _asctime " = > func! ( crate ::time ::_asctime ) ,
" _asctime_r " = > func! ( crate ::time ::_asctime_r ) ,
" _localtime " = > func! ( crate ::time ::_localtime ) ,
" _time " = > func! ( crate ::time ::_time ) ,
" _strftime " = > func! ( crate ::time ::_strftime ) ,
" _localtime_r " = > func! ( crate ::time ::_localtime_r ) ,
" _gmtime_r " = > func! ( crate ::time ::_gmtime_r ) ,
" _mktime " = > func! ( crate ::time ::_mktime ) ,
" _gmtime " = > func! ( crate ::time ::_gmtime ) ,
// Math
" f64-rem " = > func! ( crate ::math ::f64_rem ) ,
" _llvm_log10_f64 " = > func! ( crate ::math ::_llvm_log10_f64 ) ,
" _llvm_log2_f64 " = > func! ( crate ::math ::_llvm_log2_f64 ) ,
" _llvm_log10_f32 " = > func! ( crate ::math ::_llvm_log10_f32 ) ,
" _llvm_log2_f32 " = > func! ( crate ::math ::_llvm_log2_f64 ) ,
" _llvm_sin_f64 " = > func! ( crate ::math ::_llvm_sin_f64 ) ,
" _llvm_cos_f64 " = > func! ( crate ::math ::_llvm_cos_f64 ) ,
" _emscripten_random " = > func! ( crate ::math ::_emscripten_random ) ,
// Jump
" __setjmp " = > func! ( crate ::jmp ::__setjmp ) ,
" __longjmp " = > func! ( crate ::jmp ::__longjmp ) ,
" _longjmp " = > func! ( crate ::jmp ::__longjmp ) ,
2019-03-26 19:04:18 -07:00
// Bitwise
" _llvm_bswap_i64 " = > func! ( crate ::bitwise ::_llvm_bswap_i64 ) ,
2019-03-26 19:00:39 -07:00
// Linking
" _dlclose " = > func! ( crate ::linking ::_dlclose ) ,
" _dlerror " = > func! ( crate ::linking ::_dlerror ) ,
" _dlopen " = > func! ( crate ::linking ::_dlopen ) ,
" _dlsym " = > func! ( crate ::linking ::_dlsym ) ,
// wasm32-unknown-emscripten
" setTempRet0 " = > func! ( crate ::emscripten_target ::setTempRet0 ) ,
" getTempRet0 " = > func! ( crate ::emscripten_target ::getTempRet0 ) ,
" invoke_i " = > func! ( crate ::emscripten_target ::invoke_i ) ,
" invoke_ii " = > func! ( crate ::emscripten_target ::invoke_ii ) ,
" invoke_iii " = > func! ( crate ::emscripten_target ::invoke_iii ) ,
" invoke_iiii " = > func! ( crate ::emscripten_target ::invoke_iiii ) ,
" invoke_v " = > func! ( crate ::emscripten_target ::invoke_v ) ,
" invoke_vi " = > func! ( crate ::emscripten_target ::invoke_vi ) ,
" invoke_vii " = > func! ( crate ::emscripten_target ::invoke_vii ) ,
" invoke_viii " = > func! ( crate ::emscripten_target ::invoke_viii ) ,
" invoke_viiii " = > func! ( crate ::emscripten_target ::invoke_viiii ) ,
" __Unwind_Backtrace " = > func! ( crate ::emscripten_target ::__Unwind_Backtrace ) ,
" __Unwind_FindEnclosingFunction " = > func! ( crate ::emscripten_target ::__Unwind_FindEnclosingFunction ) ,
" __Unwind_GetIPInfo " = > func! ( crate ::emscripten_target ::__Unwind_GetIPInfo ) ,
" ___cxa_find_matching_catch_2 " = > func! ( crate ::emscripten_target ::___cxa_find_matching_catch_2 ) ,
" ___cxa_find_matching_catch_3 " = > func! ( crate ::emscripten_target ::___cxa_find_matching_catch_3 ) ,
" ___cxa_free_exception " = > func! ( crate ::emscripten_target ::___cxa_free_exception ) ,
" ___resumeException " = > func! ( crate ::emscripten_target ::___resumeException ) ,
" _dladdr " = > func! ( crate ::emscripten_target ::_dladdr ) ,
" _pthread_create " = > func! ( crate ::emscripten_target ::_pthread_create ) ,
" _pthread_join " = > func! ( crate ::emscripten_target ::_pthread_join ) ,
" _pthread_cond_destroy " = > func! ( crate ::emscripten_target ::_pthread_cond_destroy ) ,
" _pthread_cond_init " = > func! ( crate ::emscripten_target ::_pthread_cond_init ) ,
" _pthread_cond_signal " = > func! ( crate ::emscripten_target ::_pthread_cond_signal ) ,
" _pthread_cond_wait " = > func! ( crate ::emscripten_target ::_pthread_cond_wait ) ,
" _pthread_condattr_destroy " = > func! ( crate ::emscripten_target ::_pthread_condattr_destroy ) ,
" _pthread_condattr_init " = > func! ( crate ::emscripten_target ::_pthread_condattr_init ) ,
" _pthread_condattr_setclock " = > func! ( crate ::emscripten_target ::_pthread_condattr_setclock ) ,
" _pthread_mutex_destroy " = > func! ( crate ::emscripten_target ::_pthread_mutex_destroy ) ,
" _pthread_mutex_init " = > func! ( crate ::emscripten_target ::_pthread_mutex_init ) ,
" _pthread_mutexattr_destroy " = > func! ( crate ::emscripten_target ::_pthread_mutexattr_destroy ) ,
" _pthread_mutexattr_init " = > func! ( crate ::emscripten_target ::_pthread_mutexattr_init ) ,
" _pthread_mutexattr_settype " = > func! ( crate ::emscripten_target ::_pthread_mutexattr_settype ) ,
" _pthread_rwlock_rdlock " = > func! ( crate ::emscripten_target ::_pthread_rwlock_rdlock ) ,
" _pthread_rwlock_unlock " = > func! ( crate ::emscripten_target ::_pthread_rwlock_unlock ) ,
" _pthread_setcancelstate " = > func! ( crate ::emscripten_target ::_pthread_setcancelstate ) ,
" ___gxx_personality_v0 " = > func! ( crate ::emscripten_target ::___gxx_personality_v0 ) ,
" _getdtablesize " = > func! ( crate ::emscripten_target ::_getdtablesize ) ,
" _gethostbyaddr " = > func! ( crate ::emscripten_target ::_gethostbyaddr ) ,
" _gethostbyname_r " = > func! ( crate ::emscripten_target ::_gethostbyname_r ) ,
" _getloadavg " = > func! ( crate ::emscripten_target ::_getloadavg ) ,
" invoke_dii " = > func! ( crate ::emscripten_target ::invoke_dii ) ,
" invoke_diiii " = > func! ( crate ::emscripten_target ::invoke_diiii ) ,
" invoke_iiiii " = > func! ( crate ::emscripten_target ::invoke_iiiii ) ,
" invoke_iiiiii " = > func! ( crate ::emscripten_target ::invoke_iiiiii ) ,
" invoke_iiiiiii " = > func! ( crate ::emscripten_target ::invoke_iiiiiii ) ,
" invoke_iiiiiiii " = > func! ( crate ::emscripten_target ::invoke_iiiiiiii ) ,
" invoke_iiiiiiiiii " = > func! ( crate ::emscripten_target ::invoke_iiiiiiiiii ) ,
" invoke_vd " = > func! ( crate ::emscripten_target ::invoke_vd ) ,
" invoke_viiiii " = > func! ( crate ::emscripten_target ::invoke_viiiii ) ,
" invoke_viiiiii " = > func! ( crate ::emscripten_target ::invoke_viiiiii ) ,
" invoke_viiiiiii " = > func! ( crate ::emscripten_target ::invoke_viiiiiii ) ,
" invoke_viiiiiiii " = > func! ( crate ::emscripten_target ::invoke_viiiiiiii ) ,
" invoke_viiiiiiiii " = > func! ( crate ::emscripten_target ::invoke_viiiiiiiii ) ,
" invoke_iiji " = > func! ( crate ::emscripten_target ::invoke_iiji ) ,
" invoke_j " = > func! ( crate ::emscripten_target ::invoke_j ) ,
" invoke_ji " = > func! ( crate ::emscripten_target ::invoke_ji ) ,
" invoke_jij " = > func! ( crate ::emscripten_target ::invoke_jij ) ,
" invoke_jjj " = > func! ( crate ::emscripten_target ::invoke_jjj ) ,
" invoke_viiij " = > func! ( crate ::emscripten_target ::invoke_viiij ) ,
" invoke_viiijiiii " = > func! ( crate ::emscripten_target ::invoke_viiijiiii ) ,
" invoke_viiijiiiiii " = > func! ( crate ::emscripten_target ::invoke_viiijiiiiii ) ,
" invoke_viij " = > func! ( crate ::emscripten_target ::invoke_viij ) ,
" invoke_viiji " = > func! ( crate ::emscripten_target ::invoke_viiji ) ,
" invoke_viijiii " = > func! ( crate ::emscripten_target ::invoke_viijiii ) ,
" invoke_viijj " = > func! ( crate ::emscripten_target ::invoke_viijj ) ,
" invoke_vij " = > func! ( crate ::emscripten_target ::invoke_vij ) ,
" invoke_viji " = > func! ( crate ::emscripten_target ::invoke_viji ) ,
" invoke_vijiii " = > func! ( crate ::emscripten_target ::invoke_vijiii ) ,
" invoke_vijj " = > func! ( crate ::emscripten_target ::invoke_vijj ) ,
" invoke_viidii " = > func! ( crate ::emscripten_target ::invoke_viidii ) ,
} ;
2019-03-26 18:59:39 -07:00
for null_func_name in globals . null_func_names . iter ( ) {
2019-03-27 08:36:41 -07:00
env_ns . insert ( null_func_name . as_str ( ) , Func ::new ( nullfunc ) . to_export ( ) ) ;
2019-03-26 18:59:39 -07:00
}
let import_object : ImportObject = imports! {
" env " = > env_ns ,
2019-02-05 17:25:51 -06:00
" global " = > {
" NaN " = > Global ::new ( Value ::F64 ( f64 ::NAN ) ) ,
" Infinity " = > Global ::new ( Value ::F64 ( f64 ::INFINITY ) ) ,
} ,
2019-02-05 23:24:07 -06:00
" global.Math " = > {
2019-02-02 15:28:50 -08:00
" pow " = > func! ( crate ::math ::pow ) ,
2019-03-20 15:13:00 -07:00
" exp " = > func! ( crate ::math ::exp ) ,
" log " = > func! ( crate ::math ::log ) ,
2019-01-31 17:44:57 -08:00
} ,
2019-02-05 23:39:12 -06:00
" asm2wasm " = > {
" f64-rem " = > func! ( crate ::math ::f64_rem ) ,
} ,
2019-03-26 18:59:39 -07:00
} ;
import_object
}
2019-03-27 08:36:41 -07:00
pub fn nullfunc ( ctx : & mut Ctx , _x : u32 ) {
2019-03-26 18:59:39 -07:00
use crate ::process ::abort_with_message ;
debug! ( " emscripten::nullfunc_i {} " , _x ) ;
abort_with_message ( ctx , " Invalid function pointer called with signature 'i'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this) " ) ;
2018-11-13 19:19:23 -08:00
}
2019-01-22 15:26:56 -08:00
/// The current version of this crate
pub const VERSION : & str = env! ( " CARGO_PKG_VERSION " ) ;