01: package gnu.expr;
02:
03: import gnu.bytecode.*;
04:
05: public class ProcInitializer extends Initializer {
06: LambdaExp proc;
07:
08: public ProcInitializer(LambdaExp lexp, Compilation comp) {
09: field = lexp.allocFieldFor(comp);
10: proc = lexp;
11: LambdaExp heapLambda = lexp.getHeapLambda();
12: if (heapLambda instanceof ModuleExp
13: && comp.instanceField != null) {
14: next = comp.clinitChain;
15: comp.clinitChain = this ;
16: } else {
17: if (heapLambda instanceof ClassExp) {
18: next = heapLambda.clinitChain;
19: heapLambda.clinitChain = this ;
20: } else {
21: next = heapLambda.initChain;
22: heapLambda.initChain = this ;
23: }
24: }
25: }
26:
27: /** Create and load a ModuleMethod for the given procedure. */
28: public static void emitLoadModuleMethod(LambdaExp proc,
29: Compilation comp) {
30: CodeAttr code = comp.getCode();
31: ClassType procClass = Compilation
32: .getMethodProcType(comp.curClass);
33: code.emitNew(procClass);
34: code.emitDup(1);
35:
36: if (comp.method.getStaticFlag())
37: code.emitGetStatic(comp.topLambda.getInstanceField());
38: else
39: code.emitPushThis();
40: code.emitPushInt(proc.getSelectorValue(comp));
41: String name = proc.getName();
42: if (name == null)
43: code.emitPushNull();
44: else
45: code.emitPushString(name);
46: code.emitPushInt(proc.min_args | (proc.max_args << 12));
47: Method initModuleMethod = procClass.getDeclaredMethod("<init>",
48: 4);
49: code.emitInvokeSpecial(initModuleMethod);
50: }
51:
52: public void emit(Compilation comp) {
53: CodeAttr code = comp.getCode();
54: if (!field.getStaticFlag())
55: code.emitPushThis();
56:
57: emitLoadModuleMethod(proc, comp);
58:
59: if (proc.properties != null) {
60: int len = proc.properties.length;
61: for (int i = 0; i < len; i += 2) {
62: Object key = proc.properties[i];
63: if (key != null) {
64: Object val = proc.properties[i + 1];
65: code.emitDup(1);
66: comp.compileConstant(key);
67: Target target = Target.pushObject;
68: if (val instanceof Expression)
69: ((Expression) val).compile(comp, target);
70: else
71: comp.compileConstant(val, target);
72: Method m = comp.typeProcedure.getDeclaredMethod(
73: "setProperty", 2);
74: code.emitInvokeVirtual(m);
75: }
76: }
77: }
78:
79: if (field.getStaticFlag())
80: code.emitPutStatic(field);
81: else
82: code.emitPutField(field);
83: }
84: }
|