diff --git a/src/servo/dom/bindings/codegen/CodegenRust.py b/src/servo/dom/bindings/codegen/CodegenRust.py index 9c0b0433d0d..9334111a9c1 100644 --- a/src/servo/dom/bindings/codegen/CodegenRust.py +++ b/src/servo/dom/bindings/codegen/CodegenRust.py @@ -556,7 +556,7 @@ class PropertyDefiner: specs.append(specTerminator) prefableSpecs.append(" { false, NULL }"); - arrays = (("const %s_specs: [%s * %i] = [\n" + + arrays = (("const %s: [%s * %i] = [\n" + ',\n'.join(specs) + "\n" + "];\n\n") % (name, specType, len(specs))) #+ @@ -1199,7 +1199,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): idsToInit = [] # There is no need to init any IDs in workers, because worker bindings # don't have Xrays. - if not self.descriptor.workers: + if False and not self.descriptor.workers: #XXXjdm punt on the interned string optimization for var in self.properties.xrayRelevantArrayNames(): props = getattr(self.properties, var) # We only have non-chrome ids to init if we have no chrome ids. @@ -1262,16 +1262,16 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): if self.descriptor.proxy: domClass = "&Class" else: - domClass = "&Class.mClass" + domClass = "&Class.dom_class" else: domClass = "ptr::null()" - call = """return dom::CreateInterfaceObjects(aCx, aGlobal, aReceiver, parentProto, - %s, %s, %s, %d, - %s, - %%(methods)s, %%(attrs)s, - %%(consts)s, %%(staticMethods)s, - %s);""" % ( + call = """return CreateInterfaceObjects2(aCx, aGlobal, aReceiver, parentProto, + %s, %s, %s, %d, + %s, + %%(methods)s, ptr::to_unsafe_ptr(&%%(attrs)s[0]), + %%(consts)s, %%(staticMethods)s, + %s);""" % ( "&PrototypeClass" if needInterfacePrototypeObject else "ptr::null()", "&InterfaceObjectClass" if needInterfaceObjectClass else "ptr::null()", constructHook if needConstructor else "ptr::null()", @@ -1293,7 +1293,8 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): [CGGeneric(getParentProto), initIds, prefCache, chrome, CGGeneric(call % self.properties.variableNames(False))], "\n\n") - return CGIndenter(CGWrapper(functionBody, pre="/*", post="*/return ptr::null()")).define() + #return CGIndenter(CGWrapper(functionBody, pre="/*", post="*/return ptr::null()")).define() + return CGIndenter(functionBody).define() class CGGetPerInterfaceObject(CGAbstractMethod): """ @@ -1738,7 +1739,7 @@ class CGMemberJITInfo(CGThing): return "" def defineJitInfo(self, infoName, opName, infallible): - protoID = "prototypes::id::%s as uint" % self.descriptor.name + protoID = "prototypes::id::%s as u32" % self.descriptor.name depth = self.descriptor.interface.inheritanceDepth() failstr = "true" if infallible else "false" return ("\n" diff --git a/src/servo/dom/bindings/utils.rs b/src/servo/dom/bindings/utils.rs index 53577df81ff..130983bec2c 100644 --- a/src/servo/dom/bindings/utils.rs +++ b/src/servo/dom/bindings/utils.rs @@ -2,7 +2,8 @@ use js; use js::rust::Compartment; use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL, JS_THIS_OBJECT, JS_SET_RVAL}; -use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp}; +use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp, JSNative, + JSFunctionSpec, JSPropertySpec, JSVal}; use js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_ReportError, JS_GetReservedSlot, JS_SetReservedSlot, JS_NewStringCopyN, JS_DefineFunctions, JS_DefineProperty, JS_GetContextPrivate, @@ -197,6 +198,11 @@ pub fn define_empty_prototype(name: ~str, proto: Option<~str>, compartment: @mut // globals and non-globals. const DOM_OBJECT_SLOT: uint = 0; +// NOTE: This is baked into the Ion JIT as 0 in codegen for LGetDOMProperty and +// LSetDOMProperty. Those constants need to be changed accordingly if this value +// changes. +const DOM_PROTO_INSTANCE_CLASS_SLOT: u32 = 0; + // All DOM globals must have a slot at DOM_PROTOTYPE_SLOT. We have to // start at 1 past JSCLASS_GLOBAL_SLOT_COUNT because XPConnect uses // that one. @@ -207,7 +213,28 @@ const DOM_PROTOTYPE_SLOT: u32 = js::JSCLASS_GLOBAL_SLOT_COUNT + 1; // changes. const JSCLASS_DOM_GLOBAL: u32 = js::JSCLASS_USERBIT1; -struct NativePropertyHooks { +pub struct NativeProperties { + staticMethods: *JSFunctionSpec, + staticMethodIds: *jsid, + staticMethodsSpecs: *JSFunctionSpec, + staticAttributes: *JSPropertySpec, + staticAttributeIds: *jsid, + staticAttributeSpecs: *JSPropertySpec, + methods: *JSFunctionSpec, + methodIds: *jsid, + methodsSpecs: *JSFunctionSpec, + attributes: *JSPropertySpec, + attributeIds: *jsid, + attributeSpecs: *JSPropertySpec, + unforgeableAttributes: *JSPropertySpec, + unforgeableAttributeIds: *jsid, + unforgeableAttributeSpecs: *JSPropertySpec, + constants: *ConstantSpec, + constantIds: *jsid, + constantSpecs: *ConstantSpec +} + +pub struct NativePropertyHooks { resolve_own_property: *u8, resolve_property: *u8, enumerate_own_properties: *u8, @@ -215,7 +242,17 @@ struct NativePropertyHooks { proto_hooks: *NativePropertyHooks } -struct DOMClass { +pub struct JSNativeHolder { + native: js::jsapi::JSNative, + propertyHooks: *NativePropertyHooks +} + +pub struct ConstantSpec { + name: &str, + value: JSVal +} + +pub struct DOMClass { // A list of interfaces that this object implements, in order of decreasing // derivedness. interface_chain: [prototypes::id::Prototype * 1 /*prototypes::id::_ID_Count*/], @@ -224,7 +261,7 @@ struct DOMClass { native_hooks: *NativePropertyHooks } -struct DOMJSClass { +pub struct DOMJSClass { base: JSClass, dom_class: DOMClass } @@ -244,3 +281,53 @@ mod prototypes { } } } + +pub fn CreateInterfaceObjects2(cx: *JSContext, global: *JSObject, receiver: *JSObject, + protoProto: *JSObject, protoClass: *JSClass, + constructorClass: *JSClass, constructor: JSNative, + ctorNargs: uint, + domClass: *DOMClass, + methods: *JSFunctionSpec, + properties: *JSPropertySpec, + constants: *ConstantSpec, + staticMethods: *JSFunctionSpec, + name: &str) -> *JSObject { + unsafe { + let mut proto = ptr::null(); + if protoClass.is_not_null() { + proto = /*CreateInterfacePrototypeObject(cx, global, protoProto, + protoClass, + regularProperties, + chromeOnlyProperties);*/ptr::null(); + if proto.is_null() { + return ptr::null(); + } + + JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT, + RUST_PRIVATE_TO_JSVAL(domClass as *libc::c_void)); + } + + let mut interface = ptr::null(); + if constructorClass.is_not_null() || constructor.is_not_null() { + interface = do str::as_c_str(name) |s| { + /*CreateInterfaceObject(cx, global, constructorClass, constructor, + ctorNargs, proto, properties, + chromeOnlyProperties, s)*/ptr::null() + }; + if interface.is_null() { + return ptr::null(); + } + } + + if protoClass.is_not_null() { + proto + } else { + interface + } + } +} + +pub extern fn ThrowingConstructor(cx: *JSContext, argc: uint, vp: *JSVal) -> JSBool { + //XXX should trigger exception here + return 0; +} \ No newline at end of file