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.Procedure3;
14: import gnu.bytecode.*;
15: import gnu.expr.*;
16:
17: /**
18: Inlining of array write access.
19:
20: @version $Date: 2004/06/27 20:33:06 $
21: @author Daniel Bonniot
22: */
23: public class ArraySetOp extends Procedure3 implements Inlineable {
24: public static ArraySetOp 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 write acces operator: "
29: + param);
30:
31: return new ArraySetOp(type);
32: }
33:
34: public ArraySetOp(Type type) {
35: this .type = type;
36: }
37:
38: private final Type type;
39:
40: public void compile(ApplyExp exp, Compilation comp, Target target) {
41: Expression[] args = exp.getArgs();
42: CodeAttr code = comp.getCode();
43: boolean needReturn = !(target instanceof IgnoreTarget);
44:
45: args[0].compile(comp, Target.pushObject);
46: boolean bytecodeArray = Tools.monomorphicArray(code.topType());
47: args[1].compile(comp, Tools.intTarget);
48:
49: Type componentType = getComponentType(args[0].getType());
50:
51: args[2].compile(comp, componentType);
52:
53: if (needReturn)
54: code.emitDup(componentType.getSize() > 4 ? 2 : 1, 2);
55:
56: if (bytecodeArray)
57: code.emitArrayStore(componentType);
58: else
59: code.emitInvokeStatic(reflectSet);
60:
61: if (needReturn)
62: target.compileFromStack(comp, componentType);
63: }
64:
65: private static Method reflectSet = ClassType.make(
66: "nice.lang.rawArray").getDeclaredMethod("Array_set", 3);
67:
68: public Type getReturnType(Expression[] args) {
69: return getComponentType(args[0].getType());
70: }
71:
72: private Type getComponentType(Type array) {
73: // Try to get bytecode type information from the target array.
74: if (this .type == Type.pointer_type
75: && array instanceof ArrayType)
76: return ((ArrayType) array).getComponentType();
77:
78: return this .type;
79: }
80:
81: // Interpretation
82:
83: public Object apply3(Object arg1, Object arg2, Object arg3) {
84: java.lang.reflect.Array.set(arg1, ((Number) arg2).intValue(),
85: type.coerceFromObject(arg3));
86: return gnu.mapping.Values.empty;
87: }
88: }
|