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