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

« back to all changes in this revision

Viewing changes to pypy/objspace/dump.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
import os
 
2
from pypy.objspace.proxy import patch_space_in_place
 
3
from pypy.objspace.std.objspace import StdObjSpace, W_Object
 
4
from pypy.interpreter.error import OperationError
 
5
from pypy.interpreter import baseobjspace
 
6
 
 
7
DUMP_FILE_NAME = 'pypy-space-dump'
 
8
DUMP_FILE_MODE = 0600
 
9
 
 
10
class Dumper(object):
 
11
    dump_fd = -1
 
12
 
 
13
    def __init__(self, space):
 
14
        self.space = space
 
15
        self.dumpspace_reprs = {}
 
16
 
 
17
    def open(self):
 
18
        space = self.space
 
19
        self.dumpspace_reprs.update({
 
20
            space.w_None:  'None',
 
21
            space.w_False: 'False',
 
22
            space.w_True:  'True',
 
23
            })
 
24
        if self.dump_fd < 0:
 
25
            self.dump_fd = os.open(DUMP_FILE_NAME,
 
26
                                   os.O_WRONLY|os.O_CREAT|os.O_TRUNC,
 
27
                                   DUMP_FILE_MODE)
 
28
 
 
29
    def close(self):
 
30
        if self.dump_fd >= 0:
 
31
            os.close(self.dump_fd)
 
32
            self.dump_fd = -1
 
33
        self.dumpspace_reprs.clear()
 
34
 
 
35
    def dump_get_repr(self, w_obj):
 
36
        try:
 
37
            return self.dumpspace_reprs[w_obj]
 
38
        except KeyError:
 
39
            saved_fd = self.dump_fd
 
40
            try:
 
41
                self.dump_fd = -1
 
42
                space = self.space
 
43
                if isinstance(w_obj, W_Object):
 
44
                    w_type = space.type(w_obj)
 
45
                else:
 
46
                    w_type = None
 
47
                if w_type is space.w_int:
 
48
                    n = space.int_w(w_obj)
 
49
                    s = str(n)
 
50
                elif w_type is space.w_str:
 
51
                    s = space.str_w(w_obj)
 
52
                    digit2hex = '0123456789abcdef'
 
53
                    lst = ["'"]
 
54
                    for c in s:
 
55
                        if c == '\\':
 
56
                            lst.append('\\')
 
57
                        if c >= ' ':
 
58
                            lst.append(c)
 
59
                        else:
 
60
                            lst.append('\\')
 
61
                            if c == '\n':
 
62
                                lst.append('n')
 
63
                            elif c == '\t':
 
64
                                lst.append('t')
 
65
                            else:
 
66
                                lst.append('x')
 
67
                                lst.append(digit2hex[ord(c) >> 4])
 
68
                                lst.append(digit2hex[ord(c) & 0xf])
 
69
                    lst.append("'")
 
70
                    s = ''.join(lst)
 
71
                elif w_type is space.w_float:
 
72
                    n = space.float_w(w_obj)
 
73
                    s = str(n)
 
74
                else:
 
75
                    s = '%s at 0x%x' % (w_obj, id(w_obj))
 
76
                self.dumpspace_reprs[w_obj] = s
 
77
            finally:
 
78
                self.dump_fd = saved_fd
 
79
            return s
 
80
 
 
81
    def dump_enter(self, opname, args_w):
 
82
        if self.dump_fd >= 0:
 
83
            text = '\t'.join([self.dump_get_repr(w_arg) for w_arg in args_w])
 
84
            os.write(self.dump_fd, '%s CALL   %s\n' % (opname, text))
 
85
 
 
86
    def dump_returned_wrapped(self, opname, w_obj):
 
87
        if self.dump_fd >= 0:
 
88
            s = self.dump_get_repr(w_obj)
 
89
            os.write(self.dump_fd, '%s RETURN %s\n' % (opname, s))
 
90
 
 
91
    def dump_returned(self, opname):
 
92
        if self.dump_fd >= 0:
 
93
            os.write(self.dump_fd, '%s RETURN\n' % (opname,))
 
94
 
 
95
    def dump_raised(self, opname, e):
 
96
        if self.dump_fd >= 0:
 
97
            if isinstance(e, OperationError):
 
