Bug 863898. Add support for dictionary arguments in JS-implemented WebIDL bindings. r=mccr8
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 25 Apr 2013 12:29:55 -0400
changeset 140841 4f09599d049f29b6739e55702d99ec29d4450df5
parent 140840 74bd92b1c03343ae53e318f94690e195ca8f7966
child 140842 34819ac4912ebd5d0299d0782d7a8b108620dc8c
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs863898
milestone23.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
Bug 863898. Add support for dictionary arguments in JS-implemented WebIDL bindings. r=mccr8
dom/bindings/BindingDeclarations.h
dom/bindings/Codegen.py
dom/bindings/test/TestJSImplGen.webidl
--- a/dom/bindings/BindingDeclarations.h
+++ b/dom/bindings/BindingDeclarations.h
@@ -367,22 +367,19 @@ public:
       }
       mCx = aCx;
     }
 
     mValue = aValue;
     return true;
   }
 
-  operator JS::Value()
-  {
-    return mValue;
-  }
-
-  operator const JS::Value() const
+  // Note: This operator can be const because we return by value, not
+  // by reference.
+  operator JS::Value() const
   {
     return mValue;
   }
 
 private:
   // Don't allow copy-construction of these objects, because it'll do the wrong
   // thing with our flag mCx.
   RootedJSValue(const RootedJSValue&) MOZ_DELETE;
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -7067,17 +7067,17 @@ class CGDictionary(CGThing):
                        (self.getMemberType(m),
                         self.makeMemberName(m[0].identifier.name))
                        for m in self.memberInfo]
 
         return (string.Template(
                 "struct ${selfName} ${inheritance}{\n"
                 "  ${selfName}() {}\n"
                 "  bool Init(JSContext* cx, const JS::Value& val);\n"
-                "  bool ToObject(JSContext* cx, JS::Handle<JSObject*> parentObject, JS::Value *vp);\n"
+                "  bool ToObject(JSContext* cx, JS::Handle<JSObject*> parentObject, JS::Value *vp) const;\n"
                 "\n" +
                 ("  bool Init(const nsAString& aJSON)\n"
                  "  {\n"
                  "    Maybe<JSAutoRequest> ar;\n"
                  "    Maybe<JSAutoCompartment> ac;\n"
                  "    Maybe< JS::Rooted<JS::Value> > json;\n"
                  "    JSContext* cx = ParseJSON(aJSON, ar, ac, json);\n"
                  "    NS_ENSURE_TRUE(cx, false);\n"
@@ -7172,17 +7172,17 @@ class CGDictionary(CGThing):
             "    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY);\n"
             "  }\n"
             "\n"
             "${initMembers}\n"
             "  return true;\n"
             "}\n"
             "\n"
             "bool\n"
-            "${selfName}::ToObject(JSContext* cx, JS::Handle<JSObject*> parentObject, JS::Value *vp)\n"
+            "${selfName}::ToObject(JSContext* cx, JS::Handle<JSObject*> parentObject, JS::Value *vp) const\n"
             "{\n" +
             # NOTE: jsids are per-runtime, so don't use them in workers
             ("  if (!initedIds && !InitIds(cx)) {\n"
              "    return false;\n"
              "  }\n" if self.needToInitIds else "") +
             "${toObjectParent}"
             "${ensureObject}"
             "\n"
@@ -7319,17 +7319,17 @@ class CGDictionary(CGThing):
                 'jsvalRef': "temp",
                 'jsvalPtr': "&temp",
                 'isCreator': False,
                 'obj': "parentObject"
             }, isMember=True)
         conversion = CGGeneric(innerTemplate)
         conversion = CGWrapper(conversion,
                                pre=("JS::Value temp;\n"
-                                    "%s& currentValue = %s;\n" %
+                                    "const %s& currentValue = %s;\n" %
                                     (declType.define(), memberData)
                                     ))
 
         if not member.defaultValue:
             # Only do the conversion if we have a value
             conversion = CGIfWrapper(conversion, "%s.WasPassed()" % memberLoc)
         else:
             # Make sure we have a scope for our stuff
--- a/dom/bindings/test/TestJSImplGen.webidl
+++ b/dom/bindings/test/TestJSImplGen.webidl
@@ -319,24 +319,25 @@ interface TestJSImplInterface {
   //(BUG 856911)  void passObject(object arg);
   void passNullableObject(object? arg);
   //(BUG 856911)  void passOptionalObject(optional object arg);
   void passOptionalNullableObject(optional object? arg);
   void passOptionalNullableObjectWithDefaultValue(optional object? arg = null);
   object receiveObject();
   object? receiveNullableObject();
 
-/* The rest of these are untested.
   // Union types
   void passUnion((object or long) arg);
   void passUnionWithNullable((object? or long) arg);
-  void passNullableUnion((object or long)? arg);
+  // FIXME: Bug 863948 Nullable unions not supported yet
+  //   void passNullableUnion((object or long)? arg);
   void passOptionalUnion(optional (object or long) arg);
-  void passOptionalNullableUnion(optional (object or long)? arg);
-  void passOptionalNullableUnionWithDefaultValue(optional (object or long)? arg = null);
+  // FIXME: Bug 863948 Nullable unions not supported yet
+  //  void passOptionalNullableUnion(optional (object or long)? arg);
+  //  void passOptionalNullableUnionWithDefaultValue(optional (object or long)? arg = null);
   //void passUnionWithInterfaces((TestJSImplInterface or TestExternalInterface) arg);
   //void passUnionWithInterfacesAndNullable((TestJSImplInterface? or TestExternalInterface) arg);
   //void passUnionWithSequence((sequence<object> or long) arg);
   void passUnionWithArrayBuffer((ArrayBuffer or long) arg);
   void passUnionWithString((DOMString or object) arg);
   //void passUnionWithEnum((MyTestEnum or object) arg);
   // Trying to use a callback in a union won't include the test
   // headers, unfortunately, so won't compile.
@@ -346,42 +347,46 @@ interface TestJSImplInterface {
 
   // binaryNames tests
   void methodRenamedFrom();
   void methodRenamedFrom(byte argument);
   readonly attribute byte attributeGetterRenamedFrom;
   attribute byte attributeRenamedFrom;
 
   void passDictionary(optional Dict x);
-  //UNSUPPORTED  Dict receiveDictionary();
+  // FIXME: Bug 863949 no dictionary return values
+  //   Dict receiveDictionary();
   void passOtherDictionary(optional GrandparentDict x);
   void passSequenceOfDictionaries(sequence<Dict> x);
   void passDictionaryOrLong(optional Dict x);
   void passDictionaryOrLong(long x);
 
   void passDictContainingDict(optional DictContainingDict arg);
   void passDictContainingSequence(optional DictContainingSequence arg);
-  //UNSUPPORTED DictContainingSequence receiveDictContainingSequence();
+  // FIXME: Bug 863949 no dictionary return values
+  //   DictContainingSequence receiveDictContainingSequence();
 
   // EnforceRange/Clamp tests
   void dontEnforceRangeOrClamp(byte arg);
   void doEnforceRange([EnforceRange] byte arg);
   void doClamp([Clamp] byte arg);
 
   // Typedefs
   const myLong myLongConstant = 5;
-  // ???? What 
   void exerciseTypedefInterfaces1(AnotherNameForTestJSImplInterface arg);
   AnotherNameForTestJSImplInterface exerciseTypedefInterfaces2(NullableTestJSImplInterface arg);
   void exerciseTypedefInterfaces3(YetAnotherNameForTestJSImplInterface arg);
 
   // Static methods and attributes
+  // FIXME: Bug 863952 Static things are not supported yet
+  /*
   static attribute boolean staticAttribute;
   static void staticMethod(boolean arg);
   static void staticMethodWithContext(any arg);
+  */
 
   // Overload resolution tests
   //void overload1(DOMString... strs);
   boolean overload1(TestJSImplInterface arg);
   TestJSImplInterface overload1(DOMString strs, TestJSImplInterface arg);
   void overload2(TestJSImplInterface arg);
   void overload2(optional Dict arg);
   void overload2(DOMString arg);
@@ -392,28 +397,32 @@ interface TestJSImplInterface {
   void overload4(TestCallbackInterface arg);
   void overload4(DOMString arg);
 
   // Variadic handling
   void passVariadicThirdArg(DOMString arg1, long arg2, TestJSImplInterface... arg3);
 
   // Miscellania
   [LenientThis] attribute long attrWithLenientThis;
-  [Unforgeable] readonly attribute long unforgeableAttr;
-  [Unforgeable, ChromeOnly] readonly attribute long unforgeableAttr2;
-  stringifier;
+  // FIXME: Bug 863954 Unforgeable things get all confused when
+  // non-JS-implemented interfaces inherit from JS-implemented ones or vice
+  // versa.
+  //   [Unforgeable] readonly attribute long unforgeableAttr;
+  //   [Unforgeable, ChromeOnly] readonly attribute long unforgeableAttr2;
+  // FIXME: Bug 863955 No stringifiers yet
+  //   stringifier;
   void passRenamedInterface(TestRenamedInterface arg);
   [PutForwards=writableByte] readonly attribute TestJSImplInterface putForwardsAttr;
   [PutForwards=writableByte, LenientThis] readonly attribute TestJSImplInterface putForwardsAttr2;
   [PutForwards=writableByte, ChromeOnly] readonly attribute TestJSImplInterface putForwardsAttr3;
   [Throws] void throwingMethod();
   [Throws] attribute boolean throwingAttr;
   [GetterThrows] attribute boolean throwingGetterAttr;
   [SetterThrows] attribute boolean throwingSetterAttr;
-*/
+
   // If you add things here, add them to TestCodeGen as well
 };
 
 interface TestCImplementedInterface : TestJSImplInterface {
 };
 
 interface TestCImplementedInterface2 {
 };