use crate::types::{Error, LucetSandboxInstance}; use lucet_runtime::{DlModule, Limits, MmapRegion, Module, Region}; use lucet_runtime_internals::{module::ModuleInternal}; use lucet_wasi::WasiCtxBuilder; use std::ffi::{c_void, CStr}; use std::os::raw::c_char; use std::ptr; use std::sync::Arc; #[no_mangle] pub extern "C" fn lucet_ensure_linked() { lucet_runtime::lucet_internal_ensure_linked(); lucet_wasi::hostcalls::ensure_linked(); } #[no_mangle] pub extern "C" fn lucet_load_module(lucet_module_path: *const c_char, allow_stdio: bool) -> *mut c_void { let module_path; unsafe { module_path = CStr::from_ptr(lucet_module_path) .to_string_lossy() .into_owned(); } let result = lucet_load_module_helper(&module_path, allow_stdio); let r = match result { Ok(inst) => Box::into_raw(Box::new(inst)) as *mut c_void, Err(e) => { println!("Error {:?}!", e); ptr::null_mut() } }; return r; } #[no_mangle] pub extern "C" fn lucet_drop_module(inst_ptr: *mut c_void) { // Need to invoke the destructor let _inst = unsafe { Box::from_raw(inst_ptr as *mut LucetSandboxInstance) }; } fn lucet_load_module_helper(module_path: &String, allow_stdio: bool) -> Result { let module = DlModule::load(module_path)?; //Replicating calculations used in lucet examples let min_globals_size = module.globals().len() * std::mem::size_of::(); // Nearest 4k let globals_size = ((min_globals_size + 4096 - 1) / 4096) * 4096; let region = MmapRegion::create_aligned( 1, &Limits { heap_memory_size: 4 * 1024 * 1024 * 1024, // 4GB heap_address_space_size: 8 * 1024 * 1024 * 1024, // 8GB stack_size: 8 * 1024 * 1024, // 8MB - pthread default globals_size: globals_size, ..Limits::default() }, 4 * 1024 * 1024 * 1024, // 4GB heap alignment )?; let sig = module.get_signatures().to_vec(); // put the path to the module on the front for argv[0] let mut builder = WasiCtxBuilder::new() .args(&[&module_path]); if allow_stdio { builder = builder.inherit_stdio_no_syscall(); } let ctx = builder.build()?; let instance_handle = region .new_instance_builder(module as Arc) .with_embed_ctx(ctx) .build()?; let opaque_instance = LucetSandboxInstance { region: region, instance_handle: instance_handle, signatures: sig, }; return Ok(opaque_instance); }