From da28a791e5d43579ab1538c86734a980b816d810 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Sat, 21 Jun 2014 10:32:21 +0200 Subject: [PATCH 1/3] Store the arrays of properties as &'static [T] rather than [T, ..N]. This means the .as_slice() call (which is problematic when storing the array in a static struct) is no longer necessary. --- src/components/script/dom/bindings/codegen/CodegenRust.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index fda7fea34f8..725597b035b 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -1101,9 +1101,9 @@ class PropertyDefiner: if specTerminator: specs.append(specTerminator) - return (("static %s: [%s, ..%i] = [\n" + + return (("static %s: &'static [%s] = &[\n" + ",\n".join(specs) + "\n" + - "];\n\n") % (name, specType, len(specs))) + "];\n\n") % (name, specType)) # The length of a method is the maximum of the lengths of the # argument lists of all its overloads. @@ -1894,7 +1894,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): val = ('%(' + name + ')s') % self.properties.variableNames() if val == "ptr::null()": return "None" - return "Some(%s.as_slice())" % val + return "Some(%s)" % val if needInterfaceObject: if self.descriptor.interface.ctor(): From 886d401ff0bdbceaec528fb40b6eb719f7857e86 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Sat, 21 Jun 2014 12:38:45 +0200 Subject: [PATCH 2/3] Introduce a NativeProperties struct to store the properties. This will simplify adding more kinds of properties, such as static attributes. --- .../dom/bindings/codegen/CodegenRust.py | 52 +++++++++++++------ src/components/script/dom/bindings/utils.rs | 7 +++ 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 725597b035b..a4b6e00c388 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -1064,9 +1064,10 @@ class PropertyDefiner: self.name = name def variableName(self): - if len(self.regular) > 0: - return "s" + self.name - return "ptr::null()" + return "s" + self.name + + def length(self): + return len(self.regular) def __str__(self): # We only need to generate id arrays for things that will end @@ -1853,6 +1854,31 @@ class PropertyArrays(): define += str(getattr(self, array)) return define + +class CGNativeProperties(CGThing): + def __init__(self, descriptor, properties): + CGThing.__init__(self) + self.properties = properties + + def define(self): + def getField(array): + propertyArray = getattr(self.properties, array) + if propertyArray.length() > 0: + value = "Some(%s)" % propertyArray.variableName() + else: + value = "None" + + return CGGeneric(string.Template('${name}: ${value},').substitute({ + 'name': array, + 'value': value, + })) + + nativeProps = CGList([getField(array) for array in self.properties.arrayNames()], '\n') + return CGWrapper(CGIndenter(nativeProps), + pre="static sNativeProperties: NativeProperties = NativeProperties {\n", + post="\n};\n").define() + + class CGCreateInterfaceObjectsMethod(CGAbstractMethod): """ Generate the CreateInterfaceObjects method for an interface descriptor. @@ -1890,12 +1916,6 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): else: domClass = "ptr::null()" - def arrayPtr(name): - val = ('%(' + name + ')s') % self.properties.variableNames() - if val == "ptr::null()": - return "None" - return "Some(%s)" % val - if needInterfaceObject: if self.descriptor.interface.ctor(): constructHook = CONSTRUCT_HOOK_NAME @@ -1913,14 +1933,12 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto, &PrototypeClass, %s, %s, - %s, - %s, - %s, - %s);""" % ( + sNativeProperties.methods, + sNativeProperties.attrs, + sNativeProperties.consts, + sNativeProperties.staticMethods);""" % ( constructor, - domClass, - arrayPtr("methods"), arrayPtr("attrs"), - arrayPtr("consts"), arrayPtr("staticMethods")) + domClass) return CGList([ CGGeneric(getParentProto), @@ -3863,6 +3881,7 @@ class CGDescriptor(CGThing): properties = PropertyArrays(descriptor) cgThings.append(CGGeneric(str(properties))) + cgThings.append(CGNativeProperties(descriptor, properties)) cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties)) cgThings.append(CGNamespace.build([descriptor.name + "Constants"], @@ -4233,6 +4252,7 @@ class CGBindingRoot(CGThing): 'dom::bindings::utils::{ThrowingConstructor, unwrap, unwrap_jsmanaged}', 'dom::bindings::utils::VoidVal', 'dom::bindings::utils::get_dictionary_property', + 'dom::bindings::utils::NativeProperties', 'dom::bindings::trace::JSTraceable', 'dom::bindings::callback::{CallbackContainer,CallbackInterface,CallbackFunction}', 'dom::bindings::callback::{CallSetup,ExceptionHandling}', diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index b94dd02042a..106353e228d 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -215,6 +215,13 @@ pub fn GetProtoOrIfaceArray(global: *mut JSObject) -> *mut *mut JSObject { } } +pub struct NativeProperties { + pub methods: Option<&'static [JSFunctionSpec]>, + pub attrs: Option<&'static [JSPropertySpec]>, + pub consts: Option<&'static [ConstantSpec]>, + pub staticMethods: Option<&'static [JSFunctionSpec]>, +} + pub type NonNullJSNative = unsafe extern "C" fn (arg1: *mut JSContext, arg2: c_uint, arg3: *mut JSVal) -> JSBool; From 4964d2792e981476349f0aa5d3c12995a7838d80 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Sat, 21 Jun 2014 12:43:35 +0200 Subject: [PATCH 3/3] Pass the NativeProperties struct to CreateInterfaceObjects2. This will simplify adding more kinds of properties, such as static attributes. --- .../dom/bindings/codegen/CodegenRust.py | 7 +---- src/components/script/dom/bindings/utils.rs | 27 +++++++------------ 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index a4b6e00c388..69bf5c87335 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -1933,12 +1933,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto, &PrototypeClass, %s, %s, - sNativeProperties.methods, - sNativeProperties.attrs, - sNativeProperties.consts, - sNativeProperties.staticMethods);""" % ( - constructor, - domClass) + &sNativeProperties);""" % (constructor, domClass) return CGList([ CGGeneric(getParentProto), diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index 106353e228d..d9be42433d9 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -230,13 +230,9 @@ pub fn CreateInterfaceObjects2(cx: *mut JSContext, global: *mut JSObject, receiv protoClass: &'static JSClass, constructor: Option<(NonNullJSNative, &'static str, u32)>, domClass: *DOMClass, - methods: Option<&'static [JSFunctionSpec]>, - properties: Option<&'static [JSPropertySpec]>, - constants: Option<&'static [ConstantSpec]>, - staticMethods: Option<&'static [JSFunctionSpec]>) -> *mut JSObject { + members: &'static NativeProperties) -> *mut JSObject { let proto = CreateInterfacePrototypeObject(cx, global, protoProto, - protoClass, methods, - properties, constants); + protoClass, members); unsafe { JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT, @@ -248,7 +244,7 @@ pub fn CreateInterfaceObjects2(cx: *mut JSContext, global: *mut JSObject, receiv name.to_c_str().with_ref(|s| { CreateInterfaceObject(cx, global, receiver, native, nargs, proto, - staticMethods, constants, s) + members, s) }) }, None => (), @@ -260,8 +256,7 @@ pub fn CreateInterfaceObjects2(cx: *mut JSContext, global: *mut JSObject, receiv fn CreateInterfaceObject(cx: *mut JSContext, global: *mut JSObject, receiver: *mut JSObject, constructorNative: NonNullJSNative, ctorNargs: u32, proto: *mut JSObject, - staticMethods: Option<&'static [JSFunctionSpec]>, - constants: Option<&'static [ConstantSpec]>, + members: &'static NativeProperties, name: *libc::c_char) { unsafe { let fun = JS_NewFunction(cx, Some(constructorNative), ctorNargs, @@ -271,12 +266,12 @@ fn CreateInterfaceObject(cx: *mut JSContext, global: *mut JSObject, receiver: *m let constructor = JS_GetFunctionObject(fun); assert!(constructor.is_not_null()); - match staticMethods { + match members.staticMethods { Some(staticMethods) => DefineMethods(cx, constructor, staticMethods), _ => (), } - match constants { + match members.consts { Some(constants) => DefineConstants(cx, constructor, constants), _ => (), } @@ -330,24 +325,22 @@ fn DefineProperties(cx: *mut JSContext, obj: *mut JSObject, properties: &'static fn CreateInterfacePrototypeObject(cx: *mut JSContext, global: *mut JSObject, parentProto: *mut JSObject, protoClass: &'static JSClass, - methods: Option<&'static [JSFunctionSpec]>, - properties: Option<&'static [JSPropertySpec]>, - constants: Option<&'static [ConstantSpec]>) -> *mut JSObject { + members: &'static NativeProperties) -> *mut JSObject { unsafe { let ourProto = JS_NewObjectWithUniqueType(cx, protoClass, parentProto, global); assert!(ourProto.is_not_null()); - match methods { + match members.methods { Some(methods) => DefineMethods(cx, ourProto, methods), _ => (), } - match properties { + match members.attrs { Some(properties) => DefineProperties(cx, ourProto, properties), _ => (), } - match constants { + match members.consts { Some(constants) => DefineConstants(cx, ourProto, constants), _ => (), }