зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #577 - Autogenerate list of prototypes and code to register DOM bindings (from jdm:autogen); r=jdm,metajack
Source-Repo: https://github.com/servo/servo Source-Revision: 821192d5a8173fffcc14113703741c7b84b27e00
This commit is contained in:
Родитель
00dfda84d8
Коммит
e841c818aa
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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 {
|
||||
};
|
|
@ -97,8 +97,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() }
|
||||
|
@ -944,7 +944,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()
|
||||
|
@ -2153,6 +2153,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",
|
||||
|
@ -2180,12 +2187,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 {
|
||||
|
@ -2384,7 +2391,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
|
||||
|
@ -2396,6 +2403,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):
|
||||
|
@ -2423,6 +2431,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()
|
||||
|
@ -2435,10 +2447,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!
|
||||
|
||||
|
@ -2447,7 +2459,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)),
|
||||
|
@ -2618,7 +2630,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')
|
||||
|
@ -2759,7 +2771,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
|
||||
|
@ -2839,12 +2851,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
|
||||
|
@ -3338,7 +3350,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"
|
||||
|
@ -3438,7 +3450,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)
|
||||
|
@ -3446,7 +3458,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)
|
||||
|
@ -3454,7 +3466,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)
|
||||
|
@ -3955,6 +3967,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;
|
||||
|
@ -4200,6 +4257,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
|
||||
|
@ -4310,3 +4387,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 <prototypes::ID PrototypeID>
|
||||
#struct PrototypeTraits;
|
||||
#
|
||||
#template <class ConcreteClass>
|
||||
#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
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
interface WindowProxy;
|
||||
interface Node;
|
||||
|
||||
[Constructor(DOMString type, optional UIEventInit eventInitDict)]
|
||||
|
|
|
@ -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 {
|
||||
};
|
|
@ -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<DOMClass, ()> {
|
|||
return Err(());
|
||||
}
|
||||
|
||||
pub fn unwrap_object<T>(obj: *JSObject, proto_id: prototypes::id::Prototype, proto_depth: uint) -> Result<T, ()> {
|
||||
pub fn unwrap_object<T>(obj: *JSObject, proto_id: PrototypeList::id::ID, proto_depth: uint) -> Result<T, ()> {
|
||||
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<T>(obj: *JSObject, proto_id: prototypes::id::Prototype, pro
|
|||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_value<T>(val: *JSVal, proto_id: prototypes::id::Prototype, proto_depth: uint) -> Result<T, ()> {
|
||||
pub fn unwrap_value<T>(val: *JSVal, proto_id: PrototypeList::id::ID, proto_depth: uint) -> Result<T, ()> {
|
||||
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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -495,32 +494,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);
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче