Bug 1144340: bindings: Provide better info for value-returning maplike methods. draft
authorEmilio Cobos Álvarez <ecoal95@gmail.com>
Sat, 16 Jul 2016 22:06:30 -0700
changeset 388670 575afb2a2314bff28f63fec782b1496db7bf72c8
parent 388620 4c05938a64a7fde3ac2d7f4493aee1c5f2ad8a0a
child 525590 b1d6ef7911dffdb72598c35aa16bf755a58af41f
push id23224
push userbmo:ealvarez@mozilla.com
push dateSun, 17 Jul 2016 05:43:32 +0000
bugs1144340
milestone50.0a1
Bug 1144340: bindings: Provide better info for value-returning maplike methods. For now, this is only the |get| method. Unfortunately this doesn't change the generated JitInfo, since the return type needs to be nullable to take into account the missing key case. Still worth it, I guess, since it improves the generated code a bit. MozReview-Commit-ID: 3NH1hzBvyAI
dom/bindings/Codegen.py
dom/bindings/parser/WebIDL.py
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -7169,16 +7169,32 @@ class CGPerSignatureCall(CGThing):
                  setter=False, isConstructor=False, useCounterName=None,
                  resultVar=None):
         assert idlNode.isMethod() == (not getter and not setter)
         assert idlNode.isAttr() == (getter or setter)
         # Constructors are always static
         assert not isConstructor or static
 
         CGThing.__init__(self)
+
+        # Value-returning methods from map-like interfaces (for now, only
+        # |get|), need their return value to be overriden to |any|.
+        #
+        # This is not a problem because the validation of the type is done when
+        # the object is inserted, and allows to hook easily in JS map
+        # machinery.
+        #
+        # Doing it in the parser implies that the JIT wouldn't have the
+        # appropriate type information, see Bug 1155340.
+        if (idlNode.isMethod()
+            and idlNode.isMaplikeOrSetlikeOrIterableMethod()
+            and idlNode.maplikeOrSetlikeOrIterable.isMaplike()
+            and idlNode.identifier.name == "get"):
+          returnType = BuiltinTypes[IDLBuiltinType.Types.any]
+
         self.returnType = returnType
         self.descriptor = descriptor
         self.idlNode = idlNode
         self.extendedAttributes = descriptor.getExtendedAttributes(idlNode,
                                                                    getter=getter,
                                                                    setter=setter)
         self.arguments = arguments
         self.argCount = len(arguments)
@@ -16013,17 +16029,17 @@ class CGMaplikeOrSetlikeHelperGenerator(
         if self.maplikeOrSetlike.isMaplike():
             self.helpers.append(
                 CGMaplikeOrSetlikeHelperFunctionGenerator(descriptor,
                                                           maplikeOrSetlike,
                                                           "Set",
                                                           needsKeyArg=True,
                                                           needsValueArg=True))
         else:
-            assert(self.maplikeOrSetlike.isSetlike())
+            assert self.maplikeOrSetlike.isSetlike()
             self.helpers.append(
                 CGMaplikeOrSetlikeHelperFunctionGenerator(descriptor,
                                                           maplikeOrSetlike,
                                                           "Add",
                                                           needsKeyArg=True))
         CGNamespace.__init__(self, self.namespace, CGList(self.helpers))
 
 
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -3897,25 +3897,18 @@ class IDLMaplikeOrSetlike(IDLMaplikeOrSe
             if isJSImplemented:
                 self.addMethod("add", members, True,
                                BuiltinTypes[IDLBuiltinType.Types.object], [getKeyArg()],
                                chromeOnly=True)
             return
 
         # If we get this far, we're a maplike declaration.
 
-        # valueType get(keyType key)
-        #
-        # Note that instead of the value type, we're using any here. The
-        # validity checks should happen as things are inserted into the map,
-        # and using any as the return type makes code generation much simpler.
-        #
-        # TODO: Bug 1155340 may change this to use specific type to provide
-        # more info to JIT.
-        self.addMethod("get", members, False, BuiltinTypes[IDLBuiltinType.Types.any],
+        # valueType? get(keyType key)
+        self.addMethod("get", members, False, IDLNullableType(self.location, self.valueType),
                        [getKeyArg()], isPure=True)
 
         def getValueArg():
             return IDLArgument(self.location,
                                IDLUnresolvedIdentifier(self.location, "value"),
                                self.valueType)
 
         if not self.readonly: