RexxNativeCode.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 RexxNativeMethod.cpp */
40 /* */
41 /* Primitive Method Class */
42 /* */
43 /******************************************************************************/
44 #include <stdlib.h>
45 #include <string.h>
46 #include "RexxCore.h"
47 #include "StringClass.hpp"
48 #include "DirectoryClass.hpp"
49 #include "RexxNativeActivation.hpp"
50 #include "RexxNativeCode.hpp"
51 #include "SourceFile.hpp"
52 #include "PackageManager.hpp"
53 #include <ctype.h>
54 
55 
57 {
58  // and this is the information needed to resolve this again after an
59  // image restore
60  OrefSet(this, this->package, _package);
61  OrefSet(this, this->name, _name);
62  // this will be set later, if available
63  OrefSet(this, this->source, OREF_NULL);
64 }
65 
66 
67 void RexxNativeCode::live(size_t liveMark)
68 /******************************************************************************/
69 /* Function: Normal garbage collection live marking */
70 /******************************************************************************/
71 {
72  memory_mark(this->package);
73  memory_mark(this->name);
74  memory_mark(this->source);
75 }
76 
77 
79 /******************************************************************************/
80 /* Function: Normal garbage collection live marking */
81 /******************************************************************************/
82 {
83  // Inspired by ooRexx5, but the approach is different...
84  // Instead of assigning package = TheRexxPackage when reason == PREPARINGIMAGE (unsupported by ooRexx4)
85  // I mark the RexxNativeCode instance as belonging to the RexxPackage, and will return TheRexxPackage when asking its package.
86  if (reason == SAVINGIMAGE) this->setInRexxPackage();
87 
91 }
92 
93 
95 /******************************************************************************/
96 /* Function: Flatten an object */
97 /******************************************************************************/
98 {
100  flatten_reference(newThis->package, envelope);
101  flatten_reference(newThis->name, envelope);
102  flatten_reference(newThis->source, envelope);
104 }
105 
106 
107 /**
108  * Resolve a class in the context of this code object.
109  *
110  * @param className The name of the desired class.
111  *
112  * @return The returned class.
113  */
115 {
116  // if there is a source object attached, have it resolve things. Otherwise, go back to the default.
117  if (source != OREF_NULL)
118  {
119  return source->findClass(className);
120  }
121  return BaseCode::findClass(className);
122 }
123 
124 
125 // ooRexx5 uses setPackageObject
126 /**
127  * Set a source object into a native code context. If the
128  * object is already set, then this returns a copy of the code object.
129  *
130  * @param s The new source object.
131  *
132  * @return Either the same object, or a new copy of the code object.
133  */
135 {
136  if (source == OREF_NULL)
137  {
138  OrefSet(this, this->source, s);
139  return this;
140  }
141  else
142  {
143  RexxNativeCode *codeCopy = (RexxNativeCode *)this->copy();
144  OrefSet(codeCopy, codeCopy->source, s);
145  return codeCopy;
146  }
147 }
148 
149 
150 /**
151  * Get the source object backing this code instance. If created from
152  * a directive, this will be the source package containing the
153  * directive.
154  *
155  * @return The parent source instance.
156  */
158 {
159  return source;
160 }
161 
162 
163 /**
164  * Get the security manager associated with native code. Generally,
165  * only native methods and routines defined with directives
166  * will have an associated security manager.
167  *
168  * @return The source security manager.
169  */
171 {
172  if (source != OREF_NULL)
173  {
174  return source->getSecurityManager();
175  }
176  return OREF_NULL;
177 }
178 
179 
181 /******************************************************************************/
182 /* Function: Generalized object marking */
183 /******************************************************************************/
184 {
185  // zero the entry point if saving the image
186  if (reason == SAVINGIMAGE)
187  {
188  entry = NULL;
189  }
191 }
192 
193 
195 /******************************************************************************/
196 /* Function: Flatten an object */
197 /******************************************************************************/
198 {
200  newThis->entry = NULL;
201  RexxNativeCode::flatten(envelope);
203 }
204 
205 
207 /******************************************************************************/
208 /* Function: Generalized object marking */
209 /******************************************************************************/
210 {
211  // zero the entry point if saving the image
212  if (reason == SAVINGIMAGE)
213  {
214  entry = NULL;
215  }
217 }
218 
219 
221 /******************************************************************************/
222 /* Function: Flatten an object */
223 /******************************************************************************/
224 {
226  newThis->entry = NULL;
227  RexxNativeCode::flatten(envelope);
229 }
230 
231 
233 /******************************************************************************/
234 /* Function: Generalized object marking */
235 /******************************************************************************/
236 {
237  // zero the entry point if saving the image
238  if (reason == SAVINGIMAGE)
239  {
240  entry = NULL;
241  }
243 }
244 
245 
247 /******************************************************************************/
248 /* Function: Flatten an object */
249 /******************************************************************************/
250 {
252  newThis->entry = NULL;
253  RexxNativeCode::flatten(envelope);
255 }
256 
257 
258 /**
259  * Run a method call (vs a straight program call).
260  *
261  * @param activity The current activity.
262  * @param method The method we're attached to.
263  * @param receiver The method receiver object (the "self" object).
264  * @param messageName
265  * The name of the message used to invoke the method.
266  * @param argPtr The pointer to the arguments.
267  * @param count The count of positional arguments.
268  * @param named_count The count of named arguments.
269  * @param result The protected object used to return the result.
270  */
271 void RexxNativeMethod::run(RexxActivity *activity, RexxMethod *method, RexxObject *receiver, RexxString *messageName,
272  RexxObject **argPtr, size_t count, size_t named_count, ProtectedObject &result)
273 {
274  // if this is NULL currently, we need to lazy resolve this entry
275  if (entry == NULL)
276  {
277  // have the package manager resolve this for us before we make a call
279  }
280 
281  // create a new native activation
283  activity->pushStackFrame(newNActa); /* push it on the activity stack */
284  /* and go run it */
285  newNActa->run(method, this, receiver, messageName, argPtr, count, named_count, result);
286 }
287 
288 
289 void * RexxNativeMethod::operator new(
290  size_t size) /* object size */
291 /****************************************************************************/
292 /* Function: Create a new Native method */
293 /****************************************************************************/
294 {
295  return new_object(size, T_NativeMethod); // Get new object
296 }
297 
298 
299 /**
300  * Run a method call (vs a straight program call).
301  *
302  * @param activity The current activity.
303  * @param functionName
304  * The name of the message used to invoke the method.
305  * @param argPtr The pointer to the arguments.
306  * @param count The count of positional arguments.
307  * @param named_count The count of named arguments.
308  * @param result The protected object used to return the result.
309  */
310 void RexxNativeRoutine::call(RexxActivity *activity, RoutineClass *routine, RexxString *functionName, RexxObject **argPtr, size_t count, size_t named_count, ProtectedObject &result)
311 {
312  // if this is NULL currently, we need to lazy resolve this entry
313  if (entry == NULL)
314  {
315  // have the package manager resolve this for us before we make a call
317  }
318 
319  // create a new native activation
321  activity->pushStackFrame(newNActa); /* push it on the activity stack */
322  /* and go run it */
323  newNActa->callNativeRoutine(routine, this, functionName, argPtr, count, named_count, result);
324 }
325 
326 
327 void * RexxNativeRoutine::operator new(
328  size_t size) /* object size */
329 /****************************************************************************/
330 /* Function: Create a new Native method */
331 /****************************************************************************/
332 {
333  return new_object(size, T_NativeRoutine); // Get new object
334 }
335 
336 
337 /**
338  * Run a method call (vs a straight program call).
339  *
340  * @param activity The current activity.
341  * @param functionName
342  * The name of the message used to invoke the method.
343  * @param argPtr The pointer to the arguments.
344  * @param count The count of positional arguments.
345  * @param named_count The count of named arguments.
346  * @param result The protected object used to return the result.
347  */
348 void RegisteredRoutine::call(RexxActivity *activity, RoutineClass *routine, RexxString *functionName, RexxObject **argPtr, size_t count, size_t named_count, ProtectedObject &result)
349 {
350  // if this is NULL currently, we need to lazy resolve this entry
351  if (entry == NULL)
352  {
353  // have the package manager resolve this for us before we make a call
355  }
356 
357  // create a new native activation
359  activity->pushStackFrame(newNActa); /* push it on the activity stack */
360  /* and go run it */
361  newNActa->callRegisteredRoutine(routine, this, functionName, argPtr, count, named_count, result);
362 }
363 
364 
365 void * RegisteredRoutine::operator new(
366  size_t size) /* object size */
367 /****************************************************************************/
368 /* Function: Create a new Native method */
369 /****************************************************************************/
370 {
371  return new_object(size, T_RegisteredRoutine); // Get new object
372 }
@ T_NativeRoutine
@ T_NativeMethod
@ T_RegisteredRoutine
#define OREF_NULL
Definition: RexxCore.h:61
#define OrefSet(o, r, v)
Definition: RexxCore.h:101
#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 RexxNativeActivation * newNativeActivation(RexxActivity *activity, RexxActivation *parent)
virtual RexxClass * findClass(RexxString *className)
static PNATIVEROUTINE resolveRoutineEntry(RexxString *package, RexxString *name)
static PREGISTEREDROUTINE resolveRegisteredRoutineEntry(RexxString *package, RexxString *name)
static PNATIVEMETHOD resolveMethodEntry(RexxString *package, RexxString *name)
void liveGeneral(int reason)
void flatten(RexxEnvelope *envelope)
RexxRoutineHandler * entry
virtual void call(RexxActivity *, RoutineClass *, RexxString *, RexxObject **, size_t, size_t, ProtectedObject &)
void pushStackFrame(RexxActivationBase *new_activation)
virtual RexxObject * copy()
void callRegisteredRoutine(RoutineClass *routine, RegisteredRoutine *code, RexxString *functionName, RexxObject **list, size_t count, size_t named_count, ProtectedObject &resultObj)
void callNativeRoutine(RoutineClass *routine, RexxNativeRoutine *code, RexxString *functionName, RexxObject **list, size_t count, size_t named_count, ProtectedObject &result)
void run(RexxMethod *_method, RexxNativeMethod *_code, RexxObject *_receiver, RexxString *_msgname, RexxObject **_arglist, size_t _argcount, size_t _named_argcount, ProtectedObject &resultObj)
virtual RexxClass * findClass(RexxString *className)
RexxString * name
SecurityManager * getSecurityManager()
virtual RexxSource * getSourceObject()
virtual BaseCode * setSourceObject(RexxSource *s)
RexxString * package
void live(size_t)
void flatten(RexxEnvelope *envelope)
RexxSource * source
void liveGeneral(int reason)
PNATIVEMETHOD entry
void liveGeneral(int reason)
virtual void run(RexxActivity *activity, RexxMethod *method, RexxObject *receiver, RexxString *messageName, RexxObject **argPtr, size_t count, size_t named_count, ProtectedObject &result)
void flatten(RexxEnvelope *envelope)
virtual void call(RexxActivity *, RoutineClass *, RexxString *, RexxObject **, size_t, size_t, ProtectedObject &)
PNATIVEROUTINE entry
void flatten(RexxEnvelope *envelope)
void liveGeneral(int reason)
SecurityManager * getSecurityManager()
Definition: SourceFile.hpp:380
RexxClass * findClass(RexxString *)