| 1 4 package gnu.expr; 5 import gnu.bytecode.*; 6 import gnu.mapping.*; 7 8 12 13 public class FluidLetExp extends LetExp 14 { 15 public FluidLetExp (Expression[] i) { super(i); } 16 17 protected boolean mustCompile () { return true; } 18 19 public void compile (Compilation comp, Target target) 20 { 21 CodeAttr code = comp.getCode(); 22 Type result_type = target instanceof IgnoreTarget ? null 23 : getType(); 24 Target ttarg; 25 if (result_type == null) 26 ttarg = Target.Ignore; 27 else if (result_type == Type.pointer_type) 28 ttarg = Target.pushObject; 29 else 30 ttarg = new StackTarget(result_type); 31 Scope scope = getVarScope(); 32 code.enterScope(scope); 33 Variable ctx = scope.addVariable(code, Compilation.typeCallContext, null); 34 comp.loadCallContext(); 35 code.emitStore(ctx); 36 Variable[] save = new Variable[inits.length]; 37 38 Declaration decl = firstDecl(); 39 doInits(decl, 0, save, comp, ctx); 40 code.emitTryStart(true, result_type); 41 body.compileWithPosition(comp, ttarg); 42 code.emitTryEnd(); 43 code.emitFinallyStart(); 44 45 46 for (int i = 0; i < inits.length; i++, decl = decl.nextDecl()) 47 { 48 decl.load(null, ReferenceExp.DONT_DEREFERENCE, 49 comp, Target.pushObject); 50 code.emitLoad(save[i]); 51 code.emitLoad(ctx); 52 code.emitInvokeVirtual(Compilation.typeLocation 53 .getDeclaredMethod("setRestore", 2)); 54 55 } 56 code.emitTryCatchEnd(); 57 popScope(code); 58 if (result_type != null) 59 target.compileFromStack(comp, result_type); 60 } 61 62 private void doInits (Declaration decl, int i, Variable[] save, 63 Compilation comp, Variable ctx) 64 { 65 if (i >= inits.length) 66 return; 67 CodeAttr code = comp.getCode(); 68 save[i] = code.addLocal(Type.pointer_type); 69 decl.allocateVariable(code); 70 decl.base.load(null, ReferenceExp.DONT_DEREFERENCE, 71 comp, Target.pushObject); 72 code.emitDup(); 73 code.emitStore(decl.getVariable()); 74 inits[i].compile(comp, Target.pushObject); 75 doInits(decl.nextDecl(), i+1, save, comp, ctx); 76 code.emitLoad(ctx); 77 code.emitInvokeVirtual(Compilation.typeLocation 78 .getDeclaredMethod("setWithSave", 2)); 79 code.emitStore(save[i]); 80 } 81 82 protected Expression walk (ExpWalker walker) 83 { 84 return walker.walkFluidLetExp(this); 85 } 86 87 public void print (OutPort out) 88 { 89 print(out, "(FluidLet", ")"); 90 } 91 } 92 | Popular Tags |