| author | Boris Zbarsky <bzbarsky@mit.edu> |
| Mon, 05 Nov 2012 11:58:02 -0500 | |
| changeset 112321 | b67a1dba5690052f4c4c0785732321c6a3c05fa9 |
| parent 112320 | 6f08c574fb7968845fb886de1e1726f6886c7b1d |
| child 112322 | 6184b17f8abd6c1166d3e1c629900a4483638308 |
| push id | 23812 |
| push user | emorley@mozilla.com |
| push date | Tue, 06 Nov 2012 14:01:34 +0000 |
| treeherder | mozilla-central@f4aeed115e54 [default view] [failures only] |
| perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
| reviewers | peterv |
| bugs | 788225 |
| milestone | 19.0a1 |
| first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
| last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -591,16 +591,41 @@ DOMInterfaces = { }, 'TestRenamedInterface' : { 'headerFile': 'TestBindingHeader.h', 'register': False, 'nativeType': 'nsRenamedInterface' }, +'TestIndexedDeleterInterface' : { + 'headerFile': 'TestBindingHeader.h', + 'register': False + }, + +'TestIndexedDeleterWithRetvalInterface' : { + 'headerFile': 'TestBindingHeader.h', + 'register': False + }, + +'TestNamedDeleterInterface' : { + 'headerFile': 'TestBindingHeader.h', + 'register': False + }, + +'TestNamedDeleterWithRetvalInterface' : { + 'headerFile': 'TestBindingHeader.h', + 'register': False + }, + +'TestIndexedAndNamedDeleterInterface' : { + 'headerFile': 'TestBindingHeader.h', + 'register': False + }, + 'TestCppKeywordNamedMethodsInterface' : { 'headerFile': 'TestBindingHeader.h', 'register': False }, 'TestExampleInterface' : { # Keep this in sync with TestInterface 'headerFile': 'TestExampleInterface-example.h',
--- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -5028,22 +5028,22 @@ class CGProxySpecialOperation(CGPerSigna treatUndefinedAs=argument.treatUndefinedAs) templateValues = { "declName": argument.identifier.name, "holderName": argument.identifier.name + "_holder", "val": "desc->value", "valPtr": "&desc->value" } self.cgRoot.prepend(instantiateJSToNativeConversionTemplate(template, templateValues)) - elif operation.isGetter(): + elif operation.isGetter() or operation.isDeleter(): self.cgRoot.prepend(CGGeneric("bool found;")) def getArguments(self): args = [(a, a.identifier.name) for a in self.arguments] - if self.idlNode.isGetter(): + if self.idlNode.isGetter() or self.idlNode.isDeleter(): args.append((FakeArgument(BuiltinTypes[IDLBuiltinType.Types.boolean], self.idlNode), "found")) return args def wrap_return_value(self): if not self.idlNode.isGetter() or self.templateValues is None: return "" @@ -5079,16 +5079,30 @@ class CGProxyNamedGetter(CGProxySpecialO class CGProxyNamedSetter(CGProxySpecialOperation): """ Class to generate a call to a named setter. """ def __init__(self, descriptor): CGProxySpecialOperation.__init__(self, descriptor, 'NamedSetter') +class CGProxyIndexedDeleter(CGProxySpecialOperation): + """ + Class to generate a call to an indexed deleter. + """ + def __init__(self, descriptor): + CGProxySpecialOperation.__init__(self, descriptor, 'IndexedDeleter') + +class CGProxyNamedDeleter(CGProxySpecialOperation): + """ + Class to generate a call to a named deleter. + """ + def __init__(self, descriptor): + CGProxySpecialOperation.__init__(self, descriptor, 'NamedDeleter') + class CGProxyIsProxy(CGAbstractMethod): def __init__(self, descriptor): args = [Argument('JSObject*', 'obj')] CGAbstractMethod.__init__(self, descriptor, "IsProxy", "bool", args, alwaysInline=True) def declare(self): return "" def definition_body(self): return " return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();" @@ -5269,16 +5283,92 @@ class CGDOMJSProxyHandler_defineProperty " %s* self = UnwrapProxy(proxy);\n" + CGIndenter(CGProxyNamedGetter(self.descriptor)).define() + " if (found) {\n" " return ThrowErrorMessage(cx, MSG_NO_PROPERTY_SETTER, \"%s\");\n" + " }\n" + "}\n") % (self.descriptor.nativeType, self.descriptor.name) return set + """return mozilla::dom::DOMProxyHandler::defineProperty(%s);""" % ", ".join(a.name for a in self.args) +class CGDOMJSProxyHandler_delete(ClassMethod): + def __init__(self, descriptor): + args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'), + Argument('jsid', 'id'), + Argument('bool*', 'bp')] + ClassMethod.__init__(self, "delete_", "bool", args) + self.descriptor = descriptor + + def getBody(self): + def getDeleterBody(type): + """ + type should be "Named" or "Indexed" + """ + assert type is "Named" or type is "Indexed" + deleter = self.descriptor.operations[type + 'Deleter'] + if deleter: + if (not deleter.signatures()[0][0].isPrimitive() or + deleter.signatures()[0][0].nullable() or + deleter.signatures()[0][0].tag() != IDLType.Tags.bool): + setBp = "*bp = true;" + else: + setBp = ("if (found) {\n" + " // XXXbz we should throw as needed if Throw is true\n" + " *bp = result;\n" + "} else {\n" + " *bp = true;\n" + "}") + body = (eval("CGProxy%sDeleter" % type)(self.descriptor).define() + + setBp) + elif self.descriptor.operations[type + 'Getter']: + # XXXbz: We should be doing this for cases when we have a + # creator or setter too, but we have no way to find out + # whether the property name is supported in those cases! + body = (eval("CGProxy%sGetter" % type)(self.descriptor).define() + + "if (found) {\n" + " // XXXbz we should throw if Throw is true!\n" + " *bp = false;\n" + "} else {\n" + " *bp = true;\n" + "}") + else: + body = None + return body + + delete = "" + + indexedBody = getDeleterBody("Indexed") + if indexedBody is not None: + delete += ("int32_t index = GetArrayIndexFromId(cx, id);\n" + + "if (index >= 0) {\n" + + " %s* self = UnwrapProxy(proxy);\n" + + CGIndenter(CGGeneric(indexedBody)).define() + "\n" + " // We always return here, even if the property was not found\n" + " return true;\n" + + "}\n") % self.descriptor.nativeType + + namedBody = getDeleterBody("Named") + if namedBody is not None: + delete += ("if (JSID_IS_STRING(id) && !HasPropertyOnPrototype(cx, proxy, this, id)) {\n" + " jsval nameVal = STRING_TO_JSVAL(JSID_TO_STRING(id));\n" + + " FakeDependentString name;\n" + " if (!ConvertJSValueToString(cx, nameVal, &nameVal,\n" + + " eStringify, eStringify, name)) {\n" + + " return false;\n" + + " }\n" + + " %s* self = UnwrapProxy(proxy);\n" + + CGIndenter(CGGeneric(namedBody)).define() + "\n" + " if (found) {\n" + " return true;\n" + " }\n" + "}\n") % self.descriptor.nativeType + + delete += "return dom::DOMProxyHandler::delete_(cx, proxy, id, bp);"; + + return delete + class CGDOMJSProxyHandler_getOwnPropertyNames(ClassMethod): def __init__(self, descriptor): args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'), Argument('JS::AutoIdVector&', 'props')] ClassMethod.__init__(self, "getOwnPropertyNames", "bool", args) self.descriptor = descriptor def getBody(self): indexedGetter = self.descriptor.operations['IndexedGetter'] @@ -5514,17 +5604,18 @@ class CGDOMJSProxyHandler(CGClass): if descriptor.operations['IndexedSetter'] or descriptor.operations['NamedSetter']: methods.append(CGDOMJSProxyHandler_defineProperty(descriptor)) methods.extend([CGDOMJSProxyHandler_getOwnPropertyNames(descriptor), CGDOMJSProxyHandler_hasOwn(descriptor), CGDOMJSProxyHandler_get(descriptor), CGDOMJSProxyHandler_obj_toString(descriptor), CGDOMJSProxyHandler_finalize(descriptor), CGDOMJSProxyHandler_getElementIfPresent(descriptor), - CGDOMJSProxyHandler_getInstance()]) + CGDOMJSProxyHandler_getInstance(), + CGDOMJSProxyHandler_delete(descriptor)]) CGClass.__init__(self, 'DOMProxyHandler', bases=[ClassBase('mozilla::dom::DOMProxyHandler')], constructors=constructors, methods=methods) def stripTrailingWhitespace(text): tail = '\n' if text.endswith('\n') else '' lines = text.splitlines()
--- a/dom/bindings/Configuration.py +++ b/dom/bindings/Configuration.py @@ -229,19 +229,16 @@ class Descriptor(DescriptorProvider): if m.isGetter(): addIndexedOrNamedOperation('Getter', m) if m.isSetter(): addIndexedOrNamedOperation('Setter', m) if m.isCreator(): addIndexedOrNamedOperation('Creator', m) if m.isDeleter(): addIndexedOrNamedOperation('Deleter', m) - raise TypeError("deleter specified on %s but we " - "don't support deleters yet" % - self.interface.identifier.name) iface.setUserData('hasConcreteDescendant', True) iface = iface.parent if self.proxy: iface = self.interface while iface: iface.setUserData('hasProxyDescendant', True)
--- a/dom/bindings/test/TestBindingHeader.h +++ b/dom/bindings/test/TestBindingHeader.h @@ -691,12 +691,86 @@ public: // We need a GetParentObject to make binding codegen happy virtual nsISupports* GetParentObject(); bool Continue(); bool Delete(); int32_t Volatile(); }; +class TestIndexedDeleterInterface : public nsISupports, + public nsWrapperCache +{ +public: + NS_DECL_ISUPPORTS + + // We need a GetParentObject to make binding codegen happy + virtual nsISupports* GetParentObject(); + + void IndexedDeleter(uint32_t, bool&); + void IndexedDeleter(uint32_t) MOZ_DELETE; + void DelItem(uint32_t); + void DelItem(uint32_t, bool&) MOZ_DELETE; +}; + +class TestIndexedDeleterWithRetvalInterface : public nsISupports, + public nsWrapperCache +{ +public: + NS_DECL_ISUPPORTS + + // We need a GetParentObject to make binding codegen happy + virtual nsISupports* GetParentObject(); + + bool IndexedDeleter(uint32_t, bool&); + bool IndexedDeleter(uint32_t) MOZ_DELETE; + bool DelItem(uint32_t); + bool DelItem(uint32_t, bool&) MOZ_DELETE; +}; + +class TestNamedDeleterInterface : public nsISupports, + public nsWrapperCache +{ +public: + NS_DECL_ISUPPORTS + + // We need a GetParentObject to make binding codegen happy + virtual nsISupports* GetParentObject(); + + void NamedDeleter(const nsAString&, bool&); +}; + +class TestNamedDeleterWithRetvalInterface : public nsISupports, + public nsWrapperCache +{ +public: + NS_DECL_ISUPPORTS + + // We need a GetParentObject to make binding codegen happy + virtual nsISupports* GetParentObject(); + + bool NamedDeleter(const nsAString&, bool&); + bool NamedDeleter(const nsAString&) MOZ_DELETE; + bool DelNamedItem(const nsAString&); + bool DelNamedItem(const nsAString&, bool&) MOZ_DELETE; +}; + +class TestIndexedAndNamedDeleterInterface : public nsISupports, + public nsWrapperCache +{ +public: + NS_DECL_ISUPPORTS + + // We need a GetParentObject to make binding codegen happy + virtual nsISupports* GetParentObject(); + + void IndexedDeleter(uint32_t, bool&); + + void NamedDeleter(const nsAString&, bool&); + void NamedDeleter(const nsAString&) MOZ_DELETE; + void DelNamedItem(const nsAString&); + void DelNamedItem(const nsAString&, bool&) MOZ_DELETE; +}; + } // namespace dom } // namespace mozilla #endif /* TestBindingHeader_h */
--- a/dom/bindings/test/TestCodeGen.webidl +++ b/dom/bindings/test/TestCodeGen.webidl @@ -458,14 +458,35 @@ interface TestIndexedAndNamedGetterAndSe setter creator void (unsigned long index, long item); setter creator void (DOMString name, DOMString item); [Infallible] stringifier DOMString (); [Infallible] readonly attribute unsigned long length; }; +interface TestIndexedDeleterInterface { + deleter void delItem(unsigned long index); +}; + +interface TestIndexedDeleterWithRetvalInterface { + deleter boolean delItem(unsigned long index); +}; + +interface TestNamedDeleterInterface { + deleter void (DOMString name); +}; + +interface TestNamedDeleterWithRetvalInterface { + deleter boolean delNamedItem(DOMString name); +}; + +interface TestIndexedAndNamedDeleterInterface { + deleter void (unsigned long index); + deleter void delNamedItem(DOMString name); +}; + interface TestCppKeywordNamedMethodsInterface { boolean continue(); boolean delete(); long volatile(); };