From 36c5d5b972e595c2abf803547678f139c58e049a Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 18 Jan 2017 17:16:55 +0100 Subject: [PATCH 1/2] Ensure Runtime::get() works during the final GC under JS_DestroyRuntime. --- src/rust.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/rust.rs b/src/rust.rs index a82dad3c6..0154fb5c3 100644 --- a/src/rust.rs +++ b/src/rust.rs @@ -156,6 +156,11 @@ impl Runtime { let js_context = JS_GetContext(js_runtime); assert!(!js_context.is_null()); + CONTEXT.with(|context| { + assert!(context.get().is_null()); + context.set(js_context); + }); + InitSelfHostedCode(js_context); let runtimeopts = RuntimeOptionsRef(js_runtime); @@ -167,11 +172,6 @@ impl Runtime { JS_BeginRequest(js_context); - CONTEXT.with(|context| { - assert!(context.get().is_null()); - context.set(js_context); - }); - Runtime { rt: js_runtime, cx: js_context, @@ -224,13 +224,13 @@ impl Runtime { impl Drop for Runtime { fn drop(&mut self) { unsafe { + JS_EndRequest(self.cx); + JS_DestroyRuntime(self.rt); + CONTEXT.with(|context| { - assert!(!context.get().is_null()); + assert_eq!(context.get(), self.cx); context.set(ptr::null_mut()); }); - - JS_EndRequest(self.cx); - JS_DestroyRuntime(self.rt); } } } From 564eb8f7054bc6e2e8352faa5add07a6ad9a376c Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 18 Jan 2017 17:59:20 +0100 Subject: [PATCH 2/2] Add test. --- Cargo.toml | 2 ++ tests/runtime.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 tests/runtime.rs diff --git a/Cargo.toml b/Cargo.toml index f61817995..eae6ce03c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,8 @@ name = "panic" [[test]] name = "rooting" [[test]] +name = "runtime" +[[test]] name = "typedarray" [[test]] name = "stack_limit" diff --git a/tests/runtime.rs b/tests/runtime.rs new file mode 100644 index 000000000..6ce502787 --- /dev/null +++ b/tests/runtime.rs @@ -0,0 +1,64 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#[macro_use] +extern crate js; +extern crate libc; + +use js::jsapi::CompartmentOptions; +use js::jsapi::JSAutoCompartment; +use js::jsapi::JSClass; +use js::jsapi::JSClassOps; +use js::jsapi::JSFreeOp; +use js::jsapi::JS_NewGlobalObject; +use js::jsapi::JS_NewObject; +use js::jsapi::JSObject; +use js::jsapi::OnNewGlobalHookOption; +use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS}; +use std::ptr; + +#[test] +fn runtime() { + unsafe { + let runtime = Runtime::new(); + + let cx = runtime.cx(); + let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook; + let c_option = CompartmentOptions::default(); + + rooted!(in(cx) let global = JS_NewGlobalObject(cx, + &SIMPLE_GLOBAL_CLASS, + ptr::null_mut(), + h_option, + &c_option)); + let _ac = JSAutoCompartment::new(cx, global.get()); + rooted!(in(cx) let _object = JS_NewObject(cx, &CLASS as *const _)); + } +} + +unsafe extern fn finalize(_fop: *mut JSFreeOp, _object: *mut JSObject) { + assert!(!Runtime::get().is_null()); +} + +static CLASS_OPS: JSClassOps = JSClassOps { + addProperty: None, + delProperty: None, + getProperty: None, + setProperty: None, + enumerate: None, + resolve: None, + mayResolve: None, + finalize: Some(finalize), + call: None, + hasInstance: None, + construct: None, + trace: None, +}; + +static CLASS: JSClass = JSClass { + name: b"EventTargetPrototype\0" as *const u8 as *const libc::c_char, + flags: 0, + cOps: &CLASS_OPS as *const JSClassOps, + reserved: [0 as *mut _; 3] +};