Make generated bindings generic over DOM types (#35169)

* bindings: Start making generated bindings methods generic over DOM trait.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

* bindings: Make binding initialization generic over the DOM types trait.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

* bindings: Start making proxyhandler code generic over DOM types.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

---------

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
Josh Matthews 2025-01-25 00:08:49 -05:00 committed by GitHub
parent 8748071329
commit d5d7b0d34f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 72 additions and 52 deletions

View file

@ -42,7 +42,7 @@ use crate::dom::bindings::principals::ServoJSPrincipalsRef;
use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::reflector::DomObject;
use crate::dom::bindings::str::DOMString; use crate::dom::bindings::str::DOMString;
use crate::dom::bindings::utils::delete_property_by_id; 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::realms::{AlreadyInRealm, InRealm};
use crate::script_runtime::JSContext as SafeJSContext; 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`]. /// Implementation of `[[GetPrototypeOf]]` for [`Location`].
/// ///
/// [`Location`]: https://html.spec.whatwg.org/multipage/#location-getprototypeof /// [`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<D: crate::DomTypes>(
cx: SafeJSContext, cx: SafeJSContext,
proxy: RawHandleObject, proxy: RawHandleObject,
get_proto_object: unsafe fn(cx: SafeJSContext, global: HandleObject, rval: MutableHandleObject), 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). // > 1. If ! IsPlatformObjectSameOrigin(this) is true, then return ! OrdinaryGetPrototypeOf(this).
if is_platform_object_same_origin(cx, proxy) { if is_platform_object_same_origin(cx, proxy) {
let ac = JSAutoRealm::new(*cx, proxy.get()); 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( get_proto_object(
cx, cx,
global.reflector().get_jsobject(), global.reflector().get_jsobject(),

View file

@ -3272,3 +3272,15 @@ unsafe fn global_scope_from_global_static(global: *mut JSObject) -> DomRoot<Glob
); );
root_from_object_static(global).unwrap() root_from_object_static(global).unwrap()
} }
#[allow(unsafe_code)]
pub(crate) trait GlobalScopeHelpers<D: crate::DomTypes> {
unsafe fn from_context(cx: *mut JSContext, realm: InRealm) -> DomRoot<D::GlobalScope>;
}
#[allow(unsafe_code)]
impl GlobalScopeHelpers<crate::DomTypeHolder> for GlobalScope {
unsafe fn from_context(cx: *mut JSContext, realm: InRealm) -> DomRoot<Self> {
GlobalScope::from_context(cx, realm)
}
}

View file

@ -69,8 +69,8 @@ pub fn init() -> JSEngineSetup {
// Create the global vtables used by the (generated) DOM // Create the global vtables used by the (generated) DOM
// bindings to implement JS proxies. // bindings to implement JS proxies.
RegisterBindings::RegisterProxyHandlers(); RegisterBindings::RegisterProxyHandlers::<crate::DomTypeHolder>();
RegisterBindings::InitAllStatics(); RegisterBindings::InitAllStatics::<crate::DomTypeHolder>();
js::glue::InitializeMemoryReporter(Some(is_dom_object)); js::glue::InitializeMemoryReporter(Some(is_dom_object));
} }

View file

