KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > expr > StackTarget


1 // Copyright (c) 1999 Per M.A. Bothner.
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3

4 package gnu.expr;
5 import gnu.bytecode.*;
6 import gnu.mapping.Values;
7
8 public class StackTarget extends Target
9 {
10   Type type;
11   public StackTarget(Type type) { this.type = type; }
12
13   public Type getType() { return type; }
14
15   public static Target getInstance(Type type)
16   {
17     return (type.isVoid() ? Target.Ignore
18         : type == Type.pointer_type ? Target.pushObject
19             : new StackTarget(type));
20   }
21
22   protected boolean compileFromStack0(Compilation comp, Type stackType)
23   {
24     return compileFromStack0(comp, stackType, type);
25   }
26
27   static boolean compileFromStack0(Compilation comp, Type stackType, Type type)
28   {
29     if (type == stackType)
30       return true;
31     CodeAttr code = comp.getCode();
32     if (stackType.isVoid())
33       {
34     comp.compileConstant (Values.empty);
35     stackType = Type.pointer_type;
36       }
37     else if (stackType instanceof PrimType && type instanceof PrimType)
38       {
39     code.emitConvert(stackType, type);
40     return true;
41       }
42
43     if (stackType instanceof ArrayType)
44       {
45     if (type == Type.pointer_type
46         || "java.lang.Cloneable".equals(type.getName()))
47       return true;
48     // FIXME should check if stackType is compatible array type.
49
}
50     else
51       {
52     stackType.emitCoerceToObject(code);
53     stackType = code.topType();
54       }
55     return ! CodeAttr.castNeeded(stackType, type);
56   }
57
58   public static void convert(Compilation comp, Type stackType, Type targetType)
59   {
60     if (! compileFromStack0(comp, stackType, targetType))
61       emitCoerceFromObject(targetType, comp);
62   }
63
64   protected static void emitCoerceFromObject(Type type, Compilation comp)
65   {
66     CodeAttr code = comp.getCode();
67     if (type instanceof gnu.kawa.reflect.OccurrenceType)
68       {
69     // Kludge (OccurrenceType doesn't implement emitCoerceFromObject):
70
comp.compileConstant(type, Target.pushObject);
71     code.emitSwap();
72     code.emitInvokeVirtual(ClassType.make("gnu.bytecode.Type")
73                    .getDeclaredMethod("coerceFromObject", 1));
74       }
75     else
76       {
77     comp.usedClass(type);
78     type.emitCoerceFromObject(code);
79       }
80   }
81
82   public void compileFromStack(Compilation comp, Type stackType)
83   {
84     if (! compileFromStack0(comp, stackType))
85       emitCoerceFromObject(type, comp);
86   }
87 }
88
Popular Tags