1 /*
2 * The contents of this file are subject to the Mozilla Public License
3 * Version 1.0 (the "License"); you may not use this file except in
4 * compliance with the License. You may obtain a copy of the License at
5 * http://www.mozilla.org/MPL/
6 *
7 * Software distributed under the License is distributed on an "AS IS"
8 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
9 * License for the specific language governing rights and limitations
10 * under the License.
11 *
12 * The Initial Developer of this code is David Baum.
13 * Portions created by David Baum are Copyright (C) 1998 David Baum.
14 * All Rights Reserved.
15 *
16 * Portions created by John Hansen are Copyright (C) 2005 John Hansen.
17 * All Rights Reserved.
18 *
19 */
20
21 #include "AcquireStmt.h"
22 #include "Bytecode.h"
23 #include "Expr.h"
24 #include "RCX_Cmd.h"
25 #include "RCX_Target.h"
26 #include "Error.h"
27
AcquireStmt(UByte resources,Stmt * body,Stmt * handler,const LexLocation & loc)28 AcquireStmt::AcquireStmt(UByte resources, Stmt* body, Stmt *handler, const LexLocation &loc) :
29 BinaryStmt(body, handler), fResources(resources), fLocation(loc)
30 {
31 }
32
33
EmitActual(Bytecode & b)34 void AcquireStmt::EmitActual(Bytecode &b)
35 {
36 if (!b.GetTarget()->fResources)
37 {
38 Error(kErr_NoTargetResources, b.GetTarget()->fName).Raise(&fLocation);
39 return;
40 }
41
42 if (!b.BeginHandler(Bytecode::kAcquireHandler))
43 {
44 Error(kErr_NoNestedResources).Raise(&fLocation);
45 return;
46 }
47
48 RCX_Cmd cmd;
49 int handlerLabel = b.NewLabel();
50 int endLabel = b.NewLabel();
51
52 // start event monitoring
53 cmd.Set(kRCX_EnterAccessCtrlOp, fResources, 0, 0);
54 b.Add(cmd);
55 b.AddFixup(Bytecode::kSignBitLongFixup, handlerLabel);
56
57 GetPrimary()->Emit(b);
58
59 // end event monitoring
60 cmd.Set(kRCX_ExitAccessCtrlOp);
61 b.Add(cmd);
62
63 if (GetSecondary())
64 b.AddJump(endLabel);
65
66 // here's the handler
67 b.SetLabel(handlerLabel);
68
69 if (GetSecondary())
70 GetSecondary()->Emit(b);
71
72 b.SetLabel(endLabel);
73
74 b.EndHandler(Bytecode::kAcquireHandler);
75 }
76
77
CloneActual(Mapping * b) const78 Stmt* AcquireStmt::CloneActual(Mapping *b) const
79 {
80 Stmt *s = GetSecondary() ? GetSecondary()->Clone(b) : 0;
81 return new AcquireStmt(fResources, GetPrimary()->Clone(b), s, fLocation);
82 }
83