@ -180,6 +180,10 @@ DOMInterfaces = {
'canGc': ['PlayEffect', 'Reset'], 'canGc': ['PlayEffect', 'Reset'],
}, },
'GlobalScope': {
'additionalTraits': ['crate::dom::globalscope::GlobalScopeHelpers<Self>'],
},
'GPU': { 'GPU': {
'inRealms': ['RequestAdapter'], 'inRealms': ['RequestAdapter'],
'canGc': ['RequestAdapter', 'WgslLanguageFeatures'], 'canGc': ['RequestAdapter', 'WgslLanguageFeatures'],

View file

@ -1630,7 +1630,7 @@ class PropertyDefiner:
specsArray = f"static {name}_specs: ThreadUnsafeOnceLock<&[&[{specType}]]> = ThreadUnsafeOnceLock::new();\n" specsArray = f"static {name}_specs: ThreadUnsafeOnceLock<&[&[{specType}]]> = ThreadUnsafeOnceLock::new();\n"
initSpecs = f""" initSpecs = f"""
pub(crate) fn init_{name}_specs() {{ pub(crate) fn init_{name}_specs<D: DomTypes>() {{
{name}_specs.set(Box::leak(Box::new([{joinedSpecs}]))); {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" prefArray = f"static {name}: ThreadUnsafeOnceLock<&[Guard<&[{specType}]>]> = ThreadUnsafeOnceLock::new();\n"
initPrefs = f""" initPrefs = f"""
pub(crate) fn init_{name}_prefs() {{ pub(crate) fn init_{name}_prefs<D: DomTypes>() {{
{name}.set(Box::leak(Box::new([{joinedPrefableSpecs}]))); {name}.set(Box::leak(Box::new([{joinedPrefableSpecs}])));
}}""" }}"""
@ -1667,7 +1667,7 @@ pub(crate) fn init_{name}_prefs() {{
joinedSpecs = ',\n'.join(specsArray) joinedSpecs = ',\n'.join(specsArray)
initialSpecs = f"static {name}: ThreadUnsafeOnceLock<&[{specType}]> = ThreadUnsafeOnceLock::new();\n" initialSpecs = f"static {name}: ThreadUnsafeOnceLock<&[{specType}]> = ThreadUnsafeOnceLock::new();\n"
initSpecs = f""" initSpecs = f"""
pub(crate) fn init_{name}() {{ pub(crate) fn init_{name}<D: DomTypes>() {{
{name}.set(Box::leak(Box::new([{joinedSpecs}]))); {name}.set(Box::leak(Box::new([{joinedSpecs}])));
}}""" }}"""
return dedent(f"{initialSpecs}{initSpecs}") return dedent(f"{initialSpecs}{initSpecs}")
@ -1843,7 +1843,7 @@ class MethodDefiner(PropertyDefiner):
accessor = "Some(generic_static_promise_method)" accessor = "Some(generic_static_promise_method)"
else: else:
jitinfo = "ptr::null()" jitinfo = "ptr::null()"
accessor = f'Some({m.get("nativeName", m["name"])})' accessor = f'Some({m.get("nativeName", m["name"])}::<D>)'
if m["name"].startswith("@@"): if m["name"].startswith("@@"):
assert not self.crossorigin assert not self.crossorigin
name = f'JSPropertySpec_Name {{ symbol_: SymbolCode::{m["name"][2:]} as usize + 1 }}' 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() }" return "JSNativeWrapper { op: None, info: ptr::null() }"
if self.static: if self.static:
accessor = f'get_{self.descriptor.internalNameFor(attr.identifier.name)}' accessor = f'get_{self.descriptor.internalNameFor(attr.identifier.name)}::<D>'
jitinfo = "ptr::null()" jitinfo = "ptr::null()"
else: else:
if attr.type.isPromise(): if attr.type.isPromise():
@ -1959,7 +1959,7 @@ class AttrDefiner(PropertyDefiner):
return "JSNativeWrapper { op: None, info: ptr::null() }" return "JSNativeWrapper { op: None, info: ptr::null() }"
if self.static: if self.static:
accessor = f'set_{self.descriptor.internalNameFor(attr.identifier.name)}' accessor = f'set_{self.descriptor.internalNameFor(attr.identifier.name)}::<D>'
jitinfo = "ptr::null()" jitinfo = "ptr::null()"
else: else:
if attr.hasLegacyLenientThis(): if attr.hasLegacyLenientThis():
@ -2661,6 +2661,8 @@ def DomTypes(descriptors, descriptorProvider, dictionaries, callbacks, typedefs,
iface_name = descriptor.interface.identifier.name iface_name = descriptor.interface.identifier.name
traits = [] traits = []
traits += descriptor.additionalTraits
chain = descriptor.prototypeChain chain = descriptor.prototypeChain
upcast = descriptor.hasDescendants() upcast = descriptor.hasDescendants()
@ -3247,9 +3249,9 @@ class CGAbstractExternMethod(CGAbstractMethod):
Abstract base class for codegen of implementation-only (no Abstract base class for codegen of implementation-only (no
declaration) static methods. 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, CGAbstractMethod.__init__(self, descriptor, name, returnType, args,
inline=False, extern=True, doesNotPanic=doesNotPanic) inline=False, extern=True, doesNotPanic=doesNotPanic, templateArgs=templateArgs)
class PropertyArrays(): class PropertyArrays():
@ -3304,7 +3306,7 @@ class CGCrossOriginProperties(CGThing):
""" """
static CROSS_ORIGIN_PROPERTIES: ThreadUnsafeOnceLock<CrossOriginProperties> = ThreadUnsafeOnceLock::new(); static CROSS_ORIGIN_PROPERTIES: ThreadUnsafeOnceLock<CrossOriginProperties> = ThreadUnsafeOnceLock::new();
pub(crate) fn init_cross_origin_properties() { pub(crate) fn init_cross_origin_properties<D: DomTypes>() {
CROSS_ORIGIN_PROPERTIES.set(CrossOriginProperties { CROSS_ORIGIN_PROPERTIES.set(CrossOriginProperties {
attributes: unsafe { sCrossOriginAttributes.get() }, attributes: unsafe { sCrossOriginAttributes.get() },
methods: unsafe { sCrossOriginMethods.get() }, methods: unsafe { sCrossOriginMethods.get() },
@ -3324,7 +3326,7 @@ class CGCollectJSONAttributesMethod(CGAbstractMethod):
Argument('*mut libc::c_void', 'this'), Argument('*mut libc::c_void', 'this'),
Argument('HandleObject', 'result')] Argument('HandleObject', 'result')]
CGAbstractMethod.__init__(self, descriptor, 'CollectJSONAttributes', CGAbstractMethod.__init__(self, descriptor, 'CollectJSONAttributes',
'bool', args, pub=True, unsafe=True) 'bool', args, pub=True, unsafe=True, templateArgs=["D: DomTypes"])
self.toJSONMethod = toJSONMethod self.toJSONMethod = toJSONMethod
def definition_body(self): def definition_body(self):
@ -3346,7 +3348,7 @@ let global = incumbent_global.reflector().get_jsobject();\n"""
global)); global));
if is_satisfied { if is_satisfied {
rooted!(in(cx) let mut temp = UndefinedValue()); rooted!(in(cx) let mut temp = UndefinedValue());
if !get_${name}(cx, obj, this, JSJitGetterCallArgs { _base: temp.handle_mut().into() }) { if !get_${name}::<D>(cx, obj, this, JSJitGetterCallArgs { _base: temp.handle_mut().into() }) {
return false; return false;
} }
if !JS_DefineProperty(cx, result, if !JS_DefineProperty(cx, result,
@ -3691,7 +3693,7 @@ class CGDefineProxyHandler(CGAbstractMethod):
assert descriptor.proxy assert descriptor.proxy
CGAbstractMethod.__init__(self, descriptor, 'DefineProxyHandler', CGAbstractMethod.__init__(self, descriptor, 'DefineProxyHandler',
'*const libc::c_void', [], '*const libc::c_void', [],
pub=True, unsafe=True) pub=True, unsafe=True, templateArgs=["D: DomTypes"])
def define(self): def define(self):
return CGAbstractMethod.define(self) return CGAbstractMethod.define(self)
@ -3711,7 +3713,7 @@ class CGDefineProxyHandler(CGAbstractMethod):
customSetPrototype = 'None' customSetPrototype = 'None'
if self.descriptor.isMaybeCrossOriginObject(): if self.descriptor.isMaybeCrossOriginObject():
customGetPrototypeIfOrdinary = 'Some(proxyhandler::maybe_cross_origin_get_prototype_if_ordinary_rawcx)' customGetPrototypeIfOrdinary = 'Some(proxyhandler::maybe_cross_origin_get_prototype_if_ordinary_rawcx)'
customGetPrototype = 'Some(getPrototype)' customGetPrototype = 'Some(getPrototype::<D>)'
customSetPrototype = 'Some(proxyhandler::maybe_cross_origin_set_prototype_rawcx)' customSetPrototype = 'Some(proxyhandler::maybe_cross_origin_set_prototype_rawcx)'
# The base class `BaseProxyHandler`'s `setImmutablePrototype` (not to be # The base class `BaseProxyHandler`'s `setImmutablePrototype` (not to be
# confused with ECMAScript's `[[SetImmutablePrototype]]`) always fails. # 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 function to do the rest of the work. This function should return a
CGThing which is already properly indented. CGThing which is already properly indented.
""" """
def __init__(self, descriptor, name): def __init__(self, descriptor, name, templateArgs=None):
args = [ args = [
Argument('*mut JSContext', 'cx'), Argument('*mut JSContext', 'cx'),
Argument('libc::c_uint', 'argc'), Argument('libc::c_uint', 'argc'),
Argument('*mut JSVal', 'vp'), 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 self.exposureSet = descriptor.interface.exposureSet
def definition_body(self): def definition_body(self):
@ -4141,7 +4143,7 @@ class CGSpecializedMethod(CGAbstractExternMethod):
Argument('RawHandleObject', '_obj'), Argument('RawHandleObject', '_obj'),
Argument('*mut libc::c_void', 'this'), Argument('*mut libc::c_void', 'this'),
Argument('*const JSJitMethodCallArgs', 'args')] 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): def definition_body(self):
nativeName = CGSpecializedMethod.makeNativeName(self.descriptor, nativeName = CGSpecializedMethod.makeNativeName(self.descriptor,
@ -4178,12 +4180,12 @@ class CGMethodPromiseWrapper(CGAbstractExternMethod):
Argument('RawHandleObject', '_obj'), Argument('RawHandleObject', '_obj'),
Argument('*mut libc::c_void', 'this'), Argument('*mut libc::c_void', 'this'),
Argument('*const JSJitMethodCallArgs', 'args')] 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): def definition_body(self):
return CGGeneric(fill( return CGGeneric(fill(
""" """
let ok = ${methodName}(${args}); let ok = ${methodName}::<D>(${args});
if ok { if ok {
return true; return true;
} }
@ -4213,12 +4215,12 @@ class CGGetterPromiseWrapper(CGAbstractExternMethod):
Argument('RawHandleObject', '_obj'), Argument('RawHandleObject', '_obj'),
Argument('*mut libc::c_void', 'this'), Argument('*mut libc::c_void', 'this'),
Argument('JSJitGetterCallArgs', 'args')] Argument('JSJitGetterCallArgs', 'args')]
CGAbstractExternMethod.__init__(self, descriptor, name, 'bool', args) CGAbstractExternMethod.__init__(self, descriptor, name, 'bool', args, templateArgs=["D: DomTypes"])
def definition_body(self): def definition_body(self):
return CGGeneric(fill( return CGGeneric(fill(
""" """
let ok = ${methodName}(${args}); let ok = ${methodName}::<D>(${args});
if ok { if ok {
return true; return true;
} }
@ -4261,7 +4263,7 @@ class CGDefaultToJSONMethod(CGSpecializedMethod):
parents = len(jsonDescriptors) - 1 parents = len(jsonDescriptors) - 1
form = """ form = """
if !${parentclass}CollectJSONAttributes(cx, _obj, this, result.handle()) { if !${parentclass}CollectJSONAttributes::<D>(cx, _obj, this, result.handle()) {
return false; return false;
} }
""" """
@ -4283,7 +4285,7 @@ class CGStaticMethod(CGAbstractStaticBindingMethod):
def __init__(self, descriptor, method): def __init__(self, descriptor, method):
self.method = method self.method = method
name = method.identifier.name name = method.identifier.name
CGAbstractStaticBindingMethod.__init__(self, descriptor, name) CGAbstractStaticBindingMethod.__init__(self, descriptor, name, templateArgs=["D: DomTypes"])
def generate_code(self): def generate_code(self):
nativeName = CGSpecializedMethod.makeNativeName(self.descriptor, nativeName = CGSpecializedMethod.makeNativeName(self.descriptor,
@ -4306,7 +4308,7 @@ class CGSpecializedGetter(CGAbstractExternMethod):
Argument('RawHandleObject', '_obj'), Argument('RawHandleObject', '_obj'),
Argument('*mut libc::c_void', 'this'), Argument('*mut libc::c_void', 'this'),
Argument('JSJitGetterCallArgs', 'args')] Argument('JSJitGetterCallArgs', 'args')]
CGAbstractExternMethod.__init__(self, descriptor, name, "bool", args) CGAbstractExternMethod.__init__(self, descriptor, name, "bool", args, templateArgs=["D: DomTypes"])
def definition_body(self): def definition_body(self):
nativeName = CGSpecializedGetter.makeNativeName(self.descriptor, nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
@ -4339,7 +4341,7 @@ class CGStaticGetter(CGAbstractStaticBindingMethod):
def __init__(self, descriptor, attr): def __init__(self, descriptor, attr):
self.attr = attr self.attr = attr
name = f'get_{attr.identifier.name}' name = f'get_{attr.identifier.name}'
CGAbstractStaticBindingMethod.__init__(self, descriptor, name) CGAbstractStaticBindingMethod.__init__(self, descriptor, name, templateArgs=["D: DomTypes"])
def generate_code(self): def generate_code(self):
nativeName = CGSpecializedGetter.makeNativeName(self.descriptor, nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
@ -4363,7 +4365,7 @@ class CGSpecializedSetter(CGAbstractExternMethod):
Argument('RawHandleObject', 'obj'), Argument('RawHandleObject', 'obj'),
Argument('*mut libc::c_void', 'this'), Argument('*mut libc::c_void', 'this'),
Argument('JSJitSetterCallArgs', 'args')] Argument('JSJitSetterCallArgs', 'args')]
CGAbstractExternMethod.__init__(self, descriptor, name, "bool", args) CGAbstractExternMethod.__init__(self, descriptor, name, "bool", args, templateArgs=["D: DomTypes"])
def definition_body(self): def definition_body(self):
nativeName = CGSpecializedSetter.makeNativeName(self.descriptor, nativeName = CGSpecializedSetter.makeNativeName(self.descriptor,
@ -4390,7 +4392,7 @@ class CGStaticSetter(CGAbstractStaticBindingMethod):
def __init__(self, descriptor, attr): def __init__(self, descriptor, attr):
self.attr = attr self.attr = attr
name = f'set_{attr.identifier.name}' name = f'set_{attr.identifier.name}'
CGAbstractStaticBindingMethod.__init__(self, descriptor, name) CGAbstractStaticBindingMethod.__init__(self, descriptor, name, templateArgs=["D: DomTypes"])
def generate_code(self): def generate_code(self):
nativeName = CGSpecializedSetter.makeNativeName(self.descriptor, nativeName = CGSpecializedSetter.makeNativeName(self.descriptor,
@ -4502,7 +4504,7 @@ class CGMemberJITInfo(CGThing):
), ),
} }
""", """,
opValue=f"Some({opName})", opValue=f"Some({opName}::<D>)",
name=self.descriptor.name, name=self.descriptor.name,
depth=self.descriptor.interface.inheritanceDepth(), depth=self.descriptor.interface.inheritanceDepth(),
opType=opType, opType=opType,
@ -4530,7 +4532,7 @@ class CGMemberJITInfo(CGThing):
$*{argTypesDecl} $*{argTypesDecl}
static ${infoName}: ThreadUnsafeOnceLock<JSTypedMethodJitInfo> = ThreadUnsafeOnceLock::new(); static ${infoName}: ThreadUnsafeOnceLock<JSTypedMethodJitInfo> = ThreadUnsafeOnceLock::new();
pub(crate) fn init_${infoName}() { pub(crate) fn init_${infoName}<D: DomTypes>() {
${infoName}.set(JSTypedMethodJitInfo { ${infoName}.set(JSTypedMethodJitInfo {
base: ${jitInfoInit}, base: ${jitInfoInit},
argTypes: &${argTypes} as *const _ as *const JSJitInfo_ArgType, argTypes: &${argTypes} as *const _ as *const JSJitInfo_ArgType,
@ -4545,7 +4547,7 @@ class CGMemberJITInfo(CGThing):
return f""" return f"""
static {infoName}: ThreadUnsafeOnceLock<JSJitInfo> = ThreadUnsafeOnceLock::new(); static {infoName}: ThreadUnsafeOnceLock<JSJitInfo> = ThreadUnsafeOnceLock::new();
pub(crate) fn init_{infoName}() {{ pub(crate) fn init_{infoName}<D: DomTypes>() {{
{infoName}.set({jitInfoInitializer(False)}); {infoName}.set({jitInfoInitializer(False)});
}}""" }}"""
@ -4823,10 +4825,10 @@ class CGStaticMethodJitinfo(CGGeneric):
f""" f"""
static {method.identifier.name}_methodinfo: ThreadUnsafeOnceLock<JSJitInfo> = ThreadUnsafeOnceLock::new(); static {method.identifier.name}_methodinfo: ThreadUnsafeOnceLock<JSJitInfo> = ThreadUnsafeOnceLock::new();
pub(crate) fn init_{method.identifier.name}_methodinfo() {{ pub(crate) fn init_{method.identifier.name}_methodinfo<D: DomTypes>() {{
{method.identifier.name}_methodinfo.set(JSJitInfo {{ {method.identifier.name}_methodinfo.set(JSJitInfo {{
__bindgen_anon_1: JSJitInfo__bindgen_ty_1 {{ __bindgen_anon_1: JSJitInfo__bindgen_ty_1 {{
staticMethod: Some({method.identifier.name}) staticMethod: Some({method.identifier.name}::<D>)
}}, }},
__bindgen_anon_2: JSJitInfo__bindgen_ty_2 {{ __bindgen_anon_2: JSJitInfo__bindgen_ty_2 {{
protoID: PrototypeList::ID::Last as u16, protoID: PrototypeList::ID::Last as u16,
@ -6303,7 +6305,7 @@ class CGDOMJSProxyHandler_getPrototype(CGAbstractExternMethod):
def __init__(self, descriptor): def __init__(self, descriptor):
args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'), args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'),
Argument('RawMutableHandleObject', 'proto')] Argument('RawMutableHandleObject', 'proto')]
CGAbstractExternMethod.__init__(self, descriptor, "getPrototype", "bool", args) CGAbstractExternMethod.__init__(self, descriptor, "getPrototype", "bool", args, templateArgs=["D: DomTypes"])
assert descriptor.isMaybeCrossOriginObject() assert descriptor.isMaybeCrossOriginObject()
self.descriptor = descriptor self.descriptor = descriptor
@ -6311,7 +6313,7 @@ class CGDOMJSProxyHandler_getPrototype(CGAbstractExternMethod):
return dedent( return dedent(
""" """
let cx = SafeJSContext::from_ptr(cx); let cx = SafeJSContext::from_ptr(cx);
proxyhandler::maybe_cross_origin_get_prototype(cx, proxy, GetProtoObject, proto) proxyhandler::maybe_cross_origin_get_prototype::<D>(cx, proxy, GetProtoObject, proto)
""") """)
def definition_body(self): def definition_body(self):
@ -6667,8 +6669,8 @@ class CGInitStatics(CGThing):
arrays = [getattr(properties, name) for name in all_names] arrays = [getattr(properties, name) for name in all_names]
nonempty = map(lambda x: x.variableName(), filter(lambda x: x.length() != 0, arrays)) nonempty = map(lambda x: x.variableName(), filter(lambda x: x.length() != 0, arrays))
specs = [[ specs = [[
f'init_{name}_specs();', f'init_{name}_specs::<D>();',
f'init_{name}_prefs();', f'init_{name}_prefs::<D>();',
] for name in nonempty] ] for name in nonempty]
flat_specs = [x for xs in specs for x in xs] flat_specs = [x for xs in specs for x in xs]
specs = '\n'.join(flat_specs) specs = '\n'.join(flat_specs)
@ -6690,13 +6692,13 @@ class CGInitStatics(CGThing):
relevantMethods relevantMethods
) )
methods = [f'{module}::init_{internal(m)}_methodinfo();' for m in relevantMethods] methods = [f'{module}::init_{internal(m)}_methodinfo::<D>();' for m in relevantMethods]
getters = [ getters = [
f'init_{internal(m)}_getterinfo();' f'init_{internal(m)}_getterinfo::<D>();'
for m in descriptor.interface.members if m.isAttr() and not m.isStatic() for m in descriptor.interface.members if m.isAttr() and not m.isStatic()
] ]
setters = [ setters = [
f'init_{internal(m)}_setterinfo();' f'init_{internal(m)}_setterinfo::<D>();'
for m in descriptor.interface.members for m in descriptor.interface.members
if m.isAttr() and ( if m.isAttr() and (
not m.readonly not m.readonly
@ -6708,9 +6710,9 @@ class CGInitStatics(CGThing):
getters = '\n'.join(getters) getters = '\n'.join(getters)
setters = '\n'.join(setters) setters = '\n'.join(setters)
crossorigin = [ crossorigin = [
"init_sCrossOriginMethods();", "init_sCrossOriginMethods::<D>();",
"init_sCrossOriginAttributes();", "init_sCrossOriginAttributes::<D>();",
"init_cross_origin_properties();" "init_cross_origin_properties::<D>();"
] if descriptor.isMaybeCrossOriginObject() else [] ] if descriptor.isMaybeCrossOriginObject() else []
crossorigin_joined = '\n'.join(crossorigin) crossorigin_joined = '\n'.join(crossorigin)
interface = ( interface = (
@ -6729,7 +6731,7 @@ class CGInitStatics(CGThing):
) )
self.code = f""" self.code = f"""
pub(crate) fn init_statics() {{ pub(crate) fn init_statics<D: DomTypes>() {{
{interface} {interface}
{nonproxy} {nonproxy}
{methods} {methods}
@ -7315,13 +7317,13 @@ class CGInitAllStatics(CGAbstractMethod):
descriptors = (config.getDescriptors(isCallback=False, register=True) descriptors = (config.getDescriptors(isCallback=False, register=True)
+ config.getDescriptors(isCallback=True, hasInterfaceObject=True, register=True)) + config.getDescriptors(isCallback=True, hasInterfaceObject=True, register=True))
CGAbstractMethod.__init__(self, None, 'InitAllStatics', 'void', [], CGAbstractMethod.__init__(self, None, 'InitAllStatics', 'void', [],
pub=True, docs=docs) pub=True, docs=docs, templateArgs=["D: DomTypes"])
self.descriptors = descriptors self.descriptors = descriptors
def definition_body(self): def definition_body(self):
return CGList([ return CGList([
CGGeneric(f" Bindings::{toBindingModuleFileFromDescriptor(desc)}::{toBindingNamespace(desc.name)}" CGGeneric(f" Bindings::{toBindingModuleFileFromDescriptor(desc)}::{toBindingNamespace(desc.name)}"
"::init_statics();") "::init_statics::<D>();")
for desc in self.descriptors for desc in self.descriptors
], "\n") ], "\n")
@ -7330,14 +7332,14 @@ class CGRegisterProxyHandlersMethod(CGAbstractMethod):
def __init__(self, descriptors): def __init__(self, descriptors):
docs = "Create the global vtables used by the generated DOM bindings to implement JS proxies." docs = "Create the global vtables used by the generated DOM bindings to implement JS proxies."
CGAbstractMethod.__init__(self, None, 'RegisterProxyHandlers', 'void', [], CGAbstractMethod.__init__(self, None, 'RegisterProxyHandlers', 'void', [],
unsafe=True, pub=True, docs=docs) unsafe=True, pub=True, docs=docs, templateArgs=["D: DomTypes"])
self.descriptors = descriptors self.descriptors = descriptors
def definition_body(self): def definition_body(self):
return CGList([ return CGList([
CGGeneric(f"proxy_handlers::{desc.name}.store(\n" CGGeneric(f"proxy_handlers::{desc.name}.store(\n"
f" Bindings::{toBindingModuleFile(desc.name)}::{toBindingNamespace(desc.name)}" f" Bindings::{toBindingModuleFile(desc.name)}::{toBindingNamespace(desc.name)}"
"::DefineProxyHandler() as *mut _,\n" "::DefineProxyHandler::<D>() as *mut _,\n"
" std::sync::atomic::Ordering::Release,\n" " std::sync::atomic::Ordering::Release,\n"
");") ");")
for desc in self.descriptors for desc in self.descriptors
@ -7359,7 +7361,6 @@ class CGRegisterProxyHandlers(CGThing):
f"{body}}}\n" f"{body}}}\n"
), ),
CGRegisterProxyHandlersMethod(descriptors), CGRegisterProxyHandlersMethod(descriptors),
CGInitAllStatics(config),
], "\n") ], "\n")
def define(self): def define(self):
@ -8290,10 +8291,12 @@ class GlobalGenRoots():
# TODO - Generate the methods we want # TODO - Generate the methods we want
code = CGList([ code = CGList([
CGRegisterProxyHandlers(config), CGRegisterProxyHandlers(config),
CGInitAllStatics(config),
], "\n") ], "\n")
return CGImports(code, descriptors=[], callbacks=[], dictionaries=[], enums=[], typedefs=[], imports=[ return CGImports(code, descriptors=[], callbacks=[], dictionaries=[], enums=[], typedefs=[], imports=[
'crate::dom::bindings::codegen::Bindings', 'crate::dom::bindings::codegen::Bindings',
'crate::DomTypes',
], config=config) ], config=config)
@staticmethod @staticmethod

View file

@ -245,6 +245,7 @@ class Descriptor(DescriptorProvider):
self.path = desc.get('path', pathDefault) self.path = desc.get('path', pathDefault)
self.inRealmMethods = [name for name in desc.get('inRealms', [])] self.inRealmMethods = [name for name in desc.get('inRealms', [])]
self.canGcMethods = [name for name in desc.get('canGc', [])] 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.bindingPath = f"{getModuleFromObject(self.interface)}::{ifaceName}_Binding"
self.outerObjectHook = desc.get('outerObjectHook', 'None') self.outerObjectHook = desc.get('outerObjectHook', 'None')
self.proxy = False self.proxy = False