From c8b8550cfb42054ffbc879d622459cbfbfd8f171 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 18 Jun 2014 10:21:56 +0200 Subject: [PATCH 1/5] Correct the condition for generating CGGetConstructorObjectMethod. As we don't actually implement the feature for which this is needed, I've commented the call out for now and mentioned the issue for the feature. --- src/components/script/dom/bindings/codegen/CodegenRust.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 6962a154574..3fd95722f34 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -3807,8 +3807,10 @@ class CGDescriptor(CGThing): cgThings = [] if descriptor.interface.hasInterfacePrototypeObject(): cgThings.append(CGGetProtoObjectMethod(descriptor)) - else: - cgThings.append(CGGetConstructorObjectMethod(descriptor)) + if descriptor.interface.hasInterfaceObject(): + # https://github.com/mozilla/servo/issues/2665 + # cgThings.append(CGGetConstructorObjectMethod(descriptor)) + pass if descriptor.interface.hasInterfacePrototypeObject(): (hasMethod, hasGetter, hasLenientGetter, From f11e7ee0a9f0d0181ce5efa809ccff888d1ff06a Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 20 Jun 2014 17:31:47 +0200 Subject: [PATCH 2/5] Generate code for NoInterfaceObject interfaces in InterfaceTypes and InheritTypes. There is no reason for those interfaces to be excluded. --- .../script/dom/bindings/codegen/CodegenRust.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 3fd95722f34..3155ab2f025 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -5128,13 +5128,7 @@ class GlobalGenRoots(): @staticmethod def InterfaceTypes(config): - - def pathToType(descriptor): - if descriptor.interface.isCallback(): - return "dom::bindings::codegen::Bindings::%sBinding" % descriptor.name - return "dom::%s" % descriptor.name.lower() - - descriptors = [d.name for d in config.getDescriptors(register=True, hasInterfaceObject=True)] + descriptors = [d.name for d in config.getDescriptors(register=True, isCallback=False)] curr = CGList([CGGeneric("pub use dom::%s::%s;\n" % (name.lower(), name)) for name in descriptors]) curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT) return curr @@ -5151,7 +5145,7 @@ class GlobalGenRoots(): @staticmethod def InheritTypes(config): - descriptors = config.getDescriptors(register=True, hasInterfaceObject=True) + descriptors = config.getDescriptors(register=True, isCallback=False) allprotos = [CGGeneric("#![allow(unused_imports)]\n"), CGGeneric("use dom::types::*;\n"), CGGeneric("use dom::bindings::js::{JS, JSRef, Temporary};\n"), From 5acbea51999ead858aa90266a5ab4473a3dd11da Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 20 Jun 2014 17:50:40 +0200 Subject: [PATCH 3/5] Pass the interface object-related arguments to CreateInterfaceObjects2 together in an Option. This clarifies the code and fixes our support of NoInterfaceObject interfaces. --- .../dom/bindings/codegen/CodegenRust.py | 30 +++++++++++-------- src/components/script/dom/bindings/utils.rs | 30 +++++++++++-------- 2 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 3155ab2f025..647fd50766f 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -1880,13 +1880,6 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): getParentProto = ("let parentProto: *mut JSObject = %s;\n" "assert!(parentProto.is_not_null());\n") % getParentProto - if self.descriptor.interface.ctor(): - constructHook = CONSTRUCT_HOOK_NAME - constructArgs = methodLength(self.descriptor.interface.ctor()) - else: - constructHook = "ThrowingConstructor" - constructArgs = 0 - if self.descriptor.concrete: if self.descriptor.proxy: domClass = "&Class" @@ -1901,20 +1894,31 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): return "None" return "Some(%s.as_slice())" % val + if needInterfaceObject: + if self.descriptor.interface.ctor(): + constructHook = CONSTRUCT_HOOK_NAME + constructArgs = methodLength(self.descriptor.interface.ctor()) + else: + constructHook = "ThrowingConstructor" + constructArgs = 0 + + constructor = 'Some((%s, "%s", %d))' % ( + constructHook, self.descriptor.interface.identifier.name, + constructArgs) + else: + constructor = 'None' + call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto, - &PrototypeClass, %s, %d, - %s, + &PrototypeClass, %s, %s, %s, %s, %s, %s);""" % ( - "Some(%s)" % constructHook if needInterfaceObject else "None", - constructArgs, + constructor, domClass, arrayPtr("methods"), arrayPtr("attrs"), - arrayPtr("consts"), arrayPtr("staticMethods"), - '"' + self.descriptor.interface.identifier.name + '"' if needInterfaceObject else "ptr::null()") + arrayPtr("consts"), arrayPtr("staticMethods")) functionBody = CGList( [CGGeneric(getParentProto), diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index 1e278b8ef48..b94dd02042a 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -34,7 +34,7 @@ use js::jsapi::{JS_HasPropertyById, JS_GetPrototype}; use js::jsapi::{JS_GetProperty, JS_HasProperty}; use js::jsapi::{JS_DefineFunctions, JS_DefineProperty}; use js::jsapi::{JS_ValueToString, JS_GetReservedSlot, JS_SetReservedSlot}; -use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass, JSNative}; +use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass}; use js::jsapi::{JSFunctionSpec, JSPropertySpec}; use js::jsapi::{JS_NewGlobalObject, JS_InitStandardClasses}; use js::jsapi::{JSString}; @@ -215,17 +215,18 @@ pub fn GetProtoOrIfaceArray(global: *mut JSObject) -> *mut *mut JSObject { } } +pub type NonNullJSNative = + unsafe extern "C" fn (arg1: *mut JSContext, arg2: c_uint, arg3: *mut JSVal) -> JSBool; + pub fn CreateInterfaceObjects2(cx: *mut JSContext, global: *mut JSObject, receiver: *mut JSObject, protoProto: *mut JSObject, protoClass: &'static JSClass, - constructor: JSNative, - ctorNargs: u32, + constructor: Option<(NonNullJSNative, &'static str, u32)>, domClass: *DOMClass, methods: Option<&'static [JSFunctionSpec]>, properties: Option<&'static [JSPropertySpec]>, constants: Option<&'static [ConstantSpec]>, - staticMethods: Option<&'static [JSFunctionSpec]>, - name: &str) -> *mut JSObject { + staticMethods: Option<&'static [JSFunctionSpec]>) -> *mut JSObject { let proto = CreateInterfacePrototypeObject(cx, global, protoProto, protoClass, methods, properties, constants); @@ -235,25 +236,28 @@ pub fn CreateInterfaceObjects2(cx: *mut JSContext, global: *mut JSObject, receiv PrivateValue(domClass as *libc::c_void)); } - if constructor.is_some() { - name.to_c_str().with_ref(|s| { - CreateInterfaceObject(cx, global, receiver, - constructor, ctorNargs, proto, - staticMethods, constants, s) - }); + match constructor { + Some((native, name, nargs)) => { + name.to_c_str().with_ref(|s| { + CreateInterfaceObject(cx, global, receiver, + native, nargs, proto, + staticMethods, constants, s) + }) + }, + None => (), } proto } fn CreateInterfaceObject(cx: *mut JSContext, global: *mut JSObject, receiver: *mut JSObject, - constructorNative: JSNative, + constructorNative: NonNullJSNative, ctorNargs: u32, proto: *mut JSObject, staticMethods: Option<&'static [JSFunctionSpec]>, constants: Option<&'static [ConstantSpec]>, name: *libc::c_char) { unsafe { - let fun = JS_NewFunction(cx, constructorNative, ctorNargs, + let fun = JS_NewFunction(cx, Some(constructorNative), ctorNargs, JSFUN_CONSTRUCTOR, global, name); assert!(fun.is_not_null()); From 8df0f981fec91d069e5756f775152b6fbfd88686 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 20 Jun 2014 19:20:52 +0200 Subject: [PATCH 4/5] Keep calling the DefineDOMInterface method for NoInterfaceObject interfaces. DefineDOMInterface also creates the proxy handler for proxy classes, so it should be called in this case as well. --- .../dom/bindings/codegen/CodegenRust.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 647fd50766f..293cdf0ca4d 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -2001,13 +2001,6 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod): return CGAbstractMethod.define(self) def definition_body(self): - if self.descriptor.interface.hasInterfacePrototypeObject(): - # We depend on GetProtoObject defining an interface constructor - # object as needed. - getter = "GetProtoObject" - else: - getter = "GetConstructorObject" - body = "" #XXXjdm This self.descriptor.concrete check shouldn't be necessary if not self.descriptor.concrete or self.descriptor.proxy: @@ -2049,10 +2042,13 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod): TRACE_HOOK_NAME, self.descriptor.name) - return (body + """ let cx = (**js_info.js_context).ptr; + if self.descriptor.interface.hasInterfaceObject(): + body += """ let cx = (**js_info.js_context).ptr; let global = window.reflector().get_jsobject(); assert!(global.is_not_null()); - assert!(%s(cx, global, global).is_not_null());""" % (getter)) + assert!(GetProtoObject(cx, global, global).is_not_null());""" + + return body def needCx(returnType, arguments, extendedAttributes, considerTypes): return (considerTypes and @@ -3867,8 +3863,7 @@ class CGDescriptor(CGThing): CGConstant(m for m in descriptor.interface.members if m.isConst()), public=True)) - if descriptor.interface.hasInterfaceObject(): - cgThings.append(CGDefineDOMInterfaceMethod(descriptor)) + cgThings.append(CGDefineDOMInterfaceMethod(descriptor)) if descriptor.concrete: if descriptor.proxy: @@ -4114,7 +4109,7 @@ class CGRegisterProtos(CGAbstractMethod): def _registerProtos(self): lines = [" codegen::Bindings::%sBinding::DefineDOMInterface(window, js_info);" % desc.name - for desc in self.config.getDescriptors(hasInterfaceObject=True, + for desc in self.config.getDescriptors(isCallback=False, register=True)] return '\n'.join(lines) + '\n' def definition_body(self): From 93220523b0a76345bc2749bdba33bcef040d66c0 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Fri, 20 Jun 2014 18:57:47 +0200 Subject: [PATCH 5/5] Make AttrList NoInterfaceObject (fixes #1223). --- src/components/script/dom/webidls/AttrList.webidl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/script/dom/webidls/AttrList.webidl b/src/components/script/dom/webidls/AttrList.webidl index d37bb53a3b8..f9419f5ef62 100644 --- a/src/components/script/dom/webidls/AttrList.webidl +++ b/src/components/script/dom/webidls/AttrList.webidl @@ -2,7 +2,8 @@ * 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/. */ +[NoInterfaceObject] interface AttrList { readonly attribute unsigned long length; getter Attr? item(unsigned long index); -}; \ No newline at end of file +};