3
Special methods which we hand-generate, such as toString(), equals(), and hash().
5
These are generally added to methods listing of node.Class, and the
6
only requirement is that they must have a render(self, gen) method.
10
import pypy.translator.jvm.generator as jvmgen
11
import pypy.translator.jvm.typesystem as jvmtype
12
from pypy.rpython.ootypesystem import ootype, rclass
14
class BaseDumpMethod(object):
16
def __init__(self, db, OOCLASS, clsobj):
18
self.OOCLASS = OOCLASS
20
self.name = "toString"
21
self.jargtypes = [clsobj]
22
self.jrettype = jvmtype.jString
24
def _print_field_value(self, fieldnm, FIELDOOTY):
25
self.gen.emit(jvmgen.DUP)
26
self.gen.load_this_ptr()
27
fieldobj = self.clsobj.lookup_field(fieldnm)
28
fieldobj.load(self.gen)
29
dumpmethod = self.db.toString_method_for_ootype(FIELDOOTY)
30
self.gen.emit(dumpmethod)
31
self.gen.emit(jvmgen.PYPYAPPEND)
33
def _print(self, str):
34
self.gen.emit(jvmgen.DUP)
35
self.gen.load_string(str)
36
self.gen.emit(jvmgen.PYPYAPPEND)
38
def render(self, gen):
41
self.name, (), self.jargtypes, self.jrettype, static=False)
43
gen.new_with_jtype(jvmtype.jStringBuilder)
44
self._render_guts(gen)
45
gen.emit(jvmgen.OBJTOSTRING)
46
gen.emit(jvmgen.RETURN.for_type(jvmtype.jString))
50
class InstanceDumpMethod(BaseDumpMethod):
52
def _render_guts(self, gen):
54
genprint = self._print
57
genprint("InstanceWrapper(")
58
genprint("'" + self.OOCLASS._name + "', ")
61
for fieldnm, (FIELDOOTY, fielddef) in self.OOCLASS._fields.iteritems():
63
if FIELDOOTY is ootype.Void: continue
65
genprint('"'+fieldnm+'":')
67
print "fieldnm=%r fieldty=%r" % (fieldnm, FIELDOOTY)
69
# Print the value of the field:
70
self._print_field_value(fieldnm, FIELDOOTY)
75
class RecordDumpMethod(BaseDumpMethod):
77
def _render_guts(self, gen):
79
genprint = self._print
81
# We only render records that represent tuples:
82
# In that case, the field names look like item0, item1, etc
83
# Otherwise, we just do nothing... this is because we
84
# never return records that do not represent tuples from
86
for f_name in self.OOCLASS._fields:
87
if not f_name.startswith('item'):
91
genprint("StructTuple((")
93
numfields = len(self.OOCLASS._fields)
94
for i in range(numfields):
96
FIELD_TYPE, f_default = self.OOCLASS._fields[f_name]
97
if FIELD_TYPE is ootype.Void:
100
# Print the value of the field:
101
self._print_field_value(f_name, FIELD_TYPE)
104
# Decrement indent and dump close
107
class ConstantStringDumpMethod(BaseDumpMethod):
108
""" Just prints out a string """
110
def __init__(self, clsobj, str):
111
BaseDumpMethod.__init__(self, None, None, clsobj)
112
self.constant_string = str
114
def _render_guts(self, gen):
115
genprint = self._print
116
genprint("'" + self.constant_string + "'")
118
class DeepEqualsMethod(object):
120
def __init__(self, db, OOCLASS, clsobj):
122
self.OOCLASS = OOCLASS
125
self.jargtypes = [clsobj, jvmtype.jObject]
126
self.jrettype = jvmtype.jBool
128
def render(self, gen):
131
self.name, (), self.jargtypes, self.jrettype, static=False)
133
# Label to branch to should the items prove to be unequal
134
unequal_lbl = gen.unique_label('unequal')
136
gen.add_comment('check that the argument is of the correct type')
137
gen.load_jvm_var(self.clsobj, 1)
138
gen.instanceof(self.OOCLASS)
139
gen.goto_if_false(unequal_lbl)
141
gen.add_comment('Cast it to the right type:')
142
gen.load_jvm_var(self.clsobj, 1)
143
gen.downcast(self.OOCLASS)
144
gen.store_jvm_var(self.clsobj, 1)
146
# If so, compare field by field
147
for fieldnm, (FIELDOOTY, fielddef) in self.OOCLASS._fields.iteritems():
148
if FIELDOOTY is ootype.Void: continue
149
fieldobj = self.clsobj.lookup_field(fieldnm)
151
gen.add_comment('Compare field %s of type %s' % (fieldnm, FIELDOOTY))
153
# Load the field from both this and the argument:
154
gen.load_jvm_var(self.clsobj, 0)
156
gen.load_jvm_var(self.clsobj, 1)
160
gen.compare_values(FIELDOOTY, unequal_lbl)
162
# Return true or false as appropriate
163
gen.push_primitive_constant(ootype.Bool, True)
164
gen.return_val(jvmtype.jBool)
165
gen.mark(unequal_lbl)
166
gen.push_primitive_constant(ootype.Bool, False)
167
gen.return_val(jvmtype.jBool)
171
class DeepHashMethod(object):
173
def __init__(self, db, OOCLASS, clsobj):
175
self.OOCLASS = OOCLASS
177
self.name = "hashCode"
178
self.jargtypes = [clsobj]
179
self.jrettype = jvmtype.jInt
181
def render(self, gen):
184
self.name, (), self.jargtypes, self.jrettype, static=False)
187
gen.push_primitive_constant(ootype.Signed, 0)
189
# Get hash of each field
190
for fieldnm, (FIELDOOTY, fielddef) in self.OOCLASS._fields.iteritems():
191
if FIELDOOTY is ootype.Void: continue
192
fieldobj = self.clsobj.lookup_field(fieldnm)
194
gen.add_comment('Hash field %s of type %s' % (fieldnm, FIELDOOTY))
196
# Load the field and hash it:
197
gen.load_jvm_var(self.clsobj, 0)
199
gen.hash_value(FIELDOOTY)
201
# XOR that with the main hash
202
gen.emit(jvmgen.IXOR)
204
# Return the final hash
205
gen.return_val(jvmtype.jInt)