[mq]: do-enum-wrapping
authorBoris Zbarsky <bzbarsky@mit.edu>
Sun, 12 Feb 2012 14:07:23 -0500
changeset 86767 9eff55433c3e8d1f8027f7c9ad6172039d7fc288
parent 86766 b962d8855af70f2f88a08da764fb1539f1f11a6b
child 86811 fa6d292daead3170cf154c40ba1b0dfb27fb61d6
push id113
push userbzbarsky@mozilla.com
push dateSun, 12 Feb 2012 19:07:36 +0000
milestone13.0a1
[mq]: do-enum-wrapping
dom/bindings/Codegen.py
dom/bindings/parser/WebIDL.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -530,16 +530,19 @@ class FailureFatalConcreteObjectUnwrappe
     """
     As ConcreteObjectUnwrapper, but defaulting to throwing if unwrapping fails
     """
     def __init__(self, descriptor, source, target):
         ConcreteObjectUnwrapper.__init__(self, descriptor, source, target,
                                          "return xpc_qsThrow(cx, rv);")
 
 def getArgumentConversionTemplate(type, descriptor):
+    if type.isSequence() or type.isArray():
+        raise TypeError("Can't handle sequence or array arguments yet")
+
     if descriptor is not None:
         assert(type.isInterface())
         # This is an interface that we implement as a concrete class
         # or an XPCOM interface.
         if type.nullable():
             nameSuffix = ""
         else:
             nameSuffix = "_ptr"
@@ -577,16 +580,19 @@ def getArgumentConversionTemplate(type, 
             "  xpc_qsDOMString ${name}(cx, ${argVal}, ${argPtr},\n"
             "                       xpc_qsDOMString::eDefaultNullBehavior,\n"
             "                       xpc_qsDOMString::eDefaultUndefinedBehavior);\n"
             "  if (!${name}.IsValid()) {\n"
             "    return false;\n"
             "  }\n")
 
     if type.isEnum():
+        if type.nullable():
+            raise TypeError("We don't support nullable enumerated arguments "
+                            "yet")
         enum = type.inner.identifier.name
         return (
             "  %(enumtype)s ${name};\n"
             "  {\n"
             "    bool ok;\n"
             "    $name = (%(enumtype)s) FindEnumStringIndex(cx, ${argVal}, %(values)s, &ok);\n"
             "    if (!ok) {\n"
             "      return false;\n"
@@ -726,16 +732,19 @@ class ArgumentConverter():
 
     def __str__(self):
         return string.Template(
             "\n" + getArgumentConversionTemplate(self.argument.type,
                                                  self.descriptor)
             ).substitute(self.replacementVariables)
 
 def getWrapTemplateForTypeImpl(type, result):
+    if type.isSequence() or type.isArray():
+        raise TypeError("Can't handle sequence or array return values yet")
+
     if type.isVoid():
         return """
   ${jsvalRef} = JSVAL_VOID;
   return true;"""
 
     if type.isInterface() and not type.isArrayBuffer():
         # Wrap the object
         return """
@@ -745,20 +754,33 @@ def getWrapTemplateForTypeImpl(type, res
     if type.isString():
         if type.nullable():
             return """
   return xpc::StringToJsval(cx, %s, ${jsvalPtr});""" % result
         else:
             return """
   return xpc::NonVoidStringToJsval(cx, %s, ${jsvalPtr});""" % result
 
+    if type.isEnum():
+        if type.nullable():
+            raise TypeError("We don't support nullable enumerated return types "
+                            "yet")
+        return """
+  MOZ_ASSERT(uint32_t(result) < ArrayLength(%(strings)s));
+  JSString* result_str = JS_NewStringCopyZ(cx, %(strings)s[uint32_t(result)]);
+  if (!result_str) {
+    return false;
+  }
+  ${jsvalRef} = JS::StringValue(result_str);
+  return true;""" % { "strings" : type.inner.identifier.name + "::strings" }
+    
     if not type.isPrimitive():
         return """
-  // XXXbz need to learn to wrap other things
-  return false;"""
+  // XXXbz need to learn to wrap %s
+  return false;""" % type
 
     if type.nullable():
         return """
   if (%s.IsNull()) {
     ${jsvalRef} = JSVAL_NULL;
     return true;
   }
 %s""" % (result, getWrapTemplateForTypeImpl(type.inner, "%s.Value()" % result))
@@ -870,17 +892,21 @@ class PerSignatureCall():
             # Nothing to declare.
             resultDeclaration = ""
         elif self.returnType.isPrimitive() and self.returnType.tag() in builtinNames:
             if self.returnType.nullable():
                 resultDeclaration = "  Nullable<%s> result;\n" % builtinNames[self.returnType.tag()]
             else:
                 resultDeclaration = "  %s result = 0;\n" % builtinNames[self.returnType.tag()]
         elif self.returnType.isString():
-            resultDeclaration = "  nsAutoString result;\n"
+            resultDeclaration = "  nsString result;\n"
+        elif self.returnType.isEnum():
+            if self.returnType.nullable():
+                raise TypeError("We don't support nullable enum return values")
+            resultDeclaration = "  %s result;\n" % (self.returnType.inner.identifier.name + "::value")
         else:
             resultDeclaration = "  // XXX need to declare |result| for type %s.\n" % self.returnType
 
         if self.returnType is None or self.returnType.isVoid():
             resultAssignment = ""
         else:
             resultAssignment = "result = "
 
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -609,16 +609,19 @@ class IDLNullableType(IDLType):
         return self.inner.isArray()
 
     def isDictionary(self):
         return self.inner.isDictionary()
 
     def isInterface(self):
         return self.inner.isInterface()
 
+    def isEnum(self):
+        return self.inner.isEnum()
+
     def tag(self):
         return self.inner.tag()
 
 class IDLSequenceType(IDLType):
     def __init__(self, location, parameterType):
         assert not parameterType.isVoid()
 
         IDLType.__init__(self, location, parameterType.name)
@@ -650,16 +653,19 @@ class IDLSequenceType(IDLType):
         return self.inner.isArray()
 
     def isDictionary(self):
         return self.inner.isDictionary()
 
     def isInterface(self):
         return self.inner.isInterface()
 
+    def isEnum(self):
+        return self.inner.isEnum();
+
     def tag(self):
         return self.inner.tag()
 
 class IDLArrayType(IDLType):
     def __init__(self, location, parameterType):
         assert not parameterType.isVoid()
         if parameterType.isSequence():
             raise WebIDLError("Array type cannot parameterize over a sequence type",
@@ -699,16 +705,19 @@ class IDLArrayType(IDLType):
 
     def isDictionary(self):
         assert not self.inner.isDictionary()
         return self.inner.isDictionary()
 
     def isInterface(self):
         return self.inner.isInterface()
 
+    def isEnum(self):
+        return self.inner.isEnum()
+
     def tag(self):
         return self.inner.tag()
 
 class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
     def __init__(self, location, innerType, name):
         IDLType.__init__(self, location, innerType.name)
 
         identifier = IDLUnresolvedIdentifier(location, name)