ObjectClass.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 /* Object REXX Kernel */
40 /* */
41 /* The main REXX object definitions */
42 /* */
43 /******************************************************************************/
44 #include <ctype.h>
45 #include <string.h>
46 #include "RexxCore.h"
47 #include "ObjectClass.hpp"
48 #include "StringClass.hpp"
49 #include "BufferClass.hpp"
50 #include "RexxSmartBuffer.hpp"
51 #include "DirectoryClass.hpp"
53 #include "ArrayClass.hpp"
54 #include "RexxActivity.hpp"
55 #include "RexxActivation.hpp"
56 #include "MessageClass.hpp"
57 #include "MethodClass.hpp"
59 #include "SourceFile.hpp"
60 #include "ProtectedObject.hpp"
61 #include "PointerClass.hpp"
62 
63 
64 // singleton class instance
67 
68 
69 /**
70  * Create initial class object at bootstrap time.
71  */
73 {
74  CLASS_CREATE(Object, "Object", RexxClass);
75 }
76 
77 
78 void RexxObject::live(size_t liveMark)
79 /******************************************************************************/
80 /* Function: Normal garbage collection live marking */
81 /******************************************************************************/
82 {
83  memory_mark(this->objectVariables);
84 }
85 
86 void RexxObject::liveGeneral(int reason)
87 /******************************************************************************/
88 /* Function: Generalized object marking */
89 /******************************************************************************/
90 {
91  memory_mark_general(this->objectVariables);
92 }
93 
95 /******************************************************************************/
96 /* Function: Flatten an object */
97 /******************************************************************************/
98 {
100 
101  flatten_reference(newThis->objectVariables, envelope);
102 
104 }
105 
107 /******************************************************************************/
108 /* Function: Create a proxy object for a "special" REXX object */
109 /******************************************************************************/
110 {
111  if (this == TheNilObject)
112  {
113  return(RexxObject *)new_proxy("NIL");
114  }
115  else
116  {
117  return(RexxObject *)this;
118  }
119 }
120 
122  RexxObject *other) /* other object for comparison */
123 /******************************************************************************/
124 /* Function: primitive level equality method used by the hash collection */
125 /* classes for determining equality. */
126 /******************************************************************************/
127 {
128  return ((RexxObject *)this) == other;/* simple identity equality */
129 }
130 
132  RexxObject *other) /* other object for comparison */
133 /******************************************************************************/
134 /* Function: primitive level equality method used by the hash collection */
135 /* classes for determining equality. */
136 /******************************************************************************/
137 {
138  if (this->isBaseClass()) /* not a primitive? */
139  {
140  /* simple identity equality */
141  return ((RexxObject *)this) == other;
142  }
143  else /* return truth value of a compare */
144  {
145  ProtectedObject result;
146  this->sendMessage(OREF_STRICT_EQUAL, other, result);
147  if ((RexxObject *)result == OREF_NULL)
148  {
150  }
151  return ((RexxObject *)result)->truthValue(Error_Logical_value_method);
152  }
153 }
154 
155 
156 /**
157  * Test if an object instance is an enhanced version of a
158  * primitive class or a subclass of the primitive class.
159  *
160  * @return true if the object is a subclass instance or an enhanced one-off.
161  */
163 {
164  return behaviour->isNonPrimitive();
165 }
166 
167 
168 
169 
170 /**
171  * Test if an object instance is a true instance of a primitive
172  * class.
173  *
174  * @return true if the object is not a subclass instance or an enhanced one-off.
175  */
177 {
178  return behaviour->isPrimitive();
179 }
180 
181 
182 /**
183  * Wrapper around the compareTo() method that validates and
184  * extracts integer value.
185  *
186  * @param other The other comparison object
187  *
188  * @return -1, 0, 1 depending on the comparison result.
189  */
191 {
192  ProtectedObject result;
193 
194  sendMessage(OREF_COMPARETO, other, result);
195  if ((RexxObject *)result == OREF_NULL)
196  {
198  }
199  wholenumber_t comparison;
200 
201  if (!((RexxObject *)result)->numberValue(comparison))
202  {
204  }
205  return comparison;
206 }
207 
208 
209 /**
210  * Test if an internal object is an instance of another class.
211  *
212  * @param other The test class.
213  *
214  * @return Always returns false.
215  */
217 {
218  // internal classes always fail this
219  return false;
220 }
221 
222 
223 /**
224  * Test if a Rexx object is an instance of a given class.
225  *
226  * @param other The other test class.
227  *
228  * @return True if this object is an instance of the target class, false otherwise.
229  */
231 {
232  return classObject()->isCompatibleWith(other);
233 }
234 
235 
236 /**
237  * The Rexx external version of the instance of.
238  *
239  * @param other The other test class.
240  *
241  * @return .true if this class is an instance of the target class. .false
242  * otherwise.
243  */
245 {
246  requiredArgument(other, OREF_positional, ARG_ONE);
247  return isInstanceOf(other) ? TheTrueObject : TheFalseObject;
248 }
249 
250 
251 /**
252  * Retrieve the method instance for an object's defined method.
253  *
254  * @param method_name
255  * The method name.
256  *
257  * @return The method object that implements the object method.
258  */
260 {
261  return (RexxMethod *)TheNilObject;
262 }
263 
264 
265 /**
266  * Retrieve the method instance for an object's defined method.
267  *
268  * @param method_name
269  * The method name.
270  *
271  * @return The method object that implements the object method.
272  */
274 {
275  // the name must be a string...and we use it in upper case
276  method_name = stringArgument(method_name, OREF_positional, ARG_ONE)->upper();
277  ProtectedObject p(method_name);
278  // retrieve the method from the dictionary
279  RexxMethod *method_object = (RexxMethod *)this->behaviour->getMethodDictionary()->stringGet(method_name);
280  // We return .nil if the method doesn't exist.
281  if (method_object == OREF_NULL)
282  {
283  return (RexxMethod *)TheNilObject;
284  }
285  return method_object; // got a live one
286 }
287 
288 
289 /**
290  * Return a supplier containing the methods implemented by an
291  * object. Depending on the argument, this is either A) all of
292  * the methods, B) just the explicitly set instance methods, or
293  * C) the methods provided by a given class.
294  *
295  * @param class_object
296  * The target class object (optional).
297  *
298  * @return A supplier with the appropriate method set.
299  */
301 {
302  return OREF_NULL;
303 }
304 
305 
306 /**
307  * Return a supplier containing the methods implemented by an
308  * object. Depending on the argument, this is either A) all of
309  * the methods, B) just the explicitly set instance methods, or
310  * C) the methods provided by a given class.
311  *
312  * @param class_object
313  * The target class object (optional).
314  *
315  * @return A supplier with the appropriate method set.
316  */
318 {
319  // the behaviour handles all of this
320  return this->behaviour->getMethods(class_object);
321 }
322 
323 
324 /**
325  * Retrieve the method instance for an object's defined method.
326  *
327  * @param method_name
328  * The method name.
329  *
330  * @return The method object that implements the object method.
331  */
333 {
334  return instanceMethod(method_name);
335 }
336 
337 
338 /**
339  * Return a supplier containing the methods implemented by an
340  * object. Depending on the argument, this is either A) all of
341  * the methods, B) just the explicitly set instance methods, or
342  * C) the methods provided by a given class.
343  *
344  * @param class_object
345  * The target class object (optional).
346  *
347  * @return A supplier with the appropriate method set.
348  */
350 {
351  return instanceMethods(class_object);
352 }
353 
354 
355 /**
356  * Default implementation of the HASHCODE method.
357  *
358  * @return The object's hash code value.
359  */
361 {
362  // get the hash value directly, then turn it into a binary string value
363  HashCode h = getHashValue();
364  /* create a string value */
365  return (RexxObject *)new_string((char *)&h, sizeof(HashCode));
366 }
367 
368 
369 /**
370  * Hash an exported object. Of we're a non-primitive one, this
371  * will require us to send the HASHCODE message to request a
372  * hash value.
373  *
374  * @return A "hashed hash" that can be used by the map collections.
375  */
377 {
378  // if this is a primitive object, we can just return the primitive hash code.
379  if (this->isBaseClass())
380  {
381  return getHashValue();
382  }
383  else
384  {
385  ProtectedObject result;
386  // we have some other type of object, so we need to request a hash code
387  // by sending the HASHCODE() message.
388  this->sendMessage(OREF_HASHCODE, result);
389  return ((RexxObject *)result)->stringValue()->getObjectHashCode();
390  }
391 }
392 
393 
395  RexxObject * other) /* other object for comparison */
396 /******************************************************************************/
397 /* Function: Process the default "==" strict comparison operator */
398 /******************************************************************************/
399 {
400  requiredArgument(other, OREF_positional, ARG_ONE); /* must have the other argument */
401  /* this is direct object equality */
402  return (RexxObject *)((this == other) ? TheTrueObject : TheFalseObject);
403 }
404 
406 /******************************************************************************/
407 /* Function: Normal "=" type comparison. This only returns true if the */
408 /* two objects are the same object */
409 /******************************************************************************/
410 {
411  requiredArgument(other, OREF_positional, ARG_ONE); /* must have the other argument */
412  /* this is direct object equality */
413  return (RexxObject *)((this == other) ? TheTrueObject : TheFalseObject);
414 }
415 
417 /******************************************************************************/
418 /* Function: Return the strict inequality of two objects */
419 /******************************************************************************/
420 {
421  requiredArgument(other, OREF_positional, ARG_ONE); /* first argument is required */
422  return this != other ? TheTrueObject : TheFalseObject;
423 }
424 
426 /******************************************************************************/
427 /* Function: Return the inequality of two objects */
428 /******************************************************************************/
429 {
430  requiredArgument(other, OREF_positional, ARG_ONE); /* first argument is required */
431  return this != other ? TheTrueObject : TheFalseObject;
432 }
433 
434 /**
435  * Convert an object to a logical value without raising an
436  * error.
437  *
438  * @param result The converted value.
439  *
440  * @return true if this converted ok, false for an invalid logical.
441  */
443 {
444  return false;
445 }
446 
447 
448 /**
449  * Convert an object to a logical value without raising an
450  * error.
451  *
452  * @param result The converted value.
453  *
454  * @return true if this converted ok, false for an invalid logical.
455  */
457 {
458  return REQUEST_STRING(this)->logicalValue(result);
459 }
460 
461 
463  int errorCode) /* error to issue for bad conversion */
464 /******************************************************************************/
465 /* Function: test the truth value of a primitive object */
466 /******************************************************************************/
467 {
468  /* report the error */
469  reportException(errorCode, OREF_NULLSTRING);
470  return false; /* need a return value */
471 }
472 
474  int errorCode) /* error to issue for bad conversion */
475 /******************************************************************************/
476 /* Function: test the truth value of a primitive object */
477 /******************************************************************************/
478 {
479  /* just return string truth value */
480  return REQUEST_STRING(this)->truthValue(errorCode);
481 }
482 
484 /******************************************************************************/
485 /* Function: First level primitive copy of an object. This just copies */
486 /* the object storage, and nothing else. */
487 /******************************************************************************/
488 {
489  /* Instead of calling new_object and memcpy, ask the memory object to make */
490  /* a copy of ourself. This way, any header information can be correctly */
491  /* initialized by memory. */
492  return (RexxObject *)this->clone();
493 }
494 
495 void *RexxInternalObject::operator new(size_t size,
496  RexxClass *classObject) /* class of the object */
497 /******************************************************************************/
498 /* Function: Create a new primitive object */
499 /******************************************************************************/
500 {
501  /* get storage for a new object */
502  RexxObject *newObject = (RexxObject *)new_object(size);
503  /* use the class instance behaviour */
504  newObject->setBehaviour(classObject->getInstanceBehaviour());
505  return(void *)newObject; /* and return the new object */
506 }
507 
508 void *RexxInternalObject::operator new(size_t size,
509  RexxClass * classObject, /* class of the object */
510  RexxObject **arguments, /* arguments to the new method */
511  size_t argCount, /* the count of arguments */
512  size_t named_argCount)
513 /******************************************************************************/
514 /* Function: Create a new instance of object (with arguments) */
515 /******************************************************************************/
516 {
517  /* Get storage for a new object */
518  RexxObject *newObject = (RexxObject *)new_object(size);
519  /* use the classes instance behaviour*/
520  newObject->setBehaviour(classObject->getInstanceBehaviour());
521  return newObject; /* and return the object */
522 }
523 
525 /******************************************************************************/
526 /* Function: Copy an object that has an Object Variable Dictionary (OVD) */
527 /******************************************************************************/
528 {
529  /* Instead of calling new_object and memcpy, ask the memory object to make */
530  /* a copy of ourself. This way, any header information can be correctly */
531  /* initialized by memory. */
532  RexxObject *newObj = (RexxObject *)this->clone();
533  /* have object variables? */
534  if (this->objectVariables != OREF_NULL)
535  {
536  ProtectedObject p(newObj);
537  copyObjectVariables(newObj); /* copy the object variables into the new object */
538  }
539  /* have instance methods? */
541  {
542  /* need to copy the behaviour */
543  ProtectedObject p(newObj);
544  newObj->setBehaviour((RexxBehaviour *)newObj->behaviour->copy());
545  }
546  return newObj; /* return the copied version */
547 }
548 
550 /******************************************************************************/
551 /* Function: Copy an object's object variable dictionaries into another obj. */
552 /******************************************************************************/
553 {
554  RexxVariableDictionary *dictionary = objectVariables;
555  /* clear out the existing object variable pointer */
556  newObj->objectVariables = OREF_NULL;
557 
558  while (dictionary != OREF_NULL)
559  {
560  /* copy the dictionary */
561  RexxVariableDictionary *newDictionary = (RexxVariableDictionary *)dictionary->copy();
562  /* add this to the variable set */
563  newObj->addObjectVariables(newDictionary);
564  /* now that the dictionary is anchored in the new object, */
565  /* copy the variable objects inside. */
566  newDictionary->copyValues();
567  /* and repeat for each one */
568  dictionary = dictionary->getNextDictionary();
569  }
570 }
571 
573  RexxMethod * method) /* method to check */
574 /******************************************************************************/
575 /* Function: Check a private method for accessibility. */
576 /******************************************************************************/
577 {
578  /* get the top activation */
580  /* have an activation? */
581  if (activation != OREF_NULL)
582  {
583  RexxObject *sender = activation->getReceiver();/* get the receiving object */
584  if (sender == (RexxObject *)this) /* the same receiver? */
585  {
586  return method; /* just return the same method */
587  }
588  // no sender means this is a routine or program context. Definitely not allowed.
589  if (sender == OREF_NULL)
590  {
591  return OREF_NULL;
592  }
593  // ok, now we check the various scope possibilities
594  RexxClass *scope = method->getScope();
595  // 1) Another instance of the same class that defined the method?
596  if (sender->isInstanceOf(scope))
597  {
598  return method; // ok, we'll allow this
599  }
600  // if the sender is a class object, check the class for compatibility with the
601  // method scope
602  if (isOfClassType(Class, sender))
603  {
604  // if this class is part of the compatible hierarchy, this is also permitted
605  if (((RexxClass *)sender)->isCompatibleWith(scope))
606  {
607  return method;
608  }
609  }
610  }
611  return OREF_NULL; /* return a failure indicator */
612 }
613 
614 // Should be named sendWith
616 {
617  ProtectedObject r;
618  this->sendMessage(message, args, named_args, r);
619  return (RexxObject *)r;
620 }
621 
622 RexxObject *RexxObject::sendMessage(RexxString *message, RexxObject **args, size_t argCount, size_t named_argCount)
623 {
624  ProtectedObject r;
625  this->sendMessage(message, args, argCount, named_argCount, r);
626  return (RexxObject *)r;
627 }
628 
630 {
631  ProtectedObject r;
632  this->sendMessage(message, r);
633  return (RexxObject *)r;
634 }
635 
637 {
638  ProtectedObject r;
639  this->sendMessage(message, argument1, r);
640  return (RexxObject *)r;
641 }
642 
643 
645 {
646  ProtectedObject r;
647  this->sendMessage(message, argument1, argument2, r);
648  return (RexxObject *)r;
649 }
650 
651 
652 RexxObject *RexxObject::sendMessage(RexxString *message, RexxObject *argument1, RexxObject *argument2, RexxObject *argument3)
653 {
654  ProtectedObject r;
655  this->sendMessage(message, argument1, argument2, argument3, r);
656  return (RexxObject *)r;
657 }
658 
659 
660 RexxObject *RexxObject::sendMessage(RexxString *message, RexxObject *argument1, RexxObject *argument2, RexxObject *argument3, RexxObject *argument4)
661 {
662  ProtectedObject r;
663  this->sendMessage(message, argument1, argument2, argument3, argument4, r);
664  return (RexxObject *)r;
665 }
666 
667 
668 RexxObject *RexxObject::sendMessage(RexxString *message, RexxObject *argument1, RexxObject *argument2, RexxObject *argument3, RexxObject *argument4, RexxObject *argument5)
669 {
670  ProtectedObject r;
671  this->sendMessage(message, argument1, argument2, argument3, argument4, argument5, r);
672  return (RexxObject *)r;
673 }
674 
675 
677  RexxString *message, /* name of the message to process */
678  RexxArray *arguments, /* array of arguments */
679  RexxDirectory * named_arguments,
680  ProtectedObject &result)
681 {
682  if (named_arguments == OREF_NULL || named_arguments == TheNilObject)
683  {
684  /******************************************************************************/
685  /* Function: Issue a message using a set of arguments already in an array item*/
686  /******************************************************************************/
687  this->messageSend(message, arguments->data(), arguments->size(), 0, result);
688  }
689  else
690  {
691  size_t argumentsCount = arguments ? arguments->size() : 0;
692  RexxArray *args = arguments ? (RexxArray *)arguments->copy() : new_array();
693  ProtectedObject p(args);
694  size_t namedArgumentsCount = named_arguments->appendAllIndexesItemsTo(args, /*from*/ argumentsCount+1); // from is 1-based index
695 
696  this->messageSend(message, args->data(), argumentsCount, namedArgumentsCount, result);
697  }
698 }
699 
701 {
702  RexxObject *arguments[1];
703  arguments[0] = argument1; // positional argument
704  this->messageSend(message, arguments, 1, 0, result);
705 }
706 
708  RexxString *message, /* name of the message to process */
709  RexxObject *argument1, /* first argument */
710  RexxObject *argument2, /* second argument */
711  ProtectedObject &result)
712  /******************************************************************************/
713  /* Function: Send a message with two arguments */
714  /******************************************************************************/
715 {
716  RexxObject *arguments[2]; /* argument array */
717 
718  arguments[0] = argument1; /* set each argument */
719  arguments[1] = argument2;
720  /* just pass on to message send */
721  this->messageSend(message, arguments, 2, 0, result);
722 }
723 
725  RexxString *message, /* name of the message to process */
726  RexxObject *argument1, /* first argument */
727  RexxObject *argument2, /* second argument */
728  RexxObject *argument3, /* third argument */
729  ProtectedObject &result)
730  /******************************************************************************/
731  /* Function: Send a message with three arguments */
732  /******************************************************************************/
733 {
734  RexxObject *arguments[3]; /* argument array */
735 
736  arguments[0] = argument1; /* set each argument */
737  arguments[1] = argument2;
738  arguments[2] = argument3;
739  /* just pass on to message send */
740  this->messageSend(message, arguments, 3, 0, result);
741 }
742 
744  RexxString *message, /* name of the message to process */
745  RexxObject *argument1, /* first argument */
746  RexxObject *argument2, /* second argument */
747  RexxObject *argument3, /* third argument */
748  RexxObject *argument4, /* fourth argument */
749  ProtectedObject &result)
750  /******************************************************************************/
751  /* Function: Send a message with four arguments */
752  /******************************************************************************/
753 {
754  RexxObject *arguments[4]; /* argument array */
755 
756  arguments[0] = argument1; /* set each argument */
757  arguments[1] = argument2;
758  arguments[2] = argument3;
759  arguments[3] = argument4;
760  /* just pass on to message send */
761  this->messageSend(message, arguments, 4, 0, result);
762 }
763 
765  RexxString *message, /* name of the message to process */
766  RexxObject *argument1, /* first argument */
767  RexxObject *argument2, /* second argument */
768  RexxObject *argument3, /* third argument */
769  RexxObject *argument4, /* fourth argument */
770  RexxObject *argument5, /* fifth argument */
771  ProtectedObject &result)
772  /******************************************************************************/
773  /* Function: Send a message with five arguments */
774  /******************************************************************************/
775 {
776  RexxObject *arguments[5]; /* argument array */
777 
778  arguments[0] = argument1; /* set each argument */
779  arguments[1] = argument2;
780  arguments[2] = argument3;
781  arguments[3] = argument4;
782  arguments[4] = argument5;
783  /* just pass on to message send */
784  this->messageSend(message, arguments, 5, 0, result);
785 }
786 
788  RexxString *msgname, /* name of the message to process */
789  RexxObject **arguments, /* array of arguments */
790  size_t count, /* count of arguments */
791  size_t named_count,
792  ProtectedObject &result, // returned result
793  bool processUnknown)
794  /******************************************************************************/
795  /* Function: send a message (with message lookup) to an object. */
796  /* All types of methods are handled and dispatched */
797  /******************************************************************************/
798 {
799  ActivityManager::currentActivity->checkStackSpace(); /* have enough stack space? */
800  /* grab the method from this level */
801  RexxMethod *method_save = this->behaviour->methodLookup(msgname);
802  /* method exists...special processing*/
803  if (method_save != OREF_NULL && method_save->isSpecial())
804  {
805  if (method_save->isPrivate()) /* actually private method? */
806  {
807  /* go validate a private method */
808  method_save = this->checkPrivate(method_save);
809  }
810  /* now process protected methods */
811  if (method_save != OREF_NULL && method_save->isProtected())
812  {
813  /* really a protected method */
814  this->processProtectedMethod(msgname, method_save, arguments, count, named_count, result);
815  return true;
816  }
817  }
818  /* have a method */
819  if (method_save != OREF_NULL)
820  {
821  method_save->run(ActivityManager::currentActivity, this, msgname, arguments, count, named_count, result);
822  return true;
823  }
824  else if (processUnknown)
825  {
826  /* go process an unknown method */
827  this->processUnknown(msgname, arguments, count, named_count, result);
828  }
829  return false;
830 }
831 
833  RexxString *msgname, /* name of the message to process */
834  RexxObject **arguments, /* array of arguments */
835  size_t count, /* count of arguments */
836  size_t named_count,
837  RexxObject *startscope, /* starting superclass scope */
838  ProtectedObject &result, // returned result
839  bool processUnknown)
840  /******************************************************************************/
841  /* Function: send a message (with message lookup) to an object. */
842  /* All types of methods are handled and dispatched */
843  /******************************************************************************/
844 {
845  ActivityManager::currentActivity->checkStackSpace(); /* have enough stack space? */
846  /* go to the higher level */
847  RexxMethod *method_save = this->superMethod(msgname, startscope);
848  if (method_save != OREF_NULL && method_save->isProtected())
849  {
850  if (method_save->isPrivate()) /* actually private method? */
851  {
852  method_save = this->checkPrivate(method_save);
853  }
854  /* go validate a private method */
855  else /* really a protected method */
856  {
857  this->processProtectedMethod(msgname, method_save, arguments, count, named_count, result);
858  return true;
859  }
860  }
861  /* have a method */
862  if (method_save != OREF_NULL)
863  {
864  /* run the method */
865  method_save->run(ActivityManager::currentActivity, this, msgname, arguments, count, named_count, result);
866  return true;
867  }
868  else if (processUnknown)
869  {
870  /* go process an unknown method */
871  this->processUnknown(msgname, arguments, count, named_count, result);
872  }
873  return false;
874 }
875 
877  RexxString * messageName, /* message to issue */
878  RexxMethod * targetMethod, // the method to run
879  RexxObject ** arguments, /* actual message arguments */
880  size_t count, /* count of arguments */
881  size_t named_count,
882  ProtectedObject &result) // returned result
883 /******************************************************************************/
884 /* Function: Process an unknown message, uncluding looking for an UNKNOWN */
885 /* method and raising a NOMETHOD condition */
886 /******************************************************************************/
887 {
888  // get the current security manager
890  // the security manager can replace provide a new result
891  if (manager->checkProtectedMethod(this, messageName, count, named_count, arguments, result))
892  {
893  return;
894  }
895  /* run the method */
896  targetMethod->run(ActivityManager::currentActivity, this, messageName, arguments, count, named_count, result);
897 }
898 
900  RexxString * messageName, /* message to issue */
901  RexxObject ** arguments, /* actual message arguments */
902  size_t count, /* count of arguments */
903  size_t named_count,
904  ProtectedObject &result) // returned result
905 /******************************************************************************/
906 /* Function: Process an unknown message, uncluding looking for an UNKNOWN */
907 /* method and raising a NOMETHOD condition */
908 /******************************************************************************/
909 {
910  /* no method for this msgname */
911  /* find the unknown method */
912  RexxMethod *method_save = this->behaviour->methodLookup(OREF_UNKNOWN);
913  if (method_save == OREF_NULL) /* "unknown" method exists? */
914  /* no unknown method - try to raise */
915  /* a NOMETHOD condition, and if that */
916  {
917  reportNomethod(messageName, this); /* fails, it is an error message */
918  }
919 
920  RexxArray *argumentArray = new_array(count); /* get an array for the positional arguments */
921  ProtectedObject p(argumentArray);
922 
923  for (size_t i = 1; i <= count; i++) /* copy the positional arguments into an array */
924  {
925  argumentArray->put(arguments[i - 1], i);
926  }
927 
928  // The case no named argument is very common.
929  // To avoid any performance loss, avoid to create a directory when named_count = 0.
930  // This is managed by RexxDirectory::fromIndexItemArray which returns OREF_NULL when count = 0.
931  RexxDirectory *namedArgumentDirectory = RexxDirectory::fromIndexItemArray(arguments + count, named_count);
932  ProtectedObject p1(namedArgumentDirectory);
933 
934  RexxObject *unknown_arguments[2 + (1 * 2)];/* positional & named arguments to the unknown method */
935  unknown_arguments[0] = messageName; /* method name is first argument */
936  /* second argument is array of */
937  unknown_arguments[1] = argumentArray;/* arguments for the original call */
938  unknown_arguments[2] = OREF_NAMEDARGUMENTS;
939  unknown_arguments[3] = namedArgumentDirectory ? namedArgumentDirectory : TheNilObject;
940  /* run the unknown method */
941  method_save->run(ActivityManager::currentActivity, this, OREF_UNKNOWN, unknown_arguments, 2, 1, result);
942 }
943 
945  RexxString *msgname) /* name of the target message */
946 /******************************************************************************/
947 /* Function: Return the method object associated with a message name */
948 /******************************************************************************/
949 {
950  return this->behaviour->methodLookup(msgname);
951 }
952 
954 /******************************************************************************/
955 /* Function: Convert a primitive internal object to a long value */
956 /******************************************************************************/
957 {
958  return false; /* give a "safe" default here */
959 }
960 
962 /******************************************************************************/
963 /* Function: Convert a primitive internal object to a long value */
964 /******************************************************************************/
965 {
966  return false; /* give a "safe" default here */
967 }
968 
970 /******************************************************************************/
971 /* Function: Convert a primitive internal object to a long value */
972 /******************************************************************************/
973 {
974  return false; /* give a "safe" default here */
975 }
976 
978 /******************************************************************************/
979 /* Function: Convert a primitive internal object to a long value */
980 /******************************************************************************/
981 {
982  return false; /* give a "safe" default here */
983 }
984 
986 /******************************************************************************/
987 /* Function: Convert a primitive internal object to a double value */
988 /******************************************************************************/
989 {
990  return false; /* give a "safe" default here */
991 }
992 
994  size_t precision) /* precision to use */
995 /******************************************************************************/
996 /* Function: Convert a primitive internal object to an integer value */
997 /******************************************************************************/
998 {
999  return (RexxInteger *)TheNilObject; /* give a "safe" default here */
1000 }
1001 
1003 /******************************************************************************/
1004 /* Function: convert an internal object to a numberstring representation */
1005 /******************************************************************************/
1006 {
1007  return OREF_NULL; /* this never converts */
1008 }
1009 
1011 /******************************************************************************/
1012 /* Function: Convert a REXX object to a long value */
1013 /******************************************************************************/
1014 {
1015  /* get a string and convert */
1016  return REQUEST_STRING(this)->numberValue(result, digits);
1017 }
1018 
1020 /******************************************************************************/
1021 /* Function: Convert a REXX object to a long value */
1022 /******************************************************************************/
1023 {
1024  /* get a string and convert */
1025  return REQUEST_STRING(this)->numberValue(result);
1026 }
1027 
1029 /******************************************************************************/
1030 /* Function: Convert a REXX object to a long value */
1031 /******************************************************************************/
1032 {
1033  /* get a string and convert */
1034  return REQUEST_STRING(this)->unsignedNumberValue(result, digits);
1035 }
1036 
1038 /******************************************************************************/
1039 /* Function: Convert a REXX object to a long value */
1040 /******************************************************************************/
1041 {
1042  /* get a string and convert */
1043  return REQUEST_STRING(this)->unsignedNumberValue(result);
1044 }
1045 
1046 bool RexxObject::doubleValue(double &result)
1047 /******************************************************************************/
1048 /* Function: Convert a primitive internal object to a double value */
1049 /******************************************************************************/
1050 {
1051  /* get a string and convert */
1052  return this->requestString()->doubleValue(result);
1053 }
1054 
1056  size_t precision) /* precision to use */
1057 /******************************************************************************/
1058 /* Function: Convert a primitive internal object to an integer value */
1059 /******************************************************************************/
1060 {
1061  /* get a string and convert */
1062  return REQUEST_STRING(this)->integerValue(precision);
1063 }
1064 
1066 /******************************************************************************/
1067 /* Function: convert a standard object to a numberstring representation */
1068 /******************************************************************************/
1069 {
1070  /* get the string representation, */
1071  /* return the numberstring form */
1072  return this->requestString()->numberString();
1073 }
1074 
1076 /******************************************************************************/
1077 /* Function: Convert a primitive internal object to a string value */
1078 /******************************************************************************/
1079 {
1080  return OREF_NULLSTRING; /* give a "safe" default here */
1081 }
1082 
1084 /******************************************************************************/
1085 /* Function: Convert a primitive object to a string value */
1086 /******************************************************************************/
1087 {
1088  /* issue the object name message */
1089  return (RexxString *)this->sendMessage(OREF_OBJECTNAME);
1090 }
1091 
1093 /******************************************************************************/
1094 /* Function: Handle a string conversion REQUEST for an internal object */
1095 /******************************************************************************/
1096 {
1097  return (RexxString *)TheNilObject; /* should never occur */
1098 }
1099 
1100 
1102 /******************************************************************************/
1103 /* Function: Handle a tail construction request for an internal object */
1104 /******************************************************************************/
1105 {
1106  return; /* should never occur */
1107 }
1108 
1110 /******************************************************************************/
1111 /* Function: Handle a string conversion REQUEST for an internal object */
1112 /******************************************************************************/
1113 {
1114  return (RexxString *)TheNilObject; /* should never occur */
1115 }
1116 
1118 /******************************************************************************/
1119 /* Function: Handle a string conversion REQUEST for a REXX object */
1120 /******************************************************************************/
1121 {
1122  if (this->isBaseClass()) /* primitive object? */
1123  return (RexxString *)TheNilObject; /* this never converts */
1124  else /* process as a string request */
1125  {
1126  return (RexxString *)this->sendMessage(OREF_REQUEST, OREF_STRINGSYM);
1127  }
1128 }
1129 
1130 
1132 /******************************************************************************/
1133 /* Function: Handle a tail construction request for an internal object */
1134 /******************************************************************************/
1135 {
1136  /* get our string value */
1137  RexxString *value = REQUEST_STRING(this);
1138  ProtectedObject p(value);
1139  value->copyIntoTail(tail); /* pass this on to the string value */
1140 }
1141 
1142 
1144 /******************************************************************************/
1145 /* Function: Handle a string conversion REQUEST for a REXX object */
1146 /******************************************************************************/
1147 {
1148  return (RexxString *)TheNilObject; /* this never converts */
1149 }
1150 
1152 /******************************************************************************/
1153 /* Function: Handle an array conversion REQUEST for an internal object */
1154 /******************************************************************************/
1155 {
1156  return (RexxArray *)TheNilObject; /* should never occur */
1157 }
1158 
1160 /******************************************************************************/
1161 /* Function: Handle a string conversion REQUEST for a REXX object */
1162 /******************************************************************************/
1163 {
1164  if (this->isBaseClass()) /* primitive object? */
1165  return (RexxArray *)TheNilObject; /* this never converts */
1166  else /* process as a string request */
1167  {
1168  return (RexxArray *)this->sendMessage(OREF_REQUEST, OREF_ARRAYSYM);
1169  }
1170 }
1171 
1173 /******************************************************************************/
1174 /* Function: Handle a string request for a REXX object. This will go */
1175 /* through the whole search order to do the conversion. */
1176 /******************************************************************************/
1177 {
1178 
1179  /* primitive object? */
1180  if (this->isBaseClass())
1181  {
1182  RexxString *string_value; /* converted object */
1183  /* get the string representation */
1184  string_value = this->primitiveMakeString();
1185  if (string_value == TheNilObject)
1186  {/* didn't convert? */
1187  /* get the final string value */
1188  string_value = this->stringValue();
1189  /* raise a NOSTRING condition */
1190  ActivityManager::currentActivity->raiseCondition(OREF_NOSTRING, OREF_NULL, string_value, this, OREF_NULL);
1191  }
1192  return string_value; /* return the converted form */
1193  }
1194  else
1195  { /* do a real request for this */
1196  ProtectedObject string_value;
1197 
1198  this->sendMessage(OREF_REQUEST, OREF_STRINGSYM, string_value);
1199  // The returned value might be an Integer or NumberString value. We need to
1200  // force this to be a real string value.
1201  string_value = ((RexxObject *)string_value)->primitiveMakeString();
1202  if (string_value == TheNilObject)
1203  {/* didn't convert? */
1204  /* get the final string value */
1205  this->sendMessage(OREF_STRINGSYM, string_value);
1206  // we're really dependent upon the program respecting the protocol
1207  // here and returning a value. It is possible there is a
1208  // problem, so how to handle this. We could just raise an error, but this
1209  // isn't the most ideal message since the error is raised at the
1210  // line where the string value is required, but this is a rare
1211  // situation. As a fallback, use the default object STRING method,
1212  // then raise an error if we still don't get anything. This at least
1213  // keeps the interpreter from crashing, there's a good chance the
1214  // program will run. Frankly, there's something seriously wrong
1215  // if this error ever gets issued.
1216  if (((RexxObject *)string_value) == OREF_NULL)
1217  {
1218  string_value = RexxObject::stringValue();
1219  if (((RexxObject *)string_value) == OREF_NULL)
1220  {
1222  }
1223  }
1224  // The returned value might be an Integer or NumberString value. We need to
1225  // force this to be a real string value.
1226  string_value = ((RexxObject *)string_value)->primitiveMakeString();
1227  /* raise a NOSTRING condition */
1228  ActivityManager::currentActivity->raiseCondition(OREF_NOSTRING, OREF_NULL, (RexxString *)string_value, this, OREF_NULL);
1229  }
1230  return (RexxString *)string_value; /* return the converted form */
1231  }
1232 }
1233 
1235 /******************************************************************************/
1236 /* Function: Handle a string request for a REXX object. This will go */
1237 /* through the whole search order to do the conversion. */
1238 /******************************************************************************/
1239 {
1240 
1241  /* primitive object? */
1242  if (this->isBaseClass())
1243  {
1244  RexxString *string_value; /* converted object */
1245  /* get the string representation */
1246  string_value = this->primitiveMakeString();
1247  if (string_value == TheNilObject)
1248  {/* didn't convert? */
1249  /* get the final string value */
1250  string_value = this->stringValue();
1251  }
1252  return string_value;
1253  }
1254  else
1255  { /* do a real request for this */
1256  ProtectedObject string_value;
1257  this->sendMessage(OREF_REQUEST, OREF_STRINGSYM, string_value);
1258  if (string_value == TheNilObject)
1259  {/* didn't convert? */
1260  /* get the final string value */
1261  this->sendMessage(OREF_STRINGSYM, string_value);
1262  }
1263  return(RexxString *)string_value; /* return the converted form */
1264  }
1265 }
1266 
1267 
1269  RexxString *kind,
1270  size_t position) /* required argument position */
1271 /******************************************************************************/
1272 /* Function: Handle a string request for a REXX object in a context where */
1273 /* the object MUST have a string value. */
1274 /******************************************************************************/
1275 {
1276  RexxObject *string_value; /* converted object */
1277 
1278  if (this->isBaseClass()) /* primitive object? */
1279  {
1280  string_value = this->makeString(); /* get the string representation */
1281  }
1282  else /* do a full request for this */
1283  {
1284  string_value = this->sendMessage(OREF_REQUEST, OREF_STRINGSYM);
1285  }
1286  /* didn't convert? */
1287  if (string_value == TheNilObject)
1288  {
1289  /* this is an error */
1291  }
1292  return(RexxString *)string_value; /* return the converted form */
1293 }
1294 
1295 
1297  RexxString *kind,
1298  const char *name) /* required argument position */
1299 /******************************************************************************/
1300 /* Function: Handle a string request for a REXX object in a context where */
1301 /* the object MUST have a string value. */
1302 /******************************************************************************/
1303 {
1304  RexxObject *string_value; /* converted object */
1305 
1306  if (this->isBaseClass()) /* primitive object? */
1307  {
1308  string_value = this->makeString(); /* get the string representation */
1309  }
1310  else /* do a full request for this */
1311  {
1312  string_value = this->sendMessage(OREF_REQUEST, OREF_STRINGSYM);
1313  }
1314  /* didn't convert? */
1315  if (string_value == TheNilObject)
1316  {
1317  /* this is an error */
1319  }
1320  return(RexxString *)string_value; /* return the converted form */
1321 }
1322 
1323 /**
1324  * Handle a string request for a required string value where
1325  * the caller wishes to handle the error itself.
1326  *
1327  * @return The object's string value, or OREF_NULL if this is not a
1328  * string.
1329  */
1331 {
1332  // primitive object? We have a bypass for this
1333  if (this->isBaseClass())
1334  {
1335  return this->makeString();
1336  }
1337  else
1338  {
1339  // we have to use REQUEST to get this
1340  return (RexxString *)this->sendMessage(OREF_REQUEST, OREF_STRINGSYM);
1341  }
1342 }
1343 
1344 
1346  size_t precision) /* precision to use */
1347 /******************************************************************************/
1348 /* Function: Request an integer value from an object. If this is not a */
1349 /* primitive object, the object will be converted to a string, */
1350 /* and then the string integer value will be returned. */
1351 /******************************************************************************/
1352 {
1353  if (this->isBaseClass()) /* primitive object? */
1354  {
1355  /* return the integer value */
1356  return this->integerValue(precision);
1357  }
1358  else /* return integer value of string */
1359  {
1360  return this->requestString()->integerValue(precision);
1361  }
1362 }
1363 
1365  RexxString *kind,
1366  size_t position, /* precision to use */
1367  size_t precision) /* argument position for errors */
1368 /******************************************************************************/
1369 /* Function: Request an integer value from an object. If this is not a */
1370 /* primitive object, a REQUEST('STRING') will be performeding, */
1371 /* and then the string integer value will be returned. */
1372 /******************************************************************************/
1373 {
1374  RexxInteger *result; /* returned result */
1375 
1376  if (this->isBaseClass()) /* primitive object? */
1377  {
1378  /* return the integer value */
1379  result = this->integerValue(precision);
1380  }
1381  else /* return integer value of string */
1382  {
1383  result = this->requiredString(kind, position)->integerValue(precision);
1384  }
1385  /* didn't convert well? */
1386  if (result == (RexxInteger *)TheNilObject)
1387  {
1388  /* raise an error */
1389  reportException(Error_Incorrect_method_whole, kind, position, this);
1390  }
1391  return result; /* return the new integer */
1392 }
1393 
1394 
1395 /**
1396  * Request an object to convert itself into a number value.
1397  *
1398  * @param result The numeric result value.
1399  * @param precision The precision used for the conversion.
1400  *
1401  * @return true if the object converted ok, false for a conversion failure.
1402  */
1403 bool RexxObject::requestNumber(wholenumber_t &result, size_t precision)
1404 {
1405  if (isBaseClass())
1406  {
1407  // are we already a base class?
1408  // the base classes can handle this directly.
1409  return numberValue(result, precision);
1410  }
1411  else
1412  {
1413  // we need to perform the operation on the string value
1414  return numberValue(result, precision);
1415  }
1416 }
1417 
1418 
1419 /**
1420  * Request an object to convert itself into a number value.
1421  *
1422  * @param result The numeric result value.
1423  * @param precision The precision used for the conversion.
1424  *
1425  * @return true if the object converted ok, false for a conversion failure.
1426  */
1427 bool RexxObject::requestUnsignedNumber(stringsize_t &result, size_t precision)
1428 {
1429  if (isBaseClass())
1430  {
1431  // are we already a base class?
1432  // the base classes can handle this directly.
1433  return unsignedNumberValue(result, precision);
1434  }
1435  else
1436  {
1437  // we need to perform the operation on the string value
1438  return unsignedNumberValue(result, precision);
1439  }
1440 }
1441 
1442 
1444  RexxString *kind,
1445  size_t position, /* precision to use */
1446  size_t precision) /* argument position for errors */
1447 /******************************************************************************/
1448 /* Function: Request a long value from an object. If this is not a */
1449 /* primitive object, a REQUEST('STRING') will be performed */
1450 /* and then the string long value will be returned. */
1451 /******************************************************************************/
1452 {
1453  wholenumber_t result; /* returned result */
1454 
1455  /* primitive object? */
1456  if (this->isBaseClass() && !isOfClass(Object, this))
1457  {
1458  if (!numberValue(result, precision))
1459  {
1460  /* raise an error */
1461  reportException(Error_Incorrect_method_whole, kind, position, this);
1462  }
1463  }
1464  else /* return integer value of string */
1465  {
1466  if (!requiredString(kind, position)->numberValue(result, precision))
1467  {
1468  /* raise an error */
1469  reportException(Error_Incorrect_method_whole, kind, position, this);
1470  }
1471  }
1472  return result; /* return the result */
1473 }
1474 
1476  RexxString *kind,
1477  size_t position, /* precision to use */
1478  size_t precision) /* argument position for errors */
1479 /******************************************************************************/
1480 /* Function: Request a a positive long value from an object. If this is not */
1481 /* positive, it will raise an error. */
1482 /******************************************************************************/
1483 {
1484  stringsize_t result; /* returned result */
1485 
1486  if (!unsignedNumberValue(result, precision) || result == 0)
1487  {
1488  /* raise the error */
1489  reportException(Error_Incorrect_method_positive, kind, position, this);
1490  }
1491  return result;
1492 }
1493 
1494 
1496  RexxString *kind,
1497  size_t position, /* precision to use */
1498  size_t precision) /* argument position for errors */
1499 /******************************************************************************/
1500 /* Function: Request a non-negative long value from an object. If this is */
1501 /* less than zero, it will raise an error */
1502 /******************************************************************************/
1503 {
1504  stringsize_t result; /* returned result */
1505 
1506  if (!unsignedNumberValue(result, precision))
1507  {
1508  /* raise the error */
1509  reportException(Error_Incorrect_method_nonnegative, kind, position, this);
1510  }
1511  return result;
1512 }
1513 
1514 
1516 /******************************************************************************/
1517 /* Function: Request an array value from an object. */
1518 /******************************************************************************/
1519 {
1520  if (this->isBaseClass()) /* primitive object? */
1521  {
1522  if (isOfClass(Array, this)) /* already an array? */
1523  return (RexxArray *)this; /* return directly, don't makearray */
1524  else
1525  return this->makeArray(); /* return the array value */
1526  }
1527  else /* return integer value of string */
1528  {
1529  return (RexxArray *)this->sendMessage(OREF_REQUEST, OREF_ARRAYSYM);
1530  }
1531 }
1532 
1534 /******************************************************************************/
1535 /* Function: Request a directory value from an object. */
1536 /******************************************************************************/
1537 {
1538  if (this->isBaseClass() && isOfClass(Directory, this)) return (RexxDirectory *)this;
1539  return (RexxDirectory *)this->sendMessage(OREF_REQUEST, OREF_DIRECTORY);
1540 }
1541 
1543 /******************************************************************************/
1544 /* Function: Retrieve the object name for a primitive object */
1545 /******************************************************************************/
1546 {
1547  ProtectedObject string_value; /* returned string value */
1548 
1549  RexxObject *scope = lastMethod()->getScope(); /* get the method's scope */
1550  /* get the object name variable */
1551  string_value = (RexxString *)this->getObjectVariable(OREF_NAME, scope);
1552  if ((RexxObject *)string_value == OREF_NULL)
1553  { /* no name? */
1554  if (this->isBaseClass()) /* primitive object? */
1555  {
1556  /* use fast path to default name */
1557  string_value = this->defaultName();
1558  }
1559  else /* go through the full search */
1560  {
1561  this->sendMessage(OREF_DEFAULTNAME, string_value);
1562  }
1563  }
1564  return(RexxString *)string_value; /* return the string value */
1565 }
1566 
1568 /******************************************************************************/
1569 /* Function: retrieve an objects default name value */
1570 /******************************************************************************/
1571 {
1572  RexxObject *scope; /* scope of the object */
1573 
1574  requiredArgument(name, OREF_positional, ARG_ONE); /* must have a name */
1575  scope = lastMethod()->getScope(); /* get the method's scope */
1576  /* get this as a string */
1577  name = (RexxObject *)stringArgument(name, OREF_positional, ARG_ONE);
1578  /* set the name */
1579  this->setObjectVariable(OREF_NAME, name, scope);
1580  return OREF_NULL; /* no return value */
1581 }
1582 
1584 /******************************************************************************/
1585 /* Function: Handle "final" string coercion level */
1586 /******************************************************************************/
1587 {
1588  /* use the class id as the default */
1589  /* name */
1590  RexxString *defaultname = this->behaviour->getOwningClass()->getId();
1591  /* check if it is from an enhanced */
1592  if (this->behaviour->isEnhanced())
1593  { /* class */
1594  /* return the 'enhanced' id */
1595  return defaultname->concatToCstring("enhanced ");
1596  }
1597  switch (defaultname->getCharC(0))
1598  { /* process based on first character*/
1599  case 'a': /* vowels */
1600  case 'A':
1601  case 'e':
1602  case 'E':
1603  case 'i':
1604  case 'I':
1605  case 'o':
1606  case 'O':
1607  case 'u':
1608  case 'U':
1609  /* prefix with "an" */
1610  defaultname = defaultname->concatToCstring("an ");
1611  break;
1612 
1613  default: /* consonants */
1614  /* prefix with "a" */
1615  defaultname = defaultname->concatToCstring("a ");
1616  break;
1617  }
1618  return defaultname; /* return that value */
1619 }
1620 
1622 /******************************************************************************/
1623 /* Function: Check for the presense of a method on the object */
1624 /******************************************************************************/
1625 {
1626  /* check the behaviour for the method*/
1627  return (this->behaviour->methodLookup(msgname) != OREF_NULL) ? TheTrueObject : TheFalseObject;
1628 }
1629 
1631 /******************************************************************************/
1632 /* Function: Return the class object associated with an object */
1633 /******************************************************************************/
1634 {
1635  /* just return class from behaviour */
1636  return this->behaviour->getOwningClass();
1637 }
1638 
1640  RexxString *msgname, /* name of the new method */
1641  RexxMethod *methobj, /* associated method object/code */
1642  RexxString *option)
1643  /******************************************************************************/
1644  /* Function: Add a new method to an object instance */
1645  /******************************************************************************/
1646 {
1647  /* get the message name as a string */
1648  msgname = stringArgument(msgname, OREF_positional, ARG_ONE)->upper();
1649  ProtectedObject p(msgname);
1650  if (option)
1651  {
1652  option = stringArgument(option, OREF_positional, ARG_THREE);
1653  if (!Utilities::strCaselessCompare("OBJECT", option->getStringData()))
1654  {
1655  // do nothing if OBJECT
1656  }
1657  else if (!Utilities::strCaselessCompare("FLOAT", option->getStringData()))
1658  {
1659  // "FLOAT" makes option a NULL pointer, causing the old default behaviour on setMethod...
1660  option = OREF_NULL;
1661  }
1662  else
1663  {
1664  RexxString *info = new_string("\"FLOAT\", \"OBJECT\"");
1665  ProtectedObject p(info);
1666  reportException(Error_Incorrect_call_list, OREF_SETMETHOD, OREF_positional, IntegerThree, info, option);
1667  }
1668  }
1669  ProtectedObject p2(option);
1670 
1671  if (methobj == OREF_NULL) /* we weren't passed a method, */
1672  {
1673  /* add a dummy method */
1674  methobj = (RexxMethod *)TheNilObject;
1675  }
1676  else if (!isOfClass(Method, methobj)) /* not a method type already? */
1677  {
1678  /* make one from a string or array */
1679  methobj = RexxMethod::newMethodObject(msgname, (RexxObject *)methobj, IntegerTwo, OREF_NULL);
1680  }
1681  this->defMethod(msgname, methobj, option); /* defMethod handles all the details */
1682  return OREF_NULL; /* no return value */
1683 }
1684 
1686  RexxString *msgname) /* target message name */
1687 /******************************************************************************/
1688 /* Function: Remove a method from an object instance */
1689 /******************************************************************************/
1690 {
1691  /* get the message name as a string */
1692  msgname = stringArgument(msgname, OREF_positional, ARG_ONE)->upper();
1693  ProtectedObject p(msgname);
1694  /* now just go remove this */
1695  this->behaviour->removeMethod(msgname);
1696  return OREF_NULL; /* no return value */
1697 }
1698 
1700  RexxString *className) /* target name of the class */
1701 /******************************************************************************/
1702 /* Function: Externalized version of the REQUEST method. This tries to */
1703 /* convert one class of object into another. */
1704 /******************************************************************************/
1705 {
1706  /* Verify we have a string parm */
1707  className = stringArgument(className, OREF_positional, ARG_ONE)->upper();
1708  ProtectedObject p1(className);
1709  RexxString *class_id = this->id()->upper(); /* get the class name in uppercase */
1710  ProtectedObject p2(class_id);
1711  /* of the same class? */
1712  if (className->strictEqual(class_id) == TheTrueObject)
1713  {
1714  return this; /* already converted */
1715  }
1716  /* Get "MAKE"||class methodname */
1717  RexxString *make_method = className->concatToCstring(CHAR_MAKE);
1718  /* find the MAKExxxx method */
1719  // RexxMethod *method = this->behaviour->methodLookup(make_method);
1720  RexxMethod *method = this->instanceMethod(make_method);
1721  /* have this method? */
1722  // if (method != OREF_NULL)
1723  if (method != TheNilObject)
1724  {
1725  /* Return its results */
1726  return this->sendMessage(make_method);
1727  }
1728  else /* No makeclass method */
1729  {
1730  return TheNilObject; /* Let user handle it */
1731  }
1732 }
1733 
1734 
1735 /**
1736  * Do a dynamic invocation of an object method.
1737  *
1738  * @param message The target message. This can be either a string message
1739  * name or a string/scope pair to do a qualified invocation.
1740  * @param arguments An array of arguments to used with the message invocation.
1741  *
1742  * @return The method result.
1743  */
1745  RexxObject **named_arglist, size_t named_argcount)
1746 {
1747  RexxString *messageName;
1748  RexxObject *startScope;
1749  // decode and validate the message input
1750  decodeMessageName(this, message, messageName, startScope);
1751  ProtectedObject m(messageName);
1752 
1753  arguments = arrayArgument(arguments, OREF_positional, ARG_TWO);
1754  ProtectedObject p(arguments);
1755  size_t count = arguments->size();
1756 
1757  // Named arguments
1758  // >>-sendWith(-messagename-,-arguments-+--------------------------+--)---><
1759  // +-,-namedArguments-:-exprd-+
1760 
1761  // use strict named arg namedArguments=.NIL
1762  NamedArguments expectedNamedArguments(1); // At most, one named argument
1763  expectedNamedArguments[0] = NamedArgument("NAMEDARGUMENTS", 1, TheNilObject); // At least 1 characters, default value = .NIL
1764  expectedNamedArguments.check(named_arglist, named_argcount, /*strict*/ true, /*extraAllowed*/ false);
1765 
1766  RexxDirectory *named_arguments_value = (RexxDirectory*)expectedNamedArguments[0].value;
1767  ProtectedObject p_named_arguments_value;
1768  size_t named_count = 0;
1769  if (named_arguments_value != OREF_NULL && named_arguments_value != TheNilObject)
1770  {
1771  /* get a directory version */
1772  named_arguments_value = named_arguments_value->requestDirectory();
1773  p_named_arguments_value = named_arguments_value; // GC protect
1774 
1775  /* not a directory item ? */
1776  if (named_arguments_value == TheNilObject)
1777  {
1778  reportException(Error_Execution_user_defined, "SENDWITH namedArguments must be a directory or NIL");
1779  }
1780  named_count = named_arguments_value->items();
1781  }
1782 
1783  RexxArray *new_arguments = arguments;
1784  ProtectedObject p_new_arguments;
1785  if (named_count != 0)
1786  {
1787  // Optimization: do a copy of the positional arguments only is some named arguments must be added
1788  new_arguments = (RexxArray *)arguments->copy();
1789  p_new_arguments = new_arguments;
1790  named_arguments_value->appendAllIndexesItemsTo(new_arguments, /*from*/ count+1); // from is 1-based index
1791  }
1792 
1793  ProtectedObject r;
1794  if (startScope == OREF_NULL)
1795  {
1796  this->messageSend(messageName, new_arguments->data(), count, named_count, r);
1797  }
1798  else
1799  {
1800  this->messageSend(messageName, new_arguments->data(), count, named_count, startScope, r);
1801  }
1802  return (RexxObject *)r;
1803 }
1804 
1805 
1806 /**
1807  * Do a dynamic invocation of an object method.
1808  *
1809  * @param arguments The variable arguments passed to the method. The first
1810  * argument is a required message target, which can be either
1811  * a string method name or an array containing a name/scope
1812  * pair. The remainder of the arguments are the message
1813  * arguments.
1814  * @param argCount
1815  *
1816  * @return The method result.
1817  */
1818 RexxObject *RexxObject::send(RexxObject **arguments, size_t argCount, size_t named_argCount)
1819 {
1820  if (argCount < 1) /* no arguments? */
1821  {
1822  missingArgument(OREF_positional, ARG_ONE); /* Yes, this is an error. */
1823  }
1824 
1825  RexxString *messageName;
1826  RexxObject *startScope;
1827  // decode and validate the message input
1828  decodeMessageName(this, arguments[0], messageName, startScope);
1829  ProtectedObject m(messageName);
1830 
1831  ProtectedObject r;
1832  if (startScope == OREF_NULL)
1833  {
1834  this->messageSend(messageName, arguments + 1, argCount - 1, named_argCount, r);
1835  }
1836  else
1837  {
1838  this->messageSend(messageName, arguments + 1, argCount - 1, named_argCount, startScope, r);
1839  }
1840  return (RexxObject *)r;
1841 }
1842 
1843 
1844 /**
1845  * Perform a start() using arguments provided in an
1846  * array wrapper.
1847  *
1848  * @param message The target message. This can be either a string, or an
1849  * array containing a string/scope coupling.
1850  * @param arguments The message arguments.
1851  *
1852  * @return The message object.
1853  */
1855  RexxObject **named_arglist, size_t named_argcount)
1856 {
1857  // the message is required
1858  requiredArgument(message, OREF_positional, ARG_ONE);
1859  // this is required and must be an array
1860  arguments = arrayArgument(arguments, OREF_positional, ARG_TWO);
1861  ProtectedObject p(arguments);
1862  size_t count = arguments->size();
1863 
1864  // Named arguments
1865  // >> -startWith(-messagename - , -arguments - +-------------------------- + -)---> <
1866  // +-, -namedArguments-:-exprd-+
1867 
1868  // use strict named arg namedArguments=.NIL
1869  NamedArguments expectedNamedArguments(1); // At most, one named argument
1870  expectedNamedArguments[0] = NamedArgument("NAMEDARGUMENTS", 1, TheNilObject); // At least 1 characters, default value = .NIL
1871  expectedNamedArguments.check(named_arglist, named_argcount, /*strict*/ true, /*extraAllowed*/ false);
1872  RexxDirectory *named_arguments_value = (RexxDirectory*)expectedNamedArguments[0].value;
1873 
1874  ProtectedObject p_named_arguments_value;
1875  size_t named_count = 0;
1876  if (named_arguments_value != OREF_NULL && named_arguments_value != TheNilObject)
1877  {
1878  /* get a directory version */
1879  named_arguments_value = named_arguments_value->requestDirectory();
1880  p_named_arguments_value = named_arguments_value; // GC protect
1881 
1882  /* not a directory item ? */
1883  if (named_arguments_value == TheNilObject)
1884  {
1885  reportException(Error_Execution_user_defined, "STARTWITH namedArguments must be a directory or NIL");
1886  }
1887  named_count = named_arguments_value->items();
1888  }
1889 
1890  RexxArray *new_arguments = arguments;
1891  ProtectedObject p_new_arguments;
1892  if (named_count != 0)
1893  {
1894  new_arguments = (RexxArray *)arguments->copy();
1895  p_new_arguments = new_arguments;
1896  named_arguments_value->appendAllIndexesItemsTo(new_arguments, /*from*/ count+1); // from is 1-based index
1897  }
1898 
1899  // the rest is handled by code common to startWith();
1900  return startCommon(message, new_arguments->data(), count, named_count);
1901 }
1902 
1903 
1904 /**
1905  * Run a message send in another thread.
1906  *
1907  * @param arguments The list of arguments. This is an open-ended argument
1908  * list. The first argument is the message, the remaining
1909  * arguments are the message arguments.
1910  * @param argCount The number of arguments we were invoked with.
1911  *
1912  * @return The count of arguments.
1913  */
1914 RexxMessage *RexxObject::start(RexxObject **arguments, size_t argCount, size_t named_argCount)
1915 {
1916  if (argCount < 1) /* no arguments? */
1917  {
1918  missingArgument(OREF_positional, ARG_ONE); /* Yes, this is an error. */
1919  }
1920  /* Get the message name. */
1921  RexxObject *message = arguments[0]; /* get the message . */
1922  /* Did we receive a message name */
1923  requiredArgument(message, OREF_positional, ARG_ONE);
1924  // the rest is handled by code common to startWith();
1925  return startCommon(message, arguments + 1, argCount - 1, named_argCount);
1926 }
1927 
1928 
1929 /**
1930  * A common method to process either a start() or a
1931  * startWith() method call.
1932  *
1933  * @param message The message name (which might be an array form)
1934  * @param arguments The array of arguments.
1935  * @param argCount The number of passed arguments.
1936  *
1937  * @return The message object spun off to process this message.
1938  */
1939 RexxMessage *RexxObject::startCommon(RexxObject *message, RexxObject **arguments, size_t argCount, size_t named_argCount)
1940 {
1941  RexxString *messageName;
1942  RexxObject *startScope;
1943  // decode and validate the message input
1944  decodeMessageName(this, message, messageName, startScope);
1945  ProtectedObject m(messageName);
1946 
1947  /* Create the new message object. */
1948  RexxMessage *newMessage = new RexxMessage(this, messageName, startScope, arguments, argCount, named_argCount);
1949  ProtectedObject p(newMessage);
1950  newMessage->start(OREF_NULL); /* Tell the message object to start */
1951  return newMessage; /* return the new message object */
1952 }
1953 
1954 
1955 /**
1956  * A static method that can be used to decode the
1957  * various message argument varieties used with start(),
1958  * startWith(), and the Message class new.
1959  *
1960  * @param message The input message. This can be a message name or an
1961  * array containing a message name/startscope pairing.
1962  * @param messageName
1963  * @param startScope
1964  */
1965 void RexxObject::decodeMessageName(RexxObject *target, RexxObject *message, RexxString *&messageName, RexxObject *&startScope)
1966 {
1967  // clear the starting scope
1968  startScope = OREF_NULL;
1969 
1970  /* if 1st arg is a string, we can do */
1971  /* this quickly */
1972  if (!isOfClass(String, message))
1973  {
1974  // this must be an array
1975  RexxArray *messageArray = arrayArgument(message, OREF_positional, ARG_ONE);
1976  ProtectedObject p(messageArray);
1977 
1978  // must be single dimension with two arguments
1979  if (messageArray->getDimension() != 1 || messageArray->size() != 2)
1980  {
1981  /* raise an error */
1983  }
1984  // get the message as a string in uppercase.
1985  messageName = stringArgument(messageArray->get(1), OREF_positional, ARG_ONE)->upper();
1986  startScope = messageArray->get(2);
1987  requiredArgument(startScope, OREF_positional, ARG_TWO);
1988 
1989  // validate the message creator now
1991  /* have an activation? */
1992  if (activation != OREF_NULL)
1993  {
1994  /* get the receiving object */
1995  RexxObject *sender = activation->getReceiver();
1996  if (sender != target) /* not the same receiver? */
1997  {
1998  /* this is an error */
2000  }
2001  }
2002  else
2003  {
2004  /* this is an error */
2006  }
2007  }
2008  else /* not an array as message. */
2009  {
2010  /* force to a string value */
2011  messageName = stringArgument(message, OREF_positional, ARG_ONE)->upper();
2012  }
2013 }
2014 
2015 
2017 /****************************************************************************/
2018 /* Function: Return the objects address as a HEX string (debugging only) */
2019 /****************************************************************************/
2020 {
2021  char buffer[20]; /* buffered address */
2022 
2023  sprintf(buffer, "%p", this); /* format this */
2024  /* and return a string */
2025  return(RexxString *)new_string(buffer, 8);
2026 }
2027 
2029 /****************************************************************************/
2030 /* Function: Tag an object as having an UNINIT method */
2031 /****************************************************************************/
2032 {
2033  /* tell the activity about this */
2035 }
2036 
2037 
2039  RexxObject **arguments, /* method arguments */
2040  size_t argumentsCount, /* the number of positional arguments*/
2041  size_t named_argumentsCount)
2042 /****************************************************************************/
2043 /* Function: Run a method on an object as if it was part of the object's */
2044 /* behaviour. */
2045 /****************************************************************************/
2046 {
2047  RexxArray *arglist = OREF_NULL; /* forwarded option string */
2048  RexxDirectory *argdirectory = OREF_NULL;
2049  RexxObject **argumentPtr = OREF_NULL; /* default to no arguments passed along */
2050  size_t argcount = 0; // the number of arguments in the array expra
2051  size_t named_argcount = 0; // the number of arguments in the directory exprd
2052 
2053  ProtectedObject p_arglist;
2054  ProtectedObject p_argdirectory;
2055 
2056  /*
2057  >>-run(-method-+-------------------------------------------------------+-)--><
2058  +-,-"Individual"---| Arguments |------------------------+
2059  +--+-------------------+--+--------------------------+--+
2060  +-,-"Array"-,-expra-+ +-,-namedArguments-:-exprd-+
2061  */
2062 
2063  // must have at least a first positional argument
2064  if (argumentsCount == 0)
2065  {
2066  missingArgument(OREF_positional, "method");
2067  }
2068 
2069  /* get the method object */
2070  RexxMethod *methobj = (RexxMethod *)arguments[0];
2071  requiredArgument(methobj, OREF_positional, ARG_ONE); /* make sure we have a method */
2072  if (!isOfClass(Method, methobj)) /* this a method object? */
2073  {
2074  /* create a method object */
2075  methobj = RexxMethod::newMethodObject(OREF_RUN, (RexxObject *)methobj, IntegerOne, OREF_NULL);
2076  /* set the correct scope */
2077  methobj->setScope((RexxClass *)TheNilObject);
2078  }
2079  else
2080  {
2081  /* ensure correct scope on method */
2082  methobj = methobj->newScope((RexxClass *)TheNilObject);
2083  }
2084  // we need to save this, since we might be working off of a newly created
2085  // one or a copy
2086  ProtectedObject p(methobj);
2087 
2088  char option = ' '; // No option by default
2089  if (argumentsCount > 1) /* if any positional arguments passed */
2090  {
2091  /* get the 1st one, its the option */
2092  RexxString *optionString = (RexxString *)arguments[1];
2093  /* this is now required */
2094  optionString = stringArgument(optionString, OREF_positional, ARG_TWO);
2095  option = toupper(optionString->getCharC(0));
2096  /* process the different options */
2097  switch (option)
2098  {
2099  case 'A': /* args are an array */
2100  {
2101  /* so they say, make sure we have an */
2102  /* array and we were only passed 3 */
2103  /* args */
2104  if (argumentsCount < 3) /* not enough arguments? */
2105  {
2106  missingArgument(OREF_positional, ARG_THREE); /* this is an error*/
2107  }
2108  if (argumentsCount > 3) /* too many arguments? */
2109  {
2111  }
2112 
2113  /* now get the array */
2114  RexxArray *arglistUser = (RexxArray *)arguments[2];
2115  /* force to array form */
2116  arglist = REQUEST_ARRAY(arglistUser);
2117  p_arglist = arglist;
2118  /* not an array? */
2119  if (arglist == TheNilObject || arglist->getDimension() != 1)
2120  {
2121  /* raise an error */
2122  reportException(Error_Incorrect_method_noarray, OREF_positional, arguments[2]);
2123  }
2124 
2125  /* grab the argument information */
2126  argumentPtr = arglist->data();
2127  argcount = arglist->size();
2128 
2129  if (arglist == arglistUser)
2130  {
2131  // To not impact the array passed by the user, must create a copy because will need to append the named arguments
2132  arglist = (RexxArray *)arglist->copy();
2133  p_arglist = arglist;
2134  }
2135  break;
2136  }
2137 
2138  case 'I': /* args are "strung out" */
2139  /* point to the array data for the second value */
2140  argumentPtr = arguments + 2;
2141  argcount = argumentsCount - 2;
2142  break;
2143 
2144  default:
2145  /* invalid option */
2147  break;
2148  }
2149  }
2150 
2151  if (option == 'I')
2152  {
2153  // Nothing to do, the named arguments are supported directly
2154  named_argcount = named_argumentsCount;
2155  }
2156  else
2157  {
2158  // The directory of named arguments is passed with the named argument 'NAMEDARGUMENT' (optional)
2159 
2160  // use strict named arg namedArguments=.NIL
2161  NamedArguments expectedNamedArguments(1); // At most, one named argument
2162  expectedNamedArguments[0] = NamedArgument("NAMEDARGUMENTS", 1, TheNilObject); // At least 1 character, default value = .NIL
2163  expectedNamedArguments.check(arguments + argumentsCount, named_argumentsCount, /*strict*/ true, /*extraAllowed*/ false);
2164 
2165  argdirectory = (RexxDirectory *)expectedNamedArguments[0].value;
2166  if (argdirectory != TheNilObject)
2167  {
2168  argdirectory = argdirectory->requestDirectory();
2169  p_argdirectory = argdirectory;
2170  if (argdirectory == TheNilObject)
2171  {
2172  reportException(Error_Execution_user_defined, "RUN namedArguments must be a directory or NIL");
2173  }
2174  named_argcount = argdirectory->items();
2175  }
2176 
2177  if (named_argcount != 0)
2178  {
2179  if (arglist == OREF_NULL)
2180  {
2181  // Here argcount == 0
2182  arglist = new_array(2 * named_argcount);
2183  p_arglist = arglist;
2184  }
2185  argdirectory->appendAllIndexesItemsTo(arglist, /*from*/ argcount+1); // argcount+1 because array.put use 1-based index
2186  argumentPtr = arglist->data();
2187  }
2188  }
2189 
2190  ProtectedObject result;
2191  /* now just run the method.... */
2192  methobj->run(ActivityManager::currentActivity, this, OREF_NONE, argumentPtr, argcount, named_argcount, result);
2193  return (RexxObject *)result;
2194 }
2195 
2197  RexxDirectory *methods) /* new table of methods */
2198 /****************************************************************************/
2199 /* Function: Add a table of methods to an object's behaviour */
2200 /****************************************************************************/
2201 {
2202  /* make a copy of the behaviour */
2203  OrefSet(this, this->behaviour, (RexxBehaviour *)this->behaviour->copy());
2204  /* loop through the list of methods */
2205  for (HashLink i = methods->first(); methods->available(i); i = methods->next(i))
2206  {
2207  /* Get the methjod Object */
2208  RexxMethod *method = (RexxMethod *)methods->value(i);
2209  if (method != TheNilObject) /* not a removal? */
2210  {
2211  /* set a new scope on this */
2212  method = method->newScope((RexxClass *)this);
2213  }
2214  else
2215  {
2216  method = OREF_NULL; // this is a method removal
2217  }
2218  /* Get the name for this method */
2219  RexxString *name = (RexxString *)methods->index(i);
2220  name = name->upper(); /* make sure the name is upperCase. */
2221  ProtectedObject p(name);
2222  /* add this method to the object's */
2223  /* behaviour */
2224  this->behaviour->define(name, method);
2225  }
2226  return OREF_NULL;
2227 }
2228 
2230  RexxString *msgname, /* new method name */
2231  RexxMethod *methobj, /* associated method object */
2232  RexxString *option)
2233  /****************************************************************************/
2234  /* Function: Add a method to an object's behaviour */
2235  /****************************************************************************/
2236 {
2237  RexxMethod *methcopy; /* copy of the original method */
2238  /* default scope "FLOAT" */
2239  RexxClass *targetClass = (RexxClass*)TheNilObject;
2240 
2241  msgname = msgname->upper(); /* add this as an uppercase name */
2242  ProtectedObject p(msgname);
2243  if (methobj != TheNilObject) /* not a removal? */
2244  {
2245  /* got an option? */
2246  if (option)
2247  {
2248  if (!Utilities::strCaselessCompare("OBJECT", option->getStringData()))
2249  {
2250  targetClass = this->behaviour->getOwningClass();
2251  }
2252  else
2253  {
2254  RexxString *info = new_string("\"FLOAT\", \"OBJECT\"");
2255  ProtectedObject p(info);
2256  reportException(Error_Incorrect_call_list, OREF_SETMETHOD, OREF_positional, IntegerThree, info, option);
2257  }
2258  }
2259  /* set a new scope on this */
2260  methcopy = methobj->newScope(targetClass);
2261  }
2262  else
2263  {
2264  /* no real method added */
2265  methcopy = (RexxMethod *)TheNilObject;
2266  }
2267  ProtectedObject p1(methcopy);
2268  /* is this the first added method? */
2270  {
2271 
2272  /* copy primitive behaviour object and define the method, a copy is made to */
2273  /* ensure that we don't update the behaviour of any other object, since they*/
2274  /* may have been sharing the mvd. */
2275  OrefSet(this, this->behaviour, (RexxBehaviour *)this->behaviour->copy());
2276  }
2277  /* now add this to the behaviour */
2278  this->behaviour->addMethod(msgname, methcopy);
2279  /* adding an UNINIT method to obj? */
2280  if (methobj != TheNilObject && msgname->strCompare(CHAR_UNINIT))
2281  {
2282  this->hasUninit(); /* yes, mark it as such */
2283  }
2284  return OREF_NULL;
2285 }
2286 
2288 /******************************************************************************/
2289 /* Function: Return the object's primitive type number */
2290 /******************************************************************************/
2291 {
2292  return this->behaviour->getClassType();
2293 }
2294 
2296 /******************************************************************************/
2297 /* Function: Remove an UNINIT method from an object */
2298 /******************************************************************************/
2299 {
2301 }
2302 
2303 /**
2304  * Search through all of the scopes looking for a variable
2305  * of the given name. This will return the first match.
2306  *
2307  * @param name The target name.
2308  *
2309  * @return The value associated with the variable or OREF_NULL if
2310  * no matching variable is found.
2311  */
2313 {
2314  RexxVariableDictionary *dictionary = objectVariables;
2315  while (dictionary != OREF_NULL)
2316  {
2317  // see if this dictionary has the variable
2318  RexxObject *val = dictionary->realValue(name);
2319  // return this if it exists
2320  if (val != OREF_NULL)
2321  {
2322  return val;
2323  }
2324  // step to the next dictionary in the chain
2325  dictionary = dictionary->getNextDictionary();
2326  }
2327  return OREF_NULL; // no variable found
2328 }
2329 
2330 
2332  RexxString * name, /* variable name (name object) */
2333  RexxObject * scope) /* target variable scope */
2334  /******************************************************************************/
2335  /* Function: retrieve the value of an object variable. This name */
2336  /* must be a name object, and only simple variables are supported.*/
2337  /* If the variable has not been assigned a value, then OREF_NULL */
2338  /* is returned. */
2339  /******************************************************************************/
2340 {
2341  if (OREF_NULL == scope) /* were we passed a scope for lookup */
2342  {
2343  scope = this; /* no, we use our own. */
2344  }
2345  /* get the ovd for our scope level */
2346  RexxVariableDictionary *ovd = this->getObjectVariables(scope);
2347  return ovd->realValue(name); /* get the real variable value */
2348 }
2349 
2351  RexxString *name, /* variable name (name object) */
2352  RexxObject *value, /* new variable value */
2353  RexxObject *scope) /* target variable scope */
2354  /******************************************************************************/
2355  /* Function: assign a new value to a object variable. This name */
2356  /* must be a name object, and only simple variables are supported.*/
2357  /******************************************************************************/
2358 {
2359  if (OREF_NULL == scope) /* were we passed a scope for lookup */
2360  {
2361  scope = this; /* no, we use our own. */
2362  }
2363  /* get the ovd for our scope level */
2364  RexxVariableDictionary *ovd = this->getObjectVariables(scope);
2365  ovd->set(name, value); /* do the variable assignment */
2366 }
2367 
2369  RexxVariableDictionary *dictionary)/* new variable set */
2370 /******************************************************************************/
2371 /* Function: Add a new variable dictionary to an object with a given scope */
2372 /******************************************************************************/
2373 {
2374  /* chain any existing dictionaries off of the new one */
2375  dictionary->setNextDictionary(objectVariables);
2376  /* make this the new head of the chain */
2377  OrefSet(this, objectVariables, dictionary);
2378 }
2379 
2381  RexxObject *startScope) /* target scope */
2382  /******************************************************************************/
2383  /* Function: Find the scope of a method's super class */
2384  /******************************************************************************/
2385 {
2386  return this->behaviour->superScope(startScope);
2387 }
2388 
2390  RexxString *msgName, /* target message name */
2391  RexxObject *startScope) /* starting lookup scope */
2392  /******************************************************************************/
2393  /* Function: Find a method using the given starting scope information */
2394  /******************************************************************************/
2395 {
2396  return this->behaviour->superMethod(msgName, startScope);
2397 }
2398 
2400  RexxObject *scope) /* required dictionary scope */
2401 /******************************************************************************/
2402 /* Function: Retrieve an object dictionary for a given scope */
2403 /******************************************************************************/
2404 {
2405  RexxVariableDictionary *dictionary = objectVariables; /* get the head of the chain */
2406  while (dictionary != OREF_NULL)
2407  { /* search for a scope match */
2408  /* if we've found a match, return it */
2409  if (dictionary->isScope(scope))
2410  {
2411  return dictionary;
2412  }
2413  dictionary = dictionary->getNextDictionary();
2414  }
2415 
2416  /* just create a new vdict */
2417  dictionary = new_objectVariableDictionary(scope);
2418  /* chain any existing dictionaries off of the new one */
2419  dictionary->setNextDictionary(objectVariables);
2420  /* make this the new head of the chain */
2421  OrefSet(this, objectVariables, dictionary);
2422  this->setHasReferences(); /* we now have references */
2423  return dictionary; /* return the correct ovd */
2424 }
2425 
2426 /**
2427  * Obtain a guard lock on the target object at the given scope.
2428  *
2429  * @param activity The activity we're running on.
2430  * @param scope The scope that needs to be locked.
2431  */
2433 {
2435  vdict->reserve(activity);
2436 }
2437 
2438 
2439 /**
2440  * Release a guard lock on the target object at the given scope.
2441  *
2442  * @param activity The activity we're running on.
2443  * @param scope The scope that needs to be released.
2444  */
2446 {
2448  vdict->release(activity);
2449 }
2450 
2451 
2452 
2453 const char *RexxObject::idString(void)
2454 /******************************************************************************/
2455 /* Function: Return a pointer to the object's string value */
2456 /******************************************************************************/
2457 {
2458  RexxString *classId = this->id(); /* get the id string */
2459  if (classId == OREF_NULL) /* internal class? */
2460  {
2461  return "unknown Class"; /* return an unknown identifier */
2462  }
2463  else
2464  {
2465  return classId->getStringData(); /* return the actual class ID */
2466  }
2467 }
2468 
2470 /******************************************************************************/
2471 /* Function: Get the class string name */
2472 /******************************************************************************/
2473 {
2474  /* get the class */
2475  RexxClass *createClass = this->behaviourObject()->getOwningClass();
2476  if (createClass == OREF_NULL) /* no class object? */
2477  {
2478  return OREF_NULL; /* return nothing */
2479  }
2480  else
2481  {
2482  return createClass->getId(); /* return the class id string */
2483  }
2484 }
2485 
2487 /******************************************************************************/
2488 /* Function: Exported Object INIT method */
2489 /******************************************************************************/
2490 {
2491  return OREF_NULL; /* this is basically a no-op */
2492 }
2493 
2494 
2495 /**
2496  * Return a unique identity hash value for this object. This
2497  * hash will be unique among the set of currently active Rexx
2498  * objects.
2499  *
2500  * @return The identity hash value as an integer object.
2501  */
2503 {
2504  return new_integer(this->identityHash());
2505 }
2506 
2507 
2509 /******************************************************************************/
2510 /* Function: Exported Object INIT method */
2511 /******************************************************************************/
2512 {
2513  if (TheTrueObject == this->hasMethod(OREF_UNINIT))
2514  {
2515  this->sendMessage(OREF_UNINIT);
2516  }
2517 
2518 }
2519 
2521 /******************************************************************************/
2522 /* Function: Check to see if an object has an UNINIT method. */
2523 /******************************************************************************/
2524 {
2525  return TheTrueObject == this->hasMethod(OREF_UNINIT);
2526 }
2527 
2528 RexxObject *RexxObject::newRexx(RexxObject **arguments, size_t argCount, size_t named_argCount)
2529 /******************************************************************************/
2530 /* Function: Exposed REXX NEW method */
2531 /******************************************************************************/
2532 {
2533  return new ((RexxClass *)this, arguments, argCount, named_argCount) RexxObject;
2534 }
2535 
2536 
2538 /******************************************************************************/
2539 /* Arguments: Clone an object, and set up its header. This method should */
2540 /* be called by other _copy methods instead of using new_object */
2541 /* and memcpy, so that memory can properly initialize the new */
2542 /* object's header to avoid early gc. */
2543 /* */
2544 /* Returned: A new object copied from objr, but set to be live to avoid */
2545 /* being garbage collected on a pending sweep. */
2546 /******************************************************************************/
2547 {
2548  // we need an identically sized object
2549  size_t size = getObjectSize();
2550  RexxObject *cloneObj = new_object(size);
2551  // copy the object header. That's the only piece of this we're not going to keep from
2552  // the old object.
2553  ObjectHeader newHeader = cloneObj->header;
2554  // copy everything but the object header over from the source object.
2555  memcpy((char *)cloneObj, (char *)this, size);
2556  // restore the new header to the cloned object
2557  cloneObj->header = newHeader;
2558  return cloneObj;
2559 }
2560 
2561 #undef operatorMethod
2562 #define operatorMethod(name, message) RexxObject * RexxObject::name(RexxObject *operand) \
2563 {\
2564  ProtectedObject result; /* returned result */\
2565  /* do a real message send */\
2566  this->messageSend(OREF_##message, &operand, 1, 0, result); \
2567  if ((RexxObject *)result == OREF_NULL) /* in an expression and need a result*/ \
2568  { \
2569  RexxObject *self = this; \
2570  bool alternativeResult = operand->messageSend(OREF_##message##_RIGHT, &self, 1, 0, result, false); \
2571  if (alternativeResult && (RexxObject *)result != OREF_NULL) return (RexxObject *)result; \
2572  /* need to raise an exception */ \
2573  reportException(Error_No_result_object_message, OREF_##message); \
2574  } \
2575  return (RexxObject *)result; /* return the final result */ \
2576 }\
2577 
2578 
2579 #undef prefixOperatorMethod
2580 #define prefixOperatorMethod(name, message) RexxObject * RexxObject::name(RexxObject *operand) \
2581 {\
2582  ProtectedObject result; /* returned result */\
2583  /* do a real message send */\
2584  this->messageSend(OREF_##message, &operand, operand == OREF_NULL ? 0 : 1, 0, result); \
2585  if ((RexxObject *)result == OREF_NULL) /* in an expression and need a result*/ \
2586  { \
2587  if (operand != OREF_NULL) \
2588  { \
2589  RexxObject *self = this; \
2590  bool alternativeResult = operand->messageSend(OREF_##message##_RIGHT, &self, 1, 0, result, false); \
2591  if (alternativeResult && (RexxObject *)result != OREF_NULL) return (RexxObject *)result; \
2592  } \
2593  /* need to raise an exception */ \
2594  reportException(Error_No_result_object_message, OREF_##message); \
2595  } \
2596  return (RexxObject *)result; /* return the final result */ \
2597 }\
2598 
2599 
2600 prefixOperatorMethod(operator_plus, PLUS)
2601 prefixOperatorMethod(operator_minus, SUBTRACT)
2602 operatorMethod(operator_multiply, MULTIPLY)
2603 operatorMethod(operator_divide, DIVIDE)
2604 operatorMethod(operator_integerDivide, INTDIV)
2605 operatorMethod(operator_remainder, REMAINDER)
2606 operatorMethod(operator_power, POWER)
2607 operatorMethod(operator_abuttal, NULLSTRING)
2608 operatorMethod(operator_concat, CONCATENATE)
2609 operatorMethod(operator_concatBlank, BLANK)
2610 operatorMethod(operator_equal, EQUAL)
2611 operatorMethod(operator_notEqual, BACKSLASH_EQUAL)
2612 operatorMethod(operator_isGreaterThan, GREATERTHAN)
2613 operatorMethod(operator_isBackslashGreaterThan, BACKSLASH_GREATERTHAN)
2614 operatorMethod(operator_isLessThan, LESSTHAN)
2615 operatorMethod(operator_isBackslashLessThan, BACKSLASH_LESSTHAN)
2616 operatorMethod(operator_isGreaterOrEqual, GREATERTHAN_EQUAL)
2617 operatorMethod(operator_isLessOrEqual, LESSTHAN_EQUAL)
2618 operatorMethod(operator_strictEqual, STRICT_EQUAL)
2619 operatorMethod(operator_strictNotEqual, STRICT_BACKSLASH_EQUAL)
2620 operatorMethod(operator_strictGreaterThan, STRICT_GREATERTHAN)
2621 operatorMethod(operator_strictBackslashGreaterThan, STRICT_BACKSLASH_GREATERTHAN)
2622 operatorMethod(operator_strictLessThan, STRICT_LESSTHAN)
2623 operatorMethod(operator_strictBackslashLessThan, STRICT_BACKSLASH_LESSTHAN)
2624 operatorMethod(operator_strictGreaterOrEqual, STRICT_GREATERTHAN_EQUAL)
2625 operatorMethod(operator_strictLessOrEqual, STRICT_LESSTHAN_EQUAL)
2626 operatorMethod(operator_lessThanGreaterThan, LESSTHAN_GREATERTHAN)
2627 operatorMethod(operator_greaterThanLessThan, GREATERTHAN_LESSTHAN)
2628 operatorMethod(operator_and, AND)
2629 operatorMethod(operator_or, OR)
2630 operatorMethod(operator_xor, XOR)
2631 prefixOperatorMethod(operator_not, BACKSLASH)
2632 
2633 void *RexxObject::operator new(size_t size, RexxClass *classObject)
2634 /******************************************************************************/
2635 /* Function: Create a new translator object */
2636 /******************************************************************************/
2637 {
2638  /* get storage for new object */
2639  RexxObject *newObject = (RexxObject *)new_object(size);
2640  // the virtual function table is still object, but the behaviour is whatever
2641  // the class object defines.
2642  newObject->setBehaviour(classObject->getInstanceBehaviour());
2643  // the hash value and nulled object table was handled by new_object();
2644 
2645  if (classObject->hasUninitDefined() || classObject->parentHasUninitDefined())
2646  { /* or parent has one */
2647  newObject->hasUninit();
2648  }
2649 
2650  return(void *)newObject; /* Initialize the new object */
2651 }
2652 
2653 
2654 void *RexxObject::operator new(size_t size, RexxClass *classObject, RexxObject **args, size_t argCount, size_t named_argCount)
2655 /******************************************************************************/
2656 /* Function: Create a new instance of object */
2657 /******************************************************************************/
2658 {
2659  /* create a new object */
2660  ProtectedObject newObject(new (classObject) RexxObject);
2661  /* now drive the user INIT */
2662  ((RexxObject *)newObject)->sendMessage(OREF_INIT, args, argCount, named_argCount);
2663  return(RexxObject *)newObject; /* and returnthe new object */
2664 }
2665 
2666 
2667 /**
2668  * Concatentation operation supported by the Object class. This
2669  * converts the object into a string form, then asks the
2670  * converted object to perform the concatenaton.
2671  *
2672  * @param otherObj The object to concatenate.
2673  *
2674  * @return The concatenation result.
2675  */
2677 {
2678  RexxString *alias = (RexxString *)REQUEST_STRING(this);
2679  ProtectedObject p(alias);
2680  return alias->concatRexx(otherObj);
2681 }
2682 
2683 
2684 /**
2685  * Blank concatentation operation supported by the Object class.
2686  * This converts the object into a string form, then asks the
2687  * converted object to perform the concatenaton.
2688  *
2689  * @param otherObj The object to concatenate.
2690  *
2691  * @return The concatenation result.
2692  */
2694 {
2695  RexxString *alias = (RexxString *)REQUEST_STRING(this);
2696  ProtectedObject p(alias);
2697  return alias->concatBlank(otherObj);
2698 }
2699 
2700 
2702 /******************************************************************************/
2703 /* Function: Exported access to an object virtual function */
2704 /******************************************************************************/
2705 {
2706  return this->stringValue(); /* forward to the virtual function */
2707 }
2708 
2710 /******************************************************************************/
2711 /* Function: Exported access to an object virtual function */
2712 /******************************************************************************/
2713 {
2714  return this->makeString(); /* forward to the virtual function */
2715 }
2716 
2718 /******************************************************************************/
2719 /* Function: Exported access to an object virtual function */
2720 /******************************************************************************/
2721 {
2722  return this->makeArray(); /* forward to the virtual function */
2723 }
2724 
2726 /******************************************************************************/
2727 /* Function: Exported access to an object virtual function */
2728 /******************************************************************************/
2729 {
2730  return this->defaultName(); /* forward to the virtual function */
2731 }
2732 
2734 /******************************************************************************/
2735 /* Function: Exported access to an object virtual function */
2736 /******************************************************************************/
2737 {
2738  return this->copy(); /* forward to the virtual function */
2739 }
2740 
2742  RexxString *message, /* unknown message */
2743  RexxArray *arguments, /* message arguments */
2744  RexxObject **named_arglist,
2745  size_t named_argcount)
2746 /******************************************************************************/
2747 /* Function: Exported access to an object virtual function */
2748 /******************************************************************************/
2749 {
2750  // use strict named arg namedArguments=.NIL
2751  NamedArguments expectedNamedArguments(1); // At most, one named argument
2752  expectedNamedArguments[0] = NamedArgument("NAMEDARGUMENTS", 1, TheNilObject); // At least 1 characters, default value = .NIL
2753  expectedNamedArguments.check(named_arglist, named_argcount, /*strict*/ true, /*extraAllowed*/ false);
2754  RexxDirectory *namedArguments = (RexxDirectory*)expectedNamedArguments[0].value;
2755 
2756  /* forward to the virtual function */
2757  return this->unknown(message, arguments, namedArguments);
2758 }
2759 
2761  RexxString *message) /* method name */
2762 /******************************************************************************/
2763 /* Function: Exported access to an object virtual function */
2764 /******************************************************************************/
2765 {
2766  message = stringArgument(message, OREF_positional, ARG_ONE)->upper();
2767  return this->hasMethod(message); /* forward to the virtual function */
2768 }
2769 
2771 /******************************************************************************/
2772 /* Function: give a formatted print of object information. */
2773 /******************************************************************************/
2774 {
2775  printf("Object at %p, of type %d\n", this, (int)this->getObjectTypeNumber());
2776 }
2777 
2778 /**
2779  * Create the NIL object instance.
2780  */
2782 {
2783  // use the initial identify hash and save this.
2784  hashValue = identityHash();
2785 }
2786 
2787 /**
2788  * Override of the default hash value method.
2789  */
2791 {
2792  return hashValue;
2793 }
2794 
2795 
2796 /**
2797  * Attempt to get a CSELF value from an object instance
2798  * for a native context.
2799  *
2800  * @return An unwrapperd CSELF value, if one can be found.
2801  */
2803 {
2804  // try for the variable value
2805  RexxObject *C_self = getObjectVariable(OREF_CSELF);
2806  // if we found one, validate for unwrappering
2807  if (C_self != OREF_NULL)
2808  {
2809  // if this is a pointer, then unwrapper the value
2810  if (C_self->isInstanceOf(ThePointerClass))
2811  {
2812  return ((RexxPointer *)C_self)->pointer();
2813  }
2814  // this could be a containing buffer instance as well
2815  else if (C_self->isInstanceOf(TheBufferClass))
2816  {
2817  // return a pointer to the buffer beginning
2818  return(void *)((RexxBuffer *)C_self)->getData();
2819  }
2820  }
2821  return NULL; /* no object available */
2822 }
2823 
2824 
2825 /**
2826  * Attempt to get a CSELF value from an object instance,
2827  * starting from a given scope value and checking each of the
2828  * super scopes for the class
2829  *
2830  * @param scope The starting scope for the search.
2831  *
2832  * @return An unwrappered CSELF value, if one can be found.
2833  */
2835 {
2836  while (scope != TheNilObject)
2837  {
2838  // try for the variable value
2839  RexxObject *C_self = getObjectVariable(OREF_CSELF, scope);
2840  // if we found one, validate for unwrappering
2841  if (C_self != OREF_NULL)
2842  {
2843  // if this is a pointer, then unwrapper the value
2844  if (C_self->isInstanceOf(ThePointerClass))
2845  {
2846  return ((RexxPointer *)C_self)->pointer();
2847  }
2848  // this could be a containing buffer instance as well
2849  else if (C_self->isInstanceOf(TheBufferClass))
2850  {
2851  // return a pointer to the buffer beginning
2852  return(void *)((RexxBuffer *)C_self)->getData();
2853  }
2854  }
2855  // step to the next scope
2856  scope = this->superScope(scope);
2857  }
2858  return NULL; /* no object available */
2859 }
2860 
2861 
2862 /**
2863  * new operator for creating a RexxNilObject
2864  */
2865 void *RexxNilObject::operator new(size_t size)
2866 {
2867  // At this point, this will be an instance of object. After we've removed
2868  // some of the methods during setup but before the image save, we'll update the
2869  // behaviour type information so that it will restore with the correct virtual
2870  // function table pointer.
2871  RexxObject *newObj = new_object(size, T_Object);
2872  // we need to switch the virtual method table pointer new.
2874  return newObj;
2875 }
2876 
2877 
2879 {
2880  NULL,
2881  (PCPPM)&RexxObject::operator_plus, // "+"
2882  (PCPPM)&RexxObject::operator_minus, // "-"
2883  (PCPPM)&RexxObject::operator_multiply, // "*"
2884  (PCPPM)&RexxObject::operator_divide, // "/"
2885  (PCPPM)&RexxObject::operator_integerDivide, // "%"
2886  (PCPPM)&RexxObject::operator_remainder, // "//"
2887  (PCPPM)&RexxObject::operator_power, // "**"
2888  (PCPPM)&RexxObject::operator_abuttal, // ""
2889  (PCPPM)&RexxObject::operator_concat, // "||"
2890  (PCPPM)&RexxObject::operator_concatBlank, // " "
2891  (PCPPM)&RexxObject::operator_equal, // "="
2892  (PCPPM)&RexxObject::operator_notEqual, // "\="
2893  (PCPPM)&RexxObject::operator_isGreaterThan, // ">"
2894  (PCPPM)&RexxObject::operator_isBackslashGreaterThan, // ">"
2895  (PCPPM)&RexxObject::operator_isLessThan, // "<"
2896  (PCPPM)&RexxObject::operator_isBackslashLessThan, // "<"
2897  (PCPPM)&RexxObject::operator_isGreaterOrEqual, // ">="
2898  (PCPPM)&RexxObject::operator_isLessOrEqual, // "<="
2899  (PCPPM)&RexxObject::operator_strictEqual, // "=="
2900  (PCPPM)&RexxObject::operator_strictNotEqual, // "\=="
2901  (PCPPM)&RexxObject::operator_strictGreaterThan, // ">>"
2902  (PCPPM)&RexxObject::operator_strictBackslashGreaterThan, // ">>"
2903  (PCPPM)&RexxObject::operator_strictLessThan, // "<<"
2904  (PCPPM)&RexxObject::operator_strictBackslashLessThan, // "<<"
2905  (PCPPM)&RexxObject::operator_strictGreaterOrEqual, // ">>="
2906  (PCPPM)&RexxObject::operator_strictLessOrEqual, // "<<="
2907  (PCPPM)&RexxObject::operator_lessThanGreaterThan, // "<>"
2908  (PCPPM)&RexxObject::operator_greaterThanLessThan, // "><"
2909  (PCPPM)&RexxObject::operator_and, // "&"
2910  (PCPPM)&RexxObject::operator_or, // "|"
2911  (PCPPM)&RexxObject::operator_xor, // "&&"
2912  (PCPPM)&RexxObject::operator_not, // "\"
2913 };
2914 
void reportNomethod(RexxString *message, RexxObject *receiver)
void reportException(wholenumber_t error)
RexxMethod * lastMethod()
void missingArgument(RexxString *kind, size_t argumentPosition)
RexxArray * new_array(size_t s)
Definition: ArrayClass.hpp:259
@ T_NilObject
@ T_Object
RexxInteger * new_integer(wholenumber_t v)
#define operatorMethod(name, message)
#define prefixOperatorMethod(name, message)
RexxObject *(RexxObject::* PCPPM)()
size_t HashCode
Definition: ObjectClass.hpp:77
#define OREF_NULL
Definition: RexxCore.h:60
#define IntegerThree
Definition: RexxCore.h:192
RexxString * stringArgument(RexxObject *object, RexxString *kind, size_t position)
Definition: RexxCore.h:303
RexxArray * REQUEST_ARRAY(RexxObject *obj)
Definition: RexxCore.h:469
RexxString * REQUEST_STRING(RexxObject *object)
Definition: RexxCore.h:283
#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 TheBufferClass
Definition: RexxCore.h:168
#define IntegerTwo
Definition: RexxCore.h:191
#define isOfClass(t, r)
Definition: RexxCore.h:212
#define ThePointerClass
Definition: RexxCore.h:167
#define TheNilObject
Definition: RexxCore.h:181
#define TheFalseObject
Definition: RexxCore.h:185
#define isOfClassType(t, r)
Definition: RexxCore.h:213
const int ARG_ONE
Definition: RexxCore.h:80
RexxArray * arrayArgument(RexxObject *object, RexxString *kind, size_t position)
Definition: RexxCore.h:407
void requiredArgument(RexxObject *object, RexxString *kind, size_t position)
Definition: RexxCore.h:291
#define Error_Execution_super
#define Error_Logical_value_method
#define Error_Incorrect_method_option
#define Error_Execution_user_defined
#define Error_Incorrect_method_positive
#define Error_No_result_object_message
#define Error_Incorrect_method_nostring
#define Error_Incorrect_method_nonnegative
#define Error_Incorrect_call_list
#define Error_Incorrect_method_message
#define Error_Incorrect_method_whole
#define Error_Incorrect_method_maxarg
#define Error_Invalid_whole_number_compareto
#define Error_Incorrect_method_noarray
#define Error_Invalid_argument_string
size_t HashLink
RexxMemory memoryObject
Definition: RexxMemory.cpp:85
#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
RexxVariableDictionary * new_objectVariableDictionary(RexxObject *s)
RexxString * new_proxy(const char *name)
RexxString * new_string(const char *s, stringsizeB_t bl, sizeC_t cl=-1)
static RexxActivity *volatile currentActivity
void check(RexxObject **namedArglist, size_t namedArgCount, bool strict, bool extraAllowed, size_t minimumRequired=0)
virtual RexxObject * getReceiver()
SecurityManager * getEffectiveSecurityManager()
void checkStackSpace()
RexxActivationBase * getTopStackFrame()
bool raiseCondition(RexxString *, RexxObject *, RexxString *, RexxObject *, RexxObject *)
size_t getDimension()
Definition: ArrayClass.cpp:693
void put(RexxObject *eref, size_t pos)
Definition: ArrayClass.cpp:208
RexxObject * copy()
Definition: ArrayClass.cpp:122
size_t size()
Definition: ArrayClass.hpp:202
RexxObject * get(size_t pos)
Definition: ArrayClass.hpp:203
RexxObject ** data()
Definition: ArrayClass.hpp:204
RexxMethod * methodLookup(RexxString *)
RexxTable * getMethodDictionary()
RexxObject * define(RexxString *, RexxMethod *)
RexxObject * copy()
void removeMethod(RexxString *)
RexxClass * getOwningClass()
RexxSupplier * getMethods(RexxObject *scope)
RexxTable * getInstanceMethodDictionary()
RexxMethod * superMethod(RexxString *, RexxObject *)
RexxObject * superScope(RexxObject *)
void addMethod(RexxString *, RexxMethod *)
size_t getClassType()
bool isCompatibleWith(RexxClass *other)
RexxString * getId()
Definition: ClassClass.cpp:254
size_t appendAllIndexesItemsTo(RexxArray *array, size_t from)
static RexxDirectory * fromIndexItemArray(RexxObject **arglist, size_t count)
bool available(HashLink pos)
RexxObject * value(HashLink pos)
HashLink next(HashLink pos)
RexxObject * index(HashLink pos)
virtual RexxInteger * integerValue(size_t)
virtual bool isInstanceOf(RexxClass *)
void setBehaviour(RexxBehaviour *b)
virtual RexxString * primitiveMakeString()
virtual bool unsignedNumberValue(stringsize_t &result, size_t precision)
virtual bool isEqual(RexxObject *)
void setVirtualFunctions(void *t)
virtual RexxObject * makeProxy(RexxEnvelope *)
virtual bool doubleValue(double &result)
virtual RexxString * stringValue()
ObjectHeader header
virtual RexxSupplier * instanceMethods(RexxClass *)
RexxObject * clone()
virtual RexxString * makeString()
virtual bool numberValue(wholenumber_t &result, size_t precision)
virtual RexxArray * makeArray()
virtual RexxMethod * instanceMethod(RexxString *)
virtual void copyIntoTail(RexxCompoundTail *buffer)
virtual HashCode getHashValue()
virtual RexxObject * copy()
size_t getObjectTypeNumber()
RexxBehaviour * behaviour
virtual RexxNumberString * numberString()
virtual bool truthValue(int)
HashCode identityHash()
virtual bool logicalValue(logical_t &)
void removeUninitObject(RexxObject *obj)
Definition: RexxMemory.cpp:598
static void * virtualFunctionTable[]
Definition: RexxMemory.hpp:298
void addUninitObject(RexxObject *obj)
Definition: RexxMemory.cpp:609
RexxObject * start(RexxObject *)
bool isProtected()
bool isPrivate()
void run(RexxActivity *, RexxObject *, RexxString *, RexxObject **, size_t, size_t, ProtectedObject &)
bool isSpecial()
static RexxMethod * newMethodObject(RexxString *, RexxObject *, RexxObject *, RexxSource *a, bool isBlock=false)
RexxClass * getScope()
RexxMethod * newScope(RexxClass *)
static RexxObject * nilObject
HashCode hashValue
virtual HashCode getHashValue()
RexxObject * isInstanceOfRexx(RexxClass *)
RexxInteger * requiredInteger(RexxString *kind, size_t, size_t)
bool hasUninitMethod()
RexxString * stringRexx()
RexxString * defaultNameRexx()
bool messageSend(RexxString *, RexxObject **, size_t, size_t, ProtectedObject &, bool processUnknown=true)
stringsize_t requiredPositive(RexxString *kind, size_t position, size_t precision=Numerics::ARGUMENT_DIGITS)
RexxMessage * start(RexxObject **, size_t, size_t)
virtual wholenumber_t compareTo(RexxObject *)
RexxString * objectName()
RexxNumberString * numberString()
RexxMessage * startCommon(RexxObject *message, RexxObject **arguments, size_t argCount, size_t named_argCount)
RexxInteger * integerValue(size_t)
RexxVariableDictionary * getObjectVariables(RexxObject *)
RexxObject * requestRexx(RexxString *)
static void decodeMessageName(RexxObject *target, RexxObject *message, RexxString *&messageName, RexxObject *&startScope)
RexxObject * sendWith(RexxObject *, RexxArray *, RexxObject **, size_t)
RexxString * concatRexx(RexxObject *)
RexxObject * unknownRexx(RexxString *, RexxArray *, RexxObject **, size_t)
bool requestUnsignedNumber(stringsize_t &, size_t)
static RexxClass * classInstance
stringsize_t requiredNonNegative(RexxString *kind, size_t position, size_t precision=Numerics::ARGUMENT_DIGITS)
RexxObject * hasMethodRexx(RexxString *)
RexxMethod * instanceMethodRexx(RexxString *)
void live(size_t)
Definition: ObjectClass.cpp:78
RexxObject * unsetMethod(RexxString *)
RexxString * primitiveMakeString()
static void createInstance()
Definition: ObjectClass.cpp:72
RexxObject * superScope(RexxObject *)
virtual RexxInteger * hasMethod(RexxString *msg)
RexxObject * strictEqual(RexxObject *)
void guardOn(RexxActivity *activity, RexxObject *scope)
RexxMessage * startWith(RexxObject *, RexxArray *, RexxObject **, size_t)
void processUnknown(RexxString *, RexxObject **, size_t, size_t, ProtectedObject &)
virtual bool doubleValue(double &result)
RexxInteger * requestInteger(size_t)
RexxObject * setMethod(RexxString *, RexxMethod *, RexxString *a=OREF_NULL)
RexxMethod * methodLookup(RexxString *name)
virtual RexxObject * defMethod(RexxString *, RexxMethod *, RexxString *a=OREF_NULL)
RexxString * makeString()
RexxObject * send(RexxObject **, size_t, size_t)
RexxArray * makeArray()
RexxObject * objectNameEquals(RexxObject *)
void guardOff(RexxActivity *activity, RexxObject *scope)
RexxString * oref()
virtual RexxObject * unknown(RexxString *msg, RexxArray *args, RexxDirectory *named_args)
RexxArray * requestArray()
RexxString * requiredString()
void * getCSelf()
void processProtectedMethod(RexxString *, RexxMethod *, RexxObject **, size_t, size_t, ProtectedObject &)
RexxObject * copy()
RexxString * stringValue()
RexxSupplier * instanceMethods(RexxClass *)
void flatten(RexxEnvelope *)
Definition: ObjectClass.cpp:94
RexxObject * equal(RexxObject *)
void sendMessage(RexxString *, RexxArray *, RexxDirectory *, ProtectedObject &)
void liveGeneral(int reason)
Definition: ObjectClass.cpp:86
RexxObject * notEqual(RexxObject *other)
bool requestNumber(wholenumber_t &, size_t)
RexxMethod * checkPrivate(RexxMethod *)
HashCode hash()
RexxInteger * identityHashRexx()
RexxDirectory * requestDirectory()
RexxMethod * instanceMethod(RexxString *)
void addObjectVariables(RexxVariableDictionary *)
RexxString * requestString()
void copyIntoTail(RexxCompoundTail *buffer)
RexxObject * makeStringRexx()
virtual bool numberValue(wholenumber_t &result, size_t precision)
RexxObject * newRexx(RexxObject **arguments, size_t argCount, size_t named_argCount)
RexxBehaviour * behaviourObject()
RexxObject * defMethods(RexxDirectory *)
bool isEqual(RexxObject *)
virtual RexxString * defaultName()
bool truthValue(int)
static PCPPM operatorMethods[]
RexxString * concatBlank(RexxObject *)
virtual bool unsignedNumberValue(stringsize_t &result, size_t precision)
RexxSupplier * instanceMethodsRexx(RexxClass *)
RexxString * requestStringNoNOSTRING()
RexxString * id()
RexxClass * classObject()
const char * idString()
RexxObject * copyRexx()
void setObjectVariable(RexxString *, RexxObject *, RexxObject *)
bool isInstanceOf(RexxClass *)
RexxObject * run(RexxObject **, size_t, size_t)
RexxObject * makeArrayRexx()
RexxMethod * superMethod(RexxString *, RexxObject *)
RexxObject * strictNotEqual(RexxObject *other)
RexxObject * getObjectVariable(RexxString *)
virtual bool logicalValue(logical_t &)
RexxObject * hashCode()
void copyObjectVariables(RexxObject *newObject)
RexxObject * init()
wholenumber_t requiredNumber(RexxString *kind, size_t position, size_t precision=Numerics::ARGUMENT_DIGITS)
bool numberValue(wholenumber_t &result, size_t precision)
bool truthValue(int)
RexxString * concatRexx(RexxObject *)
RexxInteger * strictEqual(RexxObject *)
bool doubleValue(double &result)
const char * getStringData()
RexxInteger * integerValue(size_t precision)
RexxString * concatBlank(RexxObject *)
RexxNumberString * numberString()
virtual bool logicalValue(logical_t &)
RexxString * concatToCstring(const char *)
bool strCompare(const char *s)
codepoint_t getCharC(sizeC_t p)
RexxString * upper()
bool unsignedNumberValue(uwholenumber_t &result, size_t precision)
void copyIntoTail(RexxCompoundTail *buffer)
RexxObject * stringGet(RexxString *key)
Definition: TableClass.hpp:67
void setNextDictionary(RexxVariableDictionary *next)
RexxObject * realValue(RexxString *name)
bool isScope(RexxObject *otherScope)
void set(RexxString *, RexxObject *)
RexxVariableDictionary * getNextDictionary()
bool checkProtectedMethod(RexxObject *target, RexxString *messageName, size_t count, size_t named_count, RexxObject **arguments, ProtectedObject &result)
static int strCaselessCompare(const char *opt1, const char *opt2)
Definition: Utilities.cpp:82
size_t logical_t
Definition: rexx.h:231
ssize_t wholenumber_t
Definition: rexx.h:230
size_t stringsize_t
Definition: rexx.h:228