OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [contrib/] [classfile.py] - Blame information for rev 754

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 754 jeremybenn
## Copyright (C) 2004, 2005 Free Software Foundation
2
## Written by Gary Benson <gbenson@redhat.com>
3
##
4
## This program is free software; you can redistribute it and/or modify
5
## it under the terms of the GNU General Public License as published by
6
## the Free Software Foundation; either version 2 of the License, or
7
## (at your option) any later version.
8
##
9
## This program is distributed in the hope that it will be useful,
10
## but WITHOUT ANY WARRANTY; without even the implied warranty of
11
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
## GNU General Public License for more details.
13
 
14
"""Read Java(TM) class files."""
15
 
16
import cStringIO as StringIO
17
import struct
18
 
19
class Class:
20
    def __init__(self, arg):
21
        if hasattr(arg, "read"):
22
            self.fp = arg
23
        elif type(arg) == type(""):
24
            if arg.startswith("\xca\xfe\xba\xbe"):
25
                self.fp = StringIO.StringIO(arg)
26
            else:
27
                self.fp = open(arg, "r")
28
        else:
29
            raise TypeError, type(arg)
30
 
31
        magic = self._read_int()
32
        assert magic == 0xcafebabeL
33
        minor, major = self._read(">HH")
34
        self.version = (major, minor)
35
 
36
        self.pool_integrity_checks = None
37
        try:
38
            assert False
39
        except AssertionError:
40
            self.pool_integrity_checks = []
41
 
42
        self._read_constants_pool()
43
 
44
        self.access_flags = self._read_short()
45
        self.name = self._read_reference_Class()
46
        self.super = self._read_reference_Class()
47
 
48
        self.interfaces = self._read_interfaces()
49
        self.fields = self._read_fieldsormethods()
50
        self.methods = self._read_fieldsormethods()
51
        self.attributes = self._read_attributes()
52
 
53
        if self.pool_integrity_checks is not None:
54
            for index, tag in self.pool_integrity_checks:
55
                assert self.constants[index][0] == tag
56
 
57
        del self.fp, self.pool_integrity_checks
58
 
59
    def __repr__(self):
60
        result = []
61
        attrs = [attr for attr in dir(self)
62
                 if not attr.startswith("_") and attr != "Member"]
63
        attrs.sort()
64
        for attr in attrs:
65
            result.append("%-13s %s" % (
66
                attr + ":", attr == "constants" and
67
                "<ELIDED>" or repr(getattr(self, attr))))
68
        return "\n".join(result)
69
 
70
    def _read_constants_pool(self):
71
        self.constants = {}
72
        skip = False
73
        for i in xrange(1, self._read_short()):
74
            if skip:
75
                skip = False
76
                continue
77
            tag = {
78
                1: "Utf8", 3: "Integer", 4: "Float", 5: "Long",
79
                6: "Double", 7: "Class", 8: "String", 9: "Fieldref",
80
                10: "Methodref", 11: "InterfaceMethodref",
81
                12: "NameAndType"}[self._read_byte()]
82
            skip = tag in ("Long", "Double") # crack crack crack!
83
            self.constants[i] = (tag, getattr(self, "_read_constant_" + tag)())
84
 
85
    def _read_interfaces(self):
86
        result = []
87
        for i in xrange(self._read_short()):
88
            result.append(self._read_reference_Class())
89
        return result
90
 
91
    def _read_fieldsormethods(self):
92
        result = []
93
        for i in xrange(self._read_short()):
94
            result.append(self.Member(self))
95
        return result
96
 
97
    class Member:
98
        def __init__(self, source):
99
            self.access_flags = source._read_short()
100
            self.name = source._read_reference_Utf8()
101
            self.descriptor = source._read_reference_Utf8()
102
            self.attributes = source._read_attributes()
103
 
104
        def __repr__(self):
105
            result = []
106
            attrs = [attr for attr in dir(self) if not attr.startswith("_")]
107
            attrs.sort()
108
            for attr in attrs:
109
                value = getattr(self, attr)
110
                if attr == "attributes" and value.has_key("Code"):
