/** * Run a routine for a thread context API call. */ void CallProgramDispatcher::run() { RexxString *targetName = new_string(program); /* go resolve the name */ RexxString *name = activity->resolveProgramName(targetName, OREF_NULL, OREF_NULL); if (name == OREF_NULL) /* not found? */ { /* got an error here */ reportException(Error_Program_unreadable_notfound, targetName); } ProtectedObject p(name); // create a routine from this file RoutineClass *routine = RoutineClass::fromFile(name); p = routine; if (arguments != OREF_NULL) { size_t argumentsCount = arguments->size(); RexxArray *argumentsCopy = (RexxArray *)arguments->copy(); ProtectedObject p(argumentsCopy); argumentsCopy->put(IntegerZero, argumentsCount + 1); // Counter of named arguments (Zero). To support correctly omitted positional arguments, don't use append! // use the provided name for the call name routine->runProgram(activity, argumentsCopy->data(), argumentsCount, result); } else { // we use a null string for the name when things are called directly routine->runProgram(activity, NULL, 0, result); } }
/** * Return the information that needs to be saved in the saved * image. * * @return An array of the items added to the saved image. */ RexxArray *PackageManager::getImageData() { RexxArray *imageArray = new_array(IMAGE_ARRAY_SIZE); imageArray->put(packages, IMAGE_PACKAGES); imageArray->put(packageRoutines, IMAGE_PACKAGE_ROUTINES); imageArray->put(registeredRoutines, IMAGE_REGISTERED_ROUTINES); imageArray->put(loadedRequires, IMAGE_REQUIRES); return imageArray; }
/** * Extract from the method dictionary all methods defined with * a given scope. * * @param scope The target scope. If null, then all methods * are returned. * * @return A supplier holding the names and methods with the target * scope. This supplier can be empty. */ RexxSupplier *RexxBehaviour::getMethods(RexxObject *scope) { // if asking for everything, just return the supplier. if (scope == OREF_NULL) { return this->methodDictionary->supplier(); } size_t count = 0; HashLink i; // travese the method dictionary, searching for methods with the target scope for (i = this->methodDictionary->first(); this->methodDictionary->index(i) != OREF_NULL; i = this->methodDictionary->next(i)) { if (((RexxMethod *)this->methodDictionary->value(i))->getScope() == scope) { count++; } } RexxArray *names = new_array(count); RexxArray *methods = new_array(count); count = 1; // pass two, copy the entries into the array for (i = this->methodDictionary->first(); this->methodDictionary->index(i) != OREF_NULL; i = this->methodDictionary->next(i)) { if (((RexxMethod *)this->methodDictionary->value(i))->getScope() == scope) { names->put(this->methodDictionary->index(i), count); methods->put(this->methodDictionary->value(i), count); count++; } } return (RexxSupplier *)new_supplier(methods, names); }
RexxMethod *RexxBehaviour::superMethod( RexxString * messageName, /* target method name */ RexxObject * startScope) /* starting scope */ /******************************************************************************/ /* Function: Find a method using the given starting scope information */ /******************************************************************************/ { /* if we have scopes defined and we */ /* have a good start scope */ if (this->scopes != OREF_NULL && startScope != TheNilObject) { /* get the scope list for the given */ /* starting scope */ RexxArray *scopeList = (RexxArray *)this->scopes->get(startScope); if (scopeList != OREF_NULL) /* have a matching list? */ { /* get a list of methods */ RexxArray *methods = this->methodDictionary->stringGetAll(messageName); size_t scopes_size = scopeList->size(); /* get the two array sizes */ size_t methods_size = methods->size(); /* search through the methods list */ /* for the first one with a */ /* conforming scope */ for (size_t i = 1; i <= methods_size; i++) { /* get the next method */ RexxMethod *method = (RexxMethod *)methods->get(i); /* now loop through the scopes list */ for (size_t j = 1; j <= scopes_size; j++) { /* got a matching scope here? */ if (scopeList->get(j) == method->getScope()) { return method; /* return the method */ } } } } } return OREF_NULL; /* nothing found */ }
void RexxInstructionForward::execute( RexxActivation *context, /* current activation context */ RexxExpressionStack *stack) /* evaluation stack */ /******************************************************************************/ /* Function: Execute a forward instruction */ /******************************************************************************/ { RexxObject *_target; /* evaluated target */ RexxString *_message; /* evaluated message */ RexxObject *_superClass; /* evaluated super class */ RexxObject *result; /* message result */ RexxObject *temp; /* temporary object */ size_t count = 0; /* count of array expressions */ size_t i; /* loop counter */ RexxObject **_arguments; ProtectedObject p_message; context->traceInstruction(this); /* trace if necessary */ if (!context->inMethod()) /* is this a method clause? */ { /* raise an error */ reportException(Error_Execution_forward); } _target = OREF_NULL; /* no object yet */ _message = OREF_NULL; /* no message over ride */ _superClass = OREF_NULL; /* no super class over ride */ _arguments = OREF_NULL; /* no argument over ride */ if (this->target != OREF_NULL) /* sent to a different object? */ { /* get the expression value */ _target = this->target->evaluate(context, stack); } if (this->message != OREF_NULL) /* sending a different message? */ { /* get the expression value */ temp = this->message->evaluate(context, stack); _message = REQUEST_STRING(temp); /* get the string version */ p_message = _message; _message = _message->upper(); /* and force to uppercase */ p_message = _message; } if (this->superClass != OREF_NULL) /* overriding the super class? */ { /* get the expression value */ _superClass = this->superClass->evaluate(context, stack); } if (this->arguments != OREF_NULL) /* overriding the arguments? */ { /* get the expression value */ temp = this->arguments->evaluate(context, stack); /* get an array version */ RexxArray *argArray = REQUEST_ARRAY(temp); stack->push(argArray); /* protect this on the stack */ /* not an array item or a multiple */ /* dimension one? */ if (argArray == TheNilObject || argArray->getDimension() != 1) { /* this is an error */ reportException(Error_Execution_forward_arguments); } count = argArray->size(); /* get the size */ /* omitted trailing arguments? */ if (count != 0 && argArray->get(count) == OREF_NULL) { count--; /* decrement the count */ while (count > 0) /* loop down to first full one */ { /* find a real argument */ if (argArray->get(count) != OREF_NULL) { break; /* break out of here */ } count--; /* step back the count */ } } _arguments = argArray->data(); /* point directly to the argument data */ } if (this->array != OREF_NULL) /* have an array of extra info? */ { count = this->array->size(); /* get the expression count */ for (i = 1; i <= count; i++) /* loop through the expression list */ { RexxObject *argElement = this->array->get(i); /* real argument? */ if (argElement != OREF_NULL) { /* evaluate the expression */ argElement->evaluate(context, stack); } else { /* just push a null reference for the missing ones */ stack->push(OREF_NULL); } } /* now point at the stacked values */ _arguments = stack->arguments(count); } /* go forward this */ result = context->forward(_target, _message, _superClass, _arguments, count, instructionFlags&forward_continue); if (instructionFlags&forward_continue) /* not exiting? */ { if (result != OREF_NULL) /* result returned? */ { context->traceResult(result); /* trace if necessary */ /* set the RESULT variable to the */ /* message return value */ context->setLocalVariable(OREF_RESULT, VARIABLE_RESULT, result); } else /* drop the variable RESULT */ { context->dropLocalVariable(OREF_RESULT, VARIABLE_RESULT); } context->pauseInstruction(); /* do debug pause if necessary */ } }