Start on wrapping primitive values; r=bz
authorMs2ger <ms2ger@gmail.com>
Tue, 07 Feb 2012 14:48:20 +0100
changeset 86007 2f87237e2de8036d5a84035392943e321b0ae152
parent 86006 8a06ecf9b6fdba19b1004e63c567403e9fae5e07
child 86008 f4bceb2b77d09375702a92df644f88de7db39f5a
push id88
push userMs2ger@gmail.com
push dateTue, 07 Feb 2012 13:48:50 +0000
reviewersbz
milestone13.0a1
Start on wrapping primitive values; r=bz
dom/bindings/Codegen.py
dom/bindings/parser/WebIDL.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1,15 +1,18 @@
 # 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/.
 
 # Common codegen classes.
 
 import os
+import string
+
+from WebIDL import *
 
 class CGThing():
     """
     Abstract base case for things that spit out code.
     """
     def __init__(self):
         pass # Nothing for now
     def declare(self):
@@ -381,16 +384,55 @@ class CGGetProtoObjectMethod(CGAbstractM
   JSObject *ourProto = protoArray[id::%s];
   if (!ourProto) {
     ourProto = protoArray[id::%s] = CreateProtoObject(aCx, aGlobal);
   }
 
   /* ourProto might _still_ be null, but that's OK */
   return ourProto;""" % (self.descriptor.name, self.descriptor.name)
 
+builtinNames = {
+    IDLType.Tags.bool: 'bool',
+    IDLType.Tags.uint8: 'uint8_t',
+    IDLType.Tags.int16: 'int16_t',
+    IDLType.Tags.int32: 'int32_t',
+    IDLType.Tags.int64: 'int64_t',
+    IDLType.Tags.uint16: 'uint16_t',
+    IDLType.Tags.uint32: 'uint32_t',
+    IDLType.Tags.uint64: 'uint64_t',
+    IDLType.Tags.float: 'float',
+    IDLType.Tags.double: 'double'
+}
+
+def getWrapTemplateForTag(tag):
+    if tag in [IDLType.Tags.uint8, IDLType.Tags.int16, IDLType.Tags.int32, IDLType.Tags.uint16]:
+        return """
+  ${jsvalRef} = INT_TO_JSVAL(int32_t(result));
+  return true;"""
+
+    elif tag in [IDLType.Tags.int64, IDLType.Tags.uint64, IDLType.Tags.float, IDLType.Tags.double]:
+        return """
+  return JS_NewNumberValue(cx, double(result), ${jsvalPtr});"""
+
+    elif tag == IDLType.Tags.uint32:
+        return """
+  ${jsvalRef} = UINT_TO_JSVAL(result);
+  return true;"""
+
+    elif tag == IDLType.Tags.bool:
+        return """
+  ${jsvalRef} = BOOLEAN_TO_JSVAL(result);
+  return true;"""
+
+    else:
+        return """
+  // XXXbz need to learn to wrap other things
+  return false;"""
+
+
 class PerSignatureCall():
     """
     This class handles the guts of generating code for a particular
     call signature.  A call signature consists of three things:
 
     1) A return type, which can be None to indicate that there is no
        actual return value (e.g. this is an attribute setter) or an
        IDLType if there's an IDL type involved (including |void|).
@@ -420,37 +462,50 @@ class PerSignatureCall():
         return ""
 
     def generate_call(self):
         # XXXbz add provisions for infallible calls here?
         nativeArgs = ["arg" + str(i) for i in range(len(self.arguments))]
         # XXXbz arguments that have to go in outparams go here?
         nativeArgs.append("&rv")
         # XXXbz need to have full config to do this retval business right
-        nativeRetval = "" if self.returnType is None else ""
+        if self.returnType is None or self.returnType.isVoid():
+            # Nothing to declare.
+            resultDeclaration = ""
+        elif self.returnType.isPrimitive() and self.returnType.tag() in builtinNames:
+            resultDeclaration = "%s result = 0;" % builtinNames[self.returnType.tag()]
+        else:
+            resultDeclaration = "// XXX need to declare |result| for type %s." % self.returnType
+
         return """
   nsresult rv = NS_OK;
+  %s
   // XXXbz need to actually make those methods exist!
 #if 0
   self->%s(%s);
 #endif
   if (NS_FAILED(rv)) {%s
-  }""" % (self.nativeMethodName, ', '.join(nativeArgs), self.getErrorReport())
+  }""" % (resultDeclaration, self.nativeMethodName, ', '.join(nativeArgs), self.getErrorReport())
 
     def wrap_return_value(self):
         if self.returnType.isVoid():
             return """
   *vp = JSVAL_VOID;
   return true;"""
+
         if self.returnType.isInterface():
             # Wrap the object
             return """
   // XXXbz need to learn to wrap objects
   return false;"""
 
+        resultTemplateValues = {'jsvalRef': '*vp', 'jsvalPtr': 'vp'}
+        if self.returnType.isPrimitive():
+            return "\n" + string.Template(getWrapTemplateForTag(self.returnType.tag())).substitute(resultTemplateValues)
+
         return """
   // XXXbz need to learn to wrap other things
   return false;"""
 
     def __str__(self):
         return (self.unwrap_arguments() + self.generate_call() +
                 self.wrap_return_value())
 
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -846,17 +846,17 @@ class IDLBuiltinType(IDLType):
         # ArrayBuffers.
         return self.type == IDLBuiltinType.Types.ArrayBuffer
 
     def isFloat(self):
         return self.type == IDLBuiltinType.Types.float or \
                self.type == IDLBuiltinType.Types.double
 
     def tag(self):
-        return TagLookup[self.type]
+        return IDLBuiltinType.TagLookup[self.type]
 
 BuiltinTypes = {
       IDLBuiltinType.Types.byte:
           IDLBuiltinType(BuiltinLocation("<builtin type>"), "Byte",
                          IDLBuiltinType.Types.byte),
       IDLBuiltinType.Types.octet:
           IDLBuiltinType(BuiltinLocation("<builtin type>"), "Octet",
                          IDLBuiltinType.Types.octet),