MessageClass.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 Kernel */
40 /* */
41 /* Primitive Message Class */
42 /* */
43 /******************************************************************************/
44 #include "RexxCore.h"
45 #include "StringClass.hpp"
46 #include "DirectoryClass.hpp"
47 #include "ArrayClass.hpp"
48 #include "ListClass.hpp"
49 #include "MethodClass.hpp"
50 #include "RexxActivity.hpp"
51 #include "RexxActivation.hpp"
52 #include "RexxNativeActivation.hpp"
53 #include "MessageClass.hpp"
54 #include "RexxNativeCode.hpp"
55 #include "ProtectedObject.hpp"
56 
57 // singleton class instance
59 
60 
61 /**
62  * Create initial class object at bootstrap time.
63  */
65 {
66  CLASS_CREATE(Message, "Message", RexxClass);
67 }
68 
69 
70 /**
71  * Create a new message object.
72  *
73  * @param _target The receiver object.
74  * @param messageName
75  * The invoked message name.
76  * @param scope The starting scope (can be OREF_NULL).
77  * @param _args An array of arguments to the message.
78  */
79 RexxMessage::RexxMessage(RexxObject *_target, RexxString *msgName, RexxObject *scope, RexxObject **_arglist, size_t _argcount, size_t _named_argcount)
80  : waitResultSem("RexxMessage::waitResultSem")
81 {
82  /* defult target is target specified */
83  OrefSet(this, this->receiver, _target);
84  OrefSet(this, this->target, _target); /* Target specified on new */
85  /* Args to be sent wuth tmessage */
86  // OrefSet(this, this->args, _args);
87  OrefSet(this, this->arglist, _arglist);
88  OrefSet(this, this->argcount, _argcount);
89  OrefSet(this, this->named_argcount, _named_argcount);
90  OrefSet(this, this->message, msgName);
91  OrefSet(this, this->startscope, scope);
92 
93  /* initialize a list of message to be*/
94  /* once we have a result. */
95  OrefSet(this, this->interestedParties, new RexxList);
96 }
97 
98 void RexxMessage::live(size_t liveMark)
99 /******************************************************************************/
100 /* Function: Normal garbage collection live marking */
101 /******************************************************************************/
102 {
103  memory_mark(this->receiver);
104  memory_mark(this->target);
105  memory_mark(this->message);
106  memory_mark(this->startscope);
107  // memory_mark(this->args);
108  memory_mark(this->resultObject);
110  memory_mark(this->condition);
111  memory_mark(this->startActivity);
112  memory_mark(this->objectVariables);
114 
115  size_t i;
116  if (arglist != OREF_NULL)
117  {
118  for (i = 0; i < (argcount + (2 * named_argcount)); i++)
119  {
120  memory_mark(arglist[i]);
121  }
122  }
123 }
124 
125 void RexxMessage::liveGeneral(int reason)
126 /******************************************************************************/
127 /* Function: Generalized object marking */
128 /******************************************************************************/
129 {
134  // memory_mark_general(this->args);
139  memory_mark_general(this->objectVariables);
141 
142  size_t i;
143  if (arglist != OREF_NULL)
144  {
145  for (i = 0; i < (argcount + (2 * named_argcount)); i++)
146  {
148  }
149  }
150 }
151 
153 /******************************************************************************/
154 /* Function: Flatten an object */
155 /******************************************************************************/
156 {
158 
159  flatten_reference(newThis->receiver, envelope);
160  flatten_reference(newThis->target, envelope);
161  flatten_reference(newThis->message, envelope);
162  flatten_reference(newThis->startscope, envelope);
163  // flatten_reference(newThis->args, envelope);
164  flatten_reference(newThis->resultObject, envelope);
165  flatten_reference(newThis->interestedParties, envelope);
166  flatten_reference(newThis->condition, envelope);
167  flatten_reference(newThis->startActivity, envelope);
168  flatten_reference(newThis->objectVariables, envelope);
169  flatten_reference(newThis->waitingActivities, envelope);
170 
171  size_t i;
172  if (arglist != OREF_NULL)
173  {
174  for (i = 0; i < (argcount + (2 * named_argcount)); i++)
175  {
176  flatten_reference(newThis->arglist[i], envelope);
177  }
178  }
179 
181 }
182 
184 /******************************************************************************/
185 /* Function: Add a message object to the notification list */
186 /******************************************************************************/
187 {
188  /* is argument a real message object?*/
189  if (message != OREF_NULL && isOfClass(Message, _message))
190  {
191  /* Yes, then add it to the */
192  /* toBeNotified list. */
193 
194  if (this->allNotified()) /* Have all notifications been sent? */
195  {
196  /* Yes, then send notification right */
197  _message->send(OREF_NULL); /* away */
198  }
199  else
200  {
201  /* nope, add it to list and wait for */
202  /* for result. */
203  this->interestedParties->addLast(_message);
204  }
205  }
206  else
207  { /* nope, its and error, report it. */
208  if ( message == OREF_NULL)
209  {
211  }
212  else
213  {
214  reportException(Error_Incorrect_method_nomessage, OREF_positional, _message);
215  }
216  }
217  return OREF_NULL; /* all done, we return nothing */
218 }
219 
221 /******************************************************************************/
222 /* Function: Return the message result...will wait if the message isn't done */
223 /******************************************************************************/
224 {
225 
226  /* Did send/satrt cause an error */
227  /*condition Yes, we need to raise it */
228  /*here. */
229  if (this->raiseError())
230  {
232  }
233  else
234  {
235  /* Quick test to see if result */
236  /*already present */
237  if (!this->resultReturned())
238  {
239  /* got an activity available? */
240  if (this->startActivity != OREF_NULL)
241  {
242  /* go perform dead lock checks */
244  }
245 
246  /* No result yet, now we need to wait*/
247  /* until we get a result. */
248  /* Is anyone else waiting ???? */
249  if (this->waitingActivities == OREF_NULL)
250  {
251  /* No, Create a waiting list */
252  OrefSet(this, this->waitingActivities, new_list());
253  }
254  /* add this activity to the list */
256  /* now go wait to be woken up */
258  if (this->raiseError()) /* do we need to raise an error. */
259  {
260  /* yes, */
261  this->setErrorReported(); /* indicate error was reported, and */
262  /* report and error. */
263  ActivityManager::currentActivity->reraiseException(this->condition);
264  }
265  }
266  }
267  return this->resultObject; /* ok, return the result. */
268 }
269 
271 /******************************************************************************/
272 /* Function: Send the message contained by this message object */
273 /******************************************************************************/
274 {
275  if (this->msgSent())
276  {
277  /* Yes, this is an error */
279  }
280 
281  /* get the activity I'm running under*/
283  /* If we have a pending start message*/
284  /* sure this send is a result of */
285  /*that message dispatch. */
286  if (this->startPending() && myActivity != this->startActivity )
287  {
288  /* Yes, this is an error */
290  }
291  this->setMsgSent(); /* indicate we were sent a message */
292 
293  if (_receiver != OREF_NULL) /* new receiver specified? */
294  {
295  /* Yes, indicate this is the receiver*/
296  OrefSet(this, this->receiver, _receiver);
297  }
298  /* validate startscope */
299  if (startscope != OREF_NULL)
300  {
301  if (!this->receiver->behaviour->checkScope(this->startscope))
302  {
304  }
305  }
306  /* this is a primitive object? */
307  /* tell the activation/nativeact, we */
308  /*are running under to let us know */
309  /*if an error occured. */
310  myActivity->getTopStackFrame()->setObjNotify(this);
311  /* set this for resource deadlock */
312  /* checking purposes */
313  OrefSet(this, this->startActivity, myActivity);
314  ProtectedObject p(myActivity);
315  /* call message_send to do the send */
316  /* and assign our result. */
317  if (this->startscope != OREF_NULL)/* have a starting scope? */
318  {
319  /* send it with an override */
320  // this->receiver->messageSend(this->message, (RexxObject **)this->args->data(), this->args->size(), this->startscope, p);
321  this->receiver->messageSend(this->message, this->arglist, this->argcount, this->named_argcount, this->startscope, p);
322  }
323  else /* no over ride */
324  {
325  // this->receiver->messageSend(this->message, (RexxObject **)this->args->data(), this->args->size(), p);
326  this->receiver->messageSend(this->message, this->arglist, this->argcount, this->named_argcount, p);
327  }
328  this->resultObject = (RexxObject *)p;
329  this->setResultReturned(); /* Indicate we have a result. */
330  this->sendNotification();
331  return this->resultObject; /* return the result of the send. */
332 }
333 
335 /******************************************************************************/
336 /* Function: Since a start is to happen Async, we create a new activity */
337 /* using ourselves as a dispatch target. */
338 /******************************************************************************/
339 {
340  /* has message already been sent or */
341  /* is another start message pending? */
342  if (this->msgSent() || this->startPending())
343  {
344  /* Yes, this is an error */
346  }
347  /* indicate object has received a */
348  /*start we need this additional bit */
349  /*so that the send message will */
350  /*accept this msg */
351  this->setStartPending();
352 
353 
354  if (_receiver != OREF_NULL) /* new receiver specified? */
355  {
356  /* Yes, indicate this is the receiver*/
357  OrefSet(this, this->receiver, _receiver);
358  }
359 
360  /* get the current activity */
362  /* Create the new activity */
363  RexxActivity *newActivity = oldActivity->spawnReply();
364  /* indicate the activity the send */
365  /*message should come in on. */
366  OrefSet(this, this->startActivity, newActivity);
367  // tell the activity to run this
368  newActivity->run(this);
369  return OREF_NULL; /* all done here, return to caller. */
370 }
371 
373 /******************************************************************************/
374 /* Function : we now have a result from message send/start, so notify */
375 /* all interested parties, and post the waitResult semopohore if it exists */
376 /******************************************************************************/
377 {
378  /* no longer care about any error */
379  /*condition */
381  /* others waiting for a result? */
382  if (this->waitingActivities != OREF_NULL)
383  {
384  size_t i = this->waitingActivities->getSize();/* get the waiting count */
385  while (i--) /* while we have items */
386  {
387  /* get the first item */
388  RexxActivity *waitingActivity = (RexxActivity *)this->waitingActivities->removeFirst();
389  waitingActivity->postDispatch(); /* go wake it up */
390  }
391  }
392  /* now traverse the list of Iterested*/
393  /* parties, and let them know we */
394  /*have a result */
395  for (size_t listIndex = this->interestedParties->firstIndex() ;
396  listIndex != LIST_END;
397  listIndex = this->interestedParties->nextIndex(listIndex) )
398  {
399  /* Get the next message object to */
400  /*process */
401  RexxMessage *thisMessage = (RexxMessage *)this->interestedParties->getValue(listIndex);
402  /* now just have this message send */
403  /*its message */
404  thisMessage->send(OREF_NULL);
405  }
406 
407  /* indicate we notified all */
408  /*Interested parties. Not used */
409  /*yet.... */
410  this->setAllNotified();
411 }
412 
413 
415  RexxDirectory *_condition) /* error condition object */
416 /******************************************************************************/
417 /* Function : called from nativaAct/Activation to notify us that the message */
418 /* from SEND/START. */
419 /******************************************************************************/
420 {
421  this->setRaiseError(); /* indicate we had an error condition*/
422  /* save the condition object in case */
423  /*we want it. */
424  OrefSet(this, this->condition, _condition);
425  this->sendNotification(); /* do cleanup items. */
426 }
427 
429 /******************************************************************************/
430 /* Function: Give a completed polling status */
431 /******************************************************************************/
432 {
433  /* Test to see if result already */
434  /*present or error occured in send? */
435  if (this->resultReturned() || this->raiseError())
436  {
437  return(RexxObject *)TheTrueObject; /* Yes, return true */
438  }
439  else
440  {
441  return(RexxObject *)TheFalseObject;/* nope return false. */
442  }
443 }
444 
445 
446 /**
447  * Check to see if a message has an error condition. Return false
448  * if the message has not completed yet.
449  *
450  * @return True if the message has terminated with an error condition,
451  * false if it is still running or has completed without error.
452  */
454 {
455  if (this->raiseError())
456  {
457  return TheTrueObject;
458  }
459  else
460  {
461  return TheFalseObject;
462  }
463 }
464 
465 /**
466  * Return any error condition information associated with the
467  * message. This method will not block until completion, and
468  * will return .nil if the message is still running.
469  *
470  * @return Any condition object from a terminating error, or .nil if
471  * there was no error or the message is still running.
472  */
474 {
475  if (this->condition == OREF_NULL)
476  {
477  return TheNilObject;
478  }
479  else
480  {
481  return this->condition;
482  }
483 
484 }
485 
486 
487 /**
488  * Retrieve the target of the message object. This will be either
489  * the target object specified when the message object is created
490  * or a target override object specified on SEND or START.
491  *
492  * @return The current message target.
493  */
495 {
496  return receiver;
497 
498 }
499 
500 
501 /**
502  * Return the name of the message.
503  *
504  * @return The string name of the message.
505  */
507 {
508  return message;
509 }
510 
511 
512 /**
513  * Return a copy of the message argument array.
514  *
515  * @return A copy of the message arguments array.
516  */
518 {
519  // return (RexxArray *)args->copy();
520  return new (this->argcount, this->arglist) RexxArray;
521 }
522 
523 
524 void *RexxMessage::operator new(size_t size)
525 /******************************************************************************/
526 /* Function: Construct a new message object */
527 /******************************************************************************/
528 {
529  return new_object(size, T_Message); /* Get new object */
530 }
531 
532 
534  RexxObject **msgArgs, /* message argument array */
535  size_t argCount, /* the number of arguments */
536  size_t named_argCount)
537 /******************************************************************************/
538 /* Function: Rexx level new routine */
539 /******************************************************************************/
540 {
541  RexxArray *argPtr = NULL; // the arguments used with the message.
542  ProtectedObject p_argPtr;
543  size_t argCountMsg = 0; // the count of positional arguments used with the message
544  size_t named_argCountMsg = 0; // the count of named arguments used with the message
545 
546  size_t num_args = argCount; /* get number of args passed */
547 
548  if (num_args < 2 ) /* passed less than 2 args? */
549  {
550  /* Yes, this is an error. */
552  }
553  RexxObject *_target = msgArgs[0]; /* Get the receiver object */
554  requiredArgument(_target, OREF_positional, ARG_ONE);
555  RexxObject *_message = msgArgs[1]; /* get the message . */
556  requiredArgument(_message, OREF_positional, ARG_TWO);
557  RexxString *msgName;
558  RexxObject *_startScope;
559  // decode the message argument into name and scope
560  RexxObject::decodeMessageName(_target, _message, msgName, _startScope);
561  ProtectedObject m(msgName);
562 
563  /*
564  >>-new(target,messagename-+---------------------------------------------+-)--><
565  +-,Individual--| Arguments |------------------+
566  +--+-----------------+--+---------------------+
567  +-,Array,argument-+ +-,Directory,argument-+
568  */
569 
570  // TODO named arguments : add support for named argumenst
571 
572  /* are there arguments to be sent */
573  /*with the message? */
574  if (num_args > 2 )
575  {
576  /* get 3rd arg only concerned w/ 1st */
577  RexxString *optionString = (RexxString *)msgArgs[2];
578  /* Did we really get an option */
579  /*passed? */
580  if (optionString == OREF_NULL)
581  {
582  // /* nope, use null array as argument */
583  argPtr = (RexxArray *)TheNullArray->copy();
584  p_argPtr = argPtr;
585  argCountMsg = 0; // 0 positional argument
586  named_argCountMsg = 0;
587  }
588  else
589  {
590  /* Convert it into a string. */
591  optionString = stringArgument(optionString, OREF_positional, ARG_THREE);
592  /* char and make it lower case */
593  char option = tolower(optionString->getCharC(0));
594  if (option == 'a') /* args passed as an array? */
595  {
596  /* are there less than 4 required */
597  /*args? */
598  if (num_args < 4) /* this is an error */
599  {
601  }
602 
603  /* are there more than 4 required */
604  /*args? */
605  if (num_args > 4) /* this is an error */
606  {
608  }
609 
610  /* get the array of arguments */
611  argPtr = (RexxArray *)msgArgs[3];
612  if (argPtr == OREF_NULL) /* no array given? */
613  {
614  /* this is an error */
616  }
617  /* force to array form */
618  argPtr = (RexxArray *)REQUEST_ARRAY(argPtr);
619  /* not an array? */
620  if (argPtr == TheNilObject || argPtr->getDimension() != 1)
621  {
622  /* raise an error */
623  reportException(Error_Incorrect_method_noarray, OREF_positional, msgArgs[3]);
624  }
625 
626  p_argPtr = argPtr; // Protected against GC
627  argCountMsg = argPtr->size(); // count of positional arguments
628 
629  }
630  else if (option == 'i' ) /* specified as individual? */
631  {
632  /* yes, build array of all arguments */
633 
634  // should work with named argument...
635  // the array is built in-place, so the named arguments are still after the positional arguments
636  // and this array is stored as-is on the instance of Message (no copy)
637  argPtr = new (argCount - 3, msgArgs + 3) RexxArray;
638  argCountMsg = argPtr->size();
639  }
640  else
641  {
643  }
644  }
645  }
646  else
647  {
648  // /* no args, use a null array. */
649  argPtr = (RexxArray *)TheNullArray->copy();
650  p_argPtr = argPtr;
651  argCountMsg = 0; // 0 positional argument
652  named_argCountMsg = 0;
653  }
654  ProtectedObject p(argPtr);
655  /* all args are parcelled out, go */
656  /*create the new message object... */
657  RexxMessage *newMessage = new RexxMessage(_target, msgName, _startScope, argPtr->data(), argCountMsg, named_argCountMsg);
658  /* actually a subclassed item? */
659  if (((RexxClass *)this)->isPrimitive())
660  {
661  ProtectedObject p(newMessage);
662  /* Give new object its behaviour */
663  newMessage->setBehaviour(((RexxClass *)this)->getInstanceBehaviour());
664  newMessage->sendMessage(OREF_INIT);/* call any rexx inits */
665  }
666  return newMessage; /* return the new message */
667 }
668 
void reportException(wholenumber_t error)
@ T_Message
#define LIST_END
Definition: ListClass.hpp:60
RexxList * new_list()
Definition: ListClass.hpp:147
#define OREF_NULL
Definition: RexxCore.h:60
RexxString * stringArgument(RexxObject *object, RexxString *kind, size_t position)
Definition: RexxCore.h:303
RexxArray * REQUEST_ARRAY(RexxObject *obj)
Definition: RexxCore.h:469
#define IntegerFour
Definition: RexxCore.h:193
#define TheNullArray
Definition: RexxCore.h:183
#define IntegerOne
Definition: RexxCore.h:190
const int ARG_THREE
Definition: RexxCore.h:82
#define OrefSet(o, r, v)
Definition: RexxCore.h:94
#define TheTrueObject
Definition: RexxCore.h:186
const int ARG_TWO
Definition: RexxCore.h:81
#define IntegerTwo
Definition: RexxCore.h:191
#define isOfClass(t, r)
Definition: RexxCore.h:212
#define TheNilObject
Definition: RexxCore.h:181
#define TheFalseObject
Definition: RexxCore.h:185
const int ARG_ONE
Definition: RexxCore.h:80
void requiredArgument(RexxObject *object, RexxString *kind, size_t position)
Definition: RexxCore.h:291
#define Error_Incorrect_method_option
#define Error_Incorrect_method_nomessage
#define Error_Incorrect_method_array_noclass
#define Error_Execution_message_reuse
#define Error_Incorrect_method_maxarg
#define Error_Incorrect_method_minarg
#define Error_Incorrect_method_noarg
#define Error_Incorrect_method_noarray
#define memory_mark(oref)
Definition: RexxMemory.hpp:445
RexxObject * new_object(size_t s)
Definition: RexxMemory.hpp:431
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:493
#define CLASS_CREATE(name, id, className)
Definition: RexxMemory.hpp:498
#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
virtual void setObjNotify(RexxMessage *)
RexxActivity * spawnReply()
void reraiseException(RexxDirectory *)
RexxActivationBase * getTopStackFrame()
void checkDeadLock(RexxActivity *)
void waitReserve(RexxObject *)
size_t getDimension()
Definition: ArrayClass.cpp:693
size_t size()
Definition: ArrayClass.hpp:202
RexxObject ** data()
Definition: ArrayClass.hpp:204
bool checkScope(RexxObject *)
void setBehaviour(RexxBehaviour *b)
RexxBehaviour * behaviour
size_t firstIndex()
Definition: ListClass.hpp:84
size_t nextIndex(size_t i)
Definition: ListClass.cpp:804
size_t getSize()
Definition: ListClass.hpp:126
RexxObject * removeFirst()
Definition: ListClass.hpp:109
RexxObject * getValue(size_t i)
Definition: ListClass.cpp:276
void addLast(RexxObject *value)
Definition: ListClass.cpp:455
void flatten(RexxEnvelope *)
RexxString * messageName()
bool raiseError()
RexxObject * resultObject
void setMsgSent()
void liveGeneral(int reason)
RexxObject * receiver
RexxObject * completed()
RexxObject * target
size_t named_argcount
RexxObject * startscope
RexxString * message
void sendNotification()
void setResultReturned()
RexxObject * messageTarget()
static void createInstance()
RexxObject * result()
RexxObject * newRexx(RexxObject **, size_t, size_t)
RexxObject * notify(RexxMessage *)
void live(size_t)
RexxObject * start(RexxObject *)
bool startPending()
RexxDirectory * condition
RexxActivity * startActivity
RexxMessage(RexxObject *, RexxString *, RexxObject *, RexxObject **, size_t, size_t)
RexxList * interestedParties
RexxObject ** arglist
RexxList * waitingActivities
bool allNotified()
void setErrorReported()
bool msgSent()
void setRaiseError()
void setAllNotified()
bool resultReturned()
void error(RexxDirectory *)
static RexxClass * classInstance
RexxArray * arguments()
RexxObject * send(RexxObject *)
RexxObject * hasError()
void setStartPending()
RexxObject * errorCondition()
bool messageSend(RexxString *, RexxObject **, size_t, size_t, ProtectedObject &, bool processUnknown=true)
static void decodeMessageName(RexxObject *target, RexxObject *message, RexxString *&messageName, RexxObject *&startScope)
void sendMessage(RexxString *, RexxArray *, RexxDirectory *, ProtectedObject &)
codepoint_t getCharC(sizeC_t p)