#![cfg(not(target_arch = "wasm32"))]
use ::std::ptr;
use ::std::ptr::null_mut;
use mozjs::jsapi::*;
use mozjs::jsval::ObjectValue;
use mozjs::jsval::UndefinedValue;
use mozjs::realm::AutoRealm;
use mozjs::rooted;
use mozjs::rust::wrappers2::{
Call, Construct1, JS_DefineFunction, JS_GetProperty, JS_NewGlobalObject, JS_NewPlainObject,
JS_SetProperty, NewArrayBufferWithUserOwnedContents,
};
use mozjs::rust::SIMPLE_GLOBAL_CLASS;
use mozjs::rust::{HandleValue, IntoHandle, JSEngine, RealmOptions, Runtime};
use mozjs_sys::jsgc::ValueArray;
#[repr(align(8))]
struct Aligned8<T>(T);
const HI_WASM: Aligned8<[u8; 56]> = Aligned8([
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x02, 0x60, 0x01, 0x7f, 0x01, 0x7f,
0x60, 0x00, 0x01, 0x7f, 0x02, 0x0b, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x03, 0x62, 0x61, 0x72, 0x00,
0x00, 0x03, 0x02, 0x01, 0x01, 0x07, 0x07, 0x01, 0x03, 0x66, 0x6f, 0x6f, 0x00, 0x01, 0x0a, 0x08,
0x01, 0x06, 0x00, 0x41, 0x2a, 0x10, 0x00, 0x0b,
]);
unsafe extern "C" fn bar(_cx: *mut JSContext, argc: u32, vp: *mut Value) -> bool {
let args = CallArgs::from_vp(vp, argc);
args.rval().set(args.get(0).get());
true
}
fn run(mut rt: Runtime) {
let options = RealmOptions::default();
let cx = rt.cx();
rooted!(&in(cx) let global = unsafe {
JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(),
OnNewGlobalHookOption::FireOnNewGlobalHook,
&*options)
});
let mut realm = AutoRealm::new_from_handle(cx, global.handle());
let cx = &mut realm;
rooted!(&in(cx) let mut wasm = UndefinedValue());
rooted!(&in(cx) let mut wasm_module = UndefinedValue());
rooted!(&in(cx) let mut wasm_instance = UndefinedValue());
unsafe {
assert!(JS_GetProperty(
cx,
global.handle(),
c"WebAssembly".as_ptr(),
wasm.handle_mut()
));
rooted!(&in(cx) let mut wasm_obj = wasm.to_object());
assert!(JS_GetProperty(
cx,
wasm_obj.handle(),
c"Module".as_ptr(),
wasm_module.handle_mut()
));
assert!(JS_GetProperty(
cx,
wasm_obj.handle(),
c"Instance".as_ptr(),
wasm_instance.handle_mut()
));
assert!(HI_WASM.0.as_ptr() as usize % 8 == 0);
rooted!(&in(cx) let mut module = null_mut::<JSObject>());
{
let array_buffer =
NewArrayBufferWithUserOwnedContents(cx, HI_WASM.0.len(), HI_WASM.0.as_ptr() as _);
assert!(!array_buffer.is_null());
rooted!(&in(cx) let val = ObjectValue(array_buffer));
let args = HandleValueArray::from(val.handle().into_handle());
assert!(Construct1(
cx,
wasm_module.handle(),
&args,
module.handle_mut()
))
}
rooted!(&in(cx) let mut instance = null_mut::<JSObject>());
{
rooted!(&in(cx) let mut env_import_obj = JS_NewPlainObject(cx));
assert!(!env_import_obj.is_null());
let function = JS_DefineFunction(
cx,
env_import_obj.handle().into(),
c"bar".as_ptr(),
Some(bar),
1,
0,
);
assert!(!function.is_null());
rooted!(&in(cx) let mut env_import = ObjectValue(env_import_obj.get()));
rooted!(&in(cx) let mut imports = JS_NewPlainObject(cx));
assert!(!imports.is_null());
assert!(JS_SetProperty(
cx,
imports.handle(),
c"env".as_ptr(),
env_import.handle()
));
rooted!(&in(cx) let mut args = ValueArray::new([ObjectValue(module.get()), ObjectValue(imports.get())]));
assert!(Construct1(
cx,
wasm_instance.handle(),
&HandleValueArray::from(&args),
instance.handle_mut()
));
}
rooted!(&in(cx) let mut exports = UndefinedValue());
assert!(JS_GetProperty(
cx,
instance.handle(),
c"exports".as_ptr(),
exports.handle_mut()
));
rooted!(&in(cx) let mut exports_obj = exports.to_object());
rooted!(&in(cx) let mut foo = UndefinedValue());
assert!(JS_GetProperty(
cx,
exports_obj.handle(),
c"foo".as_ptr(),
foo.handle_mut()
));
rooted!(&in(cx) let mut rval = UndefinedValue());
assert!(Call(
cx,
HandleValue::undefined(),
foo.handle().into(),
&HandleValueArray::empty(),
rval.handle_mut().into()
));
assert!(rval.get().is_int32());
assert_eq!(rval.get().to_int32(), 42);
}
}
fn main() {
let engine = JSEngine::init().expect("failed to initalize JS engine");
let runtime = Runtime::new(engine.handle());
run(runtime);
}
#[test]
fn wasm_example() {
main()
}