예제 #1
0
    def _translate_record(self, OOTYPE):
        assert OOTYPE is not ootype.ROOT

        # Create class object if it does not already exist:
        if OOTYPE in self._classes:
            return self._classes[OOTYPE]

        # Create the class object first
        clsnm = self._pkg(self._uniq('Record'))
        clsobj = node.Class(clsnm, jObject)
        self._classes[OOTYPE] = clsobj

        # Add fields:
        self._translate_class_fields(clsobj, OOTYPE)

        # generate toString
        dump_method = methods.RecordDumpMethod(self, OOTYPE, clsobj)
        clsobj.add_method(dump_method)

        # generate equals and hash
        equals_method = methods.DeepEqualsMethod(self, OOTYPE, clsobj)
        clsobj.add_method(equals_method)
        hash_method = methods.DeepHashMethod(self, OOTYPE, clsobj)
        clsobj.add_method(hash_method)

        self.pending_node(clsobj)
        return clsobj
예제 #2
0
    def _translate_instance(self, OOTYPE):
        assert isinstance(OOTYPE, ootype.Instance)
        assert OOTYPE is not ootype.ROOT

        # Create class object if it does not already exist:
        if OOTYPE in self._classes:
            return self._classes[OOTYPE]

        # Create the class object first
        clsnm = self._pkg(self._uniq(OOTYPE._name))
        clsobj = node.Class(clsnm)
        self._classes[OOTYPE] = clsobj

        # Resolve super class
        assert OOTYPE._superclass
        supercls = self._translate_superclass_of(OOTYPE)
        clsobj.set_super_class(supercls)

        # TODO --- mangle field and method names?  Must be
        # deterministic, or use hashtable to avoid conflicts between
        # classes?

        # Add fields:
        self._translate_class_fields(clsobj, OOTYPE)

        # Add methods:
        for mname, mimpl in OOTYPE._methods.iteritems():
            if not hasattr(mimpl, 'graph'):
                # Abstract method
                METH = mimpl._TYPE
                arglist = [
                    self.lltype_to_cts(ARG) for ARG in METH.ARGS
                    if ARG is not ootype.Void
                ]
                returntype = self.lltype_to_cts(METH.RESULT)
                clsobj.add_abstract_method(
                    jvm.Method.v(clsobj, mname, arglist, returntype))
            else:
                # if the first argument's type is not a supertype of
                # this class it means that this method this method is
                # not really used by the class: don't render it, else
                # there would be a type mismatch.
                args = mimpl.graph.getargs()
                SELF = args[0].concretetype
                if not ootype.isSubclass(OOTYPE, SELF): continue
                mobj = self._function_for_graph(clsobj, mname, False,
                                                mimpl.graph)
                graphs = OOTYPE._lookup_graphs(mname)
                if len(graphs) == 1:
                    mobj.is_final = True
                clsobj.add_method(mobj)

        # currently, we always include a special "dump" method for debugging
        # purposes
        dump_method = node.InstanceDumpMethod(self, OOTYPE, clsobj)
        clsobj.add_method(dump_method)

        self.pending_node(clsobj)
        return clsobj
예제 #3
0
 def pending_function(self, graph):
     """
     This is invoked when a standalone function is to be compiled.
     It creates a class named after the function with a single
     method, invoke().  This class is added to the worklist.
     Returns a jvmgen.Method object that allows this function to be
     invoked.
     """
     if graph in self._functions:
         return self._functions[graph]
     classnm = self._pkg(self._uniq(graph.name))
     classobj = node.Class(classnm, self.pending_class(ootype.ROOT))
     funcobj = self._function_for_graph(classobj, "invoke", True, graph)
     classobj.add_method(funcobj)
     self.pending_node(classobj)
     res = self._functions[graph] = funcobj.method()
     return res
예제 #4
0
    def create_interlink_node(self, methods):
        """ This is invoked by create_interlinke_node() in
        jvm/prebuiltnodes.py.  It creates a Class node that will
        be an instance of the Interlink interface, which is used
        to allow the static java code to throw PyPy exceptions and the
        like.

        The 'methods' argument should be a dictionary whose keys are
        method names and whose entries are jvmgen.Method objects which
        the corresponding method should invoke. """

        nm = self._pkg(self._uniq('InterlinkImplementation'))
        cls = node.Class(nm, supercls=jObject)
        for method_name, helper in methods.items():
            cls.add_method(node.InterlinkFunction(cls, method_name, helper))
        cls.add_interface(jvmtype.jPyPyInterlink)
        self.jInterlinkImplementation = cls
        self.pending_node(cls)
예제 #5
0
    def _translate_Object(self, OBJ):
        """
        We handle the class 'Object' quite specially: we translate it
        into an interface with two implementations.  One
        implementation serves as the root of most objects, and the
        other as the root for all exceptions.
        """
        assert self.is_Object(OBJ)
        assert OBJ._superclass == ootype.ROOT

        # Have we already translated Object?
        if self._object_interf: return self._object_interf

        # Create the interface and two implementations:
        def gen_name():
            return self._pkg(self._uniq(OBJ._name))

        internm, implnm, exc_implnm = gen_name(), gen_name(), gen_name()
        self._object_interf = node.Interface(internm)
        self._object_impl = node.Class(implnm, supercls=jObject)
        self._object_exc_impl = node.Class(exc_implnm, supercls=jThrowable)
        self._object_impl.add_interface(self._object_interf)
        self._object_exc_impl.add_interface(self._object_interf)

        # Translate the fields into properties on the interface,
        # and into actual fields on the implementations.
        for fieldnm, (FIELDOOTY, fielddef) in OBJ._fields.iteritems():
            if FIELDOOTY is ootype.Void: continue
            fieldty = self.lltype_to_cts(FIELDOOTY)

            # Currently use hacky convention of _jvm_FieldName for the name
            methodnm = "_jvm_" + fieldnm

            def getter_method_obj(node):
                return Method.v(node, methodnm + "_g", [], fieldty)

            def putter_method_obj(node):
                return Method.v(node, methodnm + "_p", [fieldty], jVoid)

            # Add get/put methods to the interface:
            prop = Property(fieldnm,
                            getter_method_obj(self._object_interf),
                            putter_method_obj(self._object_interf),
                            OOTYPE=FIELDOOTY)
            self._object_interf.add_property(prop)

            # Generate implementations:
            def generate_impl(clsobj):
                clsnm = clsobj.name
                fieldobj = Field(clsnm, fieldnm, fieldty, False, FIELDOOTY)
                clsobj.add_field(fieldobj, fielddef)
                clsobj.add_method(
                    node.GetterFunction(self, clsobj,
                                        getter_method_obj(clsobj), fieldobj))
                clsobj.add_method(
                    node.PutterFunction(self, clsobj,
                                        putter_method_obj(clsobj), fieldobj))

            generate_impl(self._object_impl)
            generate_impl(self._object_exc_impl)

        # Ensure that we generate all three classes.
        self.pending_node(self._object_interf)
        self.pending_node(self._object_impl)
        self.pending_node(self._object_exc_impl)