mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Merge pull request #2695 from Ms2ger/NativeProperties
Introduce a NativeProperties struct; r=jdm
This commit is contained in:
commit
5e21e981ae
2 changed files with 51 additions and 36 deletions
|
@ -1064,9 +1064,10 @@ class PropertyDefiner:
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
def variableName(self):
|
def variableName(self):
|
||||||
if len(self.regular) > 0:
|
return "s" + self.name
|
||||||
return "s" + self.name
|
|
||||||
return "ptr::null()"
|
def length(self):
|
||||||
|
return len(self.regular)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
# We only need to generate id arrays for things that will end
|
# We only need to generate id arrays for things that will end
|
||||||
|
@ -1101,9 +1102,9 @@ class PropertyDefiner:
|
||||||
if specTerminator:
|
if specTerminator:
|
||||||
specs.append(specTerminator)
|
specs.append(specTerminator)
|
||||||
|
|
||||||
return (("static %s: [%s, ..%i] = [\n" +
|
return (("static %s: &'static [%s] = &[\n" +
|
||||||
",\n".join(specs) + "\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
|
# The length of a method is the maximum of the lengths of the
|
||||||
# argument lists of all its overloads.
|
# argument lists of all its overloads.
|
||||||
|
@ -1853,6 +1854,31 @@ class PropertyArrays():
|
||||||
define += str(getattr(self, array))
|
define += str(getattr(self, array))
|
||||||
return define
|
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):
|
class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
||||||
"""
|
"""
|
||||||
Generate the CreateInterfaceObjects method for an interface descriptor.
|
Generate the CreateInterfaceObjects method for an interface descriptor.
|
||||||
|
@ -1890,12 +1916,6 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
||||||
else:
|
else:
|
||||||
domClass = "ptr::null()"
|
domClass = "ptr::null()"
|
||||||
|
|
||||||
def arrayPtr(name):
|
|
||||||
val = ('%(' + name + ')s') % self.properties.variableNames()
|
|
||||||
if val == "ptr::null()":
|
|
||||||
return "None"
|
|
||||||
return "Some(%s.as_slice())" % val
|
|
||||||
|
|
||||||
if needInterfaceObject:
|
if needInterfaceObject:
|
||||||
if self.descriptor.interface.ctor():
|
if self.descriptor.interface.ctor():
|
||||||
constructHook = CONSTRUCT_HOOK_NAME
|
constructHook = CONSTRUCT_HOOK_NAME
|
||||||
|
@ -1913,14 +1933,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
||||||
call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto,
|
call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto,
|
||||||
&PrototypeClass, %s,
|
&PrototypeClass, %s,
|
||||||
%s,
|
%s,
|
||||||
%s,
|
&sNativeProperties);""" % (constructor, domClass)
|
||||||
%s,
|
|
||||||
%s,
|
|
||||||
%s);""" % (
|
|
||||||
constructor,
|
|
||||||
domClass,
|
|
||||||
arrayPtr("methods"), arrayPtr("attrs"),
|
|
||||||
arrayPtr("consts"), arrayPtr("staticMethods"))
|
|
||||||
|
|
||||||
return CGList([
|
return CGList([
|
||||||
CGGeneric(getParentProto),
|
CGGeneric(getParentProto),
|
||||||
|
@ -3863,6 +3876,7 @@ class CGDescriptor(CGThing):
|
||||||
|
|
||||||
properties = PropertyArrays(descriptor)
|
properties = PropertyArrays(descriptor)
|
||||||
cgThings.append(CGGeneric(str(properties)))
|
cgThings.append(CGGeneric(str(properties)))
|
||||||
|
cgThings.append(CGNativeProperties(descriptor, properties))
|
||||||
cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties))
|
cgThings.append(CGCreateInterfaceObjectsMethod(descriptor, properties))
|
||||||
|
|
||||||
cgThings.append(CGNamespace.build([descriptor.name + "Constants"],
|
cgThings.append(CGNamespace.build([descriptor.name + "Constants"],
|
||||||
|
@ -4233,6 +4247,7 @@ class CGBindingRoot(CGThing):
|
||||||
'dom::bindings::utils::{ThrowingConstructor, unwrap, unwrap_jsmanaged}',
|
'dom::bindings::utils::{ThrowingConstructor, unwrap, unwrap_jsmanaged}',
|
||||||
'dom::bindings::utils::VoidVal',
|
'dom::bindings::utils::VoidVal',
|
||||||
'dom::bindings::utils::get_dictionary_property',
|
'dom::bindings::utils::get_dictionary_property',
|
||||||
|
'dom::bindings::utils::NativeProperties',
|
||||||
'dom::bindings::trace::JSTraceable',
|
'dom::bindings::trace::JSTraceable',
|
||||||
'dom::bindings::callback::{CallbackContainer,CallbackInterface,CallbackFunction}',
|
'dom::bindings::callback::{CallbackContainer,CallbackInterface,CallbackFunction}',
|
||||||
'dom::bindings::callback::{CallSetup,ExceptionHandling}',
|
'dom::bindings::callback::{CallSetup,ExceptionHandling}',
|
||||||
|
|
|
@ -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 =
|
pub type NonNullJSNative =
|
||||||
unsafe extern "C" fn (arg1: *mut JSContext, arg2: c_uint, arg3: *mut JSVal) -> JSBool;
|
unsafe extern "C" fn (arg1: *mut JSContext, arg2: c_uint, arg3: *mut JSVal) -> JSBool;
|
||||||
|
|
||||||
|
@ -223,13 +230,9 @@ pub fn CreateInterfaceObjects2(cx: *mut JSContext, global: *mut JSObject, receiv
|
||||||
protoClass: &'static JSClass,
|
protoClass: &'static JSClass,
|
||||||
constructor: Option<(NonNullJSNative, &'static str, u32)>,
|
constructor: Option<(NonNullJSNative, &'static str, u32)>,
|
||||||
domClass: *DOMClass,
|
domClass: *DOMClass,
|
||||||
methods: Option<&'static [JSFunctionSpec]>,
|
members: &'static NativeProperties) -> *mut JSObject {
|
||||||
properties: Option<&'static [JSPropertySpec]>,
|
|
||||||
constants: Option<&'static [ConstantSpec]>,
|
|
||||||
staticMethods: Option<&'static [JSFunctionSpec]>) -> *mut JSObject {
|
|
||||||
let proto = CreateInterfacePrototypeObject(cx, global, protoProto,
|
let proto = CreateInterfacePrototypeObject(cx, global, protoProto,
|
||||||
protoClass, methods,
|
protoClass, members);
|
||||||
properties, constants);
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
|
JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
|
||||||
|
@ -241,7 +244,7 @@ pub fn CreateInterfaceObjects2(cx: *mut JSContext, global: *mut JSObject, receiv
|
||||||
name.to_c_str().with_ref(|s| {
|
name.to_c_str().with_ref(|s| {
|
||||||
CreateInterfaceObject(cx, global, receiver,
|
CreateInterfaceObject(cx, global, receiver,
|
||||||
native, nargs, proto,
|
native, nargs, proto,
|
||||||
staticMethods, constants, s)
|
members, s)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
None => (),
|
None => (),
|
||||||
|
@ -253,8 +256,7 @@ pub fn CreateInterfaceObjects2(cx: *mut JSContext, global: *mut JSObject, receiv
|
||||||
fn CreateInterfaceObject(cx: *mut JSContext, global: *mut JSObject, receiver: *mut JSObject,
|
fn CreateInterfaceObject(cx: *mut JSContext, global: *mut JSObject, receiver: *mut JSObject,
|
||||||
constructorNative: NonNullJSNative,
|
constructorNative: NonNullJSNative,
|
||||||
ctorNargs: u32, proto: *mut JSObject,
|
ctorNargs: u32, proto: *mut JSObject,
|
||||||
staticMethods: Option<&'static [JSFunctionSpec]>,
|
members: &'static NativeProperties,
|
||||||
constants: Option<&'static [ConstantSpec]>,
|
|
||||||
name: *libc::c_char) {
|
name: *libc::c_char) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fun = JS_NewFunction(cx, Some(constructorNative), ctorNargs,
|
let fun = JS_NewFunction(cx, Some(constructorNative), ctorNargs,
|
||||||
|
@ -264,12 +266,12 @@ fn CreateInterfaceObject(cx: *mut JSContext, global: *mut JSObject, receiver: *m
|
||||||
let constructor = JS_GetFunctionObject(fun);
|
let constructor = JS_GetFunctionObject(fun);
|
||||||
assert!(constructor.is_not_null());
|
assert!(constructor.is_not_null());
|
||||||
|
|
||||||
match staticMethods {
|
match members.staticMethods {
|
||||||
Some(staticMethods) => DefineMethods(cx, constructor, staticMethods),
|
Some(staticMethods) => DefineMethods(cx, constructor, staticMethods),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
match constants {
|
match members.consts {
|
||||||
Some(constants) => DefineConstants(cx, constructor, constants),
|
Some(constants) => DefineConstants(cx, constructor, constants),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
@ -323,24 +325,22 @@ fn DefineProperties(cx: *mut JSContext, obj: *mut JSObject, properties: &'static
|
||||||
fn CreateInterfacePrototypeObject(cx: *mut JSContext, global: *mut JSObject,
|
fn CreateInterfacePrototypeObject(cx: *mut JSContext, global: *mut JSObject,
|
||||||
parentProto: *mut JSObject,
|
parentProto: *mut JSObject,
|
||||||
protoClass: &'static JSClass,
|
protoClass: &'static JSClass,
|
||||||
methods: Option<&'static [JSFunctionSpec]>,
|
members: &'static NativeProperties) -> *mut JSObject {
|
||||||
properties: Option<&'static [JSPropertySpec]>,
|
|
||||||
constants: Option<&'static [ConstantSpec]>) -> *mut JSObject {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let ourProto = JS_NewObjectWithUniqueType(cx, protoClass, parentProto, global);
|
let ourProto = JS_NewObjectWithUniqueType(cx, protoClass, parentProto, global);
|
||||||
assert!(ourProto.is_not_null());
|
assert!(ourProto.is_not_null());
|
||||||
|
|
||||||
match methods {
|
match members.methods {
|
||||||
Some(methods) => DefineMethods(cx, ourProto, methods),
|
Some(methods) => DefineMethods(cx, ourProto, methods),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
match properties {
|
match members.attrs {
|
||||||
Some(properties) => DefineProperties(cx, ourProto, properties),
|
Some(properties) => DefineProperties(cx, ourProto, properties),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
match constants {
|
match members.consts {
|
||||||
Some(constants) => DefineConstants(cx, ourProto, constants),
|
Some(constants) => DefineConstants(cx, ourProto, constants),
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue