ooRexx  4.2.0-source
About: ooRexx (Open Object Rexx) is a free implementation of Object Rexx. Object Rexx is an enhancement of the classic Rexx interpreter; a full-featured programming language with a human-oriented syntax.
  Fossies Dox: ooRexx-4.2.0-source.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

CallInstruction.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 Call Parse Class */
42 /* */
43 /******************************************************************************/
44 #include <stdlib.h>
45 #include "RexxCore.h"
46 #include "StringClass.hpp"
47 #include "DirectoryClass.hpp"
48 #include "ArrayClass.hpp"
50 #include "RexxActivation.hpp"
51 #include "RexxActivity.hpp"
52 #include "CallInstruction.hpp"
53 #include "SourceFile.hpp"
54 #include "ProtectedObject.hpp"
55 
57  RexxObject *_name, /* CALL name */
58  RexxString *_condition, /* CALL ON/OFF condition */
59  size_t argCount, /* count of arguments */
60  RexxQueue *argList, /* call arguments */
61  size_t flags, /* CALL flags */
62  size_t builtin_index) /* builtin routine index */
63 /******************************************************************************/
64 /* Function: Complete CALL instruction object */
65 /******************************************************************************/
66 {
67  /* set the name */
68  OrefSet(this, this->name, (RexxString *)_name);
69  /* and the condition */
70  OrefSet(this, this->condition, _condition);
71  instructionFlags = (uint16_t)flags; /* copy the flags */
72  builtinIndex = (uint16_t)builtin_index; /* and the builtin function index */
73  /* no arguments */
74  argumentCount = (uint16_t)argCount;
75  while (argCount > 0) { /* now copy the argument pointers */
76  /* in reverse order */
77  OrefSet(this, this->arguments[--argCount], argList->pop());
78  }
79 }
80 
81 void RexxInstructionCall::live(size_t liveMark)
82 /******************************************************************************/
83 /* Function: Normal garbage collection live marking */
84 /******************************************************************************/
85 {
86  size_t i; /* loop counter */
87  size_t count; /* argument count */
88 
89  memory_mark(this->nextInstruction); /* must be first one marked */
90  memory_mark(this->name);
91  memory_mark(this->target);
92  memory_mark(this->condition);
93  for (i = 0, count = argumentCount; i < count; i++)
94  {
95  memory_mark(this->arguments[i]);
96  }
97 }
98 
100 /******************************************************************************/
101 /* Function: Generalized object marking */
102 /******************************************************************************/
103 {
104  size_t i; /* loop counter */
105  size_t count; /* argument count */
106 
107  /* must be first one marked */
109  memory_mark_general(this->name);
112  for (i = 0, count = argumentCount; i < count; i++)
113  {
114  memory_mark_general(this->arguments[i]);
115  }
116 }
117 
119 /******************************************************************************/
120 /* Function: Flatten an object */
121 /******************************************************************************/
122 {
123  size_t i; /* loop counter */
124  size_t count; /* argument count */
125 
127 
128  flatten_reference(newThis->nextInstruction, envelope);
129  flatten_reference(newThis->name, envelope);
130  flatten_reference(newThis->target, envelope);
131  flatten_reference(newThis->condition, envelope);
132  for (i = 0, count = argumentCount; i < count; i++)
133  flatten_reference(newThis->arguments[i], envelope);
134 
136 }
137 
139  RexxDirectory *labels) /* table of program labels */
140 /******************************************************************************/
141 /* Function: Resolve a CALL instruction target */
142 /******************************************************************************/
143 {
144  if (this->name == OREF_NULL) /* not a name target form? */
145  return; /* just return */
146  if (instructionFlags&call_dynamic) { // can't resolve now
147  return; //
148  }
149  if (!(instructionFlags&call_nointernal)) { /* internal routines allowed? */
150  if (labels != OREF_NULL) /* have a labels table? */
151  /* check the label table */
152  OrefSet(this, this->target, (RexxInstruction *)labels->at((RexxString *)this->name));
153  instructionFlags |= call_internal; /* this is an internal call */
154  }
155  if (this->target == OREF_NULL) { /* not found yet? */
156  /* have a builtin function? */
157  if (builtinIndex != NO_BUILTIN) {
158  instructionFlags |= call_builtin; /* this is a builtin function */
159  /* cast off the routine name */
160  OrefSet(this, this->name, OREF_NULL);
161  }
162  else
163  instructionFlags |= call_external; /* have an external routine */
164  }
165 }
166 
168  RexxActivation *context, /* current activation context */
169  RexxExpressionStack *stack) /* evaluation stack */
170 /******************************************************************************/
171 /* Function: Execute a REXX CALL instruction */
172 /******************************************************************************/
173 {
174  size_t argcount; /* count of arguments */
175  size_t i; /* loop counter */
176  int type; /* type of call */
177  size_t builtin_index; /* builtin function index */
178  ProtectedObject result; /* returned result */
179  RexxInstruction *_target; /* resolved call target */
180  RexxString *_name; /* resolved function name */
181  RexxDirectory *labels; /* labels table */
182 
183  ActivityManager::currentActivity->checkStackSpace(); /* have enough stack space? */
184  context->traceInstruction(this); /* trace if necessary */
185  if (this->condition != OREF_NULL) /* is this the ON/OFF form? */
186  {
187  if (instructionFlags&call_on_off) /* ON form? */
188  {
189  /* turn on the trap */
190  context->trapOn(this->condition, (RexxInstructionCallBase *)this);
191  }
192  else
193  {
194  /* turn off the trap */
195  context->trapOff(this->condition);
196  }
197  }
198  else /* normal form of CALL */
199  {
200  if (instructionFlags&call_dynamic) /* dynamic form of call? */
201  {
202  /* evaluate the variable */
203  result = this->name->evaluate(context, stack);
204  stack->toss(); /* toss the top item */
205  _name = REQUEST_STRING(result); /* force to string form */
206  context->traceResult(name); /* trace if necessary */
207  /* resolve potential builtins */
208  builtin_index = RexxSource::resolveBuiltin(_name);
209  _target = OREF_NULL; /* clear out the target */
210  labels = context->getLabels(); /* get the labels table */
211  if (labels != OREF_NULL) /* have labels in the program? */
212  {
213  /* look up label and go to normal */
214  /* signal processing */
215  _target = (RexxInstruction *)(labels->at(_name));
216  }
217  if (_target != OREF_NULL) /* found one? */
218  {
219  type = call_internal; /* have an internal call */
220  }
221  /* have a builtin by this name? */
222  else if (builtin_index != NO_BUILTIN)
223  {
224  type = call_builtin; /* set for a builtin */
225  }
226  else /* must be external */
227  {
228  type = call_external; /* set as so */
229  }
230  }
231  else /* set up for a normal call */
232  {
233  _target = this->target; /* copy the target */
234  _name = (RexxString *)this->name; /* the name value */
235  /* and the builtin index */
236  builtin_index = builtinIndex;
237  type = instructionFlags&call_type_mask; /* just copy the type info */
238  }
239 
240  argcount = argumentCount; /* get the argument count */
241  for (i = 0; i < argcount; i++) /* loop through the argument list */
242  {
243  /* real argument? */
244  if (this->arguments[i] != OREF_NULL)
245  {
246  /* evaluate the expression */
247  RexxObject *argResult = this->arguments[i]->evaluate(context, stack);
248 
249  /* trace if necessary */
250  context->traceIntermediate(argResult, TRACE_PREFIX_ARGUMENT);
251  }
252  else
253  {
254  stack->push(OREF_NULL); /* push an non-existent argument */
255  /* trace if necessary */
256  context->traceIntermediate(OREF_NULLSTRING, TRACE_PREFIX_ARGUMENT);
257  }
258  }
259  switch (type) /* process various call types */
260  {
261 
262  case call_internal: /* need to process internal routine */
263  /* go process the internal call */
264  context->internalCall(_name, _target, argcount, stack, result);
265  break;
266 
267  case call_builtin: /* builtin function call */
268  /* call the function */
269  result = (*(RexxSource::builtinTable[builtin_index]))(context, argcount, stack);
270  break;
271 
272  case call_external: /* need to call externally */
273  /* go process the external call */
274  context->externalCall(_name, argcount, stack, OREF_ROUTINENAME, result);
275  break;
276  }
277  if ((RexxObject *)result != OREF_NULL) /* result returned? */
278  {
279  /* set the RESULT variable to the */
280  /* message return value */
281  context->setLocalVariable(OREF_RESULT, VARIABLE_RESULT, (RexxObject *)result);
282  context->traceResult((RexxObject *)result); /* trace if necessary */
283  }
284  else /* drop the variable RESULT */
285  {
286  context->dropLocalVariable(OREF_RESULT, VARIABLE_RESULT);
287  }
288  }
289  context->pauseInstruction(); /* do debug pause if necessary */
290 }
291 
293  RexxActivation *context, /* current execution context */
294  RexxDirectory *conditionObj) /* associated condition object */
295 /******************************************************************************/
296 /* Function: Process a CALL ON trap */
297 /******************************************************************************/
298 {
299  ProtectedObject result;
300  context->trapDelay(this->condition); /* put trap into delay state */
301 
302  switch (instructionFlags&call_type_mask) /* process various call types */
303  {
304 
305  case call_internal: /* need to process internal routine */
306  /* go process the internal call */
307  context->internalCallTrap((RexxString *)this->name, this->target, conditionObj, result);
308  break;
309 
310  case call_builtin: /* builtin function call */
311  /* call the function */
312  (*(RexxSource::builtinTable[builtinIndex]))(context, 0, context->getStack());
313  break;
314 
315  case call_external: /* need to call externally */
316  /* go process the externnl call */
317  context->externalCall((RexxString *)this->name, 0, context->getStack(), OREF_ROUTINENAME, result);
318  break;
319  }
320  /* restore the trap state */
321  context->trapUndelay(this->condition);
322 }
323 
RexxActivation::internalCall
RexxObject * internalCall(RexxString *, RexxInstruction *, size_t, RexxExpressionStack *, ProtectedObject &)
Definition: RexxActivation.cpp:2844
RexxExpressionStack
Definition: ExpressionStack.hpp:53
RexxActivation::externalCall
RexxObject * externalCall(RexxString *, size_t, RexxExpressionStack *, RexxString *, ProtectedObject &)
Definition: RexxActivation.cpp:2597
RexxInternalObject::evaluate
virtual RexxObject * evaluate(RexxActivation *, RexxExpressionStack *)
Definition: ObjectClass.hpp:269
RexxInstructionCall::call_type_mask
Definition: CallInstruction.hpp:68
RexxInstruction::instructionFlags
uint16_t instructionFlags
Definition: RexxInstruction.hpp:82
memory_mark_general
#define memory_mark_general(oref)
Definition: RexxMemory.hpp:437
RexxQueue
Definition: QueueClass.hpp:49
RexxActivation::trapUndelay
void trapUndelay(RexxString *)
Definition: RexxActivation.cpp:2090
RexxActivation.hpp
type
int type
Definition: cmdparse.cpp:1965
OrefSet
#define OrefSet(o, r, v)
Definition: RexxCore.h:94
RexxSource::resolveBuiltin
static size_t resolveBuiltin(RexxString *)
Definition: KeywordConstants.cpp:511
RexxInstructionCall::call_builtin
Definition: CallInstruction.hpp:70
RexxInstructionCallBase
Definition: CallInstruction.hpp:50
RexxQueue::pop
RexxObject * pop()
Definition: QueueClass.hpp:80
RexxActivation::traceResult
void traceResult(RexxObject *v)
Definition: RexxActivation.hpp:392
RexxInstruction
Definition: RexxInstruction.hpp:54
RexxActivity::checkStackSpace
void checkStackSpace()
Definition: RexxActivity.cpp:1964
RexxDirectory::at
RexxObject * at(RexxString *)
Definition: DirectoryClass.cpp:567
RexxActivation::traceIntermediate
void traceIntermediate(RexxObject *v, int p)
Definition: RexxActivation.hpp:373
RexxActivation::trapDelay
void trapDelay(RexxString *)
Definition: RexxActivation.cpp:2074
RexxActivation::trapOn
void trapOn(RexxString *, RexxInstructionCallBase *)
Definition: RexxActivation.cpp:1451
RexxEnvelope
Definition: RexxEnvelope.hpp:53
RexxActivation::trapOff
void trapOff(RexxString *)
Definition: RexxActivation.cpp:1471
RexxInstructionCall::execute
void execute(RexxActivation *, RexxExpressionStack *)
Definition: CallInstruction.cpp:167
RexxInstructionCall::call_on_off
Definition: CallInstruction.hpp:73
RexxInstruction::nextInstruction
RexxInstruction * nextInstruction
Definition: RexxInstruction.hpp:85
RexxInstructionCall
Definition: CallInstruction.hpp:63
OREF_NULL
#define OREF_NULL
Definition: RexxCore.h:60
RexxInstructionCall::RexxInstructionCall
RexxInstructionCall(RexxObject *, RexxString *, size_t, RexxQueue *, size_t, size_t)
Definition: CallInstruction.cpp:56
ArrayClass.hpp
RexxSource::builtinTable
static pbuiltin builtinTable[]
Definition: SourceFile.hpp:406
VARIABLE_RESULT
#define VARIABLE_RESULT
Definition: RexxLocalVariables.hpp:56
RexxDirectory
Definition: DirectoryClass.hpp:49
RexxInstructionCallBase::argumentCount
uint16_t argumentCount
Definition: CallInstruction.hpp:59
RexxInstructionCallBase::builtinIndex
uint16_t builtinIndex
Definition: CallInstruction.hpp:60
ProtectedObject.hpp
RexxActivation::pauseInstruction
void pauseInstruction()
Definition: RexxActivation.hpp:401
flatten_reference
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:440
cleanUpFlatten
#define cleanUpFlatten
Definition: RexxMemory.hpp:432
RexxActivation::setLocalVariable
void setLocalVariable(RexxString *name, size_t index, RexxObject *value)
Definition: RexxActivation.hpp:520
ProtectedObject
Definition: ProtectedObject.hpp:46
StringClass.hpp
RexxInstructionCallBase::condition
RexxString * condition
Definition: CallInstruction.hpp:58
RexxInstructionCall::call_dynamic
Definition: CallInstruction.hpp:72
RexxInstructionCall::call_internal
Definition: CallInstruction.hpp:69
RexxInstructionCallBase::target
RexxInstruction * target
Definition: CallInstruction.hpp:57
TRACE_PREFIX_ARGUMENT
Definition: RexxActivity.hpp:92
RexxExpressionStack::push
void push(RexxObject *value)
Definition: ExpressionStack.hpp:77
RexxActivation::getStack
RexxExpressionStack * getStack()
Definition: RexxActivation.hpp:365
memory_mark
#define memory_mark(oref)
Definition: RexxMemory.hpp:436
CallInstruction.hpp
RexxActivation::dropLocalVariable
void dropLocalVariable(RexxString *name, size_t index)
Definition: RexxActivation.hpp:526
REQUEST_STRING
RexxString * REQUEST_STRING(RexxObject *object)
Definition: RexxCore.h:276
RexxActivation::internalCallTrap
RexxObject * internalCallTrap(RexxString *, RexxInstruction *, RexxDirectory *, ProtectedObject &)
Definition: RexxActivation.cpp:2874
RexxInstructionCall::arguments
RexxObject * arguments[1]
Definition: CallInstruction.hpp:91
RexxActivation
Definition: RexxActivation.hpp:156
NO_BUILTIN
#define NO_BUILTIN
Definition: Token.hpp:296
RexxActivation::traceInstruction
void traceInstruction(RexxInstruction *v)
Definition: RexxActivation.hpp:396
setUpFlatten
#define setUpFlatten(type)
Definition: RexxMemory.hpp:427
ActivityManager::currentActivity
static RexxActivity *volatile currentActivity
Definition: ActivityManager.hpp:95
RexxInstructionCall::call_external
Definition: CallInstruction.hpp:71
RexxActivity.hpp
RexxActivation::getLabels
RexxDirectory * getLabels()
Definition: RexxActivation.cpp:3975
RexxExpressionStack::toss
void toss()
Definition: ExpressionStack.hpp:93
RexxCore.h
DirectoryClass.hpp
RexxInstructionCall::flatten
void flatten(RexxEnvelope *)
Definition: CallInstruction.cpp:118
RexxInstructionCall::call_nointernal
Definition: CallInstruction.hpp:67
RexxVariableDictionary.hpp
RexxInstructionCall::resolve
void resolve(RexxDirectory *)
Definition: CallInstruction.cpp:138
SourceFile.hpp
RexxObject
Definition: ObjectClass.hpp:311
RexxInstructionCallBase::name
RexxObject * name
Definition: CallInstruction.hpp:54
RexxInstructionCall::liveGeneral
void liveGeneral(int reason)
Definition: CallInstruction.cpp:99
RexxInstructionCall::trap
void trap(RexxActivation *, RexxDirectory *)
Definition: CallInstruction.cpp:292
RexxString
Definition: StringClass.hpp:119
RexxInstructionCall::live
void live(size_t)
Definition: CallInstruction.cpp:81