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