diff options
Diffstat (limited to 'components/script/dom/bindings/codegen/CodegenRust.py')
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 325 |
1 files changed, 288 insertions, 37 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 353e690baaf..03998017f36 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -1642,6 +1642,33 @@ class PropertyDefiner: + "];\n") % (name, specType) return specsArray + prefArray + def generateUnguardedArray(self, array, name, specTemplate, specTerminator, + specType, getCondition, getDataTuple): + """ + Takes the same set of parameters as generateGuardedArray but instead + generates a single, flat array of type `&[specType]` that contains all + provided members. The provided members' conditions shall be homogeneous, + or else this method will fail. + """ + + # this method can't handle heterogeneous condition + groups = groupby(array, lambda m: getCondition(m, self.descriptor)) + assert len(list(groups)) == 1 + + origTemplate = specTemplate + if isinstance(specTemplate, str): + specTemplate = lambda _: origTemplate # noqa + + specsArray = [specTemplate(m) % getDataTuple(m) for m in array] + specsArray.append(specTerminator) + + return dedent( + """ + const %s: &[%s] = &[ + %s + ]; + """) % (name, specType, ',\n'.join(specsArray)) + # The length of a method is the minimum of the lengths of the # argument lists of all its overloads. @@ -1656,10 +1683,15 @@ class MethodDefiner(PropertyDefiner): """ A class for defining methods on a prototype object. """ - def __init__(self, descriptor, name, static, unforgeable): + def __init__(self, descriptor, name, static, unforgeable, crossorigin=False): assert not (static and unforgeable) + assert not (static and crossorigin) + assert not (unforgeable and crossorigin) PropertyDefiner.__init__(self, descriptor, name) + # TODO: Separate the `(static, unforgeable, crossorigin) = (False, False, True)` case + # to a separate class or something. + # FIXME https://bugzilla.mozilla.org/show_bug.cgi?id=772822 # We should be able to check for special operations without an # identifier. For now we check if the name starts with __ @@ -1668,14 +1700,15 @@ class MethodDefiner(PropertyDefiner): if not descriptor.interface.isCallback() or static: methods = [m for m in descriptor.interface.members if m.isMethod() and m.isStatic() == static + and (bool(m.getExtendedAttribute("CrossOriginCallable")) or not crossorigin) and not m.isIdentifierLess() - and MemberIsUnforgeable(m, descriptor) == unforgeable] + and (MemberIsUnforgeable(m, descriptor) == unforgeable or crossorigin)] else: methods = [] self.regular = [{"name": m.identifier.name, "methodInfo": not m.isStatic(), "length": methodLength(m), - "flags": "JSPROP_ENUMERATE", + "flags": "JSPROP_READONLY" if crossorigin else "JSPROP_ENUMERATE", "condition": PropertyDefiner.getControllingCondition(m, descriptor)} for m in methods] @@ -1693,6 +1726,7 @@ class MethodDefiner(PropertyDefiner): # neither. if (not static and not unforgeable + and not crossorigin and descriptor.supportsIndexedProperties()): # noqa if hasIterator(methods, self.regular): # noqa raise TypeError("Cannot have indexed getter/attr on " @@ -1709,7 +1743,7 @@ class MethodDefiner(PropertyDefiner): # Generate the keys/values/entries aliases for value iterables. maplikeOrSetlikeOrIterable = descriptor.interface.maplikeOrSetlikeOrIterable - if (not static and not unforgeable + if (not static and not unforgeable and not crossorigin and maplikeOrSetlikeOrIterable and maplikeOrSetlikeOrIterable.isIterable() and maplikeOrSetlikeOrIterable.isValueIterator()): @@ -1754,7 +1788,7 @@ class MethodDefiner(PropertyDefiner): }) isUnforgeableInterface = bool(descriptor.interface.getExtendedAttribute("Unforgeable")) - if not static and unforgeable == isUnforgeableInterface: + if not static and unforgeable == isUnforgeableInterface and not crossorigin: stringifier = descriptor.operations['Stringifier'] if stringifier: self.regular.append({ @@ -1765,6 +1799,7 @@ class MethodDefiner(PropertyDefiner): "condition": PropertyDefiner.getControllingCondition(stringifier, descriptor) }) self.unforgeable = unforgeable + self.crossorigin = crossorigin def generateArray(self, array, name): if len(array) == 0: @@ -1796,36 +1831,54 @@ class MethodDefiner(PropertyDefiner): jitinfo = "ptr::null()" accessor = 'Some(%s)' % m.get("nativeName", m["name"]) if m["name"].startswith("@@"): + assert not self.crossorigin name = 'JSPropertySpec_Name { symbol_: SymbolCode::%s as usize + 1 }' % m["name"][2:] else: name = ('JSPropertySpec_Name { string_: %s as *const u8 as *const libc::c_char }' % str_to_const_array(m["name"])) return (name, accessor, jitinfo, m["length"], flags, selfHostedName) - return self.generateGuardedArray( - array, name, + specTemplate = ( ' JSFunctionSpec {\n' ' name: %s,\n' ' call: JSNativeWrapper { op: %s, info: %s },\n' ' nargs: %s,\n' ' flags: (%s) as u16,\n' ' selfHostedName: %s\n' - ' }', + ' }') + specTerminator = ( ' JSFunctionSpec {\n' ' name: JSPropertySpec_Name { string_: ptr::null() },\n' ' call: JSNativeWrapper { op: None, info: ptr::null() },\n' ' nargs: 0,\n' ' flags: 0,\n' ' selfHostedName: ptr::null()\n' - ' }', - 'JSFunctionSpec', - condition, specData) + ' }') + + if self.crossorigin: + return self.generateUnguardedArray( + array, name, + specTemplate, specTerminator, + 'JSFunctionSpec', + condition, specData) + else: + return self.generateGuardedArray( + array, name, + specTemplate, specTerminator, + 'JSFunctionSpec', + condition, specData) class AttrDefiner(PropertyDefiner): - def __init__(self, descriptor, name, static, unforgeable): + def __init__(self, descriptor, name, static, unforgeable, crossorigin=False): assert not (static and unforgeable) + assert not (static and crossorigin) + assert not (unforgeable and crossorigin) PropertyDefiner.__init__(self, descriptor, name) + + # TODO: Separate the `(static, unforgeable, crossorigin) = (False, False, True)` case + # to a separate class or something. + self.name = name self.descriptor = descriptor self.regular = [ @@ -1837,12 +1890,16 @@ class AttrDefiner(PropertyDefiner): } for m in descriptor.interface.members if m.isAttr() and m.isStatic() == static - and MemberIsUnforgeable(m, descriptor) == unforgeable + and (MemberIsUnforgeable(m, descriptor) == unforgeable or crossorigin) + and (not crossorigin + or m.getExtendedAttribute("CrossOriginReadable") + or m.getExtendedAttribute("CrossOriginWritable")) ] self.static = static self.unforgeable = unforgeable + self.crossorigin = crossorigin - if not static and not unforgeable and not ( + if not static and not unforgeable and not crossorigin and not ( descriptor.interface.isNamespace() or descriptor.interface.isCallback() ): self.regular.append({ @@ -1858,6 +1915,10 @@ class AttrDefiner(PropertyDefiner): def getter(attr): attr = attr['attr'] + + if self.crossorigin and not attr.getExtendedAttribute("CrossOriginReadable"): + return "JSNativeWrapper { op: None, info: 0 as *const JSJitInfo }" + if self.static: accessor = 'get_' + self.descriptor.internalNameFor(attr.identifier.name) jitinfo = "0 as *const JSJitInfo" @@ -1874,8 +1935,11 @@ class AttrDefiner(PropertyDefiner): def setter(attr): attr = attr['attr'] - if (attr.readonly and not attr.getExtendedAttribute("PutForwards") - and not attr.getExtendedAttribute("Replaceable")): + + if ((self.crossorigin and not attr.getExtendedAttribute("CrossOriginReadable")) + or (attr.readonly + and not attr.getExtendedAttribute("PutForwards") + and not attr.getExtendedAttribute("Replaceable"))): return "JSNativeWrapper { op: None, info: 0 as *const JSJitInfo }" if self.static: @@ -1941,12 +2005,20 @@ class AttrDefiner(PropertyDefiner): } """ - return self.generateGuardedArray( - array, name, - template, - ' JSPropertySpec::ZERO', - 'JSPropertySpec', - condition, specData) + if self.crossorigin: + return self.generateUnguardedArray( + array, name, + template, + ' JSPropertySpec::ZERO', + 'JSPropertySpec', + condition, specData) + else: + return self.generateGuardedArray( + array, name, + template, + ' JSPropertySpec::ZERO', + 'JSPropertySpec', + condition, specData) class ConstDefiner(PropertyDefiner): @@ -2821,6 +2893,13 @@ class CGWrapMethod(CGAbstractMethod): def definition_body(self): unforgeable = CopyUnforgeablePropertiesToInstance(self.descriptor) if self.descriptor.proxy: + if self.descriptor.isMaybeCrossOriginObject(): + proto = "ptr::null_mut()" + lazyProto = "true" # Our proxy handler will manage the prototype + else: + proto = "proto.get()" + lazyProto = "false" + create = """ let handler: *const libc::c_void = RegisterBindings::proxy_handlers::%(concreteType)s @@ -2829,8 +2908,9 @@ rooted!(in(*cx) let obj = NewProxyObject( *cx, handler, Handle::from_raw(UndefinedHandleValue), - proto.get(), + %(proto)s, ptr::null(), + %(lazyProto)s, )); assert!(!obj.is_null()); SetProxyReservedSlot( @@ -2839,7 +2919,11 @@ SetProxyReservedSlot( &PrivateValue(raw.as_ptr() as *const %(concreteType)s as *const libc::c_void), ); """ + create = create % {"concreteType": self.descriptor.concreteType, + "proto": proto, + "lazyProto": lazyProto} else: + lazyProto = None create = """ rooted!(in(*cx) let obj = JS_NewObjectWithGivenProto( *cx, @@ -2853,7 +2937,7 @@ JS_SetReservedSlot( &PrivateValue(raw.as_ptr() as *const %(concreteType)s as *const libc::c_void), ); """ - create = create % {"concreteType": self.descriptor.concreteType} + create = create % {"concreteType": self.descriptor.concreteType} if self.descriptor.weakReferenceable: create += """ let val = PrivateValue(ptr::null()); @@ -2912,6 +2996,7 @@ class CGWrapGlobalMethod(CGAbstractMethod): return CGGeneric("""\ let raw = Root::new(MaybeUnreflectedDom::from_box(object)); +let origin = (*raw.as_ptr()).upcast::<GlobalScope>().origin(); rooted!(in(*cx) let mut obj = ptr::null_mut::<JSObject>()); create_global_object( @@ -2919,7 +3004,8 @@ create_global_object( &Class.base, raw.as_ptr() as *const %(concreteType)s as *const libc::c_void, _trace, - obj.handle_mut()); + obj.handle_mut(), + origin); assert!(!obj.is_null()); let root = raw.reflect_with(obj.get()); @@ -3069,6 +3155,25 @@ class PropertyArrays(): return define +class CGCrossOriginProperties(CGThing): + def __init__(self, descriptor): + self.methods = MethodDefiner(descriptor, "CrossOriginMethods", static=False, + unforgeable=False, crossorigin=True) + self.attributes = AttrDefiner(descriptor, "CrossOriginAttributes", static=False, + unforgeable=False, crossorigin=True) + + def define(self): + return str(self.methods) + str(self.attributes) + dedent( + """ + const CROSS_ORIGIN_PROPERTIES: proxyhandler::CrossOriginProperties = + proxyhandler::CrossOriginProperties { + attributes: sCrossOriginAttributes, + methods: sCrossOriginMethods, + }; + """ + ) + + class CGCollectJSONAttributesMethod(CGAbstractMethod): """ Generate the CollectJSONAttributes method for an interface descriptor @@ -3449,20 +3554,45 @@ class CGDefineProxyHandler(CGAbstractMethod): def definition_body(self): customDefineProperty = 'proxyhandler::define_property' - if self.descriptor.operations['IndexedSetter'] or self.descriptor.operations['NamedSetter']: + if self.descriptor.isMaybeCrossOriginObject() or self.descriptor.operations['IndexedSetter'] or \ + self.descriptor.operations['NamedSetter']: customDefineProperty = 'defineProperty' customDelete = 'proxyhandler::delete' - if self.descriptor.operations['NamedDeleter']: + if self.descriptor.isMaybeCrossOriginObject() or self.descriptor.operations['NamedDeleter']: customDelete = 'delete' + customGetPrototypeIfOrdinary = 'Some(proxyhandler::get_prototype_if_ordinary)' + customGetPrototype = 'None' + customSetPrototype = 'None' + if self.descriptor.isMaybeCrossOriginObject(): + customGetPrototypeIfOrdinary = 'Some(proxyhandler::maybe_cross_origin_get_prototype_if_ordinary_rawcx)' + 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. + # This is the desired behavior, so we don't override it. + + customSet = 'None' + if self.descriptor.isMaybeCrossOriginObject(): + # `maybe_cross_origin_set_rawcx` doesn't support legacy platform objects' + # `[[Set]]` (https://heycam.github.io/webidl/#legacy-platform-object-set) (yet). + assert not self.descriptor.operations['IndexedGetter'] + assert not self.descriptor.operations['NamedGetter'] + customSet = 'Some(proxyhandler::maybe_cross_origin_set_rawcx)' + getOwnEnumerablePropertyKeys = "own_property_keys" - if self.descriptor.interface.getExtendedAttribute("LegacyUnenumerableNamedProperties"): + if self.descriptor.interface.getExtendedAttribute("LegacyUnenumerableNamedProperties") or \ + self.descriptor.isMaybeCrossOriginObject(): getOwnEnumerablePropertyKeys = "getOwnEnumerablePropertyKeys" args = { "defineProperty": customDefineProperty, "delete": customDelete, + "getPrototypeIfOrdinary": customGetPrototypeIfOrdinary, + "getPrototype": customGetPrototype, + "setPrototype": customSetPrototype, + "set": customSet, "getOwnEnumerablePropertyKeys": getOwnEnumerablePropertyKeys, "trace": TRACE_HOOK_NAME, "finalize": FINALIZE_HOOK_NAME, @@ -3476,15 +3606,15 @@ let traps = ProxyTraps { ownPropertyKeys: Some(own_property_keys), delete_: Some(%(delete)s), enumerate: None, - getPrototypeIfOrdinary: Some(proxyhandler::get_prototype_if_ordinary), - getPrototype: None, - setPrototype: None, + getPrototypeIfOrdinary: %(getPrototypeIfOrdinary)s, + getPrototype: %(getPrototype)s, + setPrototype: %(setPrototype)s, setImmutablePrototype: None, preventExtensions: Some(proxyhandler::prevent_extensions), isExtensible: Some(proxyhandler::is_extensible), has: None, get: Some(get), - set: None, + set: %(set)s, call: None, construct: None, hasOwn: Some(hasOwn), @@ -5351,6 +5481,26 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): indexedGetter = self.descriptor.operations['IndexedGetter'] get = "let cx = SafeJSContext::from_ptr(cx);\n" + + if self.descriptor.isMaybeCrossOriginObject(): + get += dedent( + """ + if !proxyhandler::is_platform_object_same_origin(cx, proxy) { + if !proxyhandler::cross_origin_get_own_property_helper( + cx, proxy, &CROSS_ORIGIN_PROPERTIES, id, desc + ) { + return false; + } + if desc.obj.is_null() { + return proxyhandler::cross_origin_property_fallback(cx, proxy, id, desc); + } + return true; + } + + // Safe to enter the Realm of proxy now. + let _ac = JSAutoRealm::new(*cx, proxy.get()); + """) + if indexedGetter: get += "let index = get_array_index_from_id(*cx, Handle::from_raw(id));\n" @@ -5448,6 +5598,17 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod): def getBody(self): set = "let cx = SafeJSContext::from_ptr(cx);\n" + if self.descriptor.isMaybeCrossOriginObject(): + set += dedent( + """ + if !proxyhandler::is_platform_object_same_origin(cx, proxy) { + return proxyhandler::report_cross_origin_denial(cx, id, "define"); + } + + // Safe to enter the Realm of proxy now. + let _ac = JSAutoRealm::new(*cx, proxy.get()); + """) + indexedSetter = self.descriptor.operations['IndexedSetter'] if indexedSetter: set += ("let index = get_array_index_from_id(*cx, Handle::from_raw(id));\n" @@ -5495,6 +5656,18 @@ class CGDOMJSProxyHandler_delete(CGAbstractExternMethod): def getBody(self): set = "let cx = SafeJSContext::from_ptr(cx);\n" + + if self.descriptor.isMaybeCrossOriginObject(): + set += dedent( + """ + if !proxyhandler::is_platform_object_same_origin(cx, proxy) { + return proxyhandler::report_cross_origin_denial(cx, id, "delete"); + } + + // Safe to enter the Realm of proxy now. + let _ac = JSAutoRealm::new(*cx, proxy.get()); + """) + if self.descriptor.operations['NamedDeleter']: if self.descriptor.hasUnforgeableMembers: raise TypeError("Can't handle a deleter on an interface that has " @@ -5522,6 +5695,17 @@ class CGDOMJSProxyHandler_ownPropertyKeys(CGAbstractExternMethod): let unwrapped_proxy = UnwrapProxy(proxy); """) + if self.descriptor.isMaybeCrossOriginObject(): + body += dedent( + """ + if !proxyhandler::is_platform_object_same_origin(cx, proxy) { + return proxyhandler::cross_origin_own_property_keys(cx, proxy, &CROSS_ORIGIN_PROPERTIES, props); + } + + // Safe to enter the Realm of proxy now. + let _ac = JSAutoRealm::new(*cx, proxy.get()); + """) + if self.descriptor.operations['IndexedGetter']: body += dedent( """ @@ -5566,7 +5750,8 @@ class CGDOMJSProxyHandler_ownPropertyKeys(CGAbstractExternMethod): class CGDOMJSProxyHandler_getOwnEnumerablePropertyKeys(CGAbstractExternMethod): def __init__(self, descriptor): assert (descriptor.operations["IndexedGetter"] - and descriptor.interface.getExtendedAttribute("LegacyUnenumerableNamedProperties")) + and descriptor.interface.getExtendedAttribute("LegacyUnenumerableNamedProperties") + or descriptor.isMaybeCrossOriginObject()) args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'), Argument('RawMutableHandleIdVector', 'props')] @@ -5581,6 +5766,18 @@ class CGDOMJSProxyHandler_getOwnEnumerablePropertyKeys(CGAbstractExternMethod): let unwrapped_proxy = UnwrapProxy(proxy); """) + if self.descriptor.isMaybeCrossOriginObject(): + body += dedent( + """ + if !proxyhandler::is_platform_object_same_origin(cx, proxy) { + // There are no enumerable cross-origin props, so we're done. + return true; + } + + // Safe to enter the Realm of proxy now. + let _ac = JSAutoRealm::new(*cx, proxy.get()); + """) + if self.descriptor.operations['IndexedGetter']: body += dedent( """ @@ -5619,6 +5816,18 @@ class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod): def getBody(self): indexedGetter = self.descriptor.operations['IndexedGetter'] indexed = "let cx = SafeJSContext::from_ptr(cx);\n" + + if self.descriptor.isMaybeCrossOriginObject(): + indexed += dedent( + """ + if !proxyhandler::is_platform_object_same_origin(cx, proxy) { + return proxyhandler::cross_origin_has_own(cx, proxy, &CROSS_ORIGIN_PROPERTIES, id, bp); + } + + // Safe to enter the Realm of proxy now. + let _ac = JSAutoRealm::new(*cx, proxy.get()); + """) + if indexedGetter: indexed += ("let index = get_array_index_from_id(*cx, Handle::from_raw(id));\n" + "if let Some(index) = index {\n" @@ -5680,6 +5889,18 @@ class CGDOMJSProxyHandler_get(CGAbstractExternMethod): # https://heycam.github.io/webidl/#LegacyPlatformObjectGetOwnProperty def getBody(self): + if self.descriptor.isMaybeCrossOriginObject(): + maybeCrossOriginGet = dedent( + """ + if !proxyhandler::is_platform_object_same_origin(cx, proxy) { + return proxyhandler::cross_origin_get(cx, proxy, receiver, id, vp); + } + + // Safe to enter the Realm of proxy now. + let _ac = JSAutoRealm::new(*cx, proxy.get()); + """) + else: + maybeCrossOriginGet = "" getFromExpando = """\ rooted!(in(*cx) let mut expando = ptr::null_mut::<JSObject>()); get_expando_object(proxy, expando.handle_mut()); @@ -5735,6 +5956,9 @@ if !expando.is_null() { //MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy), //"Should not have a XrayWrapper here"); let cx = SafeJSContext::from_ptr(cx); + +%s + let proxy_lt = Handle::from_raw(proxy); let vp_lt = MutableHandle::from_raw(vp); let id_lt = Handle::from_raw(id); @@ -5751,7 +5975,26 @@ if found { } %s vp.set(UndefinedValue()); -return true;""" % (getIndexedOrExpando, getNamed) +return true;""" % (maybeCrossOriginGet, getIndexedOrExpando, getNamed) + + def definition_body(self): + return CGGeneric(self.getBody()) + + +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) + assert descriptor.isMaybeCrossOriginObject() + self.descriptor = descriptor + + def getBody(self): + return dedent( + """ + let cx = SafeJSContext::from_ptr(cx); + proxyhandler::maybe_cross_origin_get_prototype(cx, proxy, GetProtoObject, proto) + """) def definition_body(self): return CGGeneric(self.getBody()) @@ -6390,6 +6633,9 @@ class CGDescriptor(CGThing): if descriptor.proxy: cgThings.append(CGDefineProxyHandler(descriptor)) + if descriptor.isMaybeCrossOriginObject(): + cgThings.append(CGCrossOriginProperties(descriptor)) + properties = PropertyArrays(descriptor) if defaultToJSONMethod: @@ -6401,22 +6647,27 @@ class CGDescriptor(CGThing): cgThings.append(CGProxyUnwrap(descriptor)) cgThings.append(CGDOMJSProxyHandlerDOMClass(descriptor)) cgThings.append(CGDOMJSProxyHandler_ownPropertyKeys(descriptor)) - if descriptor.interface.getExtendedAttribute("LegacyUnenumerableNamedProperties"): + if descriptor.interface.getExtendedAttribute("LegacyUnenumerableNamedProperties") or \ + descriptor.isMaybeCrossOriginObject(): cgThings.append(CGDOMJSProxyHandler_getOwnEnumerablePropertyKeys(descriptor)) cgThings.append(CGDOMJSProxyHandler_getOwnPropertyDescriptor(descriptor)) cgThings.append(CGDOMJSProxyHandler_className(descriptor)) cgThings.append(CGDOMJSProxyHandler_get(descriptor)) cgThings.append(CGDOMJSProxyHandler_hasOwn(descriptor)) - if descriptor.operations['IndexedSetter'] or descriptor.operations['NamedSetter']: + if descriptor.isMaybeCrossOriginObject() or descriptor.operations['IndexedSetter'] or \ + descriptor.operations['NamedSetter']: cgThings.append(CGDOMJSProxyHandler_defineProperty(descriptor)) # We want to prevent indexed deleters from compiling at all. assert not descriptor.operations['IndexedDeleter'] - if descriptor.operations['NamedDeleter']: + if descriptor.isMaybeCrossOriginObject() or descriptor.operations['NamedDeleter']: cgThings.append(CGDOMJSProxyHandler_delete(descriptor)) + if descriptor.isMaybeCrossOriginObject(): + cgThings.append(CGDOMJSProxyHandler_getPrototype(descriptor)) + # cgThings.append(CGDOMJSProxyHandler(descriptor)) # cgThings.append(CGIsMethod(descriptor)) pass |