SetFieldProc.java 1.8 KB

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