RexxCode.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2009 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* http://www.oorexx.org/license.html */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 /******************************************************************************/
39 /* REXX Kernel RexxCode.cpp */
40 /* */
41 /* Primitive Method Class */
42 /* */
43 /******************************************************************************/
44 #include <stdlib.h>
45 #include <stdio.h>
46 #include <string.h>
47 #include "RexxCore.h"
48 #include "RexxCode.hpp"
49 #include "ArrayClass.hpp"
50 #include "DirectoryClass.hpp"
51 #include "RexxInstruction.hpp"
52 #include "SourceFile.hpp"
53 #include "ActivityManager.hpp"
54 #include "RexxActivation.hpp"
55 #include <ctype.h>
56 
57 
58 
60  RexxSource * _source, /* source object */
61  RexxInstruction * _start, /* start of the code tree */
62  RexxDirectory * _labels, /* method labels */
63  size_t maxstack, /* max operator stack size */
64  size_t variable_index) /* save of the vdict */
65 /******************************************************************************/
66 /* Function: Initialize a rexxmethod code object */
67 /******************************************************************************/
68 {
69  OrefSet(this, this->source, _source); /* save the program source */
70  OrefSet(this, this->start, _start); /* the parse tree */
71  OrefSet(this, this->labels, _labels); /* the method's labels */
72  /* save the stack info */
73  this->maxStack = maxstack;
74  this->vdictSize = variable_index; /* save the initial vdict size */
75 }
76 
77 
78 /**
79  * Process a detached ::requires type call.
80  *
81  * @param activity The current activity,
82  * @param routine The routine object we're executing.
83  * @param msgname The name this was invoked under.
84  * @param argPtr The pointer to the call arguments,
85  * @param argcount The count of arguments,
86  * @param result The returned result.
87  */
88 void RexxCode::call(RexxActivity *activity, RoutineClass *routine, RexxString *msgname, RexxObject**argPtr, size_t argcount, size_t named_argcount, ProtectedObject &result)
89 {
90  // just forward to the more general method
91  this->call(activity, routine, msgname, argPtr, argcount, named_argcount, OREF_SUBROUTINE, OREF_NULL, EXTERNALCALL, result);
92 }
93 
94 
96  RexxActivity *activity, /* activity running under */
97  RoutineClass *routine, // top level routine instance
98  RexxString *msgname, /* message to be run */
99  RexxObject**argPtr, /* arguments to the method */
100  size_t argcount, /* the count of positional arguments */
101  size_t named_argcount, /* the count of named arguments */
102  RexxString *calltype, /* COMMAND/ROUTINE/FUNCTION */
103  RexxString *environment, /* initial command environment */
104  int context, /* type of context */
105  ProtectedObject &result) // the method result
106 /******************************************************************************/
107 /* Function: Call a method as a top level program or external function call */
108 /******************************************************************************/
109 {
110  // check the stack space before proceeding
111  activity->checkStackSpace(); /* have enough stack space? */
112  /* add to the activity stack */
113  RexxActivation *newacta = ActivityManager::newActivation(activity, activity->getCurrentRexxFrame(), routine, this, calltype, environment, context);
114  activity->pushStackFrame(newacta);
115  /* run the method and return result */
116  newacta->run(OREF_NULL, msgname, OREF_NULL, argPtr, argcount, named_argcount, OREF_NULL, result);
117 }
118 
119 
121  RexxActivity *activity, /* activity running under */
122  RexxMethod *method, // the method object getting invoked
123  RexxObject *receiver, /* object receiving the message */
124  RexxString *msgname, /* message to be run */
125  RexxObject**argPtr, /* arguments to the method */
126  size_t argcount, /* the count of positional arguments */
127  size_t named_argcount, /* the count of named arguments */
128  ProtectedObject &result) // the method result
129 /******************************************************************************/
130 /* Function: Call a method as a top level program or external function call */
131 /******************************************************************************/
132 {
133  RexxActivation *newacta = ActivityManager::newActivation(activity, activity->getCurrentRexxFrame(), method, this);
134  /* add to the activity stack */
135  activity->pushStackFrame(newacta);
136  /* run the method and return result */
137  newacta->run(receiver, msgname, OREF_NULL, argPtr, argcount, named_argcount, OREF_NULL, result);
138  activity->relinquish(); /* yield control now */
139 }
140 
141 
142 void RexxCode::live(size_t liveMark)
143 /******************************************************************************/
144 /* Function: Normal garbage collection live marking */
145 /******************************************************************************/
146 {
147  memory_mark(this->source);
148  memory_mark(this->start);
149  memory_mark(this->labels);
150 }
151 
152 void RexxCode::liveGeneral(int reason)
153 /******************************************************************************/
154 /* Function: Generalized object marking */
155 /******************************************************************************/
156 {
157  // Inspired by ooRexx5, but the approach is different...
158  // Instead of assigning package = TheRexxPackage when reason == PREPARINGIMAGE (unsupported by ooRexx4)
159  // I mark the RexxCode instance as belonging to the RexxPackage, and will return TheRexxPackage when asking its package.
160  if (reason == SAVINGIMAGE) this->setInRexxPackage();
161 
163  memory_mark_general(this->start);
165 }
166 
168 /******************************************************************************/
169 /* Function: Flatten an object */
170 /******************************************************************************/
171 {
173 
174  flatten_reference(newThis->source, envelope);
175  flatten_reference(newThis->start, envelope);
176  flatten_reference(newThis->labels, envelope);
177 
179 }
180 
182 /******************************************************************************/
183 /* Function: Extract the source from a method from the source object as an */
184 /* array of strings. */
185 /******************************************************************************/
186 {
187  SourceLocation location; /* location information */
188  SourceLocation end_location; /* ending location */
189  RexxInstruction *current; /* current instruction */
190 
191  if (this->start == OREF_NULL) /* empty method? */
192  return new_array((size_t)0); /* just return an empty array */
193  location = start->getLocation(); /* get its location info */
194  current = this->start; /* point to the beginning */
195  /* while not at the last one */
196  while (current->nextInstruction != OREF_NULL) {
197  current = current->nextInstruction;/* step to the next one */
198  }
199 
200  end_location = current->getLocation(); /* get the end location */
201  /* copy over the ending position */
202  location.setEndLine(end_location.getEndLine());
203  location.setEndOffset(end_location.getEndOffset());
204  /* go extract the source array */
205  return this->source->extractSource(location);
206 }
207 
209 /******************************************************************************/
210 /* Function: Return the name of the program that contains this method. */
211 /**REXX****************************************************************************/
212 {
213  /* retrieve this from the source */
214  return this->source->getProgramName();
215 }
216 
217 
218 void * RexxCode::operator new(size_t size)
219 /******************************************************************************/
220 /* Function: Create a new rexx method code instance */
221 /******************************************************************************/
222 {
223  return new_object(size, T_RexxCode); /* Get new object */
224 }
225 
226 
228 /******************************************************************************/
229 /* Function: Associate a security manager with a method's source */
230 /******************************************************************************/
231 {
232  source->setSecurityManager(manager);
233  return TheTrueObject;
234 }
235 
RexxArray * new_array(size_t s)
Definition: ArrayClass.hpp:259
@ T_RexxCode
#define EXTERNALCALL
#define OREF_NULL
Definition: RexxCore.h:61
#define OrefSet(o, r, v)
Definition: RexxCore.h:101
#define TheTrueObject
Definition: RexxCore.h:196
#define memory_mark(oref)
Definition: RexxMemory.hpp:450
RexxObject * new_object(size_t s)
Definition: RexxMemory.hpp:436
#define flatten_reference(oref, envel)
Definition: RexxMemory.hpp:498
#define memory_mark_general(oref)
Definition: RexxMemory.hpp:451
@ SAVINGIMAGE
Definition: RexxMemory.hpp:117
#define cleanUpFlatten
Definition: RexxMemory.hpp:484
#define setUpFlatten(type)
Definition: RexxMemory.hpp:478
static RexxActivation * newActivation(RexxActivity *activity, RexxActivation *parent, RoutineClass *routine, RexxCode *code, RexxString *calltype, RexxString *environment, int context)
RexxObject * run(RexxObject *_receiver, RexxString *msgname, RexxArray *_arguments, RexxObject **_arglist, size_t _argcount, size_t _named_argcount, RexxInstruction *start, ProtectedObject &resultObj)
void pushStackFrame(RexxActivationBase *new_activation)
void checkStackSpace()
RexxActivation * getCurrentRexxFrame()
RexxArray * getSource()
Definition: RexxCode.cpp:181
RexxObject * setSecurityManager(RexxObject *)
Definition: RexxCode.cpp:227
RexxDirectory * labels
Definition: RexxCode.hpp:102
RexxString * getProgramName()
Definition: RexxCode.cpp:208
void flatten(RexxEnvelope *)
Definition: RexxCode.cpp:167
void live(size_t)
Definition: RexxCode.cpp:142
RexxCode(RexxSource *, RexxInstruction *, RexxDirectory *, size_t, size_t)
Definition: RexxCode.cpp:59
RexxInstruction * start
Definition: RexxCode.hpp:101
virtual void run(RexxActivity *, RexxMethod *, RexxObject *, RexxString *, RexxObject **, size_t, size_t, ProtectedObject &)
Definition: RexxCode.cpp:120
size_t vdictSize
Definition: RexxCode.hpp:104
size_t maxStack
Definition: RexxCode.hpp:103
void liveGeneral(int reason)
Definition: RexxCode.cpp:152
virtual void call(RexxActivity *, RoutineClass *, RexxString *, RexxObject **, size_t, size_t, RexxString *, RexxString *, int, ProtectedObject &)
Definition: RexxCode.cpp:95
RexxSource * source
Definition: RexxCode.hpp:100
const SourceLocation & getLocation()
RexxInstruction * nextInstruction
RexxArray * extractSource(SourceLocation &)
RexxString * getProgramName()
Definition: SourceFile.hpp:301
void setSecurityManager(RexxObject *manager)
Definition: SourceFile.hpp:379
size_t getEndLine() const
size_t getEndOffset() const
void setEndLine(size_t l)
void setEndOffset(size_t l)