4
from sets import Set as set
6
from pypy.objspace.flow import model as flowmodel
7
from pypy.rpython.lltypesystem.lltype import Signed, Unsigned, Void, Bool, Float
8
from pypy.rpython.lltypesystem.lltype import SignedLongLong, UnsignedLongLong
9
from pypy.rpython.ootypesystem import ootype
10
from pypy.translator.oosupport.metavm import Generator,InstructionList
11
from pypy.translator.oosupport import function
13
from pypy.translator.js.log import log
14
from types import FunctionType
18
class BaseGenerator(object):
20
if isinstance(v, flowmodel.Variable):
21
if v.name in self.argset:
22
selftype, selfname = self.args[0]
23
if self.is_method and v.name == selfname:
24
self.ilasm.load_self()
26
self.ilasm.load_arg(v)
28
self.ilasm.load_local(v)
29
elif isinstance(v, flowmodel.Constant):
30
self.db.load_const(v.concretetype, v.value, self.ilasm)
35
if isinstance(v, flowmodel.Variable):
36
if v.concretetype is not Void:
37
self.ilasm.store_local(v)
39
self.ilasm.store_void()
43
def change_name(self, name, to_name):
44
self.ilasm.change_name(name, to_name)
46
def add_comment(self, text):
49
def function_signature(self, graph):
50
return self.cts.graph_to_signature(graph, False)
52
def class_name(self, ooinstance):
53
return ooinstance._name
55
def emit(self, instr, *args):
56
self.ilasm.emit(instr, *args)
58
def call_graph(self, graph):
59
self.db.pending_function(graph)
60
func_sig = self.function_signature(graph)
61
self.ilasm.call(func_sig)
63
def call_external(self, name, args):
64
self.ilasm.call((name, args))
66
#def call_signature(self, signature):
67
# self.ilasm.call(signature)
69
def cast_to(self, lltype):
70
cts_type = self.cts.lltype_to_cts(lltype, False)
71
self.ilasm.castclass(cts_type)
74
self.ilasm.new(self.cts.obj_name(obj))
76
def set_field(self, obj, name):
77
self.ilasm.set_field(obj, name)
78
#self.ilasm.set_field(self.field_name(obj,name))
80
def get_field(self, useless_stuff, name):
81
self.ilasm.get_field(name)
83
def call_method(self, obj, name):
84
func_name, signature = self.cts.method_signature(obj, name)
85
self.ilasm.call_method(obj, name, signature)
87
def call_external_method(self, name, arg_len):
88
self.ilasm.call_method(None, name, [0]*arg_len)
90
def instantiate(self):
91
self.ilasm.runtimenew()
93
def downcast(self, TYPE):
96
def load_special(self, v):
97
# special case for loading value
98
# when setting builtin field we need to load function instead of None
99
# FIXME: we cheat here
100
if isinstance(v, flowmodel.Constant) and v.concretetype is ootype.Void and isinstance(v.value, FunctionType):
101
graph = self.db.translator.annotator.bookkeeper.getdesc(v.value).cachedgraph(None)
102
self.db.pending_function(graph)
104
self.ilasm.load_str(name)
108
def cast_function(self, name, num):
109
self.ilasm.cast_function(name, num)
111
def prefix_op(self, st):
112
self.ilasm.prefix_op(st)
114
def load_str(self, s):
115
self.ilasm.load_str(s)
118
self.ilasm.load_void()
120
def list_setitem(self, base_obj, item, val):
124
self.ilasm.list_setitem()
126
def list_getitem(self, base_obj, item):
129
self.ilasm.list_getitem()
131
def push_primitive_constant(self, TYPE, value):
132
self.db.load_const(TYPE, value, self.ilasm)
134
def branch_unconditionally(self, target_label):
135
self.ilasm.jump_block(self.block_map[target_label])
137
def branch_conditionally(self, exitcase, target_label):
138
self.ilasm.branch_if(exitcase)
139
self.ilasm.jump_block(self.block_map[target_label])
140
self.ilasm.close_branch()
142
class Function(function.Function, BaseGenerator):
143
def __init__(self, db, graph, name=None, is_method=False,
144
is_entrypoint=False, _class=None):
146
super(Function, self).__init__(db, graph, name, is_method, is_entrypoint)
150
self.name = name or self.db.get_uniquename(self.graph, self.graph.name)
152
def _setup_link(self, link, is_exc_link = False):
154
for to_load, to_store in zip(link.args, target.inputargs):
155
if to_load.concretetype is not Void:
156
if is_exc_link and isinstance(to_load, flowmodel.Variable) and re.match("last_exc_value", to_load.name):
157
self.ilasm.load_str("exc")
162
def _create_generator(self, ilasm):
165
def begin_render(self):
167
for blocknum, block in enumerate(self.graph.iterblocks()):
168
block_map[self._get_block_name(block)] = blocknum
169
self.block_map = block_map
172
args = self.args[1:] # self is implicit
176
self.ilasm.begin_method(self.name, self._class, [i[1] for i in args])
178
self.ilasm.begin_function(self.name, args)
179
self.ilasm.set_locals(",".join([i[1] for i in self.locals]))
180
self.ilasm.begin_for()
182
def render_return_block(self, block):
183
return_var = block.inputargs[0]
184
if return_var.concretetype is not Void:
185
self.load(return_var)
188
self.ilasm.load_void()
191
def end_render(self):
193
self.ilasm.end_function()
195
def render_raise_block(self, block):
196
self.ilasm.throw(block.inputargs[1])
198
def end_try(self, target_label):
199
self.ilasm.jump_block(self.block_map[target_label])
201
#self.ilasm.close_branch()
203
def record_ll_meta_exc(self, ll_meta_exc):
206
def begin_catch(self, llexitcase):
207
real_name = self.cts.lltype_to_cts(llexitcase._inst.class_._INSTANCE)
208
s = "isinstanceof(exc, %s)"%real_name
209
self.ilasm.branch_if_string(s)
211
def end_catch(self, target_label):
212
""" Ends the catch block, and branchs to the given target_label as the
213
last item in the catch block """
214
self.ilasm.close_branch()
216
def store_exception_and_link(self, link):
217
self._setup_link(link, True)
218
self.ilasm.jump_block(self.block_map[self._get_block_name(link.target)])
220
def after_except_block(self):
221
#self.ilasm.close_branch()
222
self.ilasm.throw_real("exc")
223
self.ilasm.close_branch()
225
def set_label(self, label):
226
self.ilasm.write_case(self.block_map[label])
227
#self.ilasm.label(label)
230
self.ilasm.begin_try()