mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
parent
c064c4950d
commit
d678b20616
4 changed files with 54 additions and 16 deletions
|
@ -1825,12 +1825,17 @@ def DOMClass(descriptor):
|
||||||
protoList.extend(['PrototypeList::ID::Last'] * (descriptor.config.maxProtoChainLength - len(protoList)))
|
protoList.extend(['PrototypeList::ID::Last'] * (descriptor.config.maxProtoChainLength - len(protoList)))
|
||||||
prototypeChainString = ', '.join(protoList)
|
prototypeChainString = ', '.join(protoList)
|
||||||
heapSizeOf = 'heap_size_of_raw_self_and_children::<%s>' % descriptor.interface.identifier.name
|
heapSizeOf = 'heap_size_of_raw_self_and_children::<%s>' % descriptor.interface.identifier.name
|
||||||
|
if descriptor.isGlobal():
|
||||||
|
globals_ = camel_to_upper_snake(descriptor.name)
|
||||||
|
else:
|
||||||
|
globals_ = 'EMPTY'
|
||||||
return """\
|
return """\
|
||||||
DOMClass {
|
DOMClass {
|
||||||
interface_chain: [ %s ],
|
interface_chain: [ %s ],
|
||||||
type_id: %s,
|
type_id: %s,
|
||||||
heap_size_of: %s as unsafe fn(_) -> _,
|
heap_size_of: %s as unsafe fn(_) -> _,
|
||||||
}""" % (prototypeChainString, DOMClassTypeId(descriptor), heapSizeOf)
|
global: InterfaceObjectMap::%s,
|
||||||
|
}""" % (prototypeChainString, DOMClassTypeId(descriptor), heapSizeOf, globals_)
|
||||||
|
|
||||||
|
|
||||||
class CGDOMJSClass(CGThing):
|
class CGDOMJSClass(CGThing):
|
||||||
|
@ -2233,9 +2238,9 @@ match result {
|
||||||
|
|
||||||
class CGConstructorEnabled(CGAbstractMethod):
|
class CGConstructorEnabled(CGAbstractMethod):
|
||||||
"""
|
"""
|
||||||
A method for testing whether we should be exposing this interface
|
A method for testing whether we should be exposing this interface object.
|
||||||
object or navigator property. This can perform various tests
|
This can perform various tests depending on what conditions are specified
|
||||||
depending on what conditions are specified on the interface.
|
on the interface.
|
||||||
"""
|
"""
|
||||||
def __init__(self, descriptor):
|
def __init__(self, descriptor):
|
||||||
CGAbstractMethod.__init__(self, descriptor,
|
CGAbstractMethod.__init__(self, descriptor,
|
||||||
|
@ -2248,6 +2253,11 @@ class CGConstructorEnabled(CGAbstractMethod):
|
||||||
conditions = []
|
conditions = []
|
||||||
iface = self.descriptor.interface
|
iface = self.descriptor.interface
|
||||||
|
|
||||||
|
bits = " | ".join(sorted(
|
||||||
|
"InterfaceObjectMap::" + camel_to_upper_snake(i) for i in iface.exposureSet
|
||||||
|
))
|
||||||
|
conditions.append("is_exposed_in(aObj, %s)" % bits)
|
||||||
|
|
||||||
pref = iface.getExtendedAttribute("Pref")
|
pref = iface.getExtendedAttribute("Pref")
|
||||||
if pref:
|
if pref:
|
||||||
assert isinstance(pref, list) and len(pref) == 1
|
assert isinstance(pref, list) and len(pref) == 1
|
||||||
|
@ -2258,8 +2268,6 @@ class CGConstructorEnabled(CGAbstractMethod):
|
||||||
assert isinstance(func, list) and len(func) == 1
|
assert isinstance(func, list) and len(func) == 1
|
||||||
conditions.append("%s(aCx, aObj)" % func[0])
|
conditions.append("%s(aCx, aObj)" % func[0])
|
||||||
|
|
||||||
assert conditions
|
|
||||||
|
|
||||||
return CGList((CGGeneric(cond) for cond in conditions), " &&\n")
|
return CGList((CGGeneric(cond) for cond in conditions), " &&\n")
|
||||||
|
|
||||||
|
|
||||||
|
@ -2805,21 +2813,20 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
|
||||||
return CGAbstractMethod.define(self)
|
return CGAbstractMethod.define(self)
|
||||||
|
|
||||||
def definition_body(self):
|
def definition_body(self):
|
||||||
def getCheck(desc):
|
|
||||||
if not desc.isExposedConditionally():
|
|
||||||
return ""
|
|
||||||
else:
|
|
||||||
return "if !ConstructorEnabled(cx, global) { return; }"
|
|
||||||
if self.descriptor.interface.isCallback():
|
if self.descriptor.interface.isCallback():
|
||||||
function = "GetConstructorObject"
|
function = "GetConstructorObject"
|
||||||
else:
|
else:
|
||||||
function = "GetProtoObject"
|
function = "GetProtoObject"
|
||||||
return CGGeneric("""\
|
return CGGeneric("""\
|
||||||
assert!(!global.get().is_null());
|
assert!(!global.get().is_null());
|
||||||
%s
|
|
||||||
|
if !ConstructorEnabled(cx, global) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rooted!(in(cx) let mut proto = ptr::null_mut());
|
rooted!(in(cx) let mut proto = ptr::null_mut());
|
||||||
%s(cx, global, proto.handle_mut());
|
%s(cx, global, proto.handle_mut());
|
||||||
assert!(!proto.is_null());""" % (getCheck(self.descriptor), function))
|
assert!(!proto.is_null());""" % (function,))
|
||||||
|
|
||||||
|
|
||||||
def needCx(returnType, arguments, considerTypes):
|
def needCx(returnType, arguments, considerTypes):
|
||||||
|
@ -5133,7 +5140,6 @@ class CGDescriptor(CGThing):
|
||||||
|
|
||||||
if descriptor.interface.hasInterfaceObject():
|
if descriptor.interface.hasInterfaceObject():
|
||||||
cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
|
cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
|
||||||
if descriptor.isExposedConditionally():
|
|
||||||
cgThings.append(CGConstructorEnabled(descriptor))
|
cgThings.append(CGConstructorEnabled(descriptor))
|
||||||
|
|
||||||
if descriptor.proxy:
|
if descriptor.proxy:
|
||||||
|
@ -5555,6 +5561,7 @@ class CGBindingRoot(CGThing):
|
||||||
'js::glue::AppendToAutoIdVector',
|
'js::glue::AppendToAutoIdVector',
|
||||||
'js::rust::{GCMethods, define_methods, define_properties}',
|
'js::rust::{GCMethods, define_methods, define_properties}',
|
||||||
'dom::bindings',
|
'dom::bindings',
|
||||||
|
'dom::bindings::codegen::InterfaceObjectMap',
|
||||||
'dom::bindings::global::{GlobalRef, global_root_from_object, global_root_from_reflector}',
|
'dom::bindings::global::{GlobalRef, global_root_from_object, global_root_from_reflector}',
|
||||||
'dom::bindings::interface::{InterfaceConstructorBehavior, NonCallbackInterfaceObjectClass}',
|
'dom::bindings::interface::{InterfaceConstructorBehavior, NonCallbackInterfaceObjectClass}',
|
||||||
'dom::bindings::interface::{create_callback_interface_object, create_interface_prototype_object}',
|
'dom::bindings::interface::{create_callback_interface_object, create_interface_prototype_object}',
|
||||||
|
@ -5562,6 +5569,7 @@ class CGBindingRoot(CGThing):
|
||||||
'dom::bindings::interface::{define_guarded_methods, define_guarded_properties}',
|
'dom::bindings::interface::{define_guarded_methods, define_guarded_properties}',
|
||||||
'dom::bindings::interface::{ConstantSpec, NonNullJSNative}',
|
'dom::bindings::interface::{ConstantSpec, NonNullJSNative}',
|
||||||
'dom::bindings::interface::ConstantVal::{IntVal, UintVal}',
|
'dom::bindings::interface::ConstantVal::{IntVal, UintVal}',
|
||||||
|
'dom::bindings::interface::is_exposed_in',
|
||||||
'dom::bindings::js::{JS, Root, RootedReference}',
|
'dom::bindings::js::{JS, Root, RootedReference}',
|
||||||
'dom::bindings::js::{OptionalRootedReference}',
|
'dom::bindings::js::{OptionalRootedReference}',
|
||||||
'dom::bindings::reflector::{Reflectable}',
|
'dom::bindings::reflector::{Reflectable}',
|
||||||
|
@ -6215,6 +6223,10 @@ class CallbackSetter(CallbackMember):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def camel_to_upper_snake(s):
|
||||||
|
return "_".join(m.group(0).upper() for m in re.finditer("[A-Z][a-z]*", s))
|
||||||
|
|
||||||
|
|
||||||
class GlobalGenRoots():
|
class GlobalGenRoots():
|
||||||
"""
|
"""
|
||||||
Roots for global codegen.
|
Roots for global codegen.
|
||||||
|
@ -6232,6 +6244,18 @@ class GlobalGenRoots():
|
||||||
]
|
]
|
||||||
imports = CGList([CGGeneric("use %s;" % mod) for mod in mods], "\n")
|
imports = CGList([CGGeneric("use %s;" % mod) for mod in mods], "\n")
|
||||||
|
|
||||||
|
global_descriptors = config.getDescriptors(isGlobal=True)
|
||||||
|
flags = [("EMPTY", 0)]
|
||||||
|
flags.extend(
|
||||||
|
(camel_to_upper_snake(d.name), 2 ** idx)
|
||||||
|
for (idx, d) in enumerate(global_descriptors)
|
||||||
|
)
|
||||||
|
global_flags = CGWrapper(CGIndenter(CGList([
|
||||||
|
CGGeneric("const %s = %#x," % args)
|
||||||
|
for args in flags
|
||||||
|
], "\n")), pre="pub flags Globals: u8 {\n", post="\n}")
|
||||||
|
globals_ = CGWrapper(CGIndenter(global_flags), pre="bitflags! {\n", post="\n}")
|
||||||
|
|
||||||
pairs = []
|
pairs = []
|
||||||
for d in config.getDescriptors(hasInterfaceObject=True):
|
for d in config.getDescriptors(hasInterfaceObject=True):
|
||||||
binding = toBindingNamespace(d.name)
|
binding = toBindingNamespace(d.name)
|
||||||
|
@ -6251,7 +6275,7 @@ class GlobalGenRoots():
|
||||||
|
|
||||||
return CGList([
|
return CGList([
|
||||||
CGGeneric(AUTOGENERATED_WARNING_COMMENT),
|
CGGeneric(AUTOGENERATED_WARNING_COMMENT),
|
||||||
CGList([imports, phf], "\n\n")
|
CGList([imports, globals_, phf], "\n\n")
|
||||||
])
|
])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -85,6 +85,8 @@ class Configuration:
|
||||||
getter = lambda x: x.interface.isCallback()
|
getter = lambda x: x.interface.isCallback()
|
||||||
elif key == 'isJSImplemented':
|
elif key == 'isJSImplemented':
|
||||||
getter = lambda x: x.interface.isJSImplemented()
|
getter = lambda x: x.interface.isJSImplemented()
|
||||||
|
elif key == 'isGlobal':
|
||||||
|
getter = lambda x: x.isGlobal()
|
||||||
else:
|
else:
|
||||||
getter = lambda x: getattr(x, key)
|
getter = lambda x: getattr(x, key)
|
||||||
curr = filter(lambda x: getter(x) == val, curr)
|
curr = filter(lambda x: getter(x) == val, curr)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
//! Machinery to initialise interface prototype objects and interface objects.
|
//! Machinery to initialise interface prototype objects and interface objects.
|
||||||
|
|
||||||
|
use dom::bindings::codegen::InterfaceObjectMap::Globals;
|
||||||
use dom::bindings::codegen::PrototypeList;
|
use dom::bindings::codegen::PrototypeList;
|
||||||
use dom::bindings::conversions::get_dom_class;
|
use dom::bindings::conversions::get_dom_class;
|
||||||
use dom::bindings::guard::Guard;
|
use dom::bindings::guard::Guard;
|
||||||
|
@ -484,3 +485,11 @@ unsafe extern "C" fn non_new_constructor(
|
||||||
throw_type_error(cx, "This constructor needs to be called with `new`.");
|
throw_type_error(cx, "This constructor needs to be called with `new`.");
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether an interface with exposure set given by `globals` should
|
||||||
|
/// be exposed in the global object `obj`.
|
||||||
|
pub unsafe fn is_exposed_in(object: HandleObject, globals: Globals) -> bool {
|
||||||
|
let unwrapped = UncheckedUnwrapObject(object.get(), /* stopAtWindowProxy = */ 0);
|
||||||
|
let dom_class = get_dom_class(unwrapped).unwrap();
|
||||||
|
globals.contains(dom_class.global)
|
||||||
|
}
|
||||||
|
|
|
@ -93,6 +93,9 @@ pub struct DOMClass {
|
||||||
|
|
||||||
/// The HeapSizeOf function wrapper for that interface.
|
/// The HeapSizeOf function wrapper for that interface.
|
||||||
pub heap_size_of: unsafe fn(*const c_void) -> usize,
|
pub heap_size_of: unsafe fn(*const c_void) -> usize,
|
||||||
|
|
||||||
|
/// The `Globals` flag for this global interface, if any.
|
||||||
|
pub global: InterfaceObjectMap::Globals,
|
||||||
}
|
}
|
||||||
unsafe impl Sync for DOMClass {}
|
unsafe impl Sync for DOMClass {}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue