01: package gnu.expr;
02:
03: import gnu.bytecode.*;
04: import gnu.mapping.*;
05:
06: public class SynchronizedExp extends Expression {
07: Expression object;
08: Expression body;
09:
10: public SynchronizedExp(Expression object, Expression body) {
11: this .object = object;
12: this .body = body;
13: }
14:
15: public Object eval(Environment env) throws Throwable {
16: Object value = object.eval(env);
17: synchronized (value) {
18: return body.eval(env);
19: }
20: }
21:
22: public void compile(Compilation comp, Target target) {
23: CodeAttr code = comp.getCode();
24: object.compile(comp, Target.pushObject);
25: code.emitDup(1);
26: Scope scope = code.pushScope();
27: Variable objvar = scope.addVariable(code, Type.pointer_type,
28: null);
29: code.emitStore(objvar);
30: code.emitMonitorEnter();
31: code
32: .emitTryStart(
33: true,
34: (target instanceof IgnoreTarget || target instanceof ConsumerTarget) ? null
35: : target.getType());
36:
37: body.compileWithPosition(comp, target);
38:
39: code.emitTryEnd();
40: code.emitFinallyStart();
41: code.emitLoad(objvar);
42: code.emitMonitorExit();
43: code.emitFinallyEnd();
44: code.emitTryCatchEnd();
45:
46: code.popScope();
47: }
48:
49: protected Expression walk(ExpWalker walker) {
50: return walker.walkSynchronizedExp(this );
51: }
52:
53: protected void walkChildren(ExpWalker walker) {
54: object = object.walk(walker);
55: if (walker.exitValue == null)
56: body = body.walk(walker);
57: }
58:
59: public void print(OutPort ps) {
60: ps.print("(Synchronized ");
61: object.print(ps);
62: ps.print(" ");
63: body.print(ps);
64: ps.print(")");
65: }
66: }
|