01: /**************************************************************************/
02: /* N I C E */
03: /* A high-level object-oriented research language */
04: /* (c) Daniel Bonniot 2000 */
05: /* */
06: /* This program is free software; you can redistribute it and/or modify */
07: /* it under the terms of the GNU General Public License as published by */
08: /* the Free Software Foundation; either version 2 of the License, or */
09: /* (at your option) any later version. */
10: /* */
11: /**************************************************************************/package nice.lang.inline;
12:
13: import gnu.mapping.Procedure2;
14: import gnu.bytecode.*;
15: import gnu.expr.*;
16:
17: /**
18: Inlining of array read access.
19:
20: @version $Date: 2003/03/17 20:11:40 $
21: @author Daniel Bonniot
22: */
23: public class ArrayGetOp extends Procedure2 implements Inlineable {
24: public static ArrayGetOp create(String param) {
25: Type type = Tools.type(param.charAt(0));
26: if (type == null)
27: bossa.util.User
28: .error("Unknown type in array read acces operator: "
29: + param);
30:
31: return new ArrayGetOp(type);
32: }
33:
34: /**
35: @param type The expected component type of the array, or null to keep
36: it unconstrained.
37: */
38: public ArrayGetOp(Type type) {
39: this .type = type;
40: if (type != null)
41: arrayTarget = new StackTarget(nice.tools.code.SpecialTypes
42: .array(type));
43: else
44: arrayTarget = StackTarget.pushObject;
45: }
46:
47: private final Type type;
48: private final Target arrayTarget;
49:
50: public void compile(ApplyExp exp, Compilation comp, Target target) {
51: Expression[] args = exp.getArgs();
52: CodeAttr code = comp.getCode();
53:
54: args[0].compile(comp, arrayTarget);
55: boolean bytecodeArray = Tools.monomorphicArray(code.topType());
56: args[1].compile(comp, Tools.intTarget);
57:
58: if (bytecodeArray)
59: code.emitArrayLoad();
60: else
61: code.emitInvokeStatic(reflectGet);
62:
63: target.compileFromStack(comp, code.topType());
64: }
65:
66: private static Method reflectGet = ClassType.make(
67: "java.lang.reflect.Array").getDeclaredMethod("get", 2);
68:
69: public Type getReturnType(Expression[] args) {
70: Type array = args[0].getType();
71:
72: // We expect an array type
73: if (array instanceof ArrayType)
74: return ((ArrayType) array).getComponentType();
75:
76: // If not (possible with polymorphism) the base type is a safe bet
77: if (type != null)
78: return type;
79:
80: return Type.pointer_type;
81: }
82:
83: // Interpretation
84:
85: public Object apply2(Object arg1, Object arg2) {
86: return java.lang.reflect.Array.get(arg1, ((Number) arg2)
87: .intValue());
88: }
89: }
|