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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [tools/] [gnu/] [classpath/] [tools/] [javah/] [ClassWrapper.java] - Blame information for rev 779

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 779 jeremybenn
/* ClassWrapper.java - wrap ASM class objects
2
 Copyright (C) 2006, 2007 Free Software Foundation, Inc.
3
 
4
 This file is part of GNU Classpath.
5
 
6
 GNU Classpath is free software; you can redistribute it and/or modify
7
 it under the terms of the GNU General Public License as published by
8
 the Free Software Foundation; either version 2, or (at your option)
9
 any later version.
10
 
11
 GNU Classpath is distributed in the hope that it will be useful, but
12
 WITHOUT ANY WARRANTY; without even the implied warranty of
13
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 General Public License for more details.
15
 
16
 You should have received a copy of the GNU General Public License
17
 along with GNU Classpath; see the file COPYING.  If not, write to the
18
 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
 02110-1301 USA.
20
 
21
 Linking this library statically or dynamically with other modules is
22
 making a combined work based on this library.  Thus, the terms and
23
 conditions of the GNU General Public License cover the whole
24
 combination.
25
 
26
 As a special exception, the copyright holders of this library give you
27
 permission to link this library with independent modules to produce an
28
 executable, regardless of the license terms of these independent
29
 modules, and to copy and distribute the resulting executable under
30
 terms of your choice, provided that you also meet, for each linked
31
 independent module, the terms and conditions of the license of that
32
 module.  An independent module is a module which is not derived from
33
 or based on this library.  If you modify this library, you may extend
34
 this exception to your version of the library, but you are not
35
 obligated to do so.  If you do not wish to do so, delete this
36
 exception statement from your version. */
37
 
38
 
39
package gnu.classpath.tools.javah;
40
 
41
import java.io.ByteArrayOutputStream;
42
import java.io.IOException;
43
import java.io.PrintStream;
44
import java.lang.reflect.Modifier;
45
import java.util.ArrayList;
46
import java.util.HashMap;
47
import java.util.HashSet;
48
import java.util.Iterator;
49
 
50
import org.objectweb.asm.tree.ClassNode;
51
import org.objectweb.asm.tree.FieldNode;
52
import org.objectweb.asm.tree.MethodNode;
53
 
54
public class ClassWrapper
55
    extends ClassNode