111
                    value = value.copy()
112
                    value.update({"Code": "<ELIDED>"})
113
                result.append("%-13s %s" % (
114
                    attr + ":", repr(value).replace(
115
                        "'Code': '<ELIDED>'", "'Code': <ELIDED>")))
116
            return ("\n%s" % (15 * " ")).join(result)
117
 
118
    def _read_attributes(self):
119
        result = {}
120
        for i in xrange(self._read_short()):
121
            name = self._read_reference_Utf8()
122
            data = self.fp.read(self._read_int())
123
            assert not result.has_key(name)
124
            result[name] = data
125
        return result
126
 
127
    # Constants pool reference reader convenience functions
128
 
129
    def _read_reference_Utf8(self):
130
        return self._read_references("Utf8")[0]
131
 
132
    def _read_reference_Class(self):
133
        return self._read_references("Class")[0]
134
 
135
    def _read_reference_Class_NameAndType(self):
136
        return self._read_references("Class", "NameAndType")
137
 
138
    def _read_references(self, *args):
139
        result = []
140
        for arg in args:
141
            index = self._read_short()
142
            if self.pool_integrity_checks is not None:
143
                self.pool_integrity_checks.append((index, arg))
144
            result.append(index)
145
        return result
146
 
147
    # Constants pool constant reader functions
148
 
149
    def _read_constant_Utf8(self):
150
        constant = self.fp.read(self._read_short())
151
        try:
152
            constant = constant.decode("utf-8")
153
        except UnicodeError:
154
            constant = _bork_utf8_decode(constant)
155
        try:
156
            constant = constant.encode("us-ascii")
157
        except UnicodeError:
158
            pass
159
        return constant
160
 
161
    def _read_constant_Integer(self):
162
        return self._read_int()
163
 
164
    def _read_constant_Float(self):
165
        return self._read(">f")[0]
166
 
167
    def _read_constant_Long(self):
168
        return self._read(">q")[0]
169
 
170
    def _read_constant_Double(self):
171
        return self._read(">d")[0]
172
 
173
    _read_constant_Class = _read_reference_Utf8
174
    _read_constant_String = _read_reference_Utf8
175
    _read_constant_Fieldref = _read_reference_Class_NameAndType
176
    _read_constant_Methodref = _read_reference_Class_NameAndType
177
    _read_constant_InterfaceMethodref = _read_reference_Class_NameAndType
178
 
179
    def _read_constant_NameAndType(self):
180
        return self._read_reference_Utf8(), self._read_reference_Utf8()
181
 
182
    # Generic reader functions
183
 
184
    def _read_int(self):
185
        # XXX how else to read 32 bits on a 64-bit box?
186
        h, l = map(long, self._read(">HH"))
187
        return (h << 16) + l
188
 
189
    def _read_short(self):
190
        return self._read(">H")[0]
191
 
192
    def _read_byte(self):
193
        return self._read("B")[0]
194
 
195
    def _read(self, fmt):
196
        return struct.unpack(fmt, self.fp.read(struct.calcsize(fmt)))
197
 
198
def _bork_utf8_decode(data):
199
    # more crack!
200
    bytes, unicode = map(ord, data), ""
201
    while bytes:
202
        b1 = bytes.pop(0)
203
        if b1 & 0x80:
204
            assert b1 & 0x40
205
            b2 = bytes.pop(0)
206
            assert b2 & 0xC0 == 0x80
207
            if b1 & 0x20:
208
                assert not b1 & 0x10
209
                b3 = bytes.pop(0)
210
                assert b3 & 0xC0 == 0x80
211
                unicode += unichr(
212
                    ((b1 & 0x0f) << 12) + ((b2 & 0x3f) << 6) + (b3 & 0x3f))
213
            else:
214
                unicode += unichr(((b1 & 0x1f) << 6) + (b2 & 0x3f))
215
        else:
216
            unicode += unichr(b1)
217
    return unicode
218
 
219
if __name__ == "__main__":
220
    print Class("/usr/share/katana/build/ListDependentClasses.class")
221
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.