BlockClass.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 #include "RexxCore.h"
40 #include "BlockClass.hpp"
41 #include "RexxActivation.hpp"
42 #include "PackageClass.hpp"
43 #include "DirectoryClass.hpp"
44 
45 
46 /******************************************************************************/
47 /* REXX Kernel */
48 /* */
49 /* Primitive Rexx source literal */
50 /* */
51 /******************************************************************************/
52 
53 /**
54  * Allocate a new RexxSourceLiteral object
55  *
56  * @param size The size of the object.
57  *
58  * @return The newly allocated object.
59  */
60 void *RexxSourceLiteral::operator new(size_t size)
61 {
62  /* Get new object */
63  return new_object(size, T_SourceLiteral);
64 }
65 
66 
67 void RexxSourceLiteral::live(size_t liveMark)
68 /******************************************************************************/
69 /* Function: Normal garbage collection live marking */
70 /******************************************************************************/
71 {
72  memory_mark(this->source);
73  memory_mark(this->package);
74  memory_mark(this->kind);
76 }
77 
79 /******************************************************************************/
80 /* Function: Generalized object marking */
81 /******************************************************************************/
82 {
87 }
88 
90 /******************************************************************************/
91 /* Function: Flatten an object */
92 /******************************************************************************/
93 {
95 
96  newThis->source = OREF_NULL; // this never should be getting flattened, so sever the connection
97  newThis->package = OREF_NULL; // idem
98  newThis->kind = OREF_NULL; // idem
99  newThis->rawExecutable = OREF_NULL; // idem
100 
102 }
103 
104 
106 {
107  ProtectedObject pThis(this);
108  RexxArray *sa = s->makeArrayRexx(NULL); // use default separator \n
109  this->source = sa; // transient, no need of OrefSet
110  this->package = p; // transient, no need of OrefSet
111  RexxArray *sourceArray = (RexxArray *)sa->copy();
112  ProtectedObject pSourceArray(sourceArray);
113 
114  // clauser = .Clauser~new(sourceArray)
115  // The clauser will have a direct impact on sourceArray :
116  // - The message KIND returns the kind of the source after removing the keyword(s) that declares the kind of the source.
117  // - The message TRANSFORMSOURCE updates directly the sourceArray.
118  RexxObject *clauserClass = TheEnvironment->at(OREF_CLAUSER);
119  RexxObject *clauser = clauserClass->sendMessage(OREF_NEW, (RexxObject *)sourceArray); // must cast sourceArray, otherwise taken as array of arguments
120  ProtectedObject pClauser(clauser);
121 
122  // kind = clauser~kind(remove: .true)
123  RexxObject *arguments[0 + (1*2)]; // 0 positional arg, 1 named arg
124  arguments[0] = OREF_REMOVE; // named arg name
125  arguments[1] = TheTrueObject; // named arg value
126  this->kind = (RexxString *)clauser->sendMessage(OREF_KIND, arguments, 0, 1); // transient, no need of OrefSet
127 
128  // clauser~transformSource(clauseBefore, clauseAfter)
129  // Transform the source to accept auto named arguments, and to return implicitely the result of the last evaluated expression
130  RexxString *clauseBefore = new_string("use auto named arg ; options \"NOCOMMANDS\"");
131  ProtectedObject pClauseBefore(clauseBefore);
132  RexxString *clauseAfter = new_string("if var(\"result\") then return result");
133  ProtectedObject pClauseAfter(clauseAfter);
134  clauser->sendMessage(OREF_TRANSFORMSOURCE, clauseBefore, clauseAfter);
135 
136  // rawExecutable = .Clauser~rawExecutable(kind, sourceArray, package)
137  this->rawExecutable =clauserClass->sendMessage(OREF_RAWEXECUTABLE, this->kind, sourceArray, this->package); // transient, no need of OrefSet
138  this->closure = (0 == strncmp(this->kind->getStringData(), "cl", 2));
139 }
140 
141 
143  RexxActivation *context, /* current activation context */
144  RexxExpressionStack *stack ) /* evaluation stack */
145 {
146  RexxContext *rexxContext = (RexxContext *)context->getContextObject();
147  RexxObject *value = new RexxBlock(this, rexxContext);
148  stack->push(value); /* place on the evaluation stack */
149  /* trace if necessary */
150  context->traceIntermediate(value, TRACE_PREFIX_LITERAL);
151  return value; /* also return the result */
152 }
153 
154 
155 /******************************************************************************/
156 /* REXX Kernel */
157 /* */
158 /* Primitive Rexx contextual source */
159 /* */
160 /******************************************************************************/
161 
162 RexxClass *RexxBlock::classInstance = OREF_NULL; // singleton class instance
163 
164 /**
165  * Create initial bootstrap objects
166  */
168 {
169  CLASS_CREATE(RexxBlock, "RexxBlock", RexxClass);
170 }
171 
172 
173 /**
174  * Allocate a new RexxBlock object
175  *
176  * @param size The size of the object.
177  *
178  * @return The newly allocated object.
179  */
180 void *RexxBlock::operator new(size_t size)
181 {
182  /* Get new object */
183  return new_object(size, T_RexxBlock);
184 }
185 
186 
187 /**
188  * Constructor for a RexxBlock object.
189  *
190  * @param p The package class.
191  */
193 {
194  OrefSet(this, this->sourceLiteral, s);
195  OrefSet(this, this->variables, (RexxDirectory *)TheNilObject);
196 
197  // c->getVariables will create a directory : see RexxVariableDictionary::getAllVariables
198  // So a GC may happen, must protect this.
199  ProtectedObject p(this);
200  if (s->isClosure()) OrefSet(this, this->variables, (RexxDirectory *)c->getVariables());
201 
202  // Normally, next lines are done from RexxBlock::newRexx
203  // But I don't allow to create a new block from Rexx code.
204  // On the other hand, I want to extend the RexxBlock class and initialize some variables,
205  // hence the sendMessage OREF_INIT.
206 
207 #if 0 // To rework... this code is wrong (crash)
208  // override the behaviour in case this is a subclass
209  RexxBehaviour *behaviour = ((RexxClass *)this)->getInstanceBehaviour();
210  if (behaviour != NULL) this->setBehaviour(behaviour);
211  if (((RexxClass *)this)->hasUninitDefined())
212  {
213  this->hasUninit();
214  }
215 #endif
216  this->sendMessage(OREF_INIT);
217 }
218 
219 
220 /**
221  * The Rexx accessible class NEW method. This raises an
222  * error because RexxBlock objects can only be created
223  * by the internal interpreter.
224  *
225  * @param args The NEW args
226  * @param argc The count of arguments
227  *
228  * @return Never returns.
229  */
230 RexxObject *RexxBlock::newRexx(RexxObject **args, size_t argc, size_t named_argc)
231 {
232  // we do not allow these to be allocated from Rexx code...
234  return TheNilObject;
235 }
236 
237 
238 /**
239  * An override for the copy method to keep RexxBlock
240  * objects from being copied.
241  *
242  * @return Never returns.
243  */
245 {
246  // we do not allow these to be allocated from Rexx code...
248  return TheNilObject;
249 }
250 
251 
252 void RexxBlock::live(size_t liveMark)
253 /******************************************************************************/
254 /* Function: Normal garbage collection live marking */
255 /******************************************************************************/
256 {
257  memory_mark(this->objectVariables);
258  memory_mark(this->sourceLiteral);
259  memory_mark(this->variables);
260 }
261 
262 void RexxBlock::liveGeneral(int reason)
263 /******************************************************************************/
264 /* Function: Generalized object marking */
265 /******************************************************************************/
266 {
267  memory_mark_general(this->objectVariables);
268  memory_mark_general(this->sourceLiteral);
269  memory_mark_general(this->variables);
270 }
271 
273 /******************************************************************************/
274 /* Function: Flatten an object */
275 /******************************************************************************/
276 {
278 
279  flatten_reference(newThis->objectVariables, envelope);
280  newThis->sourceLiteral = OREF_NULL; // this never should be getting flattened, so sever the connection
281  newThis->variables = OREF_NULL; // idem
282 
284 }
void reportException(wholenumber_t error)
@ T_SourceLiteral
@ T_RexxBlock
@ TRACE_PREFIX_LITERAL
#define OREF_NULL
Definition: RexxCore.h:60
#define TheEnvironment
Definition: RexxCore.h:174
#define OrefSet(o, r, v)
Definition: RexxCore.h:94
#define TheTrueObject
Definition: RexxCore.h:186
#define TheNilObject
Definition: RexxCore.h:181
#define Error_Unsupported_copy_method
#define Error_Unsupported_new_method
#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
RexxString * new_string(const char *s, stringsizeB_t bl, sizeC_t cl=-1)
RexxObject * getContextObject()
void traceIntermediate(RexxObject *v, int p)
RexxObject * copy()
Definition: ArrayClass.cpp:122
void flatten(RexxEnvelope *)
Definition: BlockClass.cpp:272
static void createInstance()
Definition: BlockClass.cpp:167
RexxBlock(RexxSourceLiteral *, RexxContext *)
Definition: BlockClass.cpp:192
void liveGeneral(int reason)
Definition: BlockClass.cpp:262
RexxObject * newRexx(RexxObject **args, size_t argc, size_t named_argc)
Definition: BlockClass.cpp:230
static RexxClass * classInstance
Definition: BlockClass.hpp:109
RexxObject * copyRexx()
Definition: BlockClass.cpp:244
void live(size_t)
Definition: BlockClass.cpp:252
RexxObject * getVariables()
void push(RexxObject *value)
void setBehaviour(RexxBehaviour *b)
RexxBehaviour * behaviour
void sendMessage(RexxString *, RexxArray *, RexxDirectory *, ProtectedObject &)
RexxObject * evaluate(RexxActivation *, RexxExpressionStack *)
Definition: BlockClass.cpp:142
void flatten(RexxEnvelope *)
Definition: BlockClass.cpp:89
void live(size_t)
Definition: BlockClass.cpp:67
RexxArray * source
Definition: BlockClass.hpp:76
RexxSourceLiteral(RexxString *, PackageClass *, size_t)
Definition: BlockClass.cpp:105
void liveGeneral(int reason)
Definition: BlockClass.cpp:78
PackageClass * package
Definition: BlockClass.hpp:77
RexxObject * rawExecutable
Definition: BlockClass.hpp:79
RexxString * kind
Definition: BlockClass.hpp:78
RexxArray * makeArrayRexx(RexxString *)
const char * getStringData()