From c88b8df60d4f1be7b67c32f231e6186f4e9f9214 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 13 Jan 2017 11:53:13 +0100 Subject: [PATCH 1/2] Fix rooting. See . --- src/rust.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/rust.rs b/src/rust.rs index d5ea5ec3e..a82dad3c6 100644 --- a/src/rust.rs +++ b/src/rust.rs @@ -35,7 +35,7 @@ use jsapi::{NullHandleValue, Object, ObjectGroup,ReadOnlyCompileOptions, Rooted} use jsapi::{RootedBase, RuntimeOptionsRef, SetWarningReporter, Symbol, ToBooleanSlow}; use jsapi::{ToInt32Slow, ToInt64Slow, ToNumberSlow, ToStringSlow, ToUint16Slow}; use jsapi::{ToUint32Slow, ToUint64Slow, ToWindowProxyIfWindow, UndefinedHandleValue}; -use jsapi::{Value, jsid}; +use jsapi::{Value, jsid, PerThreadDataFriendFields, PerThreadDataFriendFields_RuntimeDummy}; use jsval::{ObjectValue, UndefinedValue}; use glue::{AppendToAutoObjectVector, CallFunctionTracer, CallIdTracer, CallObjectTracer}; use glue::{CallScriptTracer, CallStringTracer, CallValueTracer, CreateAutoIdVector}; @@ -355,9 +355,19 @@ impl Rooted { pub unsafe fn add_to_root_stack(&mut self, cx: *mut JSContext) where T: RootKind { let ctxfriend = cx as *mut ContextFriendFields; + let zone = (*ctxfriend).zone_; + let roots: *mut _ = if !zone.is_null() { + &mut (*zone).stackRoots_ + } else { + let rt = (*ctxfriend).runtime_; + let rt = rt as *mut PerThreadDataFriendFields_RuntimeDummy; + let main_thread = &mut (*rt).mainThread as *mut _; + let main_thread = main_thread as *mut PerThreadDataFriendFields; + &mut (*main_thread).roots.stackRoots_ + }; let kind = T::rootKind() as usize; - let stack = &mut (*ctxfriend).roots.stackRoots_[kind] as *mut _ as *mut _; + let stack = &mut (*roots)[kind] as *mut _ as *mut _; self.stack = stack; self.prev = *stack; From c8f4cab562bb15bd6077caf3973f66c011e0fbd1 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 13 Jan 2017 14:11:57 +0100 Subject: [PATCH 2/2] Add test. --- Cargo.toml | 2 ++ tests/rooting.rs | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 tests/rooting.rs diff --git a/Cargo.toml b/Cargo.toml index b19174382..f61817995 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,8 @@ name = "evaluate" [[test]] name = "panic" [[test]] +name = "rooting" +[[test]] name = "typedarray" [[test]] name = "stack_limit" diff --git a/tests/rooting.rs b/tests/rooting.rs new file mode 100644 index 000000000..5a65b3c27 --- /dev/null +++ b/tests/rooting.rs @@ -0,0 +1,92 @@ +/* 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/. */ + +#![feature(const_fn)] +#![cfg(feature = "debugmozjs")] + +#[macro_use] +extern crate js; +extern crate libc; + +use js::jsapi::CompartmentOptions; +use js::jsapi::JSAutoCompartment; +use js::jsapi::JSClass; +use js::jsapi::JSContext; +use js::jsapi::JSFunctionSpec; +use js::jsapi::JS_GetObjectPrototype; +use js::jsapi::JSNativeWrapper; +use js::jsapi::JS_NewGlobalObject; +use js::jsapi::JS_NewObjectWithUniqueType; +use js::jsapi::JSPROP_ENUMERATE; +use js::jsapi::JS_SetGCZeal; +use js::jsapi::OnNewGlobalHookOption; +use js::jsapi::Value; +use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS, define_methods}; +use std::ptr; + +#[test] +fn rooting() { + unsafe { + let runtime = Runtime::new(); + JS_SetGCZeal(runtime.rt(), 2, 1); + + 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 prototype_proto = JS_GetObjectPrototype(cx, global.handle())); + rooted!(in(cx) let proto = JS_NewObjectWithUniqueType(cx, + &CLASS as *const _, + prototype_proto.handle())); + define_methods(cx, proto.handle(), METHODS).unwrap(); + } +} + +unsafe extern "C" fn generic_method(_: *mut JSContext, _: u32, _: *mut Value) -> bool { + true +} + +const METHODS: &'static [JSFunctionSpec] = &[ + JSFunctionSpec { + name: b"addEventListener\0" as *const u8 as *const libc::c_char, + call: JSNativeWrapper { op: Some(generic_method), info: ptr::null() }, + nargs: 2, + flags: JSPROP_ENUMERATE as u16, + selfHostedName: 0 as *const libc::c_char + }, + JSFunctionSpec { + name: b"removeEventListener\0" as *const u8 as *const libc::c_char, + call: JSNativeWrapper { op: Some(generic_method), info: ptr::null() }, + nargs: 2, + flags: JSPROP_ENUMERATE as u16, + selfHostedName: 0 as *const libc::c_char + }, + JSFunctionSpec { + name: b"dispatchEvent\0" as *const u8 as *const libc::c_char, + call: JSNativeWrapper { op: Some(generic_method), info: ptr::null() }, + nargs: 1, + flags: JSPROP_ENUMERATE as u16, + selfHostedName: 0 as *const libc::c_char + }, + JSFunctionSpec { + name: ptr::null(), + call: JSNativeWrapper { op: None, info: ptr::null() }, + nargs: 0, + flags: 0, + selfHostedName: ptr::null() + } +]; + +static CLASS: JSClass = JSClass { + name: b"EventTargetPrototype\0" as *const u8 as *const libc::c_char, + flags: 0, + cOps: 0 as *const _, + reserved: [0 as *mut _; 3] +};