98
                s = e.errorstr(self.space)
 
99
            else:
 
100
                s = '%s' % (e,)
 
101
            os.write(self.dump_fd, '%s RAISE  %s\n' % (opname, s))
 
102
 
 
103
 
 
104
# for now, always make up a wrapped StdObjSpace
 
105
class DumpSpace(StdObjSpace):
 
106
 
 
107
    def __init__(self, *args, **kwds):
 
108
        self.dumper = Dumper(self)
 
109
        StdObjSpace.__init__(self, *args, **kwds)
 
110
        patch_space_in_place(self, 'dump', proxymaker)
 
111
 
 
112
    def _freeze_(self):
 
113
        # remove strange things from the caches of self.dumper
 
114
        # before we annotate
 
115
        self.dumper.close()
 
116
        return StdObjSpace._freeze_(self)
 
117
 
 
118
    def startup(self):
 
119
        StdObjSpace.startup(self)
 
120
        self.dumper.open()
 
121
 
 
122
    def finish(self):
 
123
        self.dumper.close()
 
124
        StdObjSpace.finish(self)
 
125
 
 
126
    def wrap(self, x):
 
127
        w_res = StdObjSpace.wrap(self, x)
 
128
        self.dumper.dump_returned_wrapped('           wrap', w_res)
 
129
        return w_res
 
130
    wrap._annspecialcase_ = "specialize:wrap"
 
131
 
 
132
 
 
133
Space = DumpSpace
 
134
 
 
135
# __________________________________________________________________________
 
136
 
 
137
nb_args = {}
 
138
op_returning_wrapped = {}
 
139
 
 
140
def setup():
 
141
    nb_args.update({
 
142
        # ---- irregular operations ----
 
143
        'wrap': 0,
 
144
        'str_w': 1,
 
145
        'int_w': 1,
 
146
        'float_w': 1,
 
147
        'uint_w': 1,
 
148
        'unichars_w': 1,
 
149
        'bigint_w': 1,
 
150
        'interpclass_w': 1,
 
151
        'unwrap': 1,
 
152
        'is_true': 1,
 
153
        'is_w': 2,
 
154
        'newtuple': 0,
 
155
        'newlist': 0,
 
156
        'newstring': 0,
 
157
        'newunicode': 0,
 
158
        'newdict': 0,
 
159
        'newslice': 0,
 
160
        'call_args': 1,
 
161
        'marshal_w': 1,
 
162
        'log': 1,
 
163
        })
 
164
    op_returning_wrapped.update({
 
165
        'wrap': True,
 
166
        'newtuple': True,
 
167
        'newlist': True,
 
168
        'newstring': True,
 
169
        'newunicode': True,
 
170
        'newdict': True,
 
171
        'newslice': True,
 
172
        'call_args': True,
 
173
        })
 
174
    for opname, _, arity, _ in baseobjspace.ObjSpace.MethodTable:
 
175
        nb_args.setdefault(opname, arity)
 
176
        op_returning_wrapped[opname] = True
 
177
    for opname in baseobjspace.ObjSpace.IrregularOpTable:
 
178
        assert opname in nb_args, "missing %r" % opname
 
179
 
 
180
setup()
 
181
del setup
 
182
 
 
183
# __________________________________________________________________________
 
184
 
 
185
def proxymaker(space, opname, parentfn):
 
186
    if opname == 'wrap':
 
187
        return None
 
188
    returns_wrapped = opname in op_returning_wrapped
 
189
    aligned_opname = '%15s' % opname
 
190
    n = nb_args[opname]
 
191
    def proxy(*args, **kwds):
 
192
        dumper = space.dumper
 
193
        args_w = list(args[:n])
 
194
        dumper.dump_enter(aligned_opname, args_w)
 
195
        try:
 
196
            res = parentfn(*args, **kwds)
 
197
        except Exception, e:
 
198
            dumper.dump_raised(aligned_opname, e)
 
199
            raise
 
200
        else:
 
201
            if returns_wrapped:
 
202
                dumper.dump_returned_wrapped(aligned_opname, res)
 
203
            else:
 
204
                dumper.dump_returned(aligned_opname)
 
205
            return res
 
206
    proxy.func_name = 'proxy_%s' % (opname,)
 
207
    return proxy