ContextClass.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.ibm.com/developerworks/oss/CPLv1.0.htm */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 /******************************************************************************/
39 /* REXX Kernel */
40 /* */
41 /* Primitive Rexx execution context */
42 /* */
43 /******************************************************************************/
44 #include "RexxCore.h"
45 #include "ContextClass.hpp"
46 #include "RexxActivation.hpp"
47 #include "SupplierClass.hpp"
48 #include "DirectoryClass.hpp"
49 
50 RexxClass *RexxContext::classInstance = OREF_NULL; // singleton class instance
51 
52 /**
53  * Create initial bootstrap objects
54  */
56 {
57  CLASS_CREATE(RexxContext, "RexxContext", RexxClass);
58 }
59 
60 
61 /**
62  * Allocate a new RexxContext object
63  *
64  * @param size The size of the object.
65  *
66  * @return The newly allocated object.
67  */
68 void *RexxContext::operator new(size_t size)
69 {
70  /* Get new object */
71  return new_object(size, T_RexxContext);
72 }
73 
74 
75 /**
76  * Constructor for a RexxContext object.
77  *
78  * @param a The activation we're attached to.
79  */
81 {
82  activation = a;
83 }
84 
85 
86 /**
87  * The Rexx accessible class NEW method. This raises an
88  * error because RexxContext objects can only be created
89  * by the internal interpreter.
90  *
91  * @param args The NEW args
92  * @param argc The count of arguments
93  *
94  * @return Never returns.
95  */
96 RexxObject *RexxContext::newRexx(RexxObject **args, size_t argc, size_t named_argc)
97 {
98  // we do not allow these to be allocated from Rexx code...
100  return TheNilObject;
101 }
102 
103 
104 void RexxContext::live(size_t liveMark)
105 /******************************************************************************/
106 /* Function: Normal garbage collection live marking */
107 /******************************************************************************/
108 {
109  memory_mark(this->objectVariables);
110  memory_mark(this->activation);
111 }
112 
113 void RexxContext::liveGeneral(int reason)
114 /******************************************************************************/
115 /* Function: Generalized object marking */
116 /******************************************************************************/
117 {
118  memory_mark_general(this->objectVariables);
120 }
121 
123 /******************************************************************************/
124 /* Function: Flatten an object */
125 /******************************************************************************/
126 {
128 
129  // jlf : todo... flatten or not flatten ?
130  //flatten_reference(newThis->objectVariables, envelope);
131  newThis->objectVariables = OREF_NULL;
132  newThis->activation = OREF_NULL; // this never should be getting flattened, so sever the connection
133 
135 }
136 
137 
138 /**
139  * An override for the copy method to keep RexxContext
140  * objects from being copied.
141  *
142  * @return Never returns.
143  */
145 {
146  // we do not allow these to be allocated from Rexx code...
148  return TheNilObject;
149 }
150 
151 
152 /**
153  * Check that the backing RexxActivation is still available.
154  */
156 {
157  if (activation == OREF_NULL)
158  {
160  }
161 }
162 
163 
164 /**
165  * Return the package object for the code that's currently
166  * executing.
167  *
168  * @return The package instance.
169  */
171 {
172  checkValid();
173  return activation->getPackage();
174 }
175 
176 
177 /**
178  * Return the current digits setting for the running context
179  *
180  * @return The current digits value
181  */
183 {
184  checkValid();
185  return new_integer(activation->digits());
186 }
187 
188 
189 /**
190  * Return the current digits propagate setting for the running context
191  *
192  * @return The current digits propagate value
193  */
195 {
196  checkValid();
198 }
199 
200 
201 /**
202  * Return the current fuzz setting for the running context
203  *
204  * @return The current fuzz value
205  */
207 {
208  checkValid();
209  return new_integer(activation->fuzz());
210 }
211 
212 
213 /**
214  * Return the current form setting for the running context
215  *
216  * @return The current form value
217  */
219 {
220  checkValid();
221  return activation->form() == Numerics::FORM_SCIENTIFIC ? OREF_SCIENTIFIC : OREF_ENGINEERING;
222 }
223 
224 
225 /**
226  * Return a supplier for all of the variables in the current
227  * context.
228  *
229  * @return A supplier object for iterating over the variables
230  */
232 {
233  checkValid();
235 }
236 
237 
238 /**
239  * Return the executable backing the current context
240  *
241  * @return The executable object (either a method or routine)
242  */
244 {
245  checkValid();
246  return activation->getExecutable();
247 }
248 
249 
250 /**
251  * Return the positional arguments used to invoke the current context
252  *
253  * @return The array of positional arguments
254  */
256 {
257  checkValid();
259  size_t size = activation->getMethodArgumentCount();
260  return new (size, arglist) RexxArray;
261 }
262 
263 
264 /**
265  * Return the named arguments used to invoke the current context
266  *
267  * @return The directory of named arguments
268  */
270 {
271  checkValid();
273  if (arglist == OREF_NULL) return new_directory(); // Empty directory
274 
275  size_t argcount = activation->getMethodArgumentCount();
276  size_t named_argcount = activation->getMethodNamedArgumentCount();;
277 
278  if (named_argcount == 0) return new_directory(); // Empty directory
279 
280  // Now we are sure to have a directory on return (and not OREF_NULL)
281  return RexxDirectory::fromIndexItemArray(arglist + argcount, named_argcount);
282 }
283 
284 
285 /**
286  * Set the positional & named arguments used to invoke the current context
287  */
289  /* named arguments*/ RexxObject **named_arglist, size_t named_argcount)
290 {
291  checkValid();
292 
293  RexxArray *positionalArgumentsArray = arrayArgument(positionalArguments, OREF_positional, ARG_ONE);
294  ProtectedObject p1(positionalArgumentsArray);
295 
296  // use strict named arg namedArguments=.NIL
297  NamedArguments expectedNamedArguments(1); // At most, one named argument
298  expectedNamedArguments[0] = NamedArgument("NAMEDARGUMENTS", 1, TheNilObject); // At least 1 characters, default value = .NIL
299  expectedNamedArguments.check(named_arglist, named_argcount, /*strict*/ true, /*extraAllowed*/ false);
300 
301  ProtectedObject p2;
302  RexxDirectory *namedArgumentsDirectory = (RexxDirectory *)expectedNamedArguments[0].value;
303  if (namedArgumentsDirectory != TheNilObject)
304  {
305  namedArgumentsDirectory = namedArgumentsDirectory->requestDirectory();
306  p2 = namedArgumentsDirectory;
307  if (namedArgumentsDirectory == TheNilObject)
308  {
309  reportException(Error_Execution_user_defined , "SETARGS namedArguments must be a directory or NIL");
310  }
311  }
312 
313  activation->setArguments(positionalArgumentsArray, namedArgumentsDirectory);
314  return OREF_NULL; // no return value
315 }
316 
317 
318 /**
319  * Return the current executable condition information
320  *
321  * @return The condition information
322  */
324 {
325  checkValid();
326  /* get current trapped condition */
327  RexxObject *conditionobj = activation->getConditionObj();
328  return conditionobj == OREF_NULL ? TheNilObject : conditionobj->copy();
329 }
330 
331 
332 /**
333  * Return the execution context current line position.
334  *
335  * @return The current line number of the context.
336  */
338 {
339  checkValid();
340  return activation->getContextLine();
341 }
342 
343 
344 /**
345  * Return the execution context return status
346  *
347  * @return The .RS value of the context.
348  */
350 {
351  checkValid();
353 }
354 
355 
356 /**
357  * @return The parent's context.
358  */
360 {
361  checkValid();
363 }
364 
365 
366 /**
367  * Retrieve the name associated with the current context.
368  * If this is the top level, then the name of the package
369  * is returned. For internal call contexts, the label name
370  * is returned, and for routines or methods, the name used
371  * to invoke the code is returned.
372  *
373  * @return The appropriate name for this context.
374  */
376 {
377  checkValid();
378  return activation->getCallname();
379 }
380 
381 /**
382  * Retrieve the stack frames from the current context.
383  *
384  * @return A list of the current stack frames.
385  */
387 {
388  checkValid();
389  // we don't want to include the stackframes frame in the list, so ask
390  // that it be skipped.
391  return activation->getStackFrames(true);
392 }
void reportException(wholenumber_t error)
@ T_RexxContext
RexxDirectory * new_directory()
RexxInteger * new_integer(wholenumber_t v)
#define OREF_NULL
Definition: RexxCore.h:60
#define TheTrueObject
Definition: RexxCore.h:186
#define TheNilObject
Definition: RexxCore.h:181
#define TheFalseObject
Definition: RexxCore.h:185
const int ARG_ONE
Definition: RexxCore.h:80
RexxArray * arrayArgument(RexxObject *object, RexxString *kind, size_t position)
Definition: RexxCore.h:407
#define Error_Unsupported_copy_method
#define Error_Execution_user_defined
#define Error_Execution_context_not_active
#define Error_Unsupported_new_method
#define memory_mark(oref)
Definition: RexxMemory.hpp:445
RexxObject * new_object(size_t s)
Definition: RexxMemory.hpp:431
#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
void check(RexxObject **namedArglist, size_t namedArgCount, bool strict, bool extraAllowed, size_t minimumRequired=0)
static const bool FORM_SCIENTIFIC
Definition: Numerics.hpp:76
BaseExecutable * getExecutable()
RexxDirectory * getAllLocalVariables()
RexxString * getCallname()
size_t getMethodArgumentCount()
RexxDirectory * getConditionObj()
RexxArray * getStackFrames(bool skipFirst)
RexxObject * getParentContextObject()
RexxObject * getContextLine()
RexxObject * getContextReturnStatus()
RexxObject ** getMethodArgumentList()
void setArguments(RexxArray *positionalArguments, RexxDirectory *namedArguments)
PackageClass * getPackage()
size_t getMethodNamedArgumentCount()
bool propagateNumericSettings()
void flatten(RexxEnvelope *)
RexxObject * getFuzz()
RexxObject * copyRexx()
RexxObject * getDigits()
RexxObject * getForm()
RexxObject * getArgs()
RexxObject * getLine()
RexxObject * setArgs(RexxObject *, RexxObject **, size_t)
RexxObject * getRS()
void checkValid()
PackageClass * getPackage()
RexxActivation * activation
RexxContext(RexxActivation *)
RexxObject * getName()
RexxObject * newRexx(RexxObject **args, size_t argc, size_t named_argc)
static void createInstance()
static RexxClass * classInstance
RexxObject * getExecutable()
RexxObject * getDigitsPropagate()
RexxObject * getVariables()
RexxObject * getParentContextObject()
RexxObject * getStackFrames()
RexxObject * getCondition()
void live(size_t)
void liveGeneral(int reason)
RexxObject * getNamedArgs()
static RexxDirectory * fromIndexItemArray(RexxObject **arglist, size_t count)
RexxObject * copy()
RexxDirectory * requestDirectory()