Move JS evaluation functions to GlobalScope

This commit is contained in:
Anthony Ramine 2016-10-04 01:15:43 +02:00
parent 19108aa330
commit 9c04eb60bd
7 changed files with 67 additions and 71 deletions

View file

@ -41,7 +41,7 @@ pub fn handle_evaluate_js(global: &GlobalRef, eval: String, reply: IpcSender<Eva
let globalhandle = global.reflector().get_jsobject(); let globalhandle = global.reflector().get_jsobject();
let _ac = JSAutoCompartment::new(cx, globalhandle.get()); let _ac = JSAutoCompartment::new(cx, globalhandle.get());
rooted!(in(cx) let mut rval = UndefinedValue()); rooted!(in(cx) let mut rval = UndefinedValue());
global.evaluate_js_on_global_with_result(&eval, rval.handle_mut()); global.as_global_scope().evaluate_js_on_global_with_result(&eval, rval.handle_mut());
if rval.is_undefined() { if rval.is_undefined() {
EvaluateJSReply::VoidValue EvaluateJSReply::VoidValue

View file

@ -8,7 +8,6 @@
//! code that works in workers as well as window scopes. //! code that works in workers as well as window scopes.
use dom::bindings::conversions::root_from_object; use dom::bindings::conversions::root_from_object;
use dom::bindings::error::report_pending_exception;
use dom::bindings::inheritance::Castable; use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root; use dom::bindings::js::Root;
use dom::bindings::reflector::{Reflectable, Reflector}; use dom::bindings::reflector::{Reflectable, Reflector};
@ -17,18 +16,11 @@ use dom::window;
use dom::workerglobalscope::WorkerGlobalScope; use dom::workerglobalscope::WorkerGlobalScope;
use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL}; use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
use js::glue::{IsWrapper, UnwrapObject}; use js::glue::{IsWrapper, UnwrapObject};
use js::jsapi::{CurrentGlobalOrNull, Evaluate2, GetGlobalForObjectCrossCompartment}; use js::jsapi::{CurrentGlobalOrNull, GetGlobalForObjectCrossCompartment};
use js::jsapi::{JSAutoCompartment, JSContext, JSObject}; use js::jsapi::{JSContext, JSObject, JS_GetClass};
use js::jsapi::{JS_GetClass, MutableHandleValue}; use script_runtime::{CommonScriptMsg, EnqueuedPromiseCallback, ScriptChan, ScriptPort};
use js::rust::CompileOptionsWrapper;
use libc;
use profile_traits::time;
use script_runtime::{CommonScriptMsg, EnqueuedPromiseCallback, ScriptChan};
use script_runtime::{ScriptPort, maybe_take_panic_result};
use script_thread::{RunnableWrapper, ScriptThread}; use script_thread::{RunnableWrapper, ScriptThread};
use script_traits::MsDuration; use script_traits::MsDuration;
use std::ffi::CString;
use std::panic;
use task_source::file_reading::FileReadingTaskSource; use task_source::file_reading::FileReadingTaskSource;
use timers::{OneshotTimerCallback, OneshotTimerHandle}; use timers::{OneshotTimerCallback, OneshotTimerHandle};
@ -95,53 +87,6 @@ impl<'a> 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<u16> = 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 /// Schedule the given `callback` to be invoked after at least `duration` milliseconds have
/// passed. /// passed.
pub fn schedule_callback(&self, pub fn schedule_callback(&self,

View file

@ -5,7 +5,7 @@
use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId}; use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId};
use dom::bindings::cell::DOMRefCell; use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; 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::inheritance::Castable;
use dom::bindings::js::{JS, MutNullableHeap, Root}; use dom::bindings::js::{JS, MutNullableHeap, Root};
use dom::bindings::reflector::Reflectable; use dom::bindings::reflector::Reflectable;
@ -19,16 +19,21 @@ use dom::eventtarget::EventTarget;
use dom::window::Window; use dom::window::Window;
use dom::workerglobalscope::WorkerGlobalScope; use dom::workerglobalscope::WorkerGlobalScope;
use ipc_channel::ipc::IpcSender; 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 msg::constellation_msg::PipelineId;
use net_traits::{CoreResourceThread, ResourceThreads, IpcSend}; use net_traits::{CoreResourceThread, ResourceThreads, IpcSend};
use profile_traits::{mem, time}; use profile_traits::{mem, time};
use script_runtime::ScriptChan; use script_runtime::{ScriptChan, maybe_take_panic_result};
use script_thread::MainThreadScriptChan; use script_thread::MainThreadScriptChan;
use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest}; use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest};
use std::cell::Cell; use std::cell::Cell;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use std::ffi::CString;
use std::panic;
use time::{Timespec, get_time}; use time::{Timespec, get_time};
use url::Url; use url::Url;
@ -282,6 +287,53 @@ impl GlobalScope {
} }
unreachable!(); 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<u16> = 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 { fn timestamp_in_ms(time: Timespec) -> u64 {

View file

@ -10,7 +10,6 @@ use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use dom::bindings::codegen::Bindings::HTMLScriptElementBinding; use dom::bindings::codegen::Bindings::HTMLScriptElementBinding;
use dom::bindings::codegen::Bindings::HTMLScriptElementBinding::HTMLScriptElementMethods; use dom::bindings::codegen::Bindings::HTMLScriptElementBinding::HTMLScriptElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::global::GlobalRef;
use dom::bindings::inheritance::Castable; use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, Root}; use dom::bindings::js::{JS, Root};
use dom::bindings::js::RootedReference; use dom::bindings::js::RootedReference;
@ -21,6 +20,7 @@ use dom::document::Document;
use dom::element::{AttributeMutation, Element, ElementCreator}; use dom::element::{AttributeMutation, Element, ElementCreator};
use dom::event::{Event, EventBubbles, EventCancelable}; use dom::event::{Event, EventBubbles, EventCancelable};
use dom::eventdispatcher::EventStatus; use dom::eventdispatcher::EventStatus;
use dom::globalscope::GlobalScope;
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{ChildrenMutation, CloneChildrenFlag, Node}; use dom::node::{ChildrenMutation, CloneChildrenFlag, Node};
use dom::node::{document_from_node, window_from_node}; use dom::node::{document_from_node, window_from_node};
@ -504,7 +504,7 @@ impl HTMLScriptElement {
// Step 5.a.2. // Step 5.a.2.
let window = window_from_node(self); let window = window_from_node(self);
rooted!(in(window.get_cx()) let mut rval = UndefinedValue()); rooted!(in(window.get_cx()) let mut rval = UndefinedValue());
GlobalRef::Window(&window).evaluate_script_on_global_with_result( window.upcast::<GlobalScope>().evaluate_script_on_global_with_result(
&script.text, script.url.as_str(), rval.handle_mut()); &script.text, script.url.as_str(), rval.handle_mut());
// Step 6. // Step 6.

View file

@ -1767,7 +1767,7 @@ impl ScriptThread {
unsafe { unsafe {
let _ac = JSAutoCompartment::new(self.get_cx(), window.reflector().get_jsobject().get()); let _ac = JSAutoCompartment::new(self.get_cx(), window.reflector().get_jsobject().get());
rooted!(in(self.get_cx()) let mut jsval = UndefinedValue()); rooted!(in(self.get_cx()) let mut jsval = UndefinedValue());
GlobalRef::Window(&window).evaluate_js_on_global_with_result( window.upcast::<GlobalScope>().evaluate_js_on_global_with_result(
&script_source, jsval.handle_mut()); &script_source, jsval.handle_mut());
let strval = DOMString::from_jsval(self.get_cx(), let strval = DOMString::from_jsval(self.get_cx(),
jsval.handle(), jsval.handle(),

View file

@ -489,11 +489,11 @@ impl JsTimerTask {
// step 4.2 // step 4.2
match *&self.callback { match *&self.callback {
InternalTimerCallback::StringTimerCallback(ref code_str) => { InternalTimerCallback::StringTimerCallback(ref code_str) => {
let global = this.global(); let global = this.global_scope();
let cx = global.r().get_cx(); let cx = global.get_cx();
rooted!(in(cx) let mut rval = UndefinedValue()); 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()); code_str, rval.handle_mut());
}, },
InternalTimerCallback::FunctionTimerCallback(ref function, ref arguments) => { InternalTimerCallback::FunctionTimerCallback(ref function, ref arguments) => {

View file

@ -13,7 +13,6 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods; use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, StringificationBehavior}; use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, StringificationBehavior};
use dom::bindings::global::GlobalRef;
use dom::bindings::inheritance::Castable; use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root; use dom::bindings::js::Root;
use dom::bindings::str::DOMString; use dom::bindings::str::DOMString;
@ -93,7 +92,7 @@ pub fn handle_execute_script(context: &BrowsingContext,
let result = unsafe { let result = unsafe {
let cx = window.get_cx(); let cx = window.get_cx();
rooted!(in(cx) let mut rval = UndefinedValue()); rooted!(in(cx) let mut rval = UndefinedValue());
GlobalRef::Window(&window).evaluate_js_on_global_with_result( window.upcast::<GlobalScope>().evaluate_js_on_global_with_result(
&eval, rval.handle_mut()); &eval, rval.handle_mut());
jsval_to_webdriver(cx, rval.handle()) jsval_to_webdriver(cx, rval.handle())
}; };
@ -113,7 +112,7 @@ pub fn handle_execute_async_script(context: &BrowsingContext,
let cx = window.get_cx(); let cx = window.get_cx();
window.set_webdriver_script_chan(Some(reply)); window.set_webdriver_script_chan(Some(reply));
rooted!(in(cx) let mut rval = UndefinedValue()); rooted!(in(cx) let mut rval = UndefinedValue());
GlobalRef::Window(&window).evaluate_js_on_global_with_result( window.upcast::<GlobalScope>().evaluate_js_on_global_with_result(
&eval, rval.handle_mut()); &eval, rval.handle_mut());
} }