From 4f24ef161973419cf32256ae1aee627cddb9c2c6 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 11 Jul 2013 01:22:00 -0400 Subject: [PATCH] DOM bindings: Autogenerate list of prototypes and binding registration goop. --- .gitignore | 1 + .../script/dom/bindings/codegen/Bindings.conf | 4 +- .../script/dom/bindings/codegen/Blob.webidl | 12 ++ .../dom/bindings/codegen/CodegenRust.py | 194 ++++++++++++++++-- .../script/dom/bindings/codegen/GlobalGen.py | 21 +- .../dom/bindings/codegen/UIEvent.webidl | 1 - .../dom/bindings/codegen/WindowProxy.webidl | 9 + src/components/script/dom/bindings/utils.rs | 29 +-- src/components/script/dom/blob.rs | 28 ++- src/components/script/dom/node.rs | 30 +-- src/components/script/dom/windowproxy.rs | 13 +- src/components/script/script.rc | 4 + 12 files changed, 262 insertions(+), 84 deletions(-) create mode 100644 src/components/script/dom/bindings/codegen/WindowProxy.webidl diff --git a/.gitignore b/.gitignore index 60d8e762747..a036e91f472 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ parser.out src/components/script/dom/bindings/codegen/*.rs src/components/script/dom/bindings/codegen/_cache/ src/components/script/dom/bindings/codegen/test/*.rs +src/components/script/dom/bindings/codegen/RegisterBindings.cpp src/components/script/dom/bindings/codegen/PrototypeList.h src/components/script/dom/bindings/codegen/UnionTypes.h src/components/script/dom/bindings/codegen/UnionConversions.h diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf index 11b4b245c71..8b65ab72a24 100644 --- a/src/components/script/dom/bindings/codegen/Bindings.conf +++ b/src/components/script/dom/bindings/codegen/Bindings.conf @@ -394,6 +394,9 @@ DOMInterfaces = { 'implicitJSContext': [ 'constructor' ] }], +'WindowProxy': { +}, + #################################### # Test Interfaces of various sorts # #################################### @@ -558,5 +561,4 @@ addExternalIface('WebGLShaderPrecisionFormat', addExternalIface('WebGLTexture', nativeType='mozilla::WebGLTexture', headerFile='WebGLContext.h') addExternalIface('Window') -addExternalIface('WindowProxy', nativeType='WindowProxy') addExternalIface('XULElement') diff --git a/src/components/script/dom/bindings/codegen/Blob.webidl b/src/components/script/dom/bindings/codegen/Blob.webidl index 6cd26f8c418..bc6ad78efa5 100644 --- a/src/components/script/dom/bindings/codegen/Blob.webidl +++ b/src/components/script/dom/bindings/codegen/Blob.webidl @@ -1,2 +1,14 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. + * + * The origin of this IDL file is + * http://www.w3.org/TR/2012/WD-dom-20120105/ + * + * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ + interface Blob { }; \ No newline at end of file diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index e82c4167485..b4b418ff15d 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -95,8 +95,8 @@ class CastableObjectUnwrapper(): self.substitution = { "type" : descriptor.nativeType, "depth": descriptor.interface.inheritanceDepth(), - "prototype": "prototypes::id::" + descriptor.name, - "protoID" : "prototypes::id::" + descriptor.name + " as uint", + "prototype": "PrototypeList::id::" + descriptor.name, + "protoID" : "PrototypeList::id::" + descriptor.name + " as uint", "source" : source, "target" : target, "codeOnFailure" : CGIndenter(CGGeneric(codeOnFailure), 4).define() } @@ -942,7 +942,7 @@ for (uint32_t i = 0; i < length; ++i) { else: templateBody += ( "match unwrap_value::<" + typePtr + ">(&${val} as *JSVal, " - "prototypes::id::%s, %d) {\n" % (descriptor.name, descriptor.interface.inheritanceDepth() if descriptor.concrete else 0) + + "PrototypeList::id::%s, %d) {\n" % (descriptor.name, descriptor.interface.inheritanceDepth() if descriptor.concrete else 0) + " Err(()) => {") templateBody += CGIndenter(onFailureBadType(failureCode, descriptor.interface.identifier.name)).define() @@ -2151,6 +2151,13 @@ class CGImports(CGWrapper): CGWrapper.__init__(self, child, declarePre=_useString(sorted(declareImports))) + @staticmethod + def getDeclarationFilename(decl): + # Use our local version of the header, not the exported one, so that + # test bindings, which don't export, will work correctly. + basename = os.path.basename(decl.filename()) + return basename.replace('.webidl', 'Binding.rs') + class CGIfWrapper(CGWrapper): def __init__(self, child, condition): pre = CGWrapper(CGGeneric(condition), pre="if ", post=" {\n", @@ -2178,12 +2185,12 @@ class CGNamespace(CGWrapper): return "" def DOMClass(descriptor): - protoList = ['prototypes::id::' + proto for proto in descriptor.prototypeChain] + protoList = ['PrototypeList::id::' + proto for proto in descriptor.prototypeChain] # Pad out the list to the right length with _ID_Count so we # guarantee that all the lists are the same length. _ID_Count # is never the ID of any prototype, so it's safe to use as # padding. - protoList.extend(['prototypes::id::_ID_Count'] * (descriptor.config.maxProtoChainLength - len(protoList))) + protoList.extend(['PrototypeList::id::_ID_Count'] * (descriptor.config.maxProtoChainLength - len(protoList))) prototypeChainString = ', '.join(protoList) nativeHooks = "0 as *NativePropertyHooks" if descriptor.workers else "&NativeHooks as *NativePropertyHooks" return """DOMClass { @@ -2382,7 +2389,7 @@ class CGAbstractMethod(CGThing): template arguments, and the function will be templatized using those arguments. """ - def __init__(self, descriptor, name, returnType, args, inline=False, alwaysInline=False, static=False, extern=False, pub=False, templateArgs=None): + def __init__(self, descriptor, name, returnType, args, inline=False, alwaysInline=False, static=False, extern=False, pub=False, templateArgs=None, unsafe=True): CGThing.__init__(self) self.descriptor = descriptor self.name = name @@ -2394,6 +2401,7 @@ class CGAbstractMethod(CGThing): self.extern = extern self.templateArgs = templateArgs self.pub = pub; + self.unsafe = unsafe def _argstring(self): return ', '.join([str(a) for a in self.args]) def _template(self): @@ -2421,6 +2429,10 @@ class CGAbstractMethod(CGThing): return ' '.join(decorators) + maybeNewline def _returnType(self): return (" -> %s" % self.returnType) if self.returnType != "void" else "" + def _unsafe_open(self): + return "\n unsafe {" if self.unsafe else "" + def _unsafe_close(self): + return "\n }\n" if self.unsafe else "" def declare(self): if self.inline: return self._define() @@ -2433,10 +2445,10 @@ class CGAbstractMethod(CGThing): def define(self): return "" if self.inline else self._define() def definition_prologue(self): - return "%sfn %s%s(%s)%s {\n unsafe {" % (self._decorators(), self.name, self._template(), - self._argstring(), self._returnType()) + return "%sfn %s%s(%s)%s {%s" % (self._decorators(), self.name, self._template(), + self._argstring(), self._returnType(), self._unsafe_open()) def definition_epilogue(self): - return "\n }\n}\n" + return "%s}\n" % self._unsafe_close() def definition_body(self): assert(False) # Override me! @@ -2445,7 +2457,7 @@ def CreateBindingJSObject(descriptor, parent): handler = """ //let cache = ptr::to_unsafe_ptr(aObject.get_wrappercache()); let script_context = task_from_context(aCx); - let handler = (*script_context).dom_static.proxy_handlers.get(&(prototypes::id::%s as uint)); + let handler = (*script_context).dom_static.proxy_handlers.get(&(PrototypeList::id::%s as uint)); """ % descriptor.name create = handler + """ let obj = NewProxyObject(aCx, *handler, ptr::to_unsafe_ptr(&RUST_PRIVATE_TO_JSVAL(squirrel_away(aObject) as *libc::c_void)), @@ -2616,7 +2628,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): idsToInit.append(props.variableName(False)) if len(idsToInit) > 0: setup = CGList([CGGeneric("let script_context = task_from_context(aCx);"), - CGList([CGGeneric("let %s_ids_mut = (*script_context).dom_static.attribute_ids.get(&(prototypes::id::%s as uint));" % (varname, self.descriptor.name)) for varname in idsToInit], '\n')], '\n') + CGList([CGGeneric("let %s_ids_mut = (*script_context).dom_static.attribute_ids.get(&(PrototypeList::id::%s as uint));" % (varname, self.descriptor.name)) for varname in idsToInit], '\n')], '\n') initIds = CGList( [CGGeneric("!InitIds(aCx, %s, *%s_ids_mut)" % (varname, varname)) for varname in idsToInit], ' ||\n') @@ -2757,7 +2769,7 @@ class CGGetProtoObjectMethod(CGGetPerInterfaceObject): """ def __init__(self, descriptor): CGGetPerInterfaceObject.__init__(self, descriptor, "GetProtoObject", - "prototypes::", pub=True) + "PrototypeList::", pub=True) def definition_body(self): return """ /* Get the interface prototype object for this class. This will create the @@ -2837,12 +2849,12 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod): getElementIfPresent: ptr::null(), getPrototypeOf: ptr::null() }; - (*script_context).dom_static.proxy_handlers.insert(prototypes::id::%s as uint, + (*script_context).dom_static.proxy_handlers.insert(PrototypeList::id::%s as uint, CreateProxyHandler(ptr::to_unsafe_ptr(&traps), ptr::to_unsafe_ptr(&Class) as *libc::c_void)); """ % self.descriptor.name else: - body += """ (*script_context).dom_static.attribute_ids.insert(prototypes::id::%s as uint, + body += """ (*script_context).dom_static.attribute_ids.insert(PrototypeList::id::%s as uint, vec::cast_to_mut(vec::from_slice(sAttributes_ids))); """ % self.descriptor.name body = "" #XXXjdm xray stuff isn't necessary yet @@ -3336,7 +3348,7 @@ class CGMemberJITInfo(CGThing): return "" def defineJitInfo(self, infoName, opName, infallible): - protoID = "prototypes::id::%s as u32" % self.descriptor.name + protoID = "PrototypeList::id::%s as u32" % self.descriptor.name depth = self.descriptor.interface.inheritanceDepth() failstr = "true" if infallible else "false" return ("\n" @@ -3436,7 +3448,7 @@ class CGXrayHelper(CGAbstractExternMethod): methods = self.properties.methods if methods.hasNonChromeOnly() or methods.hasChromeOnly(): methodArgs = "Some(vec::zip_slice(%(methods)s, *method_ids))" % varNames - setup += "let method_ids = (*script_context).dom_static.method_ids.get(&(prototypes::id::ClientRect as uint));\n" + setup += "let method_ids = (*script_context).dom_static.method_ids.get(&(PrototypeList::id::ClientRect as uint));\n" else: methodArgs = "None" methodArgs = CGGeneric(methodArgs) @@ -3444,7 +3456,7 @@ class CGXrayHelper(CGAbstractExternMethod): attrs = self.properties.attrs if attrs.hasNonChromeOnly() or attrs.hasChromeOnly(): attrArgs = "Some(vec::zip_slice(%(attrs)s, *attr_ids))" % varNames - setup += "let attr_ids = (*script_context).dom_static.attribute_ids.get(&(prototypes::id::ClientRect as uint));\n" + setup += "let attr_ids = (*script_context).dom_static.attribute_ids.get(&(PrototypeList::id::ClientRect as uint));\n" else: attrArgs = "None" attrArgs = CGGeneric(attrArgs) @@ -3452,7 +3464,7 @@ class CGXrayHelper(CGAbstractExternMethod): consts = self.properties.consts if consts.hasNonChromeOnly() or consts.hasChromeOnly(): constArgs = "Some(vec::zip_slice(%(consts)s, *const_ids))" % varNames - setup += "let const_ids = (*script_context).dom_static.constant_ids.get(&(prototypes::id::ClientRect as uint));\n" + setup += "let const_ids = (*script_context).dom_static.constant_ids.get(&(PrototypeList::id::ClientRect as uint));\n" else: constArgs = "None" constArgs = CGGeneric(constArgs) @@ -3953,6 +3965,51 @@ class CGDescriptor(CGThing): def define(self): return self.cgRoot.define() +class CGNamespacedEnum(CGThing): + def __init__(self, namespace, enumName, names, values, comment="", deriving=""): + + if not values: + values = [] + + # Account for explicit enum values. + entries = [] + for i in range(0, len(names)): + if len(values) > i and values[i] is not None: + entry = "%s = %s" % (names[i], values[i]) + else: + entry = names[i] + entries.append(entry) + + # Append a Count. + entries.append('_' + enumName + '_Count') + + # Indent. + entries = [' ' + e for e in entries] + + # Build the enum body. + enumstr = comment + 'pub enum %s {\n%s\n}\n' % (enumName, ',\n'.join(entries)) + if deriving: + enumstr = ('#[deriving(%s)]\n' % deriving) + enumstr + curr = CGGeneric(enumstr) + + # Add some whitespace padding. + curr = CGWrapper(curr, pre='\n',post='\n') + + # Add the namespace. + curr = CGNamespace(namespace, curr, public=True) + + # Add the typedef + #typedef = '\ntypedef %s::%s %s;\n\n' % (namespace, enumName, enumName) + #curr = CGList([curr, CGGeneric(typedef)]) + + # Save the result. + self.node = curr + + def declare(self): + return self.node.declare() + def define(self): + return self.node.define() + class CGDictionary(CGThing): def __init__(self, dictionary, descriptorProvider): self.dictionary = dictionary; @@ -4198,6 +4255,26 @@ class CGDictionary(CGThing): deps.add(member.type.unroll().inner) return deps +class CGRegisterProtos(CGAbstractMethod): + def __init__(self, config): + CGAbstractMethod.__init__(self, None, 'Register', 'void', + [Argument('@mut Compartment', 'compartment')], + unsafe=False, pub=True) + self.config = config + + def _registerProtos(self): + lines = [" assert!(codegen::%sBinding::DefineDOMInterface(\n" + " compartment.cx.ptr,\n" + " compartment.global_obj.ptr,\n" + " &mut unused));" % (desc.name) + for desc in self.config.getDescriptors(hasInterfaceObject=True, + isExternal=False, + workers=False, + register=True)] + return '\n'.join(lines) + '\n' + def definition_body(self): + return " let mut unused = false;\n" + self._registerProtos() + class CGBindingRoot(CGThing): """ Root codegen class for binding generation. Instantiate the class, and call @@ -4308,3 +4385,84 @@ class CGBindingRoot(CGThing): return stripTrailingWhitespace(self.root.declare()) def define(self): return stripTrailingWhitespace(self.root.define()) + +class GlobalGenRoots(): + """ + Roots for global codegen. + + To generate code, call the method associated with the target, and then + call the appropriate define/declare method. + """ + + @staticmethod + def PrototypeList(config): + + # Prototype ID enum. + protos = [d.name for d in config.getDescriptors(hasInterfacePrototypeObject=True)] + + idEnum = CGNamespacedEnum('id', 'ID', protos, [0], deriving="Eq") + idEnum = CGList([idEnum]) + idEnum.append(CGGeneric(declare="pub static MAX_PROTO_CHAIN_LENGTH: uint = " + + str(config.maxProtoChainLength) + ";\n\n")) + + # Wrap all of that in our namespaces. + #idEnum = CGNamespace.build(['mozilla', 'dom', 'prototypes'], + # CGWrapper(idEnum, pre='\n')) + #idEnum = CGWrapper(idEnum, post='\n') + + curr = CGList([idEnum]) + + # Constructor ID enum. + constructors = [d.name for d in config.getDescriptors(hasInterfaceObject=True, + hasInterfacePrototypeObject=False)] + idEnum = CGNamespacedEnum('id', 'ID', constructors, [0]) + + # Wrap all of that in our namespaces. + idEnum = CGNamespace.build(['mozilla', 'dom', 'constructors'], + CGWrapper(idEnum, pre='\n')) + idEnum = CGWrapper(idEnum, post='\n') + + #XXXjdm Not sure what to do with the constructors right now + #curr.append(idEnum) + + #traitsDecl = CGGeneric(declare=""" +#template +#struct PrototypeTraits; +# +#template +#struct PrototypeIDMap; +#""") + + #traitsDecl = CGNamespace.build(['mozilla', 'dom'], + # CGWrapper(traitsDecl, post='\n')) + + #curr.append(traitsDecl) + + # Add the auto-generated comment. + curr = CGWrapper(curr, pre=AUTOGENERATED_WARNING_COMMENT) + + # Done. + return curr + + @staticmethod + def RegisterBindings(config): + + # TODO - Generate the methods we want + curr = CGRegisterProtos(config) + + # Wrap all of that in our namespaces. + #curr = CGNamespace.build(['mozilla', 'dom'], + # CGWrapper(curr, post='\n')) + #curr = CGWrapper(curr, post='\n') + + # Add the includes + defineIncludes = [CGImports.getDeclarationFilename(desc.interface) + for desc in config.getDescriptors(hasInterfaceObject=True, + workers=False, + register=True)] + curr = CGImports([], [], ['dom::bindings::codegen', + 'js::rust::Compartment'], defineIncludes, curr) + + # Done. + return curr + diff --git a/src/components/script/dom/bindings/codegen/GlobalGen.py b/src/components/script/dom/bindings/codegen/GlobalGen.py index dbfc4f86e14..ab6427a638c 100644 --- a/src/components/script/dom/bindings/codegen/GlobalGen.py +++ b/src/components/script/dom/bindings/codegen/GlobalGen.py @@ -13,7 +13,7 @@ import cStringIO import WebIDL import cPickle from Configuration import * -from Codegen import GlobalGenRoots, replaceFileIfChanged +from CodegenRust import GlobalGenRoots, replaceFileIfChanged # import Codegen in general, so we can set a variable on it import Codegen @@ -21,11 +21,16 @@ def generate_file(config, name, action): root = getattr(GlobalGenRoots, name)(config) if action is 'declare': - filename = name + '.h' + filename = name + '.rs' code = root.declare() + elif action == 'declare+define': + filename = name + '.rs' + code = root.declare() + root2 = getattr(GlobalGenRoots, name)(config) + code += root2.define() else: assert action is 'define' - filename = name + '.cpp' + filename = name + '.rs' code = root.define() if replaceFileIfChanged(filename, code): @@ -70,14 +75,14 @@ def main(): config = Configuration(configFile, parserResults) # Generate the prototype list. - generate_file(config, 'PrototypeList', 'declare') + generate_file(config, 'PrototypeList', 'declare+define') # Generate the common code. - generate_file(config, 'RegisterBindings', 'declare') - generate_file(config, 'RegisterBindings', 'define') + generate_file(config, 'RegisterBindings', 'declare+define') - generate_file(config, 'UnionTypes', 'declare') - generate_file(config, 'UnionConversions', 'declare') + #XXXjdm No union support yet + #generate_file(config, 'UnionTypes', 'declare') + #generate_file(config, 'UnionConversions', 'declare') if __name__ == '__main__': main() diff --git a/src/components/script/dom/bindings/codegen/UIEvent.webidl b/src/components/script/dom/bindings/codegen/UIEvent.webidl index 9672ea1090c..305027ec79d 100644 --- a/src/components/script/dom/bindings/codegen/UIEvent.webidl +++ b/src/components/script/dom/bindings/codegen/UIEvent.webidl @@ -10,7 +10,6 @@ * liability, trademark and document use rules apply. */ -interface WindowProxy; interface Node; [Constructor(DOMString type, optional UIEventInit eventInitDict)] diff --git a/src/components/script/dom/bindings/codegen/WindowProxy.webidl b/src/components/script/dom/bindings/codegen/WindowProxy.webidl new file mode 100644 index 00000000000..abc429d1cb6 --- /dev/null +++ b/src/components/script/dom/bindings/codegen/WindowProxy.webidl @@ -0,0 +1,9 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + +/* FIXME WindowProxy doesn't actually have an interface according to the spec, + but I'm not sure how to do fallible unwrapping without this, since + we lack Gecko's XPCOM querying facilities. */ +interface WindowProxy { +}; \ No newline at end of file diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index 1d8ece126f3..ff576758606 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -2,6 +2,7 @@ * 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/. */ +use dom::bindings::codegen::PrototypeList; use dom::bindings::node; use dom::node::{AbstractNode, ScriptView}; use script_task::task_from_context; @@ -153,7 +154,7 @@ pub unsafe fn get_dom_class(obj: *JSObject) -> Result { return Err(()); } -pub fn unwrap_object(obj: *JSObject, proto_id: prototypes::id::Prototype, proto_depth: uint) -> Result { +pub fn unwrap_object(obj: *JSObject, proto_id: PrototypeList::id::ID, proto_depth: uint) -> Result { unsafe { do get_dom_class(obj).chain |dom_class| { if dom_class.interface_chain[proto_depth] == proto_id { @@ -167,7 +168,7 @@ pub fn unwrap_object(obj: *JSObject, proto_id: prototypes::id::Prototype, pro } } -pub fn unwrap_value(val: *JSVal, proto_id: prototypes::id::Prototype, proto_depth: uint) -> Result { +pub fn unwrap_value(val: *JSVal, proto_id: PrototypeList::id::ID, proto_depth: uint) -> Result { unsafe { let obj = RUST_JSVAL_TO_OBJECT(*val); unwrap_object(obj, proto_id, proto_depth) @@ -400,7 +401,7 @@ pub struct ConstantSpec { pub struct DOMClass { // A list of interfaces that this object implements, in order of decreasing // derivedness. - interface_chain: [prototypes::id::Prototype, ..3 /*max prototype chain length*/], + interface_chain: [PrototypeList::id::ID, ..3 /*max prototype chain length*/], unused: bool, // DOMObjectIsISupports (always false) native_hooks: *NativePropertyHooks @@ -418,26 +419,6 @@ pub fn GetProtoOrIfaceArray(global: *JSObject) -> **JSObject { } } -pub mod prototypes { - pub mod id { - #[deriving(Eq)] - pub enum Prototype { - Blob, - ClientRect, - ClientRectList, - DOMParser, - HTMLCollection, - Event, - EventTarget, - FormData, - UIEvent, - MouseEvent, - WindowProxy, - _ID_Count - } - } -} - pub fn CreateInterfaceObjects2(cx: *JSContext, global: *JSObject, receiver: *JSObject, protoProto: *JSObject, protoClass: *JSClass, constructorClass: *JSClass, constructor: JSNative, @@ -635,7 +616,7 @@ pub extern fn ThrowingConstructor(_cx: *JSContext, _argc: uint, _vp: *JSVal) -> } pub fn initialize_global(global: *JSObject) { - let protoArray = @mut ([0 as *JSObject, ..10]); //XXXjdm prototypes::_ID_COUNT + let protoArray = @mut ([0 as *JSObject, ..21]); //XXXjdm PrototyepList::id::_ID_Count unsafe { //XXXjdm we should be storing the box pointer instead of the inner let box = squirrel_away(protoArray); diff --git a/src/components/script/dom/blob.rs b/src/components/script/dom/blob.rs index 6850d1a9acc..2f9d90c2b1c 100644 --- a/src/components/script/dom/blob.rs +++ b/src/components/script/dom/blob.rs @@ -2,7 +2,13 @@ * 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/. */ -use dom::bindings::utils::{WrapperCache}; +use dom::bindings::utils::{WrapperCache, BindingObject, CacheableWrapper}; +use dom::bindings::codegen::BlobBinding; +use script_task::{task_from_context}; + +use js::jsapi::{JSContext, JSObject}; + +use std::cast; pub struct Blob { wrapper: WrapperCache @@ -15,3 +21,23 @@ impl Blob { } } } + +impl CacheableWrapper for Blob { + fn get_wrappercache(&mut self) -> &mut WrapperCache { + unsafe { cast::transmute(&self.wrapper) } + } + + fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject { + let mut unused = false; + BlobBinding::Wrap(cx, scope, self, &mut unused) + } +} + +impl BindingObject for Blob { + fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper { + let script_context = task_from_context(cx); + unsafe { + (*script_context).root_frame.get_ref().window as @mut CacheableWrapper + } + } +} diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index 8ba9fc9a520..623b0367716 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -4,7 +4,6 @@ //! The core DOM types. Defines the basic DOM hierarchy as well as all the HTML elements. -use dom::bindings::codegen; use dom::bindings::node; use dom::bindings::utils::WrapperCache; use dom::bindings; @@ -477,32 +476,5 @@ pub fn define_bindings(compartment: @mut Compartment) { bindings::element::init(compartment); bindings::text::init(compartment); bindings::utils::initialize_global(compartment.global_obj.ptr); - let mut unused = false; - assert!(codegen::ClientRectBinding::DefineDOMInterface(compartment.cx.ptr, - compartment.global_obj.ptr, - &mut unused)); - assert!(codegen::ClientRectListBinding::DefineDOMInterface(compartment.cx.ptr, - compartment.global_obj.ptr, - &mut unused)); - assert!(codegen::HTMLCollectionBinding::DefineDOMInterface(compartment.cx.ptr, - compartment.global_obj.ptr, - &mut unused)); - assert!(codegen::DOMParserBinding::DefineDOMInterface(compartment.cx.ptr, - compartment.global_obj.ptr, - &mut unused)); - assert!(codegen::EventBinding::DefineDOMInterface(compartment.cx.ptr, - compartment.global_obj.ptr, - &mut unused)); - assert!(codegen::EventTargetBinding::DefineDOMInterface(compartment.cx.ptr, - compartment.global_obj.ptr, - &mut unused)); - assert!(codegen::FormDataBinding::DefineDOMInterface(compartment.cx.ptr, - compartment.global_obj.ptr, - &mut unused)); - assert!(codegen::MouseEventBinding::DefineDOMInterface(compartment.cx.ptr, - compartment.global_obj.ptr, - &mut unused)); - assert!(codegen::UIEventBinding::DefineDOMInterface(compartment.cx.ptr, - compartment.global_obj.ptr, - &mut unused)); + bindings::codegen::RegisterBindings::Register(compartment); } diff --git a/src/components/script/dom/windowproxy.rs b/src/components/script/dom/windowproxy.rs index 08edb063afc..89b373c0716 100644 --- a/src/components/script/dom/windowproxy.rs +++ b/src/components/script/dom/windowproxy.rs @@ -2,8 +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/. */ -use dom::bindings::utils::{CacheableWrapper, WrapperCache}; -use script_task::global_script_context; +use dom::bindings::utils::{CacheableWrapper, WrapperCache, BindingObject}; +use script_task::{global_script_context, task_from_context}; use js::jsapi::{JSContext, JSObject}; @@ -28,6 +28,15 @@ impl WindowProxy { } } +impl BindingObject for WindowProxy { + fn GetParentObject(&self, cx: *JSContext) -> @mut CacheableWrapper { + let script_context = task_from_context(cx); + unsafe { + (*script_context).root_frame.get_ref().window as @mut CacheableWrapper + } + } +} + impl CacheableWrapper for WindowProxy { fn get_wrappercache(&mut self) -> &mut WrapperCache { return self.get_wrappercache() diff --git a/src/components/script/script.rc b/src/components/script/script.rc index a4ca2c517e5..013a410fd54 100644 --- a/src/components/script/script.rc +++ b/src/components/script/script.rc @@ -34,6 +34,7 @@ pub mod dom { pub mod proxyhandler; pub mod domparser; pub mod codegen { + pub mod BlobBinding; pub mod ClientRectBinding; pub mod ClientRectListBinding; pub mod DOMParserBinding; @@ -42,7 +43,10 @@ pub mod dom { pub mod FormDataBinding; pub mod HTMLCollectionBinding; pub mod MouseEventBinding; + pub mod PrototypeList; + pub mod RegisterBindings; pub mod UIEventBinding; + pub mod WindowProxyBinding; } } pub mod blob;