1 package gnu.expr; 2 import gnu.bytecode.*; 3 import gnu.mapping.*; 4 5 public class SynchronizedExp extends Expression 6 { 7 Expression object; 8 Expression body; 9 10 public SynchronizedExp (Expression object, Expression body) 11 { 12 this.object = object; 13 this.body = body; 14 } 15 16 protected boolean mustCompile () { return false; } 17 18 public void apply (CallContext ctx) throws Throwable 19 { 20 Object value = object.eval(ctx); 21 Object result; 22 synchronized (value) 23 { 24 result = body.eval(ctx); 25 } 26 ctx.writeValue(result); 27 } 28 29 public void compile (Compilation comp, Target target) 30 { 31 CodeAttr code = comp.getCode(); 32 object.compile (comp, Target.pushObject); 33 code.emitDup(1); 34 Scope scope = code.pushScope(); 35 Variable objvar = scope.addVariable(code, Type.pointer_type, null); 36 code.emitStore(objvar); 37 code.emitMonitorEnter(); 38 code.emitTryStart(false, 39 (target instanceof IgnoreTarget 40 || target instanceof ConsumerTarget) ? null 41 : target.getType()); 42 43 body.compileWithPosition(comp, target); 44 code.emitLoad(objvar); 45 code.emitMonitorExit(); 46 code.emitTryEnd(); 47 code.emitCatchStart(null); 48 code.emitLoad(objvar); 49 code.emitMonitorExit(); 50 code.emitThrow(); 51 code.emitCatchEnd(); 52 code.emitTryCatchEnd(); 53 code.popScope(); 54 } 55 56 protected Expression walk (ExpWalker walker) 57 { 58 return walker.walkSynchronizedExp(this); 59 } 60 61 protected void walkChildren(ExpWalker walker) 62 { 63 object = walker.walk(object); 64 if (walker.exitValue == null) 65 body = walker.walk(body); 66 } 67 68 public void print (OutPort ps) 69 { 70 ps.print("(Synchronized "); 71 object.print(ps); 72 ps.print(" "); 73 body.print(ps); 74 ps.print(")"); 75 } 76 } 77 | Popular Tags |