56
{
57
  Main classpath;
58
 
59
  ClassWrapper superClass;
60
 
61
  ArrayList<ClassWrapper> interfaceClasses;
62
 
63
  // The virtual table for this class.
64
  ArrayList<MethodNode> vtable;
65
 
66
  // A set of all the bridge method targets we've found.
67
  HashSet<String> bridgeTargets;
68
 
69
  // A set of all the method names in this class.
70
  HashSet<String> methodNames = new HashSet<String>();
71
 
72
  // This maps a method name + descriptor, e.g. "method()V", to the
73
  // name chosen for the method.  This is used when computing the
74
  // names of bridge method targets.
75
  HashMap<String,String> methodNameMap = new HashMap<String,String>();
76
 
77
  public ClassWrapper(Main classpath)
78
  {
79
    this.classpath = classpath;
80
  }
81
 
82
  public boolean hasNativeMethod()
83
  {
84
    Iterator<?> i = methods.iterator();
85
    while (i.hasNext())
86
      {
87
        MethodNode method = (MethodNode) i.next();
88
        if (Modifier.isNative(method.access))
89
          return true;
90
      }
91
    return false;
92
  }
93
 
94
  public boolean isThrowable() throws IOException
95
  {
96
    linkSupers();
97
    ClassWrapper self = this;
98
    while (self != null)
99
      {
100
        if (self.name.equals("java/lang/Throwable"))
101
          return true;
102
        self = self.superClass;
103
      }
104
    return false;
105
  }
106
 
107
  void linkSupers() throws IOException
108
  {
109
    if (superName == null)
110
      {
111
        // Object, do nothing.
112
        return;
113
      }
114
    if (superClass == null)
115
      {
116
        superClass = classpath.getClass(superName);
117
        assert interfaceClasses == null;
118
        interfaceClasses = new ArrayList<ClassWrapper>();
119
        for (int i = 0; i < interfaces.size(); ++i)
120
          {
121
            String ifname = (String) interfaces.get(i);
122
            ClassWrapper iface = classpath.getClass(ifname);
123
            iface.linkSupers();
124
            interfaceClasses.add(iface);
125
          }
126
      }
127
    superClass.linkSupers();
128
  }
129
 
130
  private int findSlot(MethodNode method)
131
  {
132
    for (int i = vtable.size() - 1; i >= 0; --i)
133
      {
134
        MethodNode base = vtable.get(i);
135
        if (MethodHelper.overrides(method, base))
136
          return i;
137
      }
138
    return - 1;
139
  }
140
 
141
  private void addInterfaceMethods(ClassWrapper iface)
142
  {
143
    Iterator<?> i = iface.methods.iterator();
144
    while (i.hasNext())
145
      {
146
        MethodNode im = (MethodNode) i.next();
147
        int slot = findSlot(im);
148
        if (slot == - 1)
149
          {
150
            vtable.add(im);
151
            // Also add it to our local methods.
152
            methods.add(im);
153
          }
154
      }
155
    addInterfaces(iface);
156
  }
157
 
158
  private void addInterfaces(ClassWrapper base)
159
  {
160
    if (base.interfaceClasses == null)
161
      return;
162
    Iterator<?> i = base.interfaceClasses.iterator();
163
    while (i.hasNext())
164
      {
165
        ClassWrapper iface = (ClassWrapper) i.next();
166
        addInterfaceMethods(iface);
167
      }
168
  }
169
 
170
  private void addLocalMethods()
171
  {
172
    Iterator<?> i = methods.iterator();
173
    while (i.hasNext())
174
      {
175
        MethodNode meth = (MethodNode) i.next();
176
        methodNames.add(meth.name);
177
        if (Modifier.isStatic(meth.access))
178
          continue;
179
        int slot = findSlot(meth);
180
        if (slot == - 1)
181
          vtable.add(meth);
182
        else
183
          vtable.set(slot, meth);
184
      }
185
  }
186
 
187
  private void makeVtable() throws IOException
188
  {
189
    if (vtable != null)
190
      return;
191
    if (superClass != null)
192
      {
193
        superClass.makeVtable();
194
        vtable = new ArrayList<MethodNode>(superClass.vtable);
195
        bridgeTargets = new HashSet<String>(superClass.bridgeTargets);
196
        methodNameMap = new HashMap<String,String>(superClass.methodNameMap);
197
      }
198
    else
199
      {
200
        // Object.
201
        vtable = new ArrayList<MethodNode>();
202
        bridgeTargets = new HashSet<String>();
203
        methodNameMap = new HashMap<String,String>();
204
      }
205
    addLocalMethods();
206
    addInterfaces(this);
207
 
208
    // Make a set of all the targets of bridge methods.  We rename
209
    // bridge target methods to avoid problems with C++.  You might
210
    // think we could rename the bridge methods themselves, but bridge
211
    // methods by definition override a method from the superclass --
212
    // and we have to consider the superclass' header as an
213
    // unchangeable entity.
214
    Iterator<?> i = methods.iterator();
215
    while (i.hasNext())
216
      {
217
        MethodNode m = (MethodNode) i.next();
218
        String desc = MethodHelper.getBridgeTarget(m);
219
        if (desc != null)
220
          {
221
            String sum = m.name + desc;
222
            boolean newTarget = bridgeTargets.add(sum);
223
            if (newTarget)
224
              {
225
                // Bridge target that is new in this class.
226
                String cname = this.name;
227
                int index = cname.lastIndexOf('/');
228
                cname = cname.substring(index + 1);
229
                methodNameMap.put(sum, cname + "$" + m.name);
230
              }
231
          }
232
      }
233
  }
234
 
235
  private void printFields(CniPrintStream out)
236
  {
237
    Iterator<?> i = fields.iterator();
238
    ClassWrapper self = superClass;
239
    while (i.hasNext())
240
      {
241
        FieldNode f = (FieldNode) i.next();
242
        boolean hasMethodName = methodNames.contains(f.name);
243
        if (FieldHelper.print(out, f, self, hasMethodName))
244
          self = null;
245
      }
246
  }
247
 
248
  private void printMethods(CniPrintStream out) throws IOException
249
  {
250
    makeVtable();
251
 
252
    // A given method is either static, overrides a super method, or
253
    // is already in vtable order.
254
    Iterator<?> i = methods.iterator();
255
    while (i.hasNext())
256
      {
257
        MethodNode m = (MethodNode) i.next();
258
        String nameToUse;
259
        String sum = m.name + m.desc;
260
        if (bridgeTargets.contains(sum))
261
          nameToUse = (String) methodNameMap.get(sum);
262
        else
263
          nameToUse = m.name;
264
        methodNameMap.put(sum, nameToUse);
265
        MethodHelper.print(out, m, this, nameToUse);
266
      }
267
  }
268
 
269
  private void printTextList(PrintStream out, int what, ArrayList<Text> textList)
270
  {
271
    if (textList == null)
272
      return;
273
    Iterator<Text> i = textList.iterator();
274
    boolean first = true;
275
    while (i.hasNext())
276
      {
277
        Text item = i.next();
278
        if (item.type == what)
279
          {
280
            if (first)
281
              {
282
                out.println();
283
                first = false;
284
              }
285
            if (what == Text.FRIEND)
286
              out.print("  friend ");
287
            out.println(item.text);
288
          }
289
      }
290
  }
291
 
292
  public void print(CniPrintStream out)
293
  {
294
    out.print("::");
295
    out.printName(name);
296
  }
297
 
298
  // This prints the body of a class to a CxxPrintStream.
299
  private void printContents(CniPrintStream out, ArrayList<Text> textList)
300
      throws IOException
301
  {
302
    printTextList(out, Text.PREPEND, textList);
303
    out.println();
304
 
305
    out.print("class ");
306
    // Don't use our print() -- we don't want the leading "::".
307
    out.printName(name);
308
    if (superClass != null)
309
      {
310
        out.print(" : public ");
311
        superClass.print(out);
312
      }
313
    out.println();
314
    out.println("{");
315
 
316
    printTextList(out, Text.ADD, textList);
317
    out.println();
318
 
319
    // Note: methods must come first, as we build the list
320
    // of method names while printing them.
321
    printMethods(out);
322
    printFields(out);
323
 
324
    out.setModifiers(Modifier.PUBLIC);
325
    out.println("  static ::java::lang::Class class$;");
326
 
327
    printTextList(out, Text.FRIEND, textList);
328
 
329
    out.print("}");
330
    if (Modifier.isInterface(access))
331
      out.print(" __attribute__ ((java_interface))");
332
    out.println(";");
333
 
334
    printTextList(out, Text.APPEND, textList);
335
  }
336
 
337
  public void printFully(PrintStream out) throws IOException
338
  {
339
    linkSupers();
340
 
341
    ArrayList<Text> textList = classpath.getClassTextList(name);
342
 
343
    out.println("// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-");
344
    out.println();
345
    String xname = "__" + name.replaceAll("/", "_") + "__";
346
    out.println("#ifndef " + xname);
347
    out.println("#define " + xname);
348
    out.println();
349
    out.println("#pragma interface");
350
    out.println();
351
 
352
    if (superClass != null)
353
      {
354
        out.print("#include <");
355
        out.print(superName);
356
        out.println(".h>");
357
      }
358
 
359
    // Write the body of the stream here. This lets
360
    // us emit the namespaces without a second pass.
361
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
362
    CniPrintStream cxxOut = new CniPrintStream(bytes);
363
    cxxOut.addClass(this);
364
    printContents(cxxOut, textList);
365
    cxxOut.printNamespaces(out);
366
    bytes.writeTo(out);
367
 
368
    out.println();
369
    out.println("#endif // " + xname);
370
  }
371
 
372
  public String toString()
373
  {
374
    return name;
375
  }
376
}

powered by: WebSVN 2.1.0

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