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.tools.code;
12:
13: import gnu.expr.*;
14: import gnu.bytecode.*;
15:
16: /**
17: Modifies the value of an object's field and returns the new value.
18:
19: @version $Date: 2003/03/04 17:07:14 $
20: @author Daniel Bonniot
21: */
22:
23: public class SetFieldProc extends gnu.mapping.Procedure2 implements
24: Inlineable {
25: private Declaration fieldDecl;
26:
27: public SetFieldProc(Declaration fieldDecl) {
28: this .fieldDecl = fieldDecl;
29: if (fieldDecl == null)
30: throw new NullPointerException();
31: }
32:
33: public Object apply2(Object arg1, Object arg2) {
34: Field field = fieldDecl.field;
35: try {
36: java.lang.reflect.Field reflectField = field
37: .getReflectField();
38: arg2 = field.getType().coerceFromObject(arg2);
39: reflectField.set(arg1, arg2);
40: } catch (NoSuchFieldException ex) {
41: throw new RuntimeException("no such field "
42: + field.getSourceName() + " in "
43: + field.getDeclaringClass().getName());
44: } catch (IllegalAccessException ex) {
45: throw new RuntimeException("illegal access for field "
46: + field.getSourceName());
47: }
48: return arg2;
49: }
50:
51: public void compile(ApplyExp exp, Compilation comp, Target target) {
52: Field field = fieldDecl.field;
53: Type fieldType = field.getType();
54:
55: Expression[] args = exp.getArgs();
56: CodeAttr code = comp.getCode();
57:
58: // tells whether we want the value to be returned
59: boolean ignore = target instanceof IgnoreTarget;
60:
61: ClassType ctype = field.getDeclaringClass();
62: args[0].compile(comp, ctype);
63: args[1].compile(comp, fieldType);
64:
65: if (!ignore)
66: // Place a copy of the new value before the two operands
67: code.emitDup(fieldType.getSize() > 4 ? 2 : 1, 1);
68:
69: code.emitPutField(field);
70:
71: if (!ignore)
72: target.compileFromStack(comp, fieldType);
73: }
74:
75: public gnu.bytecode.Type getReturnType(Expression[] args) {
76: return fieldDecl.getType();
77: }
78: }
|