diff options
Diffstat (limited to 'components/script/dom/bindings')
-rw-r--r-- | components/script/dom/bindings/callback.rs | 6 | ||||
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 105 | ||||
-rw-r--r-- | components/script/dom/bindings/codegen/Configuration.py | 11 | ||||
-rw-r--r-- | components/script/dom/bindings/codegen/parser/WebIDL.py | 3 | ||||
-rw-r--r-- | components/script/dom/bindings/codegen/parser/inline.patch | 12 | ||||
-rwxr-xr-x | components/script/dom/bindings/codegen/parser/update.sh | 1 | ||||
-rw-r--r-- | components/script/dom/bindings/error.rs | 10 | ||||
-rw-r--r-- | components/script/dom/bindings/global.rs | 398 | ||||
-rw-r--r-- | components/script/dom/bindings/iterable.rs | 7 | ||||
-rw-r--r-- | components/script/dom/bindings/mod.rs | 8 | ||||
-rw-r--r-- | components/script/dom/bindings/reflector.rs | 23 | ||||
-rw-r--r-- | components/script/dom/bindings/structuredclone.rs | 6 |
12 files changed, 111 insertions, 479 deletions
diff --git a/components/script/dom/bindings/callback.rs b/components/script/dom/bindings/callback.rs index 7e6bb3534fb..709dab31049 100644 --- a/components/script/dom/bindings/callback.rs +++ b/components/script/dom/bindings/callback.rs @@ -5,8 +5,8 @@ //! Base classes to work with IDL callbacks. use dom::bindings::error::{Error, Fallible, report_pending_exception}; -use dom::bindings::global::global_root_from_object; use dom::bindings::reflector::Reflectable; +use dom::globalscope::GlobalScope; use js::jsapi::{Heap, MutableHandleObject, RootedObject}; use js::jsapi::{IsCallable, JSContext, JSObject, JS_WrapObject}; use js::jsapi::{JSCompartment, JS_EnterCompartment, JS_LeaveCompartment}; @@ -165,8 +165,8 @@ impl<'a> CallSetup<'a> { callback: &T, handling: ExceptionHandling) -> CallSetup<'a> { - let global = unsafe { global_root_from_object(callback.callback()) }; - let cx = global.r().get_cx(); + let global = unsafe { GlobalScope::from_object(callback.callback()) }; + let cx = global.get_cx(); exception_compartment.ptr = unsafe { GetGlobalForObjectCrossCompartment(callback.callback()) diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 4ea45ef9ded..24826ced714 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -817,16 +817,16 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, { // Scope for our JSAutoCompartment. rooted!(in(cx) let globalObj = CurrentGlobalOrNull(cx)); - let promiseGlobal = global_root_from_object_maybe_wrapped(globalObj.handle().get()); + let promiseGlobal = GlobalScope::from_object_maybe_wrapped(globalObj.handle().get()); rooted!(in(cx) let mut valueToResolve = $${val}.get()); if !JS_WrapValue(cx, valueToResolve.handle_mut()) { $*{exceptionCode} } - match Promise::Resolve(promiseGlobal.r(), cx, valueToResolve.handle()) { + match Promise::Resolve(&promiseGlobal, cx, valueToResolve.handle()) { Ok(value) => value, Err(error) => { - throw_dom_exception(cx, promiseGlobal.r(), error); + throw_dom_exception(cx, &promiseGlobal, error); $*{exceptionCode} } } @@ -1927,10 +1927,12 @@ class CGImports(CGWrapper): if t in dictionaries or t in enums: continue if t.isInterface() or t.isNamespace(): - descriptor = descriptorProvider.getDescriptor(getIdentifier(t).name) - extras += [descriptor.path] - if descriptor.interface.parent: - parentName = getIdentifier(descriptor.interface.parent).name + name = getIdentifier(t).name + descriptor = descriptorProvider.getDescriptor(name) + if name != 'GlobalScope': + extras += [descriptor.path] + parentName = descriptor.getParentName() + if parentName: descriptor = descriptorProvider.getDescriptor(parentName) extras += [descriptor.path, descriptor.bindingPath] elif t.isType() and t.isMozMap(): @@ -2523,7 +2525,8 @@ class CGWrapMethod(CGAbstractMethod): def __init__(self, descriptor): assert not descriptor.interface.isCallback() assert not descriptor.isGlobal() - args = [Argument('*mut JSContext', 'cx'), Argument('GlobalRef', 'scope'), + args = [Argument('*mut JSContext', 'cx'), + Argument('&GlobalScope', 'scope'), Argument("Box<%s>" % descriptor.concreteType, 'object')] retval = 'Root<%s>' % descriptor.concreteType CGAbstractMethod.__init__(self, descriptor, 'Wrap', retval, args, @@ -2754,7 +2757,7 @@ assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null()); getPrototypeProto = "prototype_proto.set(JS_GetObjectPrototype(cx, global))" else: getPrototypeProto = ("%s::GetProtoObject(cx, global, prototype_proto.handle_mut())" % - toBindingNamespace(self.descriptor.prototypeChain[-2])) + toBindingNamespace(self.descriptor.getParentName())) code = [CGGeneric("""\ rooted!(in(cx) let mut prototype_proto = ptr::null_mut()); @@ -2808,8 +2811,9 @@ assert!((*cache)[PrototypeList::ID::%(id)s as usize].is_null()); properties["length"] = methodLength(self.descriptor.interface.ctor()) else: properties["length"] = 0 - if self.descriptor.interface.parent: - parentName = toBindingNamespace(self.descriptor.getParentName()) + parentName = self.descriptor.getParentName() + if parentName: + parentName = toBindingNamespace(parentName) code.append(CGGeneric(""" rooted!(in(cx) let mut interface_proto = ptr::null_mut()); %s::GetConstructorObject(cx, global, interface_proto.handle_mut());""" % parentName)) @@ -3164,16 +3168,15 @@ class CGCallGenerator(CGThing): if isFallible: if static: - glob = "" + glob = "&global" else: - glob = " let global = global_root_from_reflector(this);\n" + glob = "&this.global()" self.cgRoot.append(CGGeneric( "let result = match result {\n" " Ok(result) => result,\n" " Err(e) => {\n" - "%s" - " throw_dom_exception(cx, global.r(), e);\n" + " throw_dom_exception(cx, %s, e);\n" " return%s;\n" " },\n" "};" % (glob, errorResult))) @@ -3383,7 +3386,7 @@ class CGAbstractStaticBindingMethod(CGAbstractMethod): def definition_body(self): preamble = CGGeneric("""\ -let global = global_root_from_object(JS_CALLEE(cx, vp).to_object()); +let global = GlobalScope::from_object(JS_CALLEE(cx, vp).to_object()); """) return CGList([preamble, self.generate_code()]) @@ -3435,7 +3438,7 @@ class CGStaticMethod(CGAbstractStaticBindingMethod): nativeName = CGSpecializedMethod.makeNativeName(self.descriptor, self.method) setupArgs = CGGeneric("let args = CallArgs::from_vp(vp, argc);\n") - call = CGMethodCall(["global.r()"], nativeName, True, self.descriptor, self.method) + call = CGMethodCall(["&global"], nativeName, True, self.descriptor, self.method) return CGList([setupArgs, call]) @@ -3489,7 +3492,7 @@ class CGStaticGetter(CGAbstractStaticBindingMethod): nativeName = CGSpecializedGetter.makeNativeName(self.descriptor, self.attr) setupArgs = CGGeneric("let args = CallArgs::from_vp(vp, argc);\n") - call = CGGetterCall(["global.r()"], self.attr.type, nativeName, self.descriptor, + call = CGGetterCall(["&global"], self.attr.type, nativeName, self.descriptor, self.attr) return CGList([setupArgs, call]) @@ -3542,7 +3545,7 @@ class CGStaticSetter(CGAbstractStaticBindingMethod): " throw_type_error(cx, \"Not enough arguments to %s setter.\");\n" " return false;\n" "}" % self.attr.identifier.name) - call = CGSetterCall(["global.r()"], self.attr.type, nativeName, self.descriptor, + call = CGSetterCall(["&global"], self.attr.type, nativeName, self.descriptor, self.attr) return CGList([checkForArg, call]) @@ -5249,12 +5252,12 @@ class CGClassConstructHook(CGAbstractExternMethod): def definition_body(self): preamble = CGGeneric("""\ -let global = global_root_from_object(JS_CALLEE(cx, vp).to_object()); +let global = GlobalScope::from_object(JS_CALLEE(cx, vp).to_object()); let args = CallArgs::from_vp(vp, argc); """) name = self.constructor.identifier.name nativeName = MakeNativeName(self.descriptor.binaryNameFor(name)) - callGenerator = CGMethodCall(["global.r()"], nativeName, True, + callGenerator = CGMethodCall(["&global"], nativeName, True, self.descriptor, self.constructor) return CGList([preamble, callGenerator]) @@ -5496,10 +5499,6 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries 'dom::bindings::codegen::InterfaceObjectMap', 'dom::bindings::constant::ConstantSpec', 'dom::bindings::constant::ConstantVal', - 'dom::bindings::global::GlobalRef', - 'dom::bindings::global::global_root_from_object', - 'dom::bindings::global::global_root_from_object_maybe_wrapped', - 'dom::bindings::global::global_root_from_reflector', 'dom::bindings::interface::ConstructorClassHook', 'dom::bindings::interface::InterfaceConstructorBehavior', 'dom::bindings::interface::NonCallbackInterfaceObjectClass', @@ -5593,6 +5592,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries 'dom::bindings::weakref::WeakBox', 'dom::bindings::weakref::WeakReferenceable', 'dom::browsingcontext::BrowsingContext', + 'dom::globalscope::GlobalScope', 'mem::heap_size_of_raw_self_and_children', 'libc', 'util::prefs::PREFS', @@ -5744,33 +5744,38 @@ class CGDescriptor(CGThing): cgThings.append(CGGeneric(str(properties))) - if not descriptor.interface.isCallback() and not descriptor.interface.isNamespace(): - cgThings.append(CGGetProtoObjectMethod(descriptor)) - reexports.append('GetProtoObject') - cgThings.append(CGPrototypeJSClass(descriptor)) - if descriptor.interface.hasInterfaceObject(): - if descriptor.interface.ctor(): - cgThings.append(CGClassConstructHook(descriptor)) - for ctor in descriptor.interface.namedConstructors: - cgThings.append(CGClassConstructHook(descriptor, ctor)) - if not descriptor.interface.isCallback(): - cgThings.append(CGInterfaceObjectJSClass(descriptor)) - if descriptor.shouldHaveGetConstructorObjectMethod(): - cgThings.append(CGGetConstructorObjectMethod(descriptor)) - reexports.append('GetConstructorObject') - if descriptor.register: - cgThings.append(CGDefineDOMInterfaceMethod(descriptor)) - reexports.append('DefineDOMInterface') - cgThings.append(CGConstructorEnabled(descriptor)) - cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties, haveUnscopables)) + if not descriptor.interface.getExtendedAttribute("Inline"): + if not descriptor.interface.isCallback() and not descriptor.interface.isNamespace(): + cgThings.append(CGGetProtoObjectMethod(descriptor)) + reexports.append('GetProtoObject') + cgThings.append(CGPrototypeJSClass(descriptor)) + if descriptor.interface.hasInterfaceObject(): + if descriptor.interface.ctor(): + cgThings.append(CGClassConstructHook(descriptor)) + for ctor in descriptor.interface.namedConstructors: + cgThings.append(CGClassConstructHook(descriptor, ctor)) + if not descriptor.interface.isCallback(): + cgThings.append(CGInterfaceObjectJSClass(descriptor)) + if descriptor.shouldHaveGetConstructorObjectMethod(): + cgThings.append(CGGetConstructorObjectMethod(descriptor)) + reexports.append('GetConstructorObject') + if descriptor.register: + cgThings.append(CGDefineDOMInterfaceMethod(descriptor)) + reexports.append('DefineDOMInterface') + cgThings.append(CGConstructorEnabled(descriptor)) + cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties, haveUnscopables)) cgThings = generate_imports(config, CGList(cgThings, '\n'), [descriptor]) cgThings = CGWrapper(CGNamespace(toBindingNamespace(descriptor.name), cgThings, public=True), post='\n') - reexports = ', '.join(map(lambda name: reexportedName(name), reexports)) - self.cgRoot = CGList([CGGeneric('pub use self::%s::{%s};' % (toBindingNamespace(descriptor.name), reexports)), - cgThings], '\n') + + if reexports: + reexports = ', '.join(map(lambda name: reexportedName(name), reexports)) + cgThings = CGList([CGGeneric('pub use self::%s::{%s};' % (toBindingNamespace(descriptor.name), reexports)), + cgThings], '\n') + + self.cgRoot = cgThings def define(self): return self.cgRoot.define() @@ -6799,7 +6804,7 @@ class GlobalGenRoots(): globals_ = CGWrapper(CGIndenter(global_flags), pre="bitflags! {\n", post="\n}") pairs = [] - for d in config.getDescriptors(hasInterfaceObject=True): + for d in config.getDescriptors(hasInterfaceObject=True, isInline=False): binding = toBindingNamespace(d.name) pairs.append((d.name, binding, binding)) for ctor in d.interface.namedConstructors: @@ -6927,7 +6932,7 @@ class GlobalGenRoots(): allprotos.append(CGGeneric("\n")) if downcast: - hierarchy[descriptor.getParentName()].append(name) + hierarchy[descriptor.interface.parent.identifier.name].append(name) typeIdCode = [] topTypeVariants = [ @@ -6959,7 +6964,7 @@ impl Clone for TopTypeId { for base, derived in hierarchy.iteritems(): variants = [] - if not config.getInterface(base).getExtendedAttribute("Abstract"): + if config.getDescriptor(base).concrete: variants.append(CGGeneric(base)) variants += [CGGeneric(type_id_variant(derivedName)) for derivedName in derived] derives = "Clone, Copy, Debug, PartialEq" diff --git a/components/script/dom/bindings/codegen/Configuration.py b/components/script/dom/bindings/codegen/Configuration.py index 9a1120769c8..f2f64e9bee0 100644 --- a/components/script/dom/bindings/codegen/Configuration.py +++ b/components/script/dom/bindings/codegen/Configuration.py @@ -88,6 +88,8 @@ class Configuration: getter = lambda x: x.interface.isJSImplemented() elif key == 'isGlobal': getter = lambda x: x.isGlobal() + elif key == 'isInline': + getter = lambda x: x.interface.getExtendedAttribute('Inline') is not None elif key == 'isExposedConditionally': getter = lambda x: x.interface.isExposedConditionally() elif key == 'isIteratorInterface': @@ -234,6 +236,7 @@ class Descriptor(DescriptorProvider): self.concrete = (not self.interface.isCallback() and not self.interface.isNamespace() and not self.interface.getExtendedAttribute("Abstract") and + not self.interface.getExtendedAttribute("Inline") and not spiderMonkeyInterface) self.hasUnforgeableMembers = (self.concrete and any(MemberIsUnforgeable(m, self) for m in @@ -383,8 +386,12 @@ class Descriptor(DescriptorProvider): return attrs def getParentName(self): - assert self.interface.parent is not None - return self.interface.parent.identifier.name + parent = self.interface.parent + while parent: + if not parent.getExtendedAttribute("Inline"): + return parent.identifier.name + parent = parent.parent + return None def hasDescendants(self): return (self.interface.getUserData("hasConcreteDescendant", False) or diff --git a/components/script/dom/bindings/codegen/parser/WebIDL.py b/components/script/dom/bindings/codegen/parser/WebIDL.py index 2894bbeb82e..dc9fa036141 100644 --- a/components/script/dom/bindings/codegen/parser/WebIDL.py +++ b/components/script/dom/bindings/codegen/parser/WebIDL.py @@ -1695,7 +1695,8 @@ class IDLInterface(IDLInterfaceOrNamespace): identifier == "ProbablyShortLivingObject" or identifier == "LegacyUnenumerableNamedProperties" or identifier == "NonOrdinaryGetPrototypeOf" or - identifier == "Abstract"): + identifier == "Abstract" or + identifier == "Inline"): # Known extended attributes that do not take values if not attr.noArguments(): raise WebIDLError("[%s] must take no arguments" % identifier, diff --git a/components/script/dom/bindings/codegen/parser/inline.patch b/components/script/dom/bindings/codegen/parser/inline.patch new file mode 100644 index 00000000000..5d1056d2b58 --- /dev/null +++ b/components/script/dom/bindings/codegen/parser/inline.patch @@ -0,0 +1,12 @@ +--- WebIDL.py ++++ WebIDL.py +@@ -1695,7 +1695,8 @@ class IDLInterface(IDLInterfaceOrNamespace): + identifier == "ProbablyShortLivingObject" or + identifier == "LegacyUnenumerableNamedProperties" or + identifier == "NonOrdinaryGetPrototypeOf" or +- identifier == "Abstract"): ++ identifier == "Abstract" or ++ identifier == "Inline"): + # Known extended attributes that do not take values + if not attr.noArguments(): + raise WebIDLError("[%s] must take no arguments" % identifier,
\ No newline at end of file diff --git a/components/script/dom/bindings/codegen/parser/update.sh b/components/script/dom/bindings/codegen/parser/update.sh index 6bf56cead30..213aba6df89 100755 --- a/components/script/dom/bindings/codegen/parser/update.sh +++ b/components/script/dom/bindings/codegen/parser/update.sh @@ -4,6 +4,7 @@ patch < debug.patch patch < pref-main-thread.patch patch < callback-location.patch patch < union-typedef.patch +patch < inline.patch wget https://hg.mozilla.org/mozilla-central/archive/tip.tar.gz/dom/bindings/parser/tests/ -O tests.tar.gz rm -r tests diff --git a/components/script/dom/bindings/error.rs b/components/script/dom/bindings/error.rs index 1c0d49c4976..96ae220ce98 100644 --- a/components/script/dom/bindings/error.rs +++ b/components/script/dom/bindings/error.rs @@ -8,9 +8,9 @@ use dom::bindings::codegen::Bindings::DOMExceptionBinding::DOMExceptionMethods; use dom::bindings::codegen::PrototypeList::proto_id_to_name; use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, ToJSValConvertible}; use dom::bindings::conversions::root_from_object; -use dom::bindings::global::{GlobalRef, global_root_from_context}; use dom::bindings::str::USVString; use dom::domexception::{DOMErrorName, DOMException}; +use dom::globalscope::GlobalScope; use js::error::{throw_range_error, throw_type_error}; use js::jsapi::HandleObject; use js::jsapi::JSContext; @@ -87,7 +87,7 @@ pub type Fallible<T> = Result<T, Error>; pub type ErrorResult = Fallible<()>; /// Set a pending exception for the given `result` on `cx`. -pub unsafe fn throw_dom_exception(cx: *mut JSContext, global: GlobalRef, result: Error) { +pub unsafe fn throw_dom_exception(cx: *mut JSContext, global: &GlobalScope, result: Error) { let code = match result { Error::IndexSize => DOMErrorName::IndexSizeError, Error::NotFound => DOMErrorName::NotFoundError, @@ -245,8 +245,8 @@ pub unsafe fn report_pending_exception(cx: *mut JSContext, dispatch_event: bool) error_info.message); if dispatch_event { - let global = global_root_from_context(cx); - global.r().report_an_error(error_info, value.handle()); + GlobalScope::from_context(cx) + .report_an_error(error_info, value.handle()); } } } @@ -270,7 +270,7 @@ pub unsafe fn throw_invalid_this(cx: *mut JSContext, proto_id: u16) { impl Error { /// Convert this error value to a JS value, consuming it in the process. - pub unsafe fn to_jsval(self, cx: *mut JSContext, global: GlobalRef, rval: MutableHandleValue) { + pub unsafe fn to_jsval(self, cx: *mut JSContext, global: &GlobalScope, rval: MutableHandleValue) { assert!(!JS_IsExceptionPending(cx)); throw_dom_exception(cx, global, self); assert!(JS_IsExceptionPending(cx)); diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs deleted file mode 100644 index e0341ceeb68..00000000000 --- a/components/script/dom/bindings/global.rs +++ /dev/null @@ -1,398 +0,0 @@ -/* 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/. */ - -//! Abstractions for global scopes. -//! -//! This module contains smart pointers to global scopes, to simplify writing -//! code that works in workers as well as window scopes. - -use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId}; -use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; -use dom::bindings::conversions::root_from_object; -use dom::bindings::error::{ErrorInfo, report_pending_exception}; -use dom::bindings::js::Root; -use dom::bindings::reflector::{Reflectable, Reflector}; -use dom::console::TimerSet; -use dom::window; -use dom::workerglobalscope::WorkerGlobalScope; -use ipc_channel::ipc::IpcSender; -use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL}; -use js::glue::{IsWrapper, UnwrapObject}; -use js::jsapi::{CurrentGlobalOrNull, Evaluate2, GetGlobalForObjectCrossCompartment}; -use js::jsapi::{HandleValue, JS_GetClass, JSAutoCompartment, JSContext}; -use js::jsapi::{JSObject, MutableHandleValue}; -use js::rust::CompileOptionsWrapper; -use libc; -use msg::constellation_msg::PipelineId; -use net_traits::{CoreResourceThread, IpcSend, ResourceThreads}; -use profile_traits::{mem, time}; -use script_runtime::{CommonScriptMsg, EnqueuedPromiseCallback, ScriptChan}; -use script_runtime::{ScriptPort, maybe_take_panic_result}; -use script_thread::{MainThreadScriptChan, RunnableWrapper, ScriptThread}; -use script_traits::{MsDuration, ScriptMsg as ConstellationMsg, TimerEventRequest}; -use std::ffi::CString; -use std::panic; -use task_source::file_reading::FileReadingTaskSource; -use timers::{OneshotTimerCallback, OneshotTimerHandle}; -use url::Url; - -/// A freely-copyable reference to a rooted global object. -#[derive(Copy, Clone)] -pub enum GlobalRef<'a> { - /// A reference to a `Window` object. - Window(&'a window::Window), - /// A reference to a `WorkerGlobalScope` object. - Worker(&'a WorkerGlobalScope), -} - -/// A stack-based rooted reference to a global object. -pub enum GlobalRoot { - /// A root for a `Window` object. - Window(Root<window::Window>), - /// A root for a `WorkerGlobalScope` object. - Worker(Root<WorkerGlobalScope>), -} - -impl<'a> GlobalRef<'a> { - /// Get the `JSContext` for the `JSRuntime` associated with the thread - /// this global object is on. - pub fn get_cx(&self) -> *mut JSContext { - match *self { - GlobalRef::Window(ref window) => window.get_cx(), - GlobalRef::Worker(ref worker) => worker.get_cx(), - } - } - - /// Extract a `Window`, causing thread failure if the global object is not - /// a `Window`. - pub fn as_window(&self) -> &window::Window { - match *self { - GlobalRef::Window(window) => window, - GlobalRef::Worker(_) => panic!("expected a Window scope"), - } - } - - /// Get the `PipelineId` for this global scope. - pub fn pipeline_id(&self) -> PipelineId { - match *self { - GlobalRef::Window(window) => window.pipeline_id(), - GlobalRef::Worker(worker) => worker.pipeline_id(), - } - } - - /// Get a `mem::ProfilerChan` to send messages to the memory profiler thread. - pub fn mem_profiler_chan(&self) -> &mem::ProfilerChan { - match *self { - GlobalRef::Window(window) => window.mem_profiler_chan(), - GlobalRef::Worker(worker) => worker.mem_profiler_chan(), - } - } - - /// Get a `time::ProfilerChan` to send messages to the time profiler thread. - pub fn time_profiler_chan(&self) -> &time::ProfilerChan { - match *self { - GlobalRef::Window(window) => window.time_profiler_chan(), - GlobalRef::Worker(worker) => worker.time_profiler_chan(), - } - } - - /// Get a `IpcSender` to send messages to the constellation when available. - pub fn constellation_chan(&self) -> &IpcSender<ConstellationMsg> { - match *self { - GlobalRef::Window(window) => window.constellation_chan(), - GlobalRef::Worker(worker) => worker.constellation_chan(), - } - } - - /// Get the scheduler channel to request timer events. - pub fn scheduler_chan(&self) -> &IpcSender<TimerEventRequest> { - match *self { - GlobalRef::Window(window) => window.scheduler_chan(), - GlobalRef::Worker(worker) => worker.scheduler_chan(), - } - } - - /// Get an `IpcSender<ScriptToDevtoolsControlMsg>` to send messages to Devtools - /// thread when available. - pub fn devtools_chan(&self) -> Option<IpcSender<ScriptToDevtoolsControlMsg>> { - match *self { - GlobalRef::Window(window) => window.devtools_chan(), - GlobalRef::Worker(worker) => worker.devtools_chan(), - } - } - - /// Get the `ResourceThreads` for this global scope. - pub fn resource_threads(&self) -> ResourceThreads { - match *self { - GlobalRef::Window(ref window) => window.resource_threads().clone(), - GlobalRef::Worker(ref worker) => worker.resource_threads().clone(), - } - } - - /// Get the `CoreResourceThread` for this global scope - pub fn core_resource_thread(&self) -> CoreResourceThread { - self.resource_threads().sender() - } - - /// Get next worker id. - pub fn get_next_worker_id(&self) -> WorkerId { - match *self { - GlobalRef::Window(ref window) => window.get_next_worker_id(), - GlobalRef::Worker(ref worker) => worker.get_next_worker_id(), - } - } - - /// Get the URL for this global scope. - pub fn get_url(&self) -> Url { - match *self { - GlobalRef::Window(ref window) => window.get_url(), - GlobalRef::Worker(ref worker) => worker.get_url().clone(), - } - } - - /// Get the [base url](https://html.spec.whatwg.org/multipage/#api-base-url) - /// for this global scope. - pub fn api_base_url(&self) -> Url { - match *self { - // https://html.spec.whatwg.org/multipage/#script-settings-for-browsing-contexts:api-base-url - GlobalRef::Window(ref window) => window.Document().base_url(), - // https://html.spec.whatwg.org/multipage/#script-settings-for-workers:api-base-url - GlobalRef::Worker(ref worker) => worker.get_url().clone(), - } - } - - /// `ScriptChan` used to send messages to the event loop of this global's - /// thread. - pub fn script_chan(&self) -> Box<ScriptChan + Send> { - match *self { - GlobalRef::Window(ref window) => - MainThreadScriptChan(window.main_thread_script_chan().clone()).clone(), - GlobalRef::Worker(ref worker) => worker.script_chan(), - } - } - - /// `ScriptChan` used to send messages to the event loop of this global's - /// thread. - pub fn networking_task_source(&self) -> Box<ScriptChan + Send> { - match *self { - GlobalRef::Window(ref window) => window.networking_task_source(), - GlobalRef::Worker(ref worker) => worker.script_chan(), - } - } - - /// `ScriptChan` used to send messages to the event loop of this global's - /// thread. - pub fn file_reading_task_source(&self) -> FileReadingTaskSource { - match *self { - GlobalRef::Window(ref window) => window.file_reading_task_source(), - GlobalRef::Worker(ref worker) => worker.file_reading_task_source(), - } - } - - /// Create a new sender/receiver pair that can be used to implement an on-demand - /// event loop. Used for implementing web APIs that require blocking semantics - /// without resorting to nested event loops. - pub fn new_script_pair(&self) -> (Box<ScriptChan + Send>, Box<ScriptPort + Send>) { - match *self { - GlobalRef::Window(ref window) => window.new_script_pair(), - GlobalRef::Worker(ref worker) => worker.new_script_pair(), - } - } - - /// Process a single event as if it were the next event in the thread queue for - /// this global. - pub fn process_event(&self, msg: CommonScriptMsg) { - match *self { - GlobalRef::Window(_) => ScriptThread::process_event(msg), - GlobalRef::Worker(ref worker) => worker.process_event(msg), - } - } - - /// 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.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); - } - } - ) - } - - /// Set the `bool` value to indicate whether developer tools has requested - /// updates from the global - pub fn set_devtools_wants_updates(&self, send_updates: bool) { - match *self { - GlobalRef::Window(window) => window.set_devtools_wants_updates(send_updates), - GlobalRef::Worker(worker) => worker.set_devtools_wants_updates(send_updates), - } - } - - /// Schedule the given `callback` to be invoked after at least `duration` milliseconds have - /// passed. - pub fn schedule_callback(&self, - callback: OneshotTimerCallback, - duration: MsDuration) - -> OneshotTimerHandle { - match *self { - GlobalRef::Window(window) => window.schedule_callback(callback, duration), - GlobalRef::Worker(worker) => worker.schedule_callback(callback, duration), - } - } - - /// Unschedule a previously-scheduled callback. - pub fn unschedule_callback(&self, handle: OneshotTimerHandle) { - match *self { - GlobalRef::Window(window) => window.unschedule_callback(handle), - GlobalRef::Worker(worker) => worker.unschedule_callback(handle), - } - } - - /// Returns the global's timers for the Console API. - pub fn console_timers(&self) -> &TimerSet { - match *self { - GlobalRef::Window(ref window) => window.console_timers(), - GlobalRef::Worker(ref worker) => worker.console_timers(), - } - } - - /// Returns a wrapper for runnables to ensure they are cancelled if the global - /// is being destroyed. - pub fn get_runnable_wrapper(&self) -> RunnableWrapper { - match *self { - GlobalRef::Window(ref window) => window.get_runnable_wrapper(), - GlobalRef::Worker(ref worker) => worker.get_runnable_wrapper(), - } - } - - /// Enqueue a promise callback for subsequent execution. - pub fn enqueue_promise_job(&self, job: EnqueuedPromiseCallback) { - match *self { - GlobalRef::Window(_) => ScriptThread::enqueue_promise_job(job, *self), - GlobalRef::Worker(ref worker) => worker.enqueue_promise_job(job), - } - } - - /// Start the process of executing the pending promise callbacks. They will be invoked - /// in FIFO order, synchronously, at some point in the future. - pub fn flush_promise_jobs(&self) { - match *self { - GlobalRef::Window(_) => ScriptThread::flush_promise_jobs(*self), - GlobalRef::Worker(ref worker) => worker.flush_promise_jobs(), - } - } - - /// https://html.spec.whatwg.org/multipage/#report-the-error - pub fn report_an_error(&self, error_info: ErrorInfo, value: HandleValue) { - match *self { - GlobalRef::Window(ref window) => window.report_an_error(error_info, value), - GlobalRef::Worker(ref worker) => worker.report_an_error(error_info, value), - } - } -} - -impl<'a> Reflectable for GlobalRef<'a> { - fn reflector(&self) -> &Reflector { - match *self { - GlobalRef::Window(ref window) => window.reflector(), - GlobalRef::Worker(ref worker) => worker.reflector(), - } - } -} - -impl GlobalRoot { - /// Obtain a safe reference to the global object that cannot outlive the - /// lifetime of this root. - pub fn r(&self) -> GlobalRef { - match *self { - GlobalRoot::Window(ref window) => GlobalRef::Window(window.r()), - GlobalRoot::Worker(ref worker) => GlobalRef::Worker(worker.r()), - } - } -} - -/// Returns the global object of the realm that the given DOM object's reflector was created in. -pub fn global_root_from_reflector<T: Reflectable>(reflector: &T) -> GlobalRoot { - unsafe { global_root_from_object(*reflector.reflector().get_jsobject()) } -} - -/// Returns the Rust global object from a JS global object. -#[allow(unrooted_must_root)] -unsafe fn global_root_from_global(global: *mut JSObject) -> GlobalRoot { - assert!(!global.is_null()); - let clasp = JS_GetClass(global); - assert!(((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)) != 0); - match root_from_object(global) { - Ok(window) => return GlobalRoot::Window(window), - Err(_) => (), - } - - match root_from_object(global) { - Ok(worker) => return GlobalRoot::Worker(worker), - Err(_) => (), - } - - panic!("found DOM global that doesn't unwrap to Window or WorkerGlobalScope") -} - -/// Returns the global object of the realm that the given JS object was created in. -#[allow(unrooted_must_root)] -pub unsafe fn global_root_from_object(obj: *mut JSObject) -> GlobalRoot { - assert!(!obj.is_null()); - let global = GetGlobalForObjectCrossCompartment(obj); - global_root_from_global(global) -} - -/// Returns the global object for the given JSContext -#[allow(unrooted_must_root)] -pub unsafe fn global_root_from_context(cx: *mut JSContext) -> GlobalRoot { - let global = CurrentGlobalOrNull(cx); - global_root_from_global(global) -} - -/// Returns the global object of the realm that the given JS object was created in, -/// after unwrapping any wrappers. -pub unsafe fn global_root_from_object_maybe_wrapped(mut obj: *mut JSObject) -> GlobalRoot { - if IsWrapper(obj) { - obj = UnwrapObject(obj, /* stopAtWindowProxy = */ 0); - assert!(!obj.is_null()); - } - global_root_from_object(obj) -} diff --git a/components/script/dom/bindings/iterable.rs b/components/script/dom/bindings/iterable.rs index 84381b52655..3e6febeeb5d 100644 --- a/components/script/dom/bindings/iterable.rs +++ b/components/script/dom/bindings/iterable.rs @@ -10,10 +10,10 @@ use core::nonzero::NonZero; use dom::bindings::codegen::Bindings::IterableIteratorBinding::IterableKeyAndValueResult; use dom::bindings::codegen::Bindings::IterableIteratorBinding::IterableKeyOrValueResult; use dom::bindings::error::Fallible; -use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, Root}; use dom::bindings::reflector::{Reflector, Reflectable, MutReflectable, reflect_dom_object}; use dom::bindings::trace::JSTraceable; +use dom::globalscope::GlobalScope; use js::conversions::ToJSValConvertible; use js::jsapi::{JSContext, JSObject, MutableHandleValue, MutableHandleObject, HandleValue}; use js::jsval::UndefinedValue; @@ -85,7 +85,7 @@ impl<T: Reflectable + JSTraceable + Iterable> IterableIterator<T> { /// Create a new iterator instance for the provided iterable DOM interface. pub fn new(iterable: &T, type_: IteratorType, - wrap: fn(*mut JSContext, GlobalRef, Box<IterableIterator<T>>) + wrap: fn(*mut JSContext, &GlobalScope, Box<IterableIterator<T>>) -> Root<Self>) -> Root<Self> { let iterator = box IterableIterator { reflector: Reflector::new(), @@ -93,8 +93,7 @@ impl<T: Reflectable + JSTraceable + Iterable> IterableIterator<T> { iterable: JS::from_ref(iterable), index: Cell::new(0), }; - let global = iterable.global(); - reflect_dom_object(iterator, global.r(), wrap) + reflect_dom_object(iterator, &*iterable.global(), wrap) } /// Return the next value from the iterable object. diff --git a/components/script/dom/bindings/mod.rs b/components/script/dom/bindings/mod.rs index 013484a47b9..27504efda7c 100644 --- a/components/script/dom/bindings/mod.rs +++ b/components/script/dom/bindings/mod.rs @@ -43,8 +43,9 @@ //! [`Fallible<T>`](error/type.Fallible.html). //! Methods that use certain WebIDL types like `any` or `object` will get a //! `*mut JSContext` argument prepended to the argument list. Static methods -//! will be passed a [`GlobalRef`](global/enum.GlobalRef.html) for the relevant -//! global. This argument comes before the `*mut JSContext` argument, if any. +//! will be passed a [`&GlobalScope`](../globalscope/struct.GlobalScope.html) +//! for the relevant global. This argument comes before the `*mut JSContext` +//! argument, if any. //! //! Rust reflections of WebIDL operations (methods) //! ----------------------------------------------- @@ -79,7 +80,7 @@ //! //! A WebIDL constructor is turned into a static class method named //! `Constructor`. The arguments of this method will be the arguments of the -//! WebIDL constructor, with a `GlobalRef` for the relevant global prepended. +//! WebIDL constructor, with a `&GlobalScope` for the relevant global prepended. //! The return value of the constructor for MyInterface is exactly the same as //! that of a method returning an instance of MyInterface. Constructors are //! always [allowed to throw](#throwing-exceptions). @@ -133,7 +134,6 @@ pub mod cell; pub mod constant; pub mod conversions; pub mod error; -pub mod global; pub mod guard; pub mod inheritance; pub mod interface; diff --git a/components/script/dom/bindings/reflector.rs b/components/script/dom/bindings/reflector.rs index d5280712a03..737268bf7d0 100644 --- a/components/script/dom/bindings/reflector.rs +++ b/components/script/dom/bindings/reflector.rs @@ -4,19 +4,24 @@ //! The `Reflector` struct. -use dom::bindings::global::{GlobalRef, GlobalRoot, global_root_from_reflector}; +use dom::bindings::conversions::DerivedFrom; use dom::bindings::js::Root; +use dom::globalscope::GlobalScope; use js::jsapi::{HandleObject, JSContext, JSObject}; use std::cell::UnsafeCell; use std::ptr; /// Create the reflector for a new DOM object and yield ownership to the /// reflector. -pub fn reflect_dom_object<T: Reflectable>(obj: Box<T>, - global: GlobalRef, - wrap_fn: fn(*mut JSContext, GlobalRef, Box<T>) -> Root<T>) - -> Root<T> { - wrap_fn(global.get_cx(), global, obj) +pub fn reflect_dom_object<T, U>( + obj: Box<T>, + global: &U, + wrap_fn: fn(*mut JSContext, &GlobalScope, Box<T>) -> Root<T>) + -> Root<T> + where T: Reflectable, U: DerivedFrom<GlobalScope> +{ + let global_scope = global.upcast(); + wrap_fn(global_scope.get_cx(), global_scope, obj) } /// A struct to store a reference to the reflector of a DOM object. @@ -74,9 +79,9 @@ pub trait Reflectable { /// Returns the receiver's reflector. fn reflector(&self) -> &Reflector; - /// Returns the global object of the realm that the Reflectable was created in. - fn global(&self) -> GlobalRoot where Self: Sized { - global_root_from_reflector(self) + /// Returns the global scope of the realm that the Reflectable was created in. + fn global(&self) -> Root<GlobalScope> where Self: Sized { + GlobalScope::from_reflector(self) } } diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index 21963eec172..405d245c4bb 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -6,7 +6,7 @@ //! (https://html.spec.whatwg.org/multipage/#safe-passing-of-structured-data). use dom::bindings::error::{Error, Fallible}; -use dom::bindings::global::GlobalRef; +use dom::globalscope::GlobalScope; use js::jsapi::{HandleValue, MutableHandleValue}; use js::jsapi::{JSContext, JS_ReadStructuredClone, JS_STRUCTURED_CLONE_VERSION}; use js::jsapi::{JS_ClearPendingException, JS_WriteStructuredClone}; @@ -60,7 +60,7 @@ impl StructuredCloneData { /// Reads a structured clone. /// /// Panics if `JS_ReadStructuredClone` fails. - fn read_clone(global: GlobalRef, data: *mut u64, nbytes: size_t, rval: MutableHandleValue) { + fn read_clone(global: &GlobalScope, data: *mut u64, nbytes: size_t, rval: MutableHandleValue) { unsafe { assert!(JS_ReadStructuredClone(global.get_cx(), data, @@ -73,7 +73,7 @@ impl StructuredCloneData { } /// Thunk for the actual `read_clone` method. Resolves proper variant for read_clone. - pub fn read(self, global: GlobalRef, rval: MutableHandleValue) { + pub fn read(self, global: &GlobalScope, rval: MutableHandleValue) { match self { StructuredCloneData::Vector(mut vec_msg) => { let nbytes = vec_msg.len(); |