01: // Copyright (c) 1999 Per M.A. Bothner.
02: // This is free software; for terms and warranty disclaimer see ./COPYING.
03:
04: package gnu.expr;
05:
06: import gnu.bytecode.*;
07: import gnu.mapping.Values;
08:
09: public class StackTarget extends Target {
10: Type type;
11:
12: public StackTarget(Type type) {
13: this .type = type;
14: }
15:
16: public Type getType() {
17: return type;
18: }
19:
20: public static Target getInstance(Type type) {
21: return (type == Type.pointer_type ? Target.pushObject
22: : type == Type.int_type ? intTarget : new StackTarget(
23: type));
24: }
25:
26: public static final StackTarget intTarget = new StackTarget(
27: Type.int_type);
28:
29: protected boolean compileFromStack0(Compilation comp, Type stackType) {
30: return compileFromStack0(comp, stackType, type);
31: }
32:
33: static boolean compileFromStack0(Compilation comp, Type stackType,
34: Type type) {
35: if (type == stackType)
36: return true;
37:
38: CodeAttr code = comp.getCode();
39: if (!code.reachableHere())
40: return true;
41:
42: if (stackType.isVoid()) {
43: // The value will be ignored anyway.
44: comp.compileConstant(null);
45: stackType = Type.pointer_type;
46: } else if (stackType instanceof PrimType
47: && type instanceof PrimType) {
48: code.emitConvert(stackType, type);
49: return true;
50: }
51:
52: if (code.topType().isAssignableTo(type))
53: return true;
54:
55: stackType.emitCoerceTo(type, code);
56:
57: if (code.topType().isAssignableTo(type))
58: return true;
59:
60: type.emitCoerceFrom(code.topType(), code);
61:
62: // Checks if the coercions worked.
63: // We call getImplementationType because we are only interested
64: // in knowning if we can avoid a cast; conversions should have
65: // been performed above.
66: return code.topType().getImplementationType().isAssignableTo(
67: type.getImplementationType());
68: }
69:
70: public static void convert(Compilation comp, Type stackType,
71: Type targetType) {
72: if (!compileFromStack0(comp, stackType, targetType))
73: targetType.emitCoerceFromObject(comp.getCode());
74: }
75:
76: public void compileFromStack(Compilation comp, Type stackType) {
77: if (!compileFromStack0(comp, stackType))
78: type.emitCoerceFromObject(comp.getCode());
79: }
80: }
|