RaiseInstruction.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 Raise Parse Class */
42 /* */
43 /******************************************************************************/
44 #include <stdlib.h>
45 #include "RexxCore.h"
46 #include "StringClass.hpp"
47 #include "DirectoryClass.hpp"
48 #include "ArrayClass.hpp"
49 #include "QueueClass.hpp"
50 #include "RexxActivation.hpp"
51 #include "RaiseInstruction.hpp"
52 #include "Interpreter.hpp"
53 
55  RexxString *_condition, /* condition to raise */
56  RexxObject *_expression, /* expressionial value */
57  RexxObject *_description, /* description expression */
58  RexxObject *_additional, /* additional expression */
59  RexxObject *_result, /* returned result */
60  size_t _arrayCount, /* size of the array items */
61  RexxQueue *array, /* array argument information */
62  bool raiseReturn ) /* return/exit flag */
63 /******************************************************************************/
64 /* Function: Initialize a RAISE instruction item */
65 /******************************************************************************/
66 {
67  /* save the static information */
68  OrefSet(this, this->condition, _condition);
69  OrefSet(this, this->expression, _expression);
70  OrefSet(this, this->description, _description);
71  OrefSet(this, this->result, _result);
72  if (_arrayCount != (size_t)-1) /* array form? */
73  {
74  instructionFlags |= raise_array; /* set the array form */
75  /* get the array size */
76  arrayCount = _arrayCount;
77  while (_arrayCount > 0) /* loop through the expression list */
78  {
79  /* copying each expression */
80  OrefSet(this, this->additional[--_arrayCount], array->pop());
81  }
82  }
83  else /* just the one item */
84  {
85  OrefSet(this, this->additional[0], _additional);
86  arrayCount = 1; /* just the one item */
87  }
88  if (raiseReturn) /* return form? */
89  {
90  instructionFlags |= raise_return; /* turn on the return flag */
91  }
92 }
93 
94 void RexxInstructionRaise::live(size_t liveMark)
95 /******************************************************************************/
96 /* Function: Normal garbage collection live marking */
97 /******************************************************************************/
98 {
99  size_t count; /* count of array expressions */
100  size_t i; /* loop counter */
101 
102  memory_mark(this->nextInstruction); /* must be first one marked */
103  memory_mark(this->condition);
104  memory_mark(this->expression);
105  memory_mark(this->description);
106  memory_mark(this->result);
107  for (i = 0, count = arrayCount; i < count; i++)
108  {
109  memory_mark(this->additional[i]);
110  }
111 }
112 
114 /******************************************************************************/
115 /* Function: Generalized object marking */
116 /******************************************************************************/
117 {
118  size_t count; /* count of array expressions */
119  size_t i; /* loop counter */
120 
121  /* must be first one marked */
127  for (i = 0, count = arrayCount; i < count; i++)
128  {
130  }
131 }
132 
134 /******************************************************************************/
135 /* Function: Flatten an object */
136 /******************************************************************************/
137 {
138  size_t count; /* count of array expressions */
139  size_t i; /* loop counter */
140 
142 
143  flatten_reference(newThis->nextInstruction, envelope);
144  flatten_reference(newThis->condition, envelope);
145  flatten_reference(newThis->expression, envelope);
146  flatten_reference(newThis->description, envelope);
147  flatten_reference(newThis->result, envelope);
148  for (i = 0, count = arrayCount; i < count; i++)
149  {
150  flatten_reference(this->additional[i], envelope);
151  }
152 
154 }
155 
157  RexxActivation *context, /* current activation context */
158  RexxExpressionStack *stack) /* evaluation stack */
159 /******************************************************************************/
160 /* Function: Execute a REXX RAISE instruction */
161 /******************************************************************************/
162 {
163  RexxObject *_result; /* evaluated expression */
164  RexxObject *rc; /* RC variable information */
165  RexxString *errorcode; /* converted error code */
166  RexxString *_description; /* condition description */
167  RexxObject *_additional; /* additional state information */
168  RexxDirectory *conditionobj; /* propagated condition object */
169  size_t count; /* count of array expressions */
170  size_t i; /* loop counter */
171  wholenumber_t msgNum; /* message number */
172 
173  ProtectedObject p_result;
174  ProtectedObject p_rc;
175  ProtectedObject p_description;
176  ProtectedObject p_additional;
177 
178  context->traceInstruction(this); /* trace if necessary */
179  _additional = OREF_NULL; /* no object yet */
180  _description = OREF_NULL; /* no description */
181  rc = OREF_NULL; /* no extra information */
182  _result = OREF_NULL; /* no result information */
183 
184  if (this->expression != OREF_NULL) /* extra information for RC? */
185  {
186  /* get the expression value */
187  rc = this->expression->evaluate(context, stack);
188  }
189  /* need to validate the RC value? */
190  if (this->condition->strCompare(CHAR_SYNTAX))
191  {
192  _additional = TheNullArray->copy(); /* change default additional info */
193  p_additional = _additional;
194  /* and the default description */
195  _description = OREF_NULLSTRING;
196  errorcode = REQUEST_STRING(rc); /* get the string version */
197  ProtectedObject p(errorcode);
198  if (errorcode == TheNilObject) /* didn't convert? */
199  {
200  /* raise an error */
202  }
203  /* convert to a decimal */
204  /* and get integer object */
205  msgNum = Interpreter::messageNumber(errorcode);
206  rc = (RexxObject *)new_integer(msgNum);
207  p_rc = rc;
208  }
209  if (this->description != OREF_NULL) /* given a description? */
210  {
211  /* get the expression value */
212  _description = (RexxString *)this->description->evaluate(context, stack);
213  p_description = _description;
214  }
215  if (instructionFlags&raise_array) /* array form of additional? */
216  {
217  count = arrayCount; /* get the array size */
218  _additional = new_array(count); /* get a result array */
219  stack->push(_additional); /* and protect it from collection */
220  for (i = 0; i < count; i++) /* loop through the expression list */
221  {
222  /* real argument? */
223  if (this->additional[i] != OREF_NULL)
224  {
225  /* evaluate the expression */
226  ((RexxArray *)_additional)->put((this->additional[i])->evaluate(context, stack), i + 1);
227  }
228  }
229  }
230  /* extra information with ? */
231  else if (this->additional[0] != OREF_NULL)
232  {
233  /* get the expression value */
234  _additional = this->additional[0]->evaluate(context, stack);
235  p_additional = _additional;
236  }
237  if (this->result != OREF_NULL) /* given a result value? */
238  {
239  /* get the expression value */
240  _result = this->result->evaluate(context, stack);
241  p_result = _result;
242  }
243  /* set default condition object */
244  conditionobj = (RexxDirectory *)TheNilObject;
245  /* propagating an existing condition?*/
246  if (this->condition->strCompare(CHAR_PROPAGATE))
247  {
248  /* get current trapped condition */
249  conditionobj = context->getConditionObj();
250  if (conditionobj == OREF_NULL) /* no current active condition? */
251  {
253  }
254  }
255  if (_additional != OREF_NULL) /* have additional information? */
256  {
257  /* propagate condition maybe? */
258  if (this->condition->strCompare(CHAR_PROPAGATE))
259  {
260  /* get the original condition name */
261  errorcode = (RexxString *)conditionobj->at(OREF_CONDITION);
262  }
263  else
264  {
265  errorcode = this->condition; /* just use the condition name */
266  }
267  /* description a single item? */
268  if (errorcode->strCompare(CHAR_SYNTAX))
269  {
270  /* get the array version */
271  _additional = REQUEST_ARRAY(_additional);
272  p_additional = _additional;
273  /* not an array item or a multiple */
274  /* dimension one? */
275  if (_additional == TheNilObject || ((RexxArray *)_additional)->getDimension() != 1)
276  {
277  /* this is an error */
279  }
280  }
281  }
282  if (instructionFlags&raise_return) /* is this the exit form? */
283  {
284  /* let activation handle as return */
285  context->raise(this->condition, rc, _description, _additional, _result, conditionobj);
286  }
287  else
288  {
289  /* activation needs to exit */
290  context->raiseExit(this->condition, rc, _description, _additional, _result, conditionobj);
291  }
292 }
293 
void reportException(wholenumber_t error)
RexxArray * new_array(size_t s)
Definition: ArrayClass.hpp:259
RexxInteger * new_integer(wholenumber_t v)
#define raise_array
#define raise_return
#define OREF_NULL
Definition: RexxCore.h:61
RexxArray * REQUEST_ARRAY(RexxObject *obj)
Definition: RexxCore.h:457
#define TheNullArray
Definition: RexxCore.h:193
RexxString * REQUEST_STRING(RexxObject *object)
Definition: RexxCore.h:295
#define OrefSet(o, r, v)
Definition: RexxCore.h:101
#define TheNilObject
Definition: RexxCore.h:191
#define Error_Execution_syntax_additional
#define Error_Execution_propagate
#define Error_Conversion_raise
#define memory_mark(oref)
Definition: RexxMemory.hpp:450
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:498
#define memory_mark_general(oref)
Definition: RexxMemory.hpp:451
#define cleanUpFlatten
Definition: RexxMemory.hpp:484
#define setUpFlatten(type)
Definition: RexxMemory.hpp:478
static wholenumber_t messageNumber(RexxString *)
RexxDirectory * getConditionObj()
void raise(RexxString *, RexxObject *, RexxString *, RexxObject *, RexxObject *, RexxDirectory *)
void raiseExit(RexxString *, RexxObject *, RexxString *, RexxObject *, RexxObject *, RexxDirectory *)
void traceInstruction(RexxInstruction *v)
RexxObject * at(RexxString *)
void push(RexxObject *value)
uint16_t instructionFlags
RexxInstruction * nextInstruction
void liveGeneral(int reason)
RexxInstructionRaise(RESTORETYPE restoreType)
void execute(RexxActivation *, RexxExpressionStack *)
RexxObject * additional[1]
void flatten(RexxEnvelope *)
virtual RexxObject * evaluate(RexxActivation *, RexxExpressionStack *)
RexxObject * pop()
Definition: QueueClass.hpp:80
bool strCompare(const char *s)
ssize_t wholenumber_t
Definition: rexx.h:230