~ubuntu-branches/ubuntu/karmic/pypy/karmic

« back to all changes in this revision

Viewing changes to pypy/translator/js/function.py

  • Committer: Bazaar Package Importer
  • Author(s): Alexandre Fayolle
  • Date: 2007-04-13 09:33:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070413093309-yoojh4jcoocu2krz
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
try:
 
2
    set
 
3
except NameError:
 
4
    from sets import Set as set
 
5
 
 
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
 
12
 
 
13
from pypy.translator.js.log import log
 
14
from types import FunctionType
 
15
 
 
16
import re
 
17
 
 
18
class BaseGenerator(object):
 
19
    def load(self, v):
 
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()
 
25
                else:
 
26
                    self.ilasm.load_arg(v)
 
27
            else:
 
28
                self.ilasm.load_local(v)
 
29
        elif isinstance(v, flowmodel.Constant):
 
30
            self.db.load_const(v.concretetype, v.value, self.ilasm)
 
31
        else:
 
32
            assert False
 
33
 
 
34
    def store(self, v):
 
35
        if isinstance(v, flowmodel.Variable):
 
36
            if v.concretetype is not Void:
 
37
                self.ilasm.store_local(v)
 
38
            else:
 
39
                self.ilasm.store_void()
 
40
        else:
 
41
            assert False
 
42
    
 
43
    def change_name(self, name, to_name):
 
44
        self.ilasm.change_name(name, to_name)
 
45
 
 
46
    def add_comment(self, text):
 
47
        pass
 
48
    
 
49
    def function_signature(self, graph):
 
50
        return self.cts.graph_to_signature(graph, False)
 
51
 
 
52
    def class_name(self, ooinstance):
 
53
        return ooinstance._name
 
54
 
 
55
    def emit(self, instr, *args):
 
56
        self.ilasm.emit(instr, *args)
 
57
 
 
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)
 
62
    
 
63
    def call_external(self, name, args):
 
64
        self.ilasm.call((name, args))
 
65
 
 
66
    #def call_signature(self, signature):
 
67
    #    self.ilasm.call(signature)
 
68
 
 
69
    def cast_to(self, lltype):
 
70
        cts_type = self.cts.lltype_to_cts(lltype, False)
 
71
        self.ilasm.castclass(cts_type)
 
72
        
 
73
    def new(self, obj):
 
74
        self.ilasm.new(self.cts.obj_name(obj))
 
75
 
 
76
    def set_field(self, obj, name):
 
77
        self.ilasm.set_field(obj, name)
 
78
        #self.ilasm.set_field(self.field_name(obj,name))
 
79
 
 
80
    def get_field(self, useless_stuff, name):
 
81
        self.ilasm.get_field(name)
 
82
        
 
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)
 
86
    
 
87
    def call_external_method(self, name, arg_len):
 
88
        self.ilasm.call_method(None, name, [0]*arg_len)
 
89
        
 
90
    def instantiate(self):
 
91
        self.ilasm.runtimenew()
 
92
    
 
93
    def downcast(self, TYPE):
 
94
        pass
 
95
        
 
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)
 
103
            name = graph.name
 
104
            self.ilasm.load_str(name)
 
105
        else:
 
106
            self.load(v)
 
107
            
 
108
    def cast_function(self, name, num):
 
109
        self.ilasm.cast_function(name, num)
 
110
 
 
111
    def prefix_op(self, st):
 
112
        self.ilasm.prefix_op(st)
 
113
    
 
114
    def load_str(self, s):
 
115
        self.ilasm.load_str(s)
 
116
    
 
117
    def load_void(self):
 
118
        self.ilasm.load_void()
 
119
    
 
120
    def list_setitem(self, base_obj, item, val):
 
121
        self.load(base_obj)
 
122
        self.load(val)
 
123
        self.load(item)
 
124
        self.ilasm.list_setitem()
 
125
    
 
126
    def list_getitem(self, base_obj, item):
 
127
        self.load(base_obj)
 
128
        self.load(item)
 
129
        self.ilasm.list_getitem()
 
130
 
 
131
    def push_primitive_constant(self, TYPE, value):
 
132
        self.db.load_const(TYPE, value, self.ilasm)        
 
133
 
 
134
    def branch_unconditionally(self, target_label):
 
135
        self.ilasm.jump_block(self.block_map[target_label])
 
136
 
 
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()
 
141
 
 
142
class Function(function.Function, BaseGenerator):
 
143
    def __init__(self, db, graph, name=None, is_method=False,
 
144
                 is_entrypoint=False, _class=None):
 
145
        self._class = _class
 
146
        super(Function, self).__init__(db, graph, name, is_method, is_entrypoint)
 
147
        self._set_args()
 
148
        self._set_locals()
 
149
        self.order = 0
 
150
        self.name = name or self.db.get_uniquename(self.graph, self.graph.name)
 
151
 
 
152
    def _setup_link(self, link, is_exc_link = False):
 
153
        target = link.target
 
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")
 
158
                else:
 
159
                    self.load(to_load)
 
160
                self.store(to_store)
 
161
 
 
162
    def _create_generator(self, ilasm):
 
163
        return self
 
164
 
 
165
    def begin_render(self):
 
166
        block_map = {}
 
167
        for blocknum, block in enumerate(self.graph.iterblocks()):
 
168
            block_map[self._get_block_name(block)] = blocknum
 
169
        self.block_map = block_map
 
170
 
 
171
        if self.is_method:
 
172
            args = self.args[1:] # self is implicit
 
173
        else:
 
174
            args = self.args
 
175
        if self.is_method:
 
176
            self.ilasm.begin_method(self.name, self._class, [i[1] for i in args])
 
177
        else:
 
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()
 
181
 
 
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)
 
186
            self.ilasm.ret()
 
187
        else:
 
188
            self.ilasm.load_void()
 
189
            self.ilasm.ret()
 
190
 
 
191
    def end_render(self):
 
192
        self.ilasm.end_for()        
 
193
        self.ilasm.end_function()
 
194
 
 
195
    def render_raise_block(self, block):
 
196
        self.ilasm.throw(block.inputargs[1])
 
197
 
 
198
    def end_try(self, target_label):
 
199
        self.ilasm.jump_block(self.block_map[target_label])
 
200
        self.ilasm.catch()
 
201
        #self.ilasm.close_branch()
 
202
 
 
203
    def record_ll_meta_exc(self, ll_meta_exc):
 
204
        pass
 
205
 
 
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)
 
210
    
 
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()
 
215
 
 
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)])
 
219
 
 
220
    def after_except_block(self):
 
221
        #self.ilasm.close_branch()
 
222
        self.ilasm.throw_real("exc")
 
223
        self.ilasm.close_branch()
 
224
 
 
225
    def set_label(self, label):
 
226
        self.ilasm.write_case(self.block_map[label])
 
227
        #self.ilasm.label(label)
 
228
 
 
229
    def begin_try(self):
 
230
        self.ilasm.begin_try()