summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/runtime.rs48
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());
+ }
+ }
}