diff --git a/components/script/dom/bindings/proxyhandler.rs b/components/script/dom/bindings/proxyhandler.rs index 0111dc27509..1258ee2220a 100644 --- a/components/script/dom/bindings/proxyhandler.rs +++ b/components/script/dom/bindings/proxyhandler.rs @@ -42,7 +42,7 @@ use crate::dom::bindings::principals::ServoJSPrincipalsRef; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::str::DOMString; use crate::dom::bindings::utils::delete_property_by_id; -use crate::dom::globalscope::GlobalScope; +use crate::dom::globalscope::{GlobalScope, GlobalScopeHelpers}; use crate::realms::{AlreadyInRealm, InRealm}; use crate::script_runtime::JSContext as SafeJSContext; @@ -376,7 +376,7 @@ pub(crate) unsafe extern "C" fn maybe_cross_origin_get_prototype_if_ordinary_raw /// Implementation of `[[GetPrototypeOf]]` for [`Location`]. /// /// [`Location`]: https://html.spec.whatwg.org/multipage/#location-getprototypeof -pub(crate) unsafe fn maybe_cross_origin_get_prototype( +pub(crate) unsafe fn maybe_cross_origin_get_prototype( cx: SafeJSContext, proxy: RawHandleObject, get_proto_object: unsafe fn(cx: SafeJSContext, global: HandleObject, rval: MutableHandleObject), @@ -385,7 +385,7 @@ pub(crate) unsafe fn maybe_cross_origin_get_prototype( // > 1. If ! IsPlatformObjectSameOrigin(this) is true, then return ! OrdinaryGetPrototypeOf(this). if is_platform_object_same_origin(cx, proxy) { let ac = JSAutoRealm::new(*cx, proxy.get()); - let global = GlobalScope::from_context(*cx, InRealm::Entered(&ac)); + let global = D::GlobalScope::from_context(*cx, InRealm::Entered(&ac)); get_proto_object( cx, global.reflector().get_jsobject(), diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index fc42131fc37..119d8c239ab 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -3272,3 +3272,15 @@ unsafe fn global_scope_from_global_static(global: *mut JSObject) -> DomRoot { + unsafe fn from_context(cx: *mut JSContext, realm: InRealm) -> DomRoot; +} + +#[allow(unsafe_code)] +impl GlobalScopeHelpers for GlobalScope { + unsafe fn from_context(cx: *mut JSContext, realm: InRealm) -> DomRoot { + GlobalScope::from_context(cx, realm) + } +} diff --git a/components/script/init.rs b/components/script/init.rs index f2e88f6ea1a..bf3d2b15747 100644 --- a/components/script/init.rs +++ b/components/script/init.rs @@ -69,8 +69,8 @@ pub fn init() -> JSEngineSetup { // Create the global vtables used by the (generated) DOM // bindings to implement JS proxies. - RegisterBindings::RegisterProxyHandlers(); - RegisterBindings::InitAllStatics(); + RegisterBindings::RegisterProxyHandlers::(); + RegisterBindings::InitAllStatics::(); js::glue::InitializeMemoryReporter(Some(is_dom_object)); } diff --git a/components/script_bindings/codegen/Bindings.conf b/components/script_bindings/codegen/Bindings.conf index 6d52f5634d9..0d616381e71 100644 --- a/components/script_bindings/codegen/Bindings.conf +++ b/components/script_bindings/codegen/Bindings.conf @@ -180,6 +180,10 @@ DOMInterfaces = { 'canGc': ['PlayEffect', 'Reset'], }, +'GlobalScope': { + 'additionalTraits': ['crate::dom::globalscope::GlobalScopeHelpers'], +}, + 'GPU': { 'inRealms': ['RequestAdapter'], 'canGc': ['RequestAdapter', 'WgslLanguageFeatures'], diff --git a/components/script_bindings/codegen/CodegenRust.py b/components/script_bindings/codegen/CodegenRust.py index 1f7830c2040..e0fccc2be9f 100644 --- a/components/script_bindings/codegen/CodegenRust.py +++ b/components/script_bindings/codegen/CodegenRust.py @@ -1630,7 +1630,7 @@ class PropertyDefiner: specsArray = f"static {name}_specs: ThreadUnsafeOnceLock<&[&[{specType}]]> = ThreadUnsafeOnceLock::new();\n" initSpecs = f""" -pub(crate) fn init_{name}_specs() {{ +pub(crate) fn init_{name}_specs() {{ {name}_specs.set(Box::leak(Box::new([{joinedSpecs}]))); }}""" @@ -1638,7 +1638,7 @@ pub(crate) fn init_{name}_specs() {{ prefArray = f"static {name}: ThreadUnsafeOnceLock<&[Guard<&[{specType}]>]> = ThreadUnsafeOnceLock::new();\n" initPrefs = f""" -pub(crate) fn init_{name}_prefs() {{ +pub(crate) fn init_{name}_prefs() {{ {name}.set(Box::leak(Box::new([{joinedPrefableSpecs}]))); }}""" @@ -1667,7 +1667,7 @@ pub(crate) fn init_{name}_prefs() {{ joinedSpecs = ',\n'.join(specsArray) initialSpecs = f"static {name}: ThreadUnsafeOnceLock<&[{specType}]> = ThreadUnsafeOnceLock::new();\n" initSpecs = f""" -pub(crate) fn init_{name}() {{ +pub(crate) fn init_{name}() {{ {name}.set(Box::leak(Box::new([{joinedSpecs}]))); }}""" return dedent(f"{initialSpecs}{initSpecs}") @@ -1843,7 +1843,7 @@ class MethodDefiner(PropertyDefiner): accessor = "Some(generic_static_promise_method)" else: jitinfo = "ptr::null()" - accessor = f'Some({m.get("nativeName", m["name"])})' + accessor = f'Some({m.get("nativeName", m["name"])}::)' if m["name"].startswith("@@"): assert not self.crossorigin name = f'JSPropertySpec_Name {{ symbol_: SymbolCode::{m["name"][2:]} as usize + 1 }}' @@ -1933,7 +1933,7 @@ class AttrDefiner(PropertyDefiner): return "JSNativeWrapper { op: None, info: ptr::null() }" if self.static: - accessor = f'get_{self.descriptor.internalNameFor(attr.identifier.name)}' + accessor = f'get_{self.descriptor.internalNameFor(attr.identifier.name)}::' jitinfo = "ptr::null()" else: if attr.type.isPromise(): @@ -1959,7 +1959,7 @@ class AttrDefiner(PropertyDefiner): return "JSNativeWrapper { op: None, info: ptr::null() }" if self.static: - accessor = f'set_{self.descriptor.internalNameFor(attr.identifier.name)}' + accessor = f'set_{self.descriptor.internalNameFor(attr.identifier.name)}::' jitinfo = "ptr::null()" else: if attr.hasLegacyLenientThis(): @@ -2661,6 +2661,8 @@ def DomTypes(descriptors, descriptorProvider, dictionaries, callbacks, typedefs, iface_name = descriptor.interface.identifier.name traits = [] + traits += descriptor.additionalTraits + chain = descriptor.prototypeChain upcast = descriptor.hasDescendants() @@ -3247,9 +3249,9 @@ class CGAbstractExternMethod(CGAbstractMethod): Abstract base class for codegen of implementation-only (no declaration) static methods. """ - def __init__(self, descriptor, name, returnType, args, doesNotPanic=False): + def __init__(self, descriptor, name, returnType, args, doesNotPanic=False, templateArgs=None): CGAbstractMethod.__init__(self, descriptor, name, returnType, args, - inline=False, extern=True, doesNotPanic=doesNotPanic) + inline=False, extern=True, doesNotPanic=doesNotPanic, templateArgs=templateArgs) class PropertyArrays(): @@ -3304,7 +3306,7 @@ class CGCrossOriginProperties(CGThing): """ static CROSS_ORIGIN_PROPERTIES: ThreadUnsafeOnceLock = ThreadUnsafeOnceLock::new(); - pub(crate) fn init_cross_origin_properties() { + pub(crate) fn init_cross_origin_properties() { CROSS_ORIGIN_PROPERTIES.set(CrossOriginProperties { attributes: unsafe { sCrossOriginAttributes.get() }, methods: unsafe { sCrossOriginMethods.get() }, @@ -3324,7 +3326,7 @@ class CGCollectJSONAttributesMethod(CGAbstractMethod): Argument('*mut libc::c_void', 'this'), Argument('HandleObject', 'result')] CGAbstractMethod.__init__(self, descriptor, 'CollectJSONAttributes', - 'bool', args, pub=True, unsafe=True) + 'bool', args, pub=True, unsafe=True, templateArgs=["D: DomTypes"]) self.toJSONMethod = toJSONMethod def definition_body(self): @@ -3346,7 +3348,7 @@ let global = incumbent_global.reflector().get_jsobject();\n""" global)); if is_satisfied { rooted!(in(cx) let mut temp = UndefinedValue()); - if !get_${name}(cx, obj, this, JSJitGetterCallArgs { _base: temp.handle_mut().into() }) { + if !get_${name}::(cx, obj, this, JSJitGetterCallArgs { _base: temp.handle_mut().into() }) { return false; } if !JS_DefineProperty(cx, result, @@ -3691,7 +3693,7 @@ class CGDefineProxyHandler(CGAbstractMethod): assert descriptor.proxy CGAbstractMethod.__init__(self, descriptor, 'DefineProxyHandler', '*const libc::c_void', [], - pub=True, unsafe=True) + pub=True, unsafe=True, templateArgs=["D: DomTypes"]) def define(self): return CGAbstractMethod.define(self) @@ -3711,7 +3713,7 @@ class CGDefineProxyHandler(CGAbstractMethod): customSetPrototype = 'None' if self.descriptor.isMaybeCrossOriginObject(): customGetPrototypeIfOrdinary = 'Some(proxyhandler::maybe_cross_origin_get_prototype_if_ordinary_rawcx)' - customGetPrototype = 'Some(getPrototype)' + customGetPrototype = 'Some(getPrototype::)' customSetPrototype = 'Some(proxyhandler::maybe_cross_origin_set_prototype_rawcx)' # The base class `BaseProxyHandler`'s `setImmutablePrototype` (not to be # confused with ECMAScript's `[[SetImmutablePrototype]]`) always fails. @@ -4096,13 +4098,13 @@ class CGAbstractStaticBindingMethod(CGAbstractMethod): function to do the rest of the work. This function should return a CGThing which is already properly indented. """ - def __init__(self, descriptor, name): + def __init__(self, descriptor, name, templateArgs=None): args = [ Argument('*mut JSContext', 'cx'), Argument('libc::c_uint', 'argc'), Argument('*mut JSVal', 'vp'), ] - CGAbstractMethod.__init__(self, descriptor, name, "bool", args, extern=True) + CGAbstractMethod.__init__(self, descriptor, name, "bool", args, extern=True, templateArgs=templateArgs) self.exposureSet = descriptor.interface.exposureSet def definition_body(self): @@ -4141,7 +4143,7 @@ class CGSpecializedMethod(CGAbstractExternMethod): Argument('RawHandleObject', '_obj'), Argument('*mut libc::c_void', 'this'), Argument('*const JSJitMethodCallArgs', 'args')] - CGAbstractExternMethod.__init__(self, descriptor, name, 'bool', args) + CGAbstractExternMethod.__init__(self, descriptor, name, 'bool', args, templateArgs=["D: DomTypes"]) def definition_body(self): nativeName = CGSpecializedMethod.makeNativeName(self.descriptor, @@ -4178,12 +4180,12 @@ class CGMethodPromiseWrapper(CGAbstractExternMethod): Argument('RawHandleObject', '_obj'), Argument('*mut libc::c_void', 'this'), Argument('*const JSJitMethodCallArgs', 'args')] - CGAbstractExternMethod.__init__(self, descriptor, name, 'bool', args) + CGAbstractExternMethod.__init__(self, descriptor, name, 'bool', args, templateArgs=["D: DomTypes"]) def definition_body(self): return CGGeneric(fill( """ - let ok = ${methodName}(${args}); + let ok = ${methodName}::(${args}); if ok { return true; } @@ -4213,12 +4215,12 @@ class CGGetterPromiseWrapper(CGAbstractExternMethod): Argument('RawHandleObject', '_obj'), Argument('*mut libc::c_void', 'this'), Argument('JSJitGetterCallArgs', 'args')] - CGAbstractExternMethod.__init__(self, descriptor, name, 'bool', args) + CGAbstractExternMethod.__init__(self, descriptor, name, 'bool', args, templateArgs=["D: DomTypes"]) def definition_body(self): return CGGeneric(fill( """ - let ok = ${methodName}(${args}); + let ok = ${methodName}::(${args}); if ok { return true; } @@ -4261,7 +4263,7 @@ class CGDefaultToJSONMethod(CGSpecializedMethod): parents = len(jsonDescriptors) - 1 form = """ - if !${parentclass}CollectJSONAttributes(cx, _obj, this, result.handle()) { + if !${parentclass}CollectJSONAttributes::(cx, _obj, this, result.handle()) { return false; } """ @@ -4283,7 +4285,7 @@ class CGStaticMethod(CGAbstractStaticBindingMethod): def __init__(self, descriptor, method): self.method = method name = method.identifier.name - CGAbstractStaticBindingMethod.__init__(self, descriptor, name) + CGAbstractStaticBindingMethod.__init__(self, descriptor, name, templateArgs=["D: DomTypes"]) def generate_code(self): nativeName = CGSpecializedMethod.makeNativeName(self.descriptor, @@ -4306,7 +4308,7 @@ class CGSpecializedGetter(CGAbstractExternMethod): Argument('RawHandleObject', '_obj'), Argument('*mut libc::c_void', 'this'), Argument('JSJitGetterCallArgs', 'args')] - CGAbstractExternMethod.__init__(self, descriptor, name, "bool", args) + CGAbstractExternMethod.__init__(self, descriptor, name, "bool", args, templateArgs=["D: DomTypes"]) def definition_body(self): nativeName = CGSpecializedGetter.makeNativeName(self.descriptor, @@ -4339,7 +4341,7 @@ class CGStaticGetter(CGAbstractStaticBindingMethod): def __init__(self, descriptor, attr): self.attr = attr name = f'get_{attr.identifier.name}' - CGAbstractStaticBindingMethod.__init__(self, descriptor, name) + CGAbstractStaticBindingMethod.__init__(self, descriptor, name, templateArgs=["D: DomTypes"]) def generate_code(self): nativeName = CGSpecializedGetter.makeNativeName(self.descriptor, @@ -4363,7 +4365,7 @@ class CGSpecializedSetter(CGAbstractExternMethod): Argument('RawHandleObject', 'obj'), Argument('*mut libc::c_void', 'this'), Argument('JSJitSetterCallArgs', 'args')] - CGAbstractExternMethod.__init__(self, descriptor, name, "bool", args) + CGAbstractExternMethod.__init__(self, descriptor, name, "bool", args, templateArgs=["D: DomTypes"]) def definition_body(self): nativeName = CGSpecializedSetter.makeNativeName(self.descriptor, @@ -4390,7 +4392,7 @@ class CGStaticSetter(CGAbstractStaticBindingMethod): def __init__(self, descriptor, attr): self.attr = attr name = f'set_{attr.identifier.name}' - CGAbstractStaticBindingMethod.__init__(self, descriptor, name) + CGAbstractStaticBindingMethod.__init__(self, descriptor, name, templateArgs=["D: DomTypes"]) def generate_code(self): nativeName = CGSpecializedSetter.makeNativeName(self.descriptor, @@ -4502,7 +4504,7 @@ class CGMemberJITInfo(CGThing): ), } """, - opValue=f"Some({opName})", + opValue=f"Some({opName}::)", name=self.descriptor.name, depth=self.descriptor.interface.inheritanceDepth(), opType=opType, @@ -4530,7 +4532,7 @@ class CGMemberJITInfo(CGThing): $*{argTypesDecl} static ${infoName}: ThreadUnsafeOnceLock = ThreadUnsafeOnceLock::new(); - pub(crate) fn init_${infoName}() { + pub(crate) fn init_${infoName}() { ${infoName}.set(JSTypedMethodJitInfo { base: ${jitInfoInit}, argTypes: &${argTypes} as *const _ as *const JSJitInfo_ArgType, @@ -4545,7 +4547,7 @@ class CGMemberJITInfo(CGThing): return f""" static {infoName}: ThreadUnsafeOnceLock = ThreadUnsafeOnceLock::new(); -pub(crate) fn init_{infoName}() {{ +pub(crate) fn init_{infoName}() {{ {infoName}.set({jitInfoInitializer(False)}); }}""" @@ -4823,10 +4825,10 @@ class CGStaticMethodJitinfo(CGGeneric): f""" static {method.identifier.name}_methodinfo: ThreadUnsafeOnceLock = ThreadUnsafeOnceLock::new(); - pub(crate) fn init_{method.identifier.name}_methodinfo() {{ + pub(crate) fn init_{method.identifier.name}_methodinfo() {{ {method.identifier.name}_methodinfo.set(JSJitInfo {{ __bindgen_anon_1: JSJitInfo__bindgen_ty_1 {{ - staticMethod: Some({method.identifier.name}) + staticMethod: Some({method.identifier.name}::) }}, __bindgen_anon_2: JSJitInfo__bindgen_ty_2 {{ protoID: PrototypeList::ID::Last as u16, @@ -6303,7 +6305,7 @@ class CGDOMJSProxyHandler_getPrototype(CGAbstractExternMethod): def __init__(self, descriptor): args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'), Argument('RawMutableHandleObject', 'proto')] - CGAbstractExternMethod.__init__(self, descriptor, "getPrototype", "bool", args) + CGAbstractExternMethod.__init__(self, descriptor, "getPrototype", "bool", args, templateArgs=["D: DomTypes"]) assert descriptor.isMaybeCrossOriginObject() self.descriptor = descriptor @@ -6311,7 +6313,7 @@ class CGDOMJSProxyHandler_getPrototype(CGAbstractExternMethod): return dedent( """ let cx = SafeJSContext::from_ptr(cx); - proxyhandler::maybe_cross_origin_get_prototype(cx, proxy, GetProtoObject, proto) + proxyhandler::maybe_cross_origin_get_prototype::(cx, proxy, GetProtoObject, proto) """) def definition_body(self): @@ -6667,8 +6669,8 @@ class CGInitStatics(CGThing): arrays = [getattr(properties, name) for name in all_names] nonempty = map(lambda x: x.variableName(), filter(lambda x: x.length() != 0, arrays)) specs = [[ - f'init_{name}_specs();', - f'init_{name}_prefs();', + f'init_{name}_specs::();', + f'init_{name}_prefs::();', ] for name in nonempty] flat_specs = [x for xs in specs for x in xs] specs = '\n'.join(flat_specs) @@ -6690,13 +6692,13 @@ class CGInitStatics(CGThing): relevantMethods ) - methods = [f'{module}::init_{internal(m)}_methodinfo();' for m in relevantMethods] + methods = [f'{module}::init_{internal(m)}_methodinfo::();' for m in relevantMethods] getters = [ - f'init_{internal(m)}_getterinfo();' + f'init_{internal(m)}_getterinfo::();' for m in descriptor.interface.members if m.isAttr() and not m.isStatic() ] setters = [ - f'init_{internal(m)}_setterinfo();' + f'init_{internal(m)}_setterinfo::();' for m in descriptor.interface.members if m.isAttr() and ( not m.readonly @@ -6708,9 +6710,9 @@ class CGInitStatics(CGThing): getters = '\n'.join(getters) setters = '\n'.join(setters) crossorigin = [ - "init_sCrossOriginMethods();", - "init_sCrossOriginAttributes();", - "init_cross_origin_properties();" + "init_sCrossOriginMethods::();", + "init_sCrossOriginAttributes::();", + "init_cross_origin_properties::();" ] if descriptor.isMaybeCrossOriginObject() else [] crossorigin_joined = '\n'.join(crossorigin) interface = ( @@ -6729,7 +6731,7 @@ class CGInitStatics(CGThing): ) self.code = f""" - pub(crate) fn init_statics() {{ + pub(crate) fn init_statics() {{ {interface} {nonproxy} {methods} @@ -7315,13 +7317,13 @@ class CGInitAllStatics(CGAbstractMethod): descriptors = (config.getDescriptors(isCallback=False, register=True) + config.getDescriptors(isCallback=True, hasInterfaceObject=True, register=True)) CGAbstractMethod.__init__(self, None, 'InitAllStatics', 'void', [], - pub=True, docs=docs) + pub=True, docs=docs, templateArgs=["D: DomTypes"]) self.descriptors = descriptors def definition_body(self): return CGList([ CGGeneric(f" Bindings::{toBindingModuleFileFromDescriptor(desc)}::{toBindingNamespace(desc.name)}" - "::init_statics();") + "::init_statics::();") for desc in self.descriptors ], "\n") @@ -7330,14 +7332,14 @@ class CGRegisterProxyHandlersMethod(CGAbstractMethod): def __init__(self, descriptors): docs = "Create the global vtables used by the generated DOM bindings to implement JS proxies." CGAbstractMethod.__init__(self, None, 'RegisterProxyHandlers', 'void', [], - unsafe=True, pub=True, docs=docs) + unsafe=True, pub=True, docs=docs, templateArgs=["D: DomTypes"]) self.descriptors = descriptors def definition_body(self): return CGList([ CGGeneric(f"proxy_handlers::{desc.name}.store(\n" f" Bindings::{toBindingModuleFile(desc.name)}::{toBindingNamespace(desc.name)}" - "::DefineProxyHandler() as *mut _,\n" + "::DefineProxyHandler::() as *mut _,\n" " std::sync::atomic::Ordering::Release,\n" ");") for desc in self.descriptors @@ -7359,7 +7361,6 @@ class CGRegisterProxyHandlers(CGThing): f"{body}}}\n" ), CGRegisterProxyHandlersMethod(descriptors), - CGInitAllStatics(config), ], "\n") def define(self): @@ -8290,10 +8291,12 @@ class GlobalGenRoots(): # TODO - Generate the methods we want code = CGList([ CGRegisterProxyHandlers(config), + CGInitAllStatics(config), ], "\n") return CGImports(code, descriptors=[], callbacks=[], dictionaries=[], enums=[], typedefs=[], imports=[ 'crate::dom::bindings::codegen::Bindings', + 'crate::DomTypes', ], config=config) @staticmethod diff --git a/components/script_bindings/codegen/Configuration.py b/components/script_bindings/codegen/Configuration.py index 07822eac1b3..bae19bb915a 100644 --- a/components/script_bindings/codegen/Configuration.py +++ b/components/script_bindings/codegen/Configuration.py @@ -245,6 +245,7 @@ class Descriptor(DescriptorProvider): self.path = desc.get('path', pathDefault) self.inRealmMethods = [name for name in desc.get('inRealms', [])] self.canGcMethods = [name for name in desc.get('canGc', [])] + self.additionalTraits = [name for name in desc.get('additionalTraits', [])] self.bindingPath = f"{getModuleFromObject(self.interface)}::{ifaceName}_Binding" self.outerObjectHook = desc.get('outerObjectHook', 'None') self.proxy = False