GuardInstruction.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2009 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* http://www.oorexx.org/license.html */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 /******************************************************************************/
39 /* REXX Translator */
40 /* */
41 /* Primitive Guard Parse Class */
42 /* */
43 /******************************************************************************/
44 #include <stdlib.h>
45 #include "RexxCore.h"
46 #include "ArrayClass.hpp"
47 #include "RexxActivity.hpp"
48 #include "RexxActivation.hpp"
49 #include "GuardInstruction.hpp"
51 
53  RexxObject *_expression, /* guard expression */
54  RexxArray *variable_list, /* list of variables to trigger on */
55  bool on_off) /* ON or OFF form */
56 /******************************************************************************/
57 /* Function: Complete initialization of a GUARD instruction object */
58 /******************************************************************************/
59 {
60  size_t i; /* loop counter */
61 
62  /* save the guard expression */
63  OrefSet(this, this->expression, _expression);
64  if (on_off) /* this the ON form? */
65  {
66  instructionFlags |= guard_on_form; /* turn on the flag */
67  }
68  if (variable_list != OREF_NULL) /* got a guard expression? */
69  {
70  /* get the variable size */
71  variableCount = variable_list->size();
72  /* loop through the variable list */
73  for (i = 1; i <= variableCount; i++)
74  {
75  /* copying each variable */
76  OrefSet(this, this->variables[i-1], (RexxVariableBase *)(variable_list->get(i)));
77  }
78  }
79  else
80  {
81  variableCount = 0; /* no extra variables */
82  }
83 }
84 
86  RexxActivation *context, /* current activation context */
87  RexxExpressionStack *stack ) /* evaluation stack */
88 /****************************************************************************/
89 /* Function: Execute a REXX GUARD instruction */
90 /****************************************************************************/
91 {
92  size_t size; /* size of guard variables list */
93  size_t i; /* loop counter */
94  RexxObject *result; /* guard expression result */
95 
96  context->traceInstruction(this); /* trace if necessary */
97  if (!context->inMethod()) /* is this a method clause? */
98  {
99  /* raise an error */
101  }
102  /* non-expression form? */
103  else if (this->expression == OREF_NULL)
104  {
105 
106  if (!(instructionFlags&guard_on_form)) /* is this the OFF form? */
107  {
108  context->guardOff(); /* set unguarded status in activation*/
109  }
110  else
111  {
112  context->guardOn(); /* set guarded status in activation */
113  }
114  }
115  else
116  {
117  size = variableCount; /* get variable list count */
118  for (i = 0; i < size; i++) /* loop through the variable list */
119  {
120  /* set a guard on each variable, */
121  /* counting the guards on each */
122  /* variable that is actually exposed */
123  this->variables[i]->setGuard(context);
124  }
125 
126  if (!(instructionFlags&guard_on_form)) /* is this the OFF form? */
127  {
128  context->guardOff(); /* set unguarded status in activation*/
129  }
130  else
131  {
132  context->guardOn(); /* set guarded status in activation */
133  }
134 
135  ActivityManager::currentActivity->guardSet(); /* initialize the guard sem */
136  /* get the expression value */
137  result = this->expression->evaluate(context, stack);
138  context->traceResult(result); /* trace if necessary */
139  /* do first evaluation without */
140  /* establishing any variable guards */
141  /* false on first attempt? */
143  {
144  do /* need to loop until true */
145  {
146  stack->clear(); /* clear the expression stack */
147  context->guardWait(); /* establish guards and wait */
148  ActivityManager::currentActivity->guardSet(); /* initialize the guard sem */
149  result = this->expression->evaluate(context, stack);
150  context->traceResult(result); /* trace if necessary */
151  /* while this is still false */
152  } while (!result->truthValue(Error_Logical_value_guard));
153  }
154  for (i = 0; i < size; i++) /* loop through the variable list */
155  {
156  /* set a guard on each variable, */
157  /* counting the guards on each */
158  /* variable that is actually exposed */
159  this->variables[i]->clearGuard(context);
160  }
161  }
162 }
163 
164 void RexxInstructionGuard::live(size_t liveMark)
165 /******************************************************************************/
166 /* Function: Normal garbage collection live marking */
167 /******************************************************************************/
168 {
169  size_t i; /* loop counter */
170  size_t count; /* argument count */
171 
172  memory_mark(this->nextInstruction); /* must be first one marked */
173  for (i = 0, count = variableCount; i < count; i++)
174  {
175  memory_mark(this->variables[i]);
176  }
177  memory_mark(this->expression);
178 }
179 
180 
181 
183 /******************************************************************************/
184 /* Function: Generalized object marking */
185 /******************************************************************************/
186 {
187  size_t i; /* loop counter */
188  size_t count; /* argument count */
189 
190  /* must be first one marked */
193  for (i = 0, count = variableCount; i < count; i++)
194  {
195  memory_mark_general(this->variables[i]);
196  }
197 }
198 
200 /******************************************************************************/
201 /* Function: Flatten an object */
202 /******************************************************************************/
203 {
204  size_t i; /* loop counter */
205  size_t count; /* argument count */
206 
208 
209  flatten_reference(newThis->nextInstruction, envelope);
210  flatten_reference(newThis->expression, envelope);
211  for (i = 0, count = variableCount; i < count; i++)
212  {
213  flatten_reference(newThis->variables[i], envelope);
214  }
215 
217 }
218 
void reportException(wholenumber_t error)
#define guard_on_form
#define OREF_NULL
Definition: RexxCore.h:60
#define OrefSet(o, r, v)
Definition: RexxCore.h:94
#define Error_Logical_value_guard
#define Error_Translation_guard_guard
#define memory_mark(oref)
Definition: RexxMemory.hpp:445
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:493
#define memory_mark_general(oref)
Definition: RexxMemory.hpp:446
#define cleanUpFlatten
Definition: RexxMemory.hpp:479
#define setUpFlatten(type)
Definition: RexxMemory.hpp:473
static RexxActivity *volatile currentActivity
void traceResult(RexxObject *v)
void traceInstruction(RexxInstruction *v)
size_t size()
Definition: ArrayClass.hpp:202
RexxObject * get(size_t pos)
Definition: ArrayClass.hpp:203
void flatten(RexxEnvelope *)
RexxVariableBase * variables[1]
RexxInstructionGuard(RexxObject *, RexxArray *, bool)
void execute(RexxActivation *, RexxExpressionStack *)
void liveGeneral(int reason)
uint16_t instructionFlags
RexxInstruction * nextInstruction
virtual RexxObject * evaluate(RexxActivation *, RexxExpressionStack *)
bool truthValue(int)
virtual void clearGuard(RexxActivation *)
virtual void setGuard(RexxActivation *)