01: package kawa.lang;
02:
03: import gnu.bytecode.*;
04: import gnu.mapping.*;
05: import gnu.expr.*;
06:
07: // Should be called PrimSetField for consistency.
08:
09: public class SetFieldProc extends Procedure2 implements Inlineable {
10: ClassType ctype;
11: Field field;
12:
13: public SetFieldProc(Class clas, String fname) {
14: this ((ClassType) Type.make(clas), fname);
15: }
16:
17: public SetFieldProc(ClassType ctype, String fname) {
18: this .ctype = ctype;
19: this .field = Field.searchField(ctype.getFields(), fname);
20: }
21:
22: public SetFieldProc(ClassType ctype, String name, Type ftype,
23: int flags) {
24: this .ctype = ctype;
25: field = ctype.getField(name);
26: if (field == null)
27: field = ctype.addField(name, ftype, flags);
28: }
29:
30: public Object apply2(Object arg1, Object arg2) {
31: try {
32: java.lang.reflect.Field reflectField = field
33: .getReflectField();
34: arg2 = field.getType().coerceFromObject(arg2);
35: reflectField.set(arg1, arg2);
36: } catch (NoSuchFieldException ex) {
37: throw new RuntimeException("no such field "
38: + field.getSourceName() + " in " + ctype.getName());
39: } catch (IllegalAccessException ex) {
40: throw new RuntimeException("illegal access for field "
41: + field.getSourceName());
42: }
43: return Values.empty;
44: }
45:
46: public void compile(ApplyExp exp, Compilation comp, Target target) {
47: ClassLoader loader = ctype.getReflectClass().getClassLoader();
48: if (loader instanceof gnu.bytecode.ArrayClassLoader) {
49: ApplyExp.compile(exp, comp, target);
50: return;
51: }
52: Expression[] args = exp.getArgs();
53: args[0].compile(comp, ctype);
54: args[1].compile(comp, field.getType());
55: gnu.bytecode.CodeAttr code = comp.getCode();
56: code.emitPutField(field);
57: comp.compileConstant(Values.empty, target);
58: }
59:
60: public gnu.bytecode.Type getReturnType(Expression[] args) {
61: return Type.void_type;
62: }
63: }
|