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
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
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
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)
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)