diff options
-rw-r--r-- | core/runtime.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/core/runtime.rs b/core/runtime.rs index cf7980fb4..3578b216a 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -3400,4 +3400,52 @@ assertEquals(1, notify_return_value); let scope = &mut realm.handle_scope(&mut runtime); assert_eq!(ret, serde_v8::to_v8(scope, "Test").unwrap()); } + + #[test] + fn js_realm_sync_ops() { + // Test that returning a ZeroCopyBuf and throwing an exception from a sync + // op result in objects with prototypes from the right realm. Note that we + // don't test the result of returning structs, because they will be + // serialized to objects with null prototype. + + #[op] + fn op_test(fail: bool) -> Result<ZeroCopyBuf, Error> { + if !fail { + Ok(ZeroCopyBuf::empty()) + } else { + Err(crate::error::type_error("Test")) + } + } + + let mut runtime = JsRuntime::new(RuntimeOptions { + extensions: vec![Extension::builder().ops(vec![op_test::decl()]).build()], + get_error_class_fn: Some(&|error| { + crate::error::get_custom_error_class(error).unwrap() + }), + ..Default::default() + }); + let new_realm = runtime.create_realm().unwrap(); + + // Test in both realms + for realm in [runtime.global_realm(), new_realm].into_iter() { + let ret = realm + .execute_script( + &mut runtime, + "", + r#" + const buf = Deno.core.opSync("op_test", false); + let err; + try { + Deno.core.opSync("op_test", true); + } catch(e) { + err = e; + } + buf instanceof Uint8Array && buf.byteLength === 0 && + err instanceof TypeError && err.message === "Test" + "#, + ) + .unwrap(); + assert!(ret.open(runtime.v8_isolate()).is_true()); + } + } } |