diff --git a/components/script/devtools.rs b/components/script/devtools.rs index eb4a31d794c..d12e24f5152 100644 --- a/components/script/devtools.rs +++ b/components/script/devtools.rs @@ -41,7 +41,7 @@ pub fn handle_evaluate_js(global: &GlobalRef, eval: String, reply: IpcSender GlobalRef<'a> { } } - /// Evaluate JS code on this global. - pub fn evaluate_js_on_global_with_result( - &self, code: &str, rval: MutableHandleValue) { - self.evaluate_script_on_global_with_result(code, "", rval) - } - - /// Evaluate a JS script on this global. - #[allow(unsafe_code)] - pub fn evaluate_script_on_global_with_result( - &self, code: &str, filename: &str, rval: MutableHandleValue) { - let metadata = time::TimerMetadata { - url: if filename.is_empty() { - self.as_global_scope().get_url().as_str().into() - } else { - filename.into() - }, - iframe: time::TimerMetadataFrameType::RootWindow, - incremental: time::TimerMetadataReflowType::FirstReflow, - }; - time::profile( - time::ProfilerCategory::ScriptEvaluate, - Some(metadata), - self.as_global_scope().time_profiler_chan().clone(), - || { - let cx = self.get_cx(); - let globalhandle = self.reflector().get_jsobject(); - let code: Vec = code.encode_utf16().collect(); - let filename = CString::new(filename).unwrap(); - - let _ac = JSAutoCompartment::new(cx, globalhandle.get()); - let options = CompileOptionsWrapper::new(cx, filename.as_ptr(), 1); - unsafe { - if !Evaluate2(cx, options.ptr, code.as_ptr(), - code.len() as libc::size_t, - rval) { - debug!("error evaluating JS string"); - report_pending_exception(cx, true); - } - } - - if let Some(error) = maybe_take_panic_result() { - panic::resume_unwind(error); - } - } - ) - } - /// Schedule the given `callback` to be invoked after at least `duration` milliseconds have /// passed. pub fn schedule_callback(&self, diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 29c918d28f0..64f932c31f9 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -5,7 +5,7 @@ use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId}; use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; -use dom::bindings::error::ErrorInfo; +use dom::bindings::error::{ErrorInfo, report_pending_exception}; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, MutNullableHeap, Root}; use dom::bindings::reflector::Reflectable; @@ -19,16 +19,21 @@ use dom::eventtarget::EventTarget; use dom::window::Window; use dom::workerglobalscope::WorkerGlobalScope; use ipc_channel::ipc::IpcSender; -use js::jsapi::{HandleValue, JS_GetContext, JS_GetObjectRuntime, JSContext}; +use js::jsapi::{HandleValue, Evaluate2, JS_GetContext, JS_GetObjectRuntime}; +use js::jsapi::{JSAutoCompartment, JSContext, MutableHandleValue}; +use js::rust::CompileOptionsWrapper; +use libc; use msg::constellation_msg::PipelineId; use net_traits::{CoreResourceThread, ResourceThreads, IpcSend}; use profile_traits::{mem, time}; -use script_runtime::ScriptChan; +use script_runtime::{ScriptChan, maybe_take_panic_result}; use script_thread::MainThreadScriptChan; use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest}; use std::cell::Cell; use std::collections::HashMap; use std::collections::hash_map::Entry; +use std::ffi::CString; +use std::panic; use time::{Timespec, get_time}; use url::Url; @@ -282,6 +287,53 @@ impl GlobalScope { } unreachable!(); } + + /// Evaluate JS code on this global scope. + pub fn evaluate_js_on_global_with_result( + &self, code: &str, rval: MutableHandleValue) { + self.evaluate_script_on_global_with_result(code, "", rval) + } + + /// Evaluate a JS script on this global scope. + #[allow(unsafe_code)] + pub fn evaluate_script_on_global_with_result( + &self, code: &str, filename: &str, rval: MutableHandleValue) { + let metadata = time::TimerMetadata { + url: if filename.is_empty() { + self.get_url().as_str().into() + } else { + filename.into() + }, + iframe: time::TimerMetadataFrameType::RootWindow, + incremental: time::TimerMetadataReflowType::FirstReflow, + }; + time::profile( + time::ProfilerCategory::ScriptEvaluate, + Some(metadata), + self.time_profiler_chan().clone(), + || { + let cx = self.get_cx(); + let globalhandle = self.reflector().get_jsobject(); + let code: Vec = code.encode_utf16().collect(); + let filename = CString::new(filename).unwrap(); + + let _ac = JSAutoCompartment::new(cx, globalhandle.get()); + let options = CompileOptionsWrapper::new(cx, filename.as_ptr(), 1); + unsafe { + if !Evaluate2(cx, options.ptr, code.as_ptr(), + code.len() as libc::size_t, + rval) { + debug!("error evaluating JS string"); + report_pending_exception(cx, true); + } + } + + if let Some(error) = maybe_take_panic_result() { + panic::resume_unwind(error); + } + } + ) + } } fn timestamp_in_ms(time: Timespec) -> u64 { diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 2132d41edf7..1bee0c9c32f 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -10,7 +10,6 @@ use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods; use dom::bindings::codegen::Bindings::HTMLScriptElementBinding; use dom::bindings::codegen::Bindings::HTMLScriptElementBinding::HTMLScriptElementMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; -use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, Root}; use dom::bindings::js::RootedReference; @@ -21,6 +20,7 @@ use dom::document::Document; use dom::element::{AttributeMutation, Element, ElementCreator}; use dom::event::{Event, EventBubbles, EventCancelable}; use dom::eventdispatcher::EventStatus; +use dom::globalscope::GlobalScope; use dom::htmlelement::HTMLElement; use dom::node::{ChildrenMutation, CloneChildrenFlag, Node}; use dom::node::{document_from_node, window_from_node}; @@ -504,7 +504,7 @@ impl HTMLScriptElement { // Step 5.a.2. let window = window_from_node(self); rooted!(in(window.get_cx()) let mut rval = UndefinedValue()); - GlobalRef::Window(&window).evaluate_script_on_global_with_result( + window.upcast::().evaluate_script_on_global_with_result( &script.text, script.url.as_str(), rval.handle_mut()); // Step 6. diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 582ebfdb153..0669808c7ac 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -1767,7 +1767,7 @@ impl ScriptThread { unsafe { let _ac = JSAutoCompartment::new(self.get_cx(), window.reflector().get_jsobject().get()); rooted!(in(self.get_cx()) let mut jsval = UndefinedValue()); - GlobalRef::Window(&window).evaluate_js_on_global_with_result( + window.upcast::().evaluate_js_on_global_with_result( &script_source, jsval.handle_mut()); let strval = DOMString::from_jsval(self.get_cx(), jsval.handle(), diff --git a/components/script/timers.rs b/components/script/timers.rs index 601755c6fc4..7b326f6b164 100644 --- a/components/script/timers.rs +++ b/components/script/timers.rs @@ -489,11 +489,11 @@ impl JsTimerTask { // step 4.2 match *&self.callback { InternalTimerCallback::StringTimerCallback(ref code_str) => { - let global = this.global(); - let cx = global.r().get_cx(); + let global = this.global_scope(); + let cx = global.get_cx(); rooted!(in(cx) let mut rval = UndefinedValue()); - global.r().evaluate_js_on_global_with_result( + global.evaluate_js_on_global_with_result( code_str, rval.handle_mut()); }, InternalTimerCallback::FunctionTimerCallback(ref function, ref arguments) => { diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs index 95e300b1527..bcb0186d8e6 100644 --- a/components/script/webdriver_handlers.rs +++ b/components/script/webdriver_handlers.rs @@ -13,7 +13,6 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods; use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, StringificationBehavior}; -use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; use dom::bindings::js::Root; use dom::bindings::str::DOMString; @@ -93,7 +92,7 @@ pub fn handle_execute_script(context: &BrowsingContext, let result = unsafe { let cx = window.get_cx(); rooted!(in(cx) let mut rval = UndefinedValue()); - GlobalRef::Window(&window).evaluate_js_on_global_with_result( + window.upcast::().evaluate_js_on_global_with_result( &eval, rval.handle_mut()); jsval_to_webdriver(cx, rval.handle()) }; @@ -113,7 +112,7 @@ pub fn handle_execute_async_script(context: &BrowsingContext, let cx = window.get_cx(); window.set_webdriver_script_chan(Some(reply)); rooted!(in(cx) let mut rval = UndefinedValue()); - GlobalRef::Window(&window).evaluate_js_on_global_with_result( + window.upcast::().evaluate_js_on_global_with_result( &eval, rval.handle_mut()); }