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: protected boolean mustCompile() {
16: return false;
17: }
18:
19: public void apply(CallContext ctx) throws Throwable {
20: Object value = object.eval(ctx);
21: Object result;
22: synchronized (value) {
23: result = body.eval(ctx);
24: }
25: ctx.writeValue(result);
26: }
27:
28: public void compile(Compilation comp, Target target) {
29: CodeAttr code = comp.getCode();
30: object.compile(comp, Target.pushObject);
31: code.emitDup(1);
32: Scope scope = code.pushScope();
33: Variable objvar = scope.addVariable(code, Type.pointer_type,
34: null);
35: code.emitStore(objvar);
36: code.emitMonitorEnter();
37: code
38: .emitTryStart(
39: false,
40: (target instanceof IgnoreTarget || 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: return walker.walkSynchronizedExp(this );
58: }
59:
60: protected void walkChildren(ExpWalker walker) {
61: object = walker.walk(object);
62: if (walker.exitValue == null)
63: body = walker.walk(body);
64: }
65:
66: public void print(OutPort ps) {
67: ps.print("(Synchronized ");
68: object.print(ps);
69: ps.print(" ");
70: body.print(ps);
71: ps.print(")");
72: }
73: }
|