From: <bi...@us...> - 2008-02-26 00:29:36
|
Revision: 2378 http://oorexx.svn.sourceforge.net/oorexx/?rev=2378&view=rev Author: bigrixx Date: 2008-02-25 16:29:33 -0800 (Mon, 25 Feb 2008) Log Message: ----------- incremental checkin Modified Paths: -------------- sandbox/rick/opt/kernel/classes/MethodClass.cpp sandbox/rick/opt/kernel/classes/MethodClass.hpp sandbox/rick/opt/kernel/classes/ObjectClass.cpp sandbox/rick/opt/kernel/classes/ObjectClass.hpp sandbox/rick/opt/kernel/classes/PackageClass.cpp sandbox/rick/opt/kernel/classes/PackageClass.hpp sandbox/rick/opt/kernel/classes/RoutineClass.cpp sandbox/rick/opt/kernel/classes/RoutineClass.hpp sandbox/rick/opt/kernel/parser/Scanner.cpp sandbox/rick/opt/kernel/parser/SourceFile.cpp sandbox/rick/opt/kernel/parser/SourceFile.hpp sandbox/rick/opt/kernel/runtime/LibraryPackage.cpp sandbox/rick/opt/kernel/runtime/PackageManager.cpp sandbox/rick/opt/kernel/runtime/PackageManager.hpp sandbox/rick/opt/kernel/runtime/RexxBehaviour.cpp sandbox/rick/opt/kernel/runtime/RexxBehaviour.hpp sandbox/rick/opt/kernel/runtime/RexxConstants.hpp sandbox/rick/opt/kernel/runtime/RexxCore.h sandbox/rick/opt/kernel/runtime/RexxMemory.hpp sandbox/rick/opt/kernel/runtime/Setup.cpp Modified: sandbox/rick/opt/kernel/classes/MethodClass.cpp =================================================================== --- sandbox/rick/opt/kernel/classes/MethodClass.cpp 2008-02-24 01:18:25 UTC (rev 2377) +++ sandbox/rick/opt/kernel/classes/MethodClass.cpp 2008-02-26 00:29:33 UTC (rev 2378) @@ -60,6 +60,7 @@ #include "RexxInternalApis.h" #include "RoutineClass.hpp" #include "Interpreter.hpp" +#include "RexxCode.hpp" // singleton class instance RexxClass *RexxMethod::classInstance = OREF_NULL; @@ -136,26 +137,117 @@ } -RexxMethod::RexxMethod(BaseCode *codeObj) -/******************************************************************************/ -/* Function: Initialize a method object */ -/******************************************************************************/ + +/** + * Generate a method directly from a source object. + * + * @param source The source object. + */ +RexxMethod::RexxMethod(RexxString *name, RexxSource *source) { this->clearObject(); /* start out fresh */ - this->methodFlags = 0; /* clear all of the flags */ + ProtectedObject p2(source); + OrefSet(this, this->executableName, name); + // generate our code object and make the file hook up. + RexxCode *codeObj = source->generateCode(); + OrefSet(this, this->code, codeObj); +} + + +/** + * Initialize a Routine object from a generated code object. Generally + * used for routines generated from ::METHOD directives. + * + * @param name The routine name. + * @param codeObj The associated code object. + */ +RexxMethod::RexxMethod(RexxString *name, BaseCode *codeObj) +{ + this->clearObject(); /* start out fresh */ + OrefSet(this, this->executableName, name); OrefSet(this, this->code, codeObj); /* store the code */ } -RexxMethod::RexxMethod(RexxSource *source) -/******************************************************************************/ -/* Function: Initialize a method object */ -/******************************************************************************/ + +/** + * Initialize a RexxMethod object from a file source. + * + * @param name The routine name (and the resolved name of the file). + */ +RexxMethod::RexxMethod(RexxString *name) { this->clearObject(); /* start out fresh */ - this->methodFlags = 0; /* clear all of the flags */ - OrefSet(this, this->code, source->generateCode()); /* store the code */ + ProtectedObject p(this); // protect during processing + OrefSet(this, this->executableName, name); + // get a source object to generat this from + RexxSource *source = new RexxSource(name); + ProtectedObject p2(source); + // generate our code object and make the file hook up. + RexxCode *codeObj = source->generateCode(); + OrefSet(this, this->code, codeObj); } + +/** + * Initialize a Routine object using a buffered source. + * + * @param name The name of the routine. + * @param source the source buffer. + */ +RexxMethod::RexxMethod(RexxString *name, RexxBuffer *buf) +{ + this->clearObject(); /* start out fresh */ + ProtectedObject p(this); // protect during processing + OrefSet(this, this->executableName, name); + // get a source object to generat this from + RexxSource *source = new RexxSource(name, buf); + ProtectedObject p2(source); + // generate our code object and make the file hook up. + RexxCode *codeObj = source->generateCode(); + OrefSet(this, this->code, codeObj); +} + + +/** + * Initialize a Routine object using directly provided source. + * + * @param name The name of the routine. + * @param data The source data buffer pointer. + * @param length the length of the source buffer. + */ +RexxMethod::RexxMethod(RexxString *name, const char *data, size_t length) +{ + this->clearObject(); /* start out fresh */ + ProtectedObject p(this); // protect during processing + OrefSet(this, this->executableName, name); + // get a source object to generat this from + RexxSource *source = new RexxSource(name, data, length); + ProtectedObject p2(source); + // generate our code object and make the file hook up. + RexxCode *codeObj = source->generateCode(); + OrefSet(this, this->code, codeObj); +} + + +/** + * Initialize a Routine object using an array source. + * + * @param name The name of the routine. + * @param source the source buffer. + */ +RexxMethod::RexxMethod(RexxString *name, RexxArray *s) +{ + this->clearObject(); /* start out fresh */ + ProtectedObject p(this); // protect during processing + OrefSet(this, this->executableName, name); + // get a source object to generat this from + RexxSource *source = new RexxSource(name, s); + ProtectedObject p2(source); + // generate our code object and make the file hook up. + RexxCode *codeObj = source->generateCode(); + OrefSet(this, this->code, codeObj); +} + void RexxMethod::live(size_t liveMark) /******************************************************************************/ /* Function: Normal garbage collection live marking */ @@ -163,6 +255,7 @@ { memory_mark(this->scope); memory_mark(this->code); + memory_mark(this->executableName); memory_mark(this->objectVariables); } @@ -173,6 +266,7 @@ { memory_mark_general(this->scope); memory_mark_general(this->code); + memory_mark_general(this->executableName); memory_mark_general(this->objectVariables); } @@ -185,6 +279,7 @@ flatten_reference(newThis->scope, envelope); flatten_reference(newThis->code, envelope); + flatten_reference(newThis->executableName, envelope); flatten_reference(newThis->objectVariables, envelope); cleanUpFlatten @@ -216,19 +311,20 @@ /* Function: Create a new method with a given scope */ /******************************************************************************/ { - RexxMethod *newMethod; /* the copied method */ - - if (this->scope == OREF_NULL) { /* nothing set yet? */ - OrefSet(this, this->scope, _scope); /* just set it directly */ - return this; /* and pass back unchanged */ - } - else { - /* copy the method */ - newMethod= (RexxMethod *)this->copy(); - /* give the method the new scope */ - OrefSet(newMethod, newMethod->scope, _scope); - return newMethod; /* and return it */ - } + // if this doesn't have a scope yet, we can just override what's here + if (this->scope == OREF_NULL) + { + OrefSet(this, this->scope, _scope); /* just set it directly */ + return this; /* and pass back unchanged */ + } + else + { + /* copy the method */ + RexxMethod *newMethod= (RexxMethod *)this->copy(); + /* give the method the new scope */ + OrefSet(newMethod, newMethod->scope, _scope); + return newMethod; /* and return it */ + } } @@ -369,25 +465,6 @@ } -RexxMethod *RexxMethod::newRexxMethod( - RexxSource *source, /* source object for the method */ - RexxClass *scope) /* scope to use */ -/******************************************************************************/ -/* Function: Convert a new source object to a method with the given scope */ -/******************************************************************************/ -{ - - - /* create a new method object */ - RexxMethod *newMethod = new RexxMethod(source); - if (scope != OREF_NULL) /* given a scope too? */ - { - newMethod->setScope(scope); /* set the scope */ - } - return newMethod; /* return the new method object */ -} - - /** * Static method used for constructing new method objects in * various contexts (such as the define method on the Class class). @@ -450,12 +527,8 @@ } } - /* create a source object */ - RexxSource *newSource = new RexxSource (pgmname, newSourceArray); + RexxMethod *result = new RexxMethod(pgmname, newSourceArray); - ProtectedObject p(newSource); - RexxMethod *result = RexxMethod::newRexxMethod(newSource, OREF_NULL); - // if we've been provided with a scope, use it if (parentSource == OREF_NULL) { @@ -470,7 +543,7 @@ // if there is a parent source, then merge in the scope information if (parentSource != OREF_NULL) { - newSource->inheritSourceContext(parentSource); + result->getSourceObject()->inheritSourceContext(parentSource); } return result; @@ -546,70 +619,24 @@ /* Function: Create a method from a fully resolved file name */ /******************************************************************************/ { - /* get the method name as a string */ - filename = REQUIRED_STRING(filename, ARG_ONE); - /* create a source object */ - RexxSource *source = RexxSource::classNewFile(filename); - ProtectedObject p(source); - /* finish up processing of this */ - RexxMethod * newMethod = newRexxMethod(source, (RexxClass *)TheNilObject); - ProtectedObject p2(newMethod); - /* Give new object its behaviour */ - newMethod->setBehaviour(((RexxClass *)this)->getInstanceBehaviour()); - if (((RexxClass *)this)->hasUninitDefined()) /* does object have an UNINT method */ - { - newMethod->hasUninit(); /* Make sure everyone is notified. */ - } - /* now send an INIT message */ - newMethod->sendMessage(OREF_INIT); - return newMethod; + /* get the method name as a string */ + filename = REQUIRED_STRING(filename, ARG_ONE); + /* create a source object */ + RexxMethod *newMethod = new RexxMethod(filename); + ProtectedObject p(newMethod); + newMethod->setScope((RexxClass *)TheNilObject); + /* Give new object its behaviour */ + newMethod->setBehaviour(((RexxClass *)this)->getInstanceBehaviour()); + if (((RexxClass *)this)->hasUninitDefined()) /* does object have an UNINT method */ + { + newMethod->hasUninit(); /* Make sure everyone is notified. */ + } + /* now send an INIT message */ + newMethod->sendMessage(OREF_INIT); + return newMethod; } -RexxMethod *RexxMethod::newRexxBuffer( - RexxString *pgmname, /* file name to process */ - RexxBuffer *source, /* String or buffer with source */ - RexxClass *scope) /* Scope for this method */ -/******************************************************************************/ -/* Function: Build a new method object from buffered REXX source */ -/******************************************************************************/ -{ - if (source == OREF_NULL) /* didn't get source? */ - { - /* raise an error */ - reportException(Error_Incorrect_method_noarg, IntegerTwo); - } - /* create a source object */ - RexxSource *newSource = RexxSource::classNewBuffered(pgmname, source); - // we need to protect this source object until parsing is complete - ProtectedObject p(newSource); - /* now complete method creation */ - return newRexxMethod(newSource, scope); -} - - - - -/** - * Create a method object from an in-store source. - * - * @param pgmname The program name (as an ASCII-Z string). - * @param source The pointer to the program source. - * @param length The length of the source. - * - * @return A translated Method object. - */ -RexxMethod *RexxMethod::newRexxBuffer(const char *pgmname, const char *source, size_t length) -{ - /* create a source object */ - RexxSource *newSource = RexxSource::classNewBuffered(new_string(pgmname), source, length); - // we need to protect this source object until parsing is complete - ProtectedObject p(newSource); - /* now complete method creation */ - return newRexxMethod(newSource, OREF_NULL); -} - - RexxMethod *RexxMethod::restore( RexxBuffer *buffer, /* buffer containing the method */ char *startPointer) /* first character of the method */ @@ -630,21 +657,6 @@ } -RexxMethod *RexxMethod::newFile( - RexxString *filename) /* name of the target file */ -/******************************************************************************/ -/* Function: Create a method from a fully resolved file name */ -/******************************************************************************/ -{ - /* create a source object */ - RexxSource *source = RexxSource::classNewFile(filename); - ProtectedObject p(source); - /* finish up processing of this */ - return newRexxMethod(source, (RexxClass *)TheNilObject); -} - - - /** * Run this code as a method invocation. * Modified: sandbox/rick/opt/kernel/classes/MethodClass.hpp =================================================================== --- sandbox/rick/opt/kernel/classes/MethodClass.hpp 2008-02-24 01:18:25 UTC (rev 2377) +++ sandbox/rick/opt/kernel/classes/MethodClass.hpp 2008-02-26 00:29:33 UTC (rev 2378) @@ -92,6 +92,7 @@ BaseExecutable *setSourceObject(RexxSource *s); protected: + RexxString *executableName; // the created name of this routine BaseCode *code; // the backing code object }; @@ -101,8 +102,12 @@ public: void *operator new(size_t); inline void *operator new(size_t size, void *ptr) { return ptr; }; - RexxMethod(BaseCode *_code); - RexxMethod(RexxSource *source); + RexxMethod(RexxString *name, BaseCode *_code); + RexxMethod(RexxString *name, RexxSource *source); + RexxMethod(RexxString *name); + RexxMethod(RexxString *name, RexxBuffer *source); + RexxMethod(RexxString *name, const char *data, size_t length); + RexxMethod(RexxString *name, RexxArray *source); inline RexxMethod(RESTORETYPE restoreType) { ; }; void execute(RexxObject *, RexxObject *); @@ -140,13 +145,8 @@ RexxMethod *newRexx(RexxObject **, size_t); RexxMethod *newFileRexx(RexxString *); - static RexxMethod *newRexxMethod(RexxSource *, RexxClass *); static RexxMethod *newMethodObject(RexxString *, RexxObject *, RexxObject *, RexxSource *a); - static RexxMethod *newRexxBuffer(RexxString *, RexxBuffer *, RexxClass *); - static RexxMethod *newRexxBuffer(const char *, const char *, size_t); - static RexxMethod *newEntry(PNATIVEMETHOD); static RexxMethod *restore(RexxBuffer *, char *); - static RexxMethod *newFile(RexxString *); static RexxClass *classInstance; @@ -162,9 +162,4 @@ RexxClass *scope; /* pointer to the method scope */ }; - - -inline RexxMethod *new_method(BaseCode *c) { return new RexxMethod(c); } - - #endif Modified: sandbox/rick/opt/kernel/classes/ObjectClass.cpp =================================================================== --- sandbox/rick/opt/kernel/classes/ObjectClass.cpp 2008-02-24 01:18:25 UTC (rev 2377) +++ sandbox/rick/opt/kernel/classes/ObjectClass.cpp 2008-02-26 00:29:33 UTC (rev 2378) @@ -1130,6 +1130,7 @@ } } + RexxString *RexxObject::requiredString( size_t position ) /* required argument position */ /******************************************************************************/ @@ -1137,19 +1138,52 @@ /* the object MUST have a string value. */ /******************************************************************************/ { - RexxObject *string_value; /* converted object */ + RexxObject *string_value; /* converted object */ - if (this->isBaseClass()) /* primitive object? */ - string_value = this->makeString(); /* get the string representation */ - else /* do a full request for this */ - string_value = this->sendMessage(OREF_REQUEST, OREF_STRINGSYM); - /* didn't convert? */ - if (string_value == TheNilObject) - /* this is an error */ - reportException(Error_Incorrect_method_nostring, position); - return (RexxString *)string_value; /* return the converted form */ + if (this->isBaseClass()) /* primitive object? */ + { + string_value = this->makeString(); /* get the string representation */ + } + else /* do a full request for this */ + { + string_value = this->sendMessage(OREF_REQUEST, OREF_STRINGSYM); + } + /* didn't convert? */ + if (string_value == TheNilObject) + { + /* this is an error */ + reportException(Error_Incorrect_method_nostring, position); + } + return(RexxString *)string_value; /* return the converted form */ } + +RexxString *RexxObject::requiredString( + const char *name) /* required argument position */ +/******************************************************************************/ +/* Function: Handle a string request for a REXX object in a context where */ +/* the object MUST have a string value. */ +/******************************************************************************/ +{ + RexxObject *string_value; /* converted object */ + + if (this->isBaseClass()) /* primitive object? */ + { + string_value = this->makeString(); /* get the string representation */ + } + else /* do a full request for this */ + { + string_value = this->sendMessage(OREF_REQUEST, OREF_STRINGSYM); + } + /* didn't convert? */ + if (string_value == TheNilObject) + { + /* this is an error */ + reportException(Error_Incorrect_argument_string, name); + } + return(RexxString *)string_value; /* return the converted form */ +} + /** * Handle a string request for a required string value where * the caller wishes to handle the error itself. Modified: sandbox/rick/opt/kernel/classes/ObjectClass.hpp =================================================================== --- sandbox/rick/opt/kernel/classes/ObjectClass.hpp 2008-02-24 01:18:25 UTC (rev 2377) +++ sandbox/rick/opt/kernel/classes/ObjectClass.hpp 2008-02-26 00:29:33 UTC (rev 2378) @@ -391,6 +391,7 @@ bool requestUnsignedNumber(stringsize_t &, size_t); RexxArray *requestArray(); RexxString *requiredString(size_t); + RexxString *requiredString(const char *); RexxString *requiredString(); RexxInteger *requiredInteger(size_t, size_t); wholenumber_t requiredNumber(size_t position, size_t precision = Numerics::DEFAULT_DIGITS); Modified: sandbox/rick/opt/kernel/classes/PackageClass.cpp =================================================================== --- sandbox/rick/opt/kernel/classes/PackageClass.cpp 2008-02-24 01:18:25 UTC (rev 2377) +++ sandbox/rick/opt/kernel/classes/PackageClass.cpp 2008-02-26 00:29:33 UTC (rev 2378) @@ -80,6 +80,7 @@ /******************************************************************************/ { memory_mark(this->source); + memory_mark(this->objectVariables); } void PackageClass::liveGeneral(int reason) @@ -88,6 +89,7 @@ /******************************************************************************/ { memory_mark_general(this->source); + memory_mark_general(this->objectVariables); } void PackageClass::flatten(RexxEnvelope *envelope) @@ -98,6 +100,7 @@ setUpFlatten(PackageClass) flatten_reference(newThis->source, envelope); + flatten_reference(newThis->objectVariables, envelope); cleanUpFlatten } @@ -154,6 +157,17 @@ /** + * Get the number of source lines in the package + * + * @return the count of lines + */ +RexxInteger *PackageClass::getSourceSize() +{ + return new_integer(source->sourceSize()); +} + + +/** * Retrieve all classes defined by this package. * * @return A directory of all of the classes defined by this package. @@ -354,6 +368,74 @@ /** + * Add a routine to this package's private routine list. + * + * @param routine The routine to add. + * + * @return The target package object. + */ +RexxObject *PackageClass::addRoutine(RexxString *name, RoutineClass *routine) +{ + name = REQUIRED_STRING(name, "name"); + REQUIRED_INSTANCE(routine, TheRoutineClass, "routine"); + + source->addInstalledRoutine(name, routine, false); + return this; +} + + +/** + * Add a routine to this package's public routine list. + * + * @param routine The routine to add. + * + * @return The target package object. + */ +RexxObject *PackageClass::addPublicRoutine(RoutineClass *routine) +{ + name = REQUIRED_STRING(name, "name"); + REQUIRED_INSTANCE(routine, TheRoutineClass, "routine"); + + source->addInstalledRoutine(name, routine, true); + return this; +} + + +/** + * Add a class to this package's class list. + * + * @param clazz The class to add. + * + * @return The target package object. + */ +RexxObject *PackageClass::addClass(RexxClass *clazz) +{ + name = REQUIRED_STRING(name, "name"); + REQUIRED_INSTANCE(clazz, TheClassClass, "class"); + + source->addInstalledClass(name, clazz, false); + return this; +} + + +/** + * Add a class to this package's public class list. + * + * @param clazz The class to add. + * + * @return The target package object. + */ +RexxObject *PackageClass::addPublicClass(RexxClass *clazz) +{ + name = REQUIRED_STRING(name, "name"); + REQUIRED_INSTANCE(clazz, TheClassClass, "class"); + + source->addInstalledClass(name, clazz, true); + return this; +} + + +/** * Resolve a class in the context of a package. * * @param name The required class name. @@ -364,3 +446,48 @@ { return source->resolveClass(name); } + + +PackageClass *PackageClass::newRexx( + RexxObject **init_args, /* subclass init arguments */ + size_t argCount) /* number of arguments passed */ +/******************************************************************************/ +/* Function: Create a new packag from REXX code contained in a file or an */ +/* array */ +/******************************************************************************/ +{ + RexxObject *pgmname; /* method name */ + RexxObject *source; /* Array or string object */ + RexxObject *option = OREF_NULL; + size_t initCount = 0; /* count of arguments we pass along */ + + /* break up the arguments */ + + process_new_args(init_args, argCount, &init_args, &initCount, 2, (RexxObject **)&pgmname, (RexxObject **)&source); + + PackageClass *package = OREF_NULL; + + /* get the package name as a string */ + RexxString *nameString = REQUIRED_STRING(pgmname, ARG_ONE); + if (source == OREF_NULL) + { + RexxString *resolvedName = ActivityManager::currentActivity->getInstance()->resolveProgramName(pgmname, OREF_NULL, OREF_NULL); + package = PackageManager::loadRequires(ActivityManager::currentActivity, pgmname, resolvedName, package); + } + else + { + RexxArray *sourceArray = REQUIRED_ARRAY(soource, IntegerTwo); + package = PackageManager::loadRequires(ActivityManager::currentActivity, pgmname, sourceArray, package); + } + + ProtectedObject p(package); + /* Give new object its behaviour */ + newRoutine->setBehaviour(((RexxClass *)this)->getInstanceBehaviour()); + if (((RexxClass *)this)->hasUninitDefined()) + { + newRoutine->hasUninit(); /* Make sure everyone is notified. */ + } + /* now send an INIT message */ + newRoutine->sendMessage(OREF_INIT, init_args, initCount); + return newRoutine; /* return the new method */ +} Modified: sandbox/rick/opt/kernel/classes/PackageClass.hpp =================================================================== --- sandbox/rick/opt/kernel/classes/PackageClass.hpp 2008-02-24 01:18:25 UTC (rev 2377) +++ sandbox/rick/opt/kernel/classes/PackageClass.hpp 2008-02-26 00:29:33 UTC (rev 2378) @@ -62,7 +62,9 @@ RexxString *getName(); RexxArray *getSource(); RexxString *getSourceLine(size_t); + RexxInteger *getSourceSize(); RexxString *getSourceLineRexx(RexxObject *); + RexxObject *setSecurityManager(RexxObject *); RexxDirectory *getClasses(); RexxDirectory *getPublicClasses(); @@ -72,10 +74,17 @@ RexxDirectory *getPublicRoutines(); RexxDirectory *getImportedRoutines(); RexxArray *getImportedPackages(); - PackageClass *loadPackage(RexxString *name); + PackageClass *loadPackage(RexxString *name, RexxArray *source); RexxObject *addPackage(PackageClass *package); - RexxClass *resolveClass(RexxString *name); + RexxClass *findClass(RexxString *name); + RoutineClass *findRoutine(RexxString *name); + RexxObject *addRoutine(RexxString *name, RoutineClass *routine); + RexxObject *addPublicRoutine(RexxString *name, RoutineClass *routine); + RexxObject *addClass(RexxString *name, RexxClass *clazz); + RexxObject *addPublicClass(RexxString *name, RexxClass *clazz); + PackageClass *newRexx(RexxString *name, RexxArray *source); + inline RexxSource *getSourceObject() { return source; } protected: Modified: sandbox/rick/opt/kernel/classes/RoutineClass.cpp =================================================================== --- sandbox/rick/opt/kernel/classes/RoutineClass.cpp 2008-02-24 01:18:25 UTC (rev 2377) +++ sandbox/rick/opt/kernel/classes/RoutineClass.cpp 2008-02-26 00:29:33 UTC (rev 2378) @@ -68,21 +68,109 @@ RexxClass *RoutineClass::classInstance = OREF_NULL; -RoutineClass::RoutineClass(BaseCode *codeObj) -/******************************************************************************/ -/* Function: Initialize a method object */ -/******************************************************************************/ +/** + * Initialize a Routine object from a generated code object. Generally + * used for routines generated from ::ROUTINE directives. + * + * @param name The routine name. + * @param codeObj The associated code object. + */ +RoutineClass::RoutineClass(RexxString *name, BaseCode *codeObj) { this->clearObject(); /* start out fresh */ OrefSet(this, this->code, codeObj); /* store the code */ + OrefSet(this, this->executableName, name); } + +/** + * Initialize a RoutineClass object from a file source. + * + * @param name The routine name (and the resolved name of the file). + */ +RoutineClass::RoutineClass(RexxString *name) +{ + this->clearObject(); /* start out fresh */ + ProtectedObject p(this); // protect during processing + OrefSet(this, this->executableName, name); + // get a source object to generat this from + RexxSource *source = new RexxSource(name); + ProtectedObject p2(source); + // generate our code object and make the file hook up. + RexxCode *codeObj = source->generateCode(); + OrefSet(this, this->code, codeObj); +} + + +/** + * Initialize a Routine object using a buffered source. + * + * @param name The name of the routine. + * @param source the source buffer. + */ +RoutineClass::RoutineClass(RexxString *name, RexxBuffer *s) +{ + this->clearObject(); /* start out fresh */ + ProtectedObject p(this); // protect during processing + OrefSet(this, this->executableName, name); + // get a source object to generat this from + RexxSource *source = new RexxSource(name, s); + ProtectedObject p2(source); + // generate our code object and make the file hook up. + RexxCode *codeObj = source->generateCode(); + OrefSet(this, this->code, codeObj); +} + + +/** + * Initialize a Routine object using directly provided source. + * + * @param name The name of the routine. + * @param data The source data buffer pointer. + * @param length the length of the source buffer. + */ +RoutineClass::RoutineClass(RexxString *name, const char *data, size_t length) +{ + this->clearObject(); /* start out fresh */ + ProtectedObject p(this); // protect during processing + OrefSet(this, this->executableName, name); + // get a source object to generat this from + RexxSource *source = new RexxSource(name, data, length); + ProtectedObject p2(source); + // generate our code object and make the file hook up. + RexxCode *codeObj = source->generateCode(); + OrefSet(this, this->code, codeObj); +} + + +/** + * Initialize a Routine object using an array source. + * + * @param name The name of the routine. + * @param source the source buffer. + */ +RoutineClass::RoutineClass(RexxString *name, RexxArray *s) +{ + this->clearObject(); /* start out fresh */ + ProtectedObject p(this); // protect during processing + OrefSet(this, this->executableName, name); + // get a source object to generat this from + RexxSource *source = new RexxSource(name, s); + ProtectedObject p2(source); + // generate our code object and make the file hook up. + RexxCode *codeObj = source->generateCode(); + OrefSet(this, this->code, codeObj); +} + + void RoutineClass::live(size_t liveMark) /******************************************************************************/ /* Function: Normal garbage collection live marking */ /******************************************************************************/ { memory_mark(this->code); + memory_mark(this->executableName); + memory_mark(this->objectVariables); } void RoutineClass::liveGeneral(int reason) @@ -91,6 +179,8 @@ /******************************************************************************/ { memory_mark_general(this->code); + memory_mark_general(this->executableName); + memory_mark_general(this->objectVariables); } void RoutineClass::flatten(RexxEnvelope *envelope) @@ -101,6 +191,8 @@ setUpFlatten(RoutineClass) flatten_reference(newThis->code, envelope); + flatten_reference(newThis->executableName, envelope); + flatten_reference(newThis->objectVariables, envelope); cleanUpFlatten } @@ -141,6 +233,43 @@ } +/** + * Call a routine object from Rexx-level code. + * + * @param args The call arguments. + * @param count The count of arguments. + * + * @return The call result (if any). + */ +RexxObject *RoutineClass::callRexx(RexxObject **args, size_t count) +{ + ProtectedObject result; + + code->call(ActivityManager::currentActivity, this, executableName, args, count, result); + return (RexxObject *)result; +} + + +/** + * Call a routine object from Rexx-level code. + * + * @param args The call arguments. + * + * @return The call result (if any). + */ +RexxObject *RoutineClass::callWithRexx(RexxArray *args) +{ + // this is required and must be an array + args = REQUIRED_ARRAY(args, 1); + + ProtectedObject result; + + code->call(ActivityManager::currentActivity, this, executableName, args->data(), args->size(), result); + return (RexxObject *)result; +} + + + void RoutineClass::runProgram( RexxActivity *activity, RexxString * calltype, /* type of invocation */ @@ -254,20 +383,6 @@ /** - * Create a new Routine object from a source object. This - * creates a top-level routine object. - * - * @param source The original source object. - * - * @return A RoutineClass instance. - */ -RoutineClass *RoutineClass::newRoutine(RexxSource *source) -{ - // generate a new routine from the base source - return new_routine(source->generateCode()); -} - -/** * Construct a Routine using different forms of in-memory * source file. * @@ -327,13 +442,10 @@ } } } + // create the routine + RoutineClass *result = new RoutineClass(pgmname, newSourceArray); + ProtectedObject p(result); - /* create a source object */ - RexxSource *newSource = new RexxSource (pgmname, newSourceArray); - - ProtectedObject p(newSource); - RoutineClass *result = newRoutine(newSource); - p = result; // switch the protectiong // if we've been provided with a scope, use it @@ -357,6 +469,63 @@ } +/** + * Construct a Routine using different forms of in-memory + * source file. + * + * @param pgmname The name of the program. + * @param source The program source. This can be a string or an array of strings. + * @param position The argument position used for error reporting. + * @param parentSource + * A parent source context used to provide additional class and + * routine definitions. + * + * @return A constructed Routine object. + */ +RoutineClass *RoutineClass::newRoutineObject(RexxString *pgmname, RexxArray *source, RexxObject *position) +{ + // request this as an array. If not convertable, then we'll use it as a string + RexxArray *newSourceArray = source->requestArray(); + /* couldn't convert? */ + if (newSourceArray == (RexxArray *)TheNilObject) + { + /* raise an error */ + reportException(Error_Incorrect_method_no_method, position); + } + else /* have an array, make sure all */ + { + /* is it single dimensional? */ + if (newSourceArray->getDimension() != 1) + { + /* raise an error */ + reportException(Error_Incorrect_method_noarray, position); + } + /* element are strings. */ + /* Make a source array safe. */ + ProtectedObject p(newSourceArray); + /* Make sure all elements in array */ + for (size_t counter = 1; counter <= newSourceArray->size(); counter++) + { + /* Get element as string object */ + RexxString *sourceString = newSourceArray ->get(counter)->makeString(); + /* Did it convert? */ + if (sourceString == (RexxString *)TheNilObject) + { + /* and report the error. */ + reportException(Error_Incorrect_method_nostring_inarray, IntegerTwo); + } + else + { + /* itsa string add to source array */ + newSourceArray ->put(sourceString, counter); + } + } + } + // create the routine + return new RoutineClass(pgmname, newSourceArray); +} + + RoutineClass *RoutineClass::newRexx( RexxObject **init_args, /* subclass init arguments */ size_t argCount) /* number of arguments passed */ @@ -428,11 +597,8 @@ { /* get the method name as a string */ filename = REQUIRED_STRING(filename, ARG_ONE); - /* create a source object */ - RexxSource *source = RexxSource::classNewFile(filename); - ProtectedObject p(source); /* finish up processing of this */ - RoutineClass * newMethod = newRoutine(source); + RoutineClass * newMethod = new RoutineClass(filename); ProtectedObject p2(newMethod); /* Give new object its behaviour */ newMethod->setBehaviour(((RexxClass *)this)->getInstanceBehaviour()); @@ -447,48 +613,7 @@ } -RoutineClass *RoutineClass::newRexxBuffer( - RexxString *pgmname, /* file name to process */ - RexxBuffer *source) /* String or buffer with source */ -/******************************************************************************/ -/* Function: Build a new method object from buffered REXX source */ -/******************************************************************************/ -{ - if (source == OREF_NULL) /* didn't get source? */ - { - /* raise an error */ - reportException(Error_Incorrect_method_noarg, IntegerTwo); - } - /* create a source object */ - RexxSource *newSource = (RexxSource *)RexxSource::classNewBuffered(pgmname, source); - // we need to protect this source object until parsing is complete - ProtectedObject p(newSource); - /* now complete method creation */ - return newRoutine(newSource); -} - - /** - * Create a routine object from an in-store source. - * - * @param pgmname The program name (as an ASCII-Z string). - * @param source The pointer to the program source. - * @param length The length of the source. - * - * @return A translated Routine object. - */ -RoutineClass *RoutineClass::newRexxBuffer(RexxString *pgmname, const char *source, size_t length) -{ - /* create a source object */ - RexxSource *newSource = RexxSource::classNewBuffered(pgmname, source, length); - // we need to protect this source object until parsing is complete - ProtectedObject p(newSource); - /* now complete method creation */ - return newRoutine(newSource); -} - - -/** * Create a routine from a macrospace source. * * @param name The name of the macrospace item. @@ -553,7 +678,7 @@ } /* translate this source */ - RoutineClass *routine = newRexxBuffer(name, source_buffer); + RoutineClass *routine = new RoutineClass(name, source_buffer); /* return this back in instore[1] */ routine->save(&instore[1]); return routine; /* return translated source */ @@ -682,6 +807,21 @@ /** + * Set a security manager on a package. + * + * @param manager The security manager object. + * + * @return The security manager object. + */ +RexxObject *RoutineClass::setSecurityManager( + RexxObject *manager) /* supplied security manager */ +{ + source->setSecurityManager(manager); + return TheTrueObject; +} + + +/** * Retrieve a routine object from a file. This will first attempt * to restore a previously translated image, then will try to * translate the source if that fails. @@ -699,7 +839,7 @@ } // process this from the source - return newFile(filename); + return new RoutineClass(filename); } @@ -723,16 +863,4 @@ } -RoutineClass *RoutineClass::newFile( - RexxString *filename) /* name of the target file */ -/******************************************************************************/ -/* Function: Create a method from a fully resolved file name */ -/******************************************************************************/ -{ - /* create a source object */ - RexxSource *source = RexxSource::classNewFile(filename); - ProtectedObject p(source); - /* finish up processing of this */ - return newRoutine(source); -} Modified: sandbox/rick/opt/kernel/classes/RoutineClass.hpp =================================================================== --- sandbox/rick/opt/kernel/classes/RoutineClass.hpp 2008-02-24 01:18:25 UTC (rev 2377) +++ sandbox/rick/opt/kernel/classes/RoutineClass.hpp 2008-02-26 00:29:33 UTC (rev 2378) @@ -51,7 +51,11 @@ public: void *operator new(size_t); inline void *operator new(size_t size, void *ptr) { return ptr; }; - RoutineClass(BaseCode *_code); + RoutineClass(RexxString *n, BaseCode *_code); + RoutineClass(RexxString *name); + RoutineClass(RexxString *name, RexxBuffer *source); + RoutineClass(RexxString *name, const char *data, size_t length); + RoutineClass(RexxString *name, RexxArray *source); inline RoutineClass(RESTORETYPE restoreType) { ; }; void execute(RexxObject *, RexxObject *); @@ -64,6 +68,9 @@ void runProgram(RexxActivity *activity, RexxString * calltype, RexxString * environment, RexxObject **arguments, size_t argCount, ProtectedObject &result); void runProgram(RexxActivity *activity, RexxObject **arguments, size_t argCount, ProtectedObject &result); + RexxObject *callRexx(RexxObject **, size_t); + RexxObject *callWithRexx(RexxArray *); + RexxBuffer *save(); void save(PRXSTRING outBuffer); void save(const char *filename); @@ -81,19 +88,15 @@ static RoutineClass *fromFile(RexxString *filename); static RoutineClass *restoreFromFile(RexxString *filename); - static RoutineClass *newRoutine(RexxSource *); static RoutineClass *newRoutineObject(RexxString *, RexxObject *, RexxObject *, RexxSource *s); - static RoutineClass *newRexxBuffer(RexxString *, RexxBuffer *); - static RoutineClass *newRexxBuffer(RexxString *, const char *, size_t); + static RoutineClass *newRoutineObject(RexxString *, RexxArray *, RexxObject *); - static RoutineClass *newFile(RexxString *); - static RoutineClass *processInstore(PRXSTRING instore, RexxString * name ); static RexxClass *classInstance; }; -inline RoutineClass *new_routine(BaseCode *c) { return new RoutineClass(c); } +inline RoutineClass *new_routine(RexxString *n, BaseCode *c) { return new RoutineClass(n, c); } #endif Modified: sandbox/rick/opt/kernel/parser/Scanner.cpp =================================================================== --- sandbox/rick/opt/kernel/parser/Scanner.cpp 2008-02-24 01:18:25 UTC (rev 2377) +++ sandbox/rick/opt/kernel/parser/Scanner.cpp 2008-02-26 00:29:33 UTC (rev 2378) @@ -118,25 +118,6 @@ } } -RexxSource::RexxSource( - RexxString *programname, /* source program name */ - RexxArray *source_array ) /* program source array */ -/******************************************************************************/ -/* Function: Initialize a source object */ -/******************************************************************************/ -{ - this->clearObject(); /* start completely clean */ - /* fill in the name */ - OrefSet(this, this->programName, programname); - /* fill in the source array */ - OrefSet(this, this->sourceArray, source_array); - if (this->sourceArray) { /* have an array? */ - /* fill in the source size */ - this->line_count = sourceArray->size(); - this->position(1, 0); /* set position at the first line */ - } -} - /********************************************************************* * The following table detects alphanumeric characters and * * special characters that can be part of an REXX symbol. * Modified: sandbox/rick/opt/kernel/parser/SourceFile.cpp =================================================================== --- sandbox/rick/opt/kernel/parser/SourceFile.cpp 2008-02-24 01:18:25 UTC (rev 2377) +++ sandbox/rick/opt/kernel/parser/SourceFile.cpp 2008-02-26 00:29:33 UTC (rev 2378) @@ -43,7 +43,6 @@ /******************************************************************************/ #include <ctype.h> #include <string.h> -#define INCL_REXX_STREAM /* bring in all stream defines */ #include "RexxCore.h" #include "StringClass.hpp" #include "ArrayClass.hpp" @@ -96,6 +95,87 @@ #define line_delimiters "\r\n" /* stream file line end characters */ #define ctrl_z 0x0a // the end of file marker + +/** + * Create a source object with source provided from an array. + * + * @param programname + * The name of the program. + * @param source_array + * The array of the source lines. + */ +RexxSource::RexxSource(RexxString *programname, RexxArray *source_array) +{ + this->clearObject(); /* start completely clean */ + /* fill in the name */ + OrefSet(this, this->programName, programname); + /* fill in the source array */ + OrefSet(this, this->sourceArray, source_array); + /* fill in the source size */ + this->line_count = sourceArray->size(); + this->position(1, 0); /* set position at the first line */ +} + + +/** + * Create a source object with source provided from a buffer. + * + * @param programname + * The name of the program. + * @param source_buffer + * The source buffer holding the source data. + */ +RexxSource::RexxSource(RexxString *programname, RexxBuffer *source_buffer) +{ + this->clearObject(); /* start completely clean */ + /* fill in the name */ + OrefSet(this, this->programName, programname); + // we require a bit of protection while doing this + ProtectedObject p(this); + // initialize from the buffer data + initBuffered(source_buffer); +} + + +/** + * Create a source object with source provided from a a data buffer + * (not a buffer object). + * + * @param programname + * The name of the program. + * @param data The data buffer pointer. + * @param length the size of the source buffer. + */ +RexxSource::RexxSource(RexxString *programname, const char *data, size_t length) +{ + this->clearObject(); /* start completely clean */ + /* fill in the name */ + OrefSet(this, this->programName, programname); + // we require a bit of protection while doing this + ProtectedObject p(this); + // initialize from the buffer data + initBuffered(new_buffer(data, length)); +} + + +/** + * Create a source object with source provided from a filo. + * + * @param programname + * The name of the program (also the file name) + */ +RexxSource::RexxSource(RexxString *programname) +{ + this->clearObject(); /* start completely clean */ + /* fill in the name */ + OrefSet(this, this->programName, programname); + // we require a bit of protection while doing this + ProtectedObject p(this); + // read the file data and initialize. + initFile(); +} + + void RexxSource::initBuffered( RexxBuffer *source_buffer) /* containing source buffer */ /******************************************************************************/ @@ -2745,7 +2825,7 @@ { /* go do the next block of code */ RexxCode *code = this->translateBlock(OREF_NULL); - RoutineClass *routine = new_routine(code); + RoutineClass *routine = new_routine(name, code); /* add to the routine directory */ this->routines->setEntry(name, routine); if (Public == PUBLIC_SCOPE) /* a public routine? */ @@ -5115,48 +5195,7 @@ return newObject; /* return the new object */ } -RexxSource *RexxSource::classNewBuffered( - RexxString *programname, /* name of the program */ - RexxBuffer *source_buffer ) /* buffer containing the source */ -/******************************************************************************/ -/* Function: Create a new source object, using buffered input */ -/******************************************************************************/ -{ - RexxSource *newObject; /* newly created source object */ - ProtectedObject p(source_buffer); - newObject = new RexxSource (programname, OREF_NULL); - ProtectedObject p1(newObject); - /* process the buffering */ - newObject->initBuffered(source_buffer); - return newObject; /* return the new source object */ -} - -RexxSource *RexxSource::classNewBuffered(RexxString *programname, const char *source, size_t length) -{ - RexxSource *newObject = new RexxSource (programname, OREF_NULL); - ProtectedObject p1(newObject); - /* process the buffering */ - newObject->initBuffered(new_buffer(source, length)); - return newObject; /* return the new source object */ -} - -RexxSource *RexxSource::classNewFile( - RexxString *programname ) /* program file name */ -/******************************************************************************/ -/* Function: Create a source object from a file. */ -/******************************************************************************/ -{ - RexxSource *newObject; /* newly created source object */ - - /* create a new source object */ - newObject = new RexxSource (programname, OREF_NULL); - ProtectedObject p(newObject); - newObject->initFile(); /* go process the file */ - return newObject; /* return the new object */ -} - - /** * Generate a code object from a source file. * @@ -5167,13 +5206,11 @@ */ RexxCode *RexxSource::generateCodeFromFile(RexxString *programname ) { - RexxSource *newObject; /* newly created source object */ - - /* create a new source object */ - newObject = new RexxSource (programname, OREF_NULL); - ProtectedObject p(newObject); - newObject->initFile(); /* go process the file */ - return newObject->generateCode(); // generate a code object + // create a new source object from the file + RexxObject *newObject = new RexxSource(programname); + ProtectedObject p(newObject); + // now generate a code object from this file + return newObject->generateCode(); } @@ -5607,3 +5644,25 @@ installed_public_classes->setEntry(name, classObject); } } + + +/** + * Add an installed routine to this source package + * + * @param name The routine name + * @param classObject + * The routine object + * @param publicClass + * Indicates whether this needs to be added to the public list as well. + */ +void RexxSource::addInstalledClass(RexxString *name, RoutineClass *routinebject, bool publicRoutine) +{ + installed_routines->setEntry(name, routinedObject); + if (publicRoutine) + { + installed_public_routines->setEntry(name, routineObject); + } +} + + + Modified: sandbox/rick/opt/kernel/parser/SourceFile.hpp =================================================================== --- sandbox/rick/opt/kernel/parser/SourceFile.hpp 2008-02-24 01:18:25 UTC (rev 2377) +++ sandbox/rick/opt/kernel/parser/SourceFile.hpp 2008-02-26 00:29:33 UTC (rev 2378) @@ -98,6 +98,9 @@ inline void operator delete(void *) { ; } inline void operator delete(void *, void *) { ; } RexxSource(RexxString *, RexxArray *); + RexxSource(RexxString *programname, RexxBuffer *source_buffer); + RexxSource(RexxString *programname, const char *data, size_t length); + RexxSource(RexxString *programname); inline RexxSource(RESTORETYPE restoreType) { ; }; void initBuffered(RexxBuffer *); void initFile(); @@ -221,9 +224,6 @@ void errorPosition(int, RexxToken *); void errorToken(int, RexxToken *); void blockError(RexxInstruction *); - static RexxSource *classNewBuffered(RexxString *, RexxBuffer *); - static RexxSource *classNewBuffered(RexxString *, const char *, size_t length); - static RexxSource *classNewFile(RexxString *); static RexxCode *generateCodeFromFile(RexxString *); RexxObject *sourceNewObject(size_t, RexxBehaviour *, int); void parseTraceSetting(RexxString *, size_t *, size_t *); @@ -337,6 +337,7 @@ } void addInstalledClass(RexxString *name, RexxClass *classObject, bool publicClass); + void addInstalledRoutine(RexxString *name, RoutineClass *routineObject, bool publicRoutine); RexxDirectory *getInstalledClasses() { return installed_classes; } RexxDirectory *getInstalledPublicClasses() { return installed_public_classes; } Modified: sandbox/rick/opt/kernel/runtime/LibraryPackage.cpp =================================================================== --- sandbox/rick/opt/kernel/runtime/LibraryPackage.cpp 2008-02-24 01:18:25 UTC (rev 2377) +++ sandbox/rick/opt/kernel/runtime/LibraryPackage.cpp 2008-02-26 00:29:33 UTC (rev 2378) @@ -257,23 +257,24 @@ // convert them to uppercase because "normal" Rexx function names // tend to be uppercase. RexxString *target = new_upper_string(table->name)->upper(); + RexxString *routineName = new_string(table->name); RexxRoutine *func = OREF_NULL; if (table->style == ROUTINE_CLASSIC_STYLE) { - func = new RegisteredRoutine(libraryName, new_string(table->name), (PREGISTEREDROUTINE)table->entryPoint); + func = new RegisteredRoutine(libraryName, routineName, (PREGISTEREDROUTINE)table->entryPoint); } else { - func = new RexxNativeRoutine(libraryName, new_string(table->name), (PNATIVEROUTINE)table->entryPoint); + func = new RexxNativeRoutine(libraryName, routineName, (PNATIVEROUTINE)table->entryPoint); } - RoutineClass *routine = new_routine(func); + RoutineClass *routine = new_routine(name, func); // add this to our local table routines->put(routine, target); // add this to the global function pool - PackageManager::addPackageRoutine(target, new_routine(func)); + PackageManager::addPackageRoutine(target, routine); // step to the next table entry table++; } Modified: sandbox/rick/opt/kernel/runtime/PackageManager.cpp =================================================================== --- sandbox/rick/opt/kernel/runtime/PackageManager.cpp 2008-02-24 01:18:25 UTC (rev 2377) +++ sandbox/rick/opt/kernel/runtime/PackageManager.cpp 2008-02-26 00:29:33 UTC (rev 2378) @@ -573,20 +573,15 @@ return OREF_NULL; } + // first check this using the specified name. Since we need to perform checks in the // macro space, it's possible this will be loaded under the simple name. We'll need to check // table again using the fully resolved name afterward. - WeakReference *requiresRef = (WeakReference *)loadedRequires->get(shortName); - if (requiresRef != OREF_NULL) + + PackageClass *package = checkRequiresCache(shortName, result); + if (package != OREF_NULL) { - PackageClass *resolved = (PackageClass *)requiresRef->get(); - if (resolved != OREF_NULL) - { - result = resolved; - return resolved; - } - // this was garbage collected, remove it from the table - loadedRequires->remove(shortName); + return package; } unsigned short macroPosition; // a macrospace position marker @@ -612,21 +607,14 @@ } - // first check this using the specified name. Since we need to perform checks in the - // macro space, it's possible this will be loaded under the simple name. We'll need to check - // table again using the fully resolved name afterward. - requiresRef = (WeakReference *)loadedRequires->get(resolvedName); - if (requiresRef != OREF_NULL) + // now check again using the longer name + package = checkRequiresCache(resolvedName, result); + if (package != OREF_NULL) { - PackageClass *resolved = (PackageClass *)requiresRef->get(); - if (resolved != OREF_NULL) - { - result = resolved; - return resolved; - } - // this was garbage collected, remove it from the table - loadedRequires->remove(resolvedName); + return package; } + + // load the file version of this. return getRequiresFile(activity, resolvedName, securityManager, result); } @@ -717,7 +705,64 @@ */ PackageClass *PackageManager::loadRequires(RexxActivity *activity, RexxString *name, const char *data, size_t length, ProtectedObject &result) { + // first check this using the specified name. + PackageClass *resolved = checkRequiresCache(name, result); + if (resolved != OREF_NULL) + { + return resolved; + } + RoutineClass *code = RoutineClass::newRexxBuffer(name, data, length); + PackageClass *package = code->getPackage(); + result = package; + + runRequires(activity, name, code); + + + WeakReference *ref = new WeakReference(package); + loadedRequires->put(ref, name); + return package; +} + + +/** + * Loade a requires file from an array source. NOTE: This is + * not cached like the other requires files + * + * @param activity The current activity. + * @param name The fully resolved file name. + * @param result The return routine object. + * + * @... [truncated message content] |