Ejemplo n.º 1
0
Archivo: IoCoroutine.c Proyecto: jdp/io
IoObject *IoObject_performWithDebugger(IoCoroutine *self, IoObject *locals, IoMessage *m)
{
	IoState *state = IOSTATE;
	IoObject *currentCoroutine = IoState_currentCoroutine(state);

	if (IoCoroutine_rawDebuggingOn(currentCoroutine))
	{
		IoObject *debugger = state->debugger; // stack retain it?

		if (debugger)
		{
			IoObject_setSlot_to_(debugger, IOSYMBOL("messageCoroutine"), currentCoroutine);
			IoObject_setSlot_to_(debugger, IOSYMBOL("messageSelf"), self);
			IoObject_setSlot_to_(debugger, IOSYMBOL("messageLocals"), locals);
			IoObject_setSlot_to_(debugger, IOSYMBOL("message"), m);

			{
				IoObject *context;
				IoCoroutine *c = IoObject_rawGetSlot_context_(debugger, IOSYMBOL("debuggerCoroutine"), &context);
				IOASSERT(c, "Debugger needs a debuggerCoroutine slot");
				IoCoroutine_rawResume(c);
			}
		}
	}

	return IoObject_perform(self, locals, m);
}
Ejemplo n.º 2
0
IoObject *IoMessage_locals_performOn_(IoMessage *self, IoObject *locals, IoObject *target)
{
	IoState *state = IOSTATE;
	IoMessage *m = self;
	IoObject *result = target;
	IoObject *cachedTarget = target;
	//IoObject *semicolonSymbol = state->semicolonSymbol;
	//IoMessageData *md;
	IoMessageData *md;

	if (state->receivedSignal) 
	{
		IoState_callUserInterruptHandler(IOSTATE);
	}
			
	do
	{
		//md = DATA(m);
		//printf("%s %i\n", CSTRING(IoMessage_name(m)), state->stopStatus);
		//if(state->showAllMessages) 
		//printf("M:%s:%s:%i\n", CSTRING(IoMessage_name(m)), CSTRING(IoMessage_rawLabel(m)), IoMessage_rawLineNumber(m));
		
		md = DATA(m);

		if(md->name == state->semicolonSymbol)
		{
			target = cachedTarget;
		}
		else
		{
			result = md->cachedResult; // put it on the stack?
			/*
			if(state->debugOn)
			{
				char *s = CSTRING(DATA(m)->name);
				printf("%s\n", s);
				if (strcmp(s, "clone") == 0)
				{
					printf("found '%s'\n", s);
				}
			}
			*/

			if (!result)
			{
				IoState_pushRetainPool(state);
#ifdef IOMESSAGE_INLINE_PERFORM
				if(IoObject_tag(target)->performFunc == NULL)
				{
					result = IoObject_perform(target, locals, m);
				}
				else
				{
					result = IoObject_tag(target)->performFunc(target, locals, m);
				}
#else
				result = IoObject_tag(target)->performFunc(target, locals, m);
#endif
				IoState_popRetainPoolExceptFor_(state, result);
			}

			//IoObject_freeIfUnreferenced(target);
			target = result;
			
			if (state->stopStatus != MESSAGE_STOP_STATUS_NORMAL)
			{
					return state->returnValue;
					/*
					result = state->returnValue;

					if (result)
					{
						//IoState_stackRetain_(state, result);
						return result;
					}
					printf("IoBlock no result!\n");
					return state->ioNil;
					*/
			}
		}
	} while ((m = md->next));
			
	return result;
}
Ejemplo n.º 3
0
IoObject *IoMessage_locals_performOn_(IoMessage *self, IoObject *locals, IoObject *target)
{
	IoState *state = IOSTATE;
	IoMessage *m = self;                // The message being processed
	IoObject *result = target;          // The value that this function will return
	IoObject *cachedTarget = target;    // The original target
	IoMessageData *md;                  // Data for the message being processed
    int hereStepOut = 0;            // Step out from this invocation of IoMessage_locals_performOn_
    int hereStepNext = 0;           // Step next in this invocation of IoMessage_locals_performOn_

    /*
	if (state->receivedSignal)
	{
		IoState_callUserInterruptHandler(IOSTATE);
	}
	*/

    // Catch step next into first line of this block of code,
    // handle it like a step in on the first message.
    if (state->stepMode == StepMode_StepNext)
    {
        state->stepMode = StepMode_StopOnAnyMessage;
    }

	do
	{
		md = DATA(m);
		//printf("%s %i\n", CSTRING(IoMessage_name(m)), state->stopStatus);
		//if(state->showAllMessages)
		//printf("M:%s:%s:%i\n", CSTRING(IoMessage_name(m)), CSTRING(IoMessage_rawLabel(m)), IoMessage_rawLineNumber(m));

		if (md->breakpoint || state->stepMode == StepMode_StopOnAnyMessage)
		{
		    StepMode_t mode;

		    if (md->breakpoint)
                mode = iovm_hit_breakpoint(md->breakpoint, target, locals, m);
		    else
                mode = iovm_step_stop(target, locals, m);

            if (mode == StepMode_StepOut)
            {
                state->stepMode = StepMode_RunOut;
                hereStepOut = 1;
                hereStepNext = 0;
            }
            else if (mode == StepMode_StepNext)
            {
                state->stepMode = StepMode_RunNext;
                hereStepNext = 1;
                hereStepOut = 0;
            }
            else
            {
                state->stepMode = mode;
                hereStepNext = 0;
                hereStepOut = 0;
            }
		}

        // Here we're checking if the current message is an end-of-line or semicolon.
		if(md->name == state->semicolonSymbol)
		{
		    // What we are doing here is reseting the environment so that we
		    // process the next line with the same target (such as locals)
		    // as we previously used to process the beginning of the line that is ending.
			target = cachedTarget;

            // If we were running over a step next from this level,
            // convert that to a stop on the very next message.
			if (hereStepNext && state->stepMode == StepMode_RunNext)
			{
                state->stepMode = StepMode_StopOnAnyMessage;
			}
		}
		else
		{
		    // OK not the end of a line so process a message in the chain.

		    // If there's a cached result in this component, use it.
			result = md->cachedResult; // put it on the stack?

			/*
			if(state->debugOn)
			{
				char *s = CSTRING(DATA(m)->name);
				printf("%s\n", s);
				if (strcmp(s, "clone") == 0)
				{
					printf("found '%s'\n", s);
				}
			}
			*/

            // Check if there wasn't a cached result
			if (!result)
			{
			    // There was not a cached result so perform the message.

			    // Is the stack frame pushed here?
				IoState_pushRetainPool(state);

#ifdef IOMESSAGE_INLINE_PERFORM

                // Here is where we actually perform the message.
                // Step-in would have to break in new copy of this function.

				if(IoObject_tag(target)->performFunc == NULL)
				{
					result = IoObject_perform(target, locals, m);
				}
				else
				{
					result = IoObject_tag(target)->performFunc(target, locals, m);
				}

#else
				result = IoObject_tag(target)->performFunc(target, locals, m);
#endif

                // Don't collect the result object
				IoState_popRetainPoolExceptFor_(state, result);
			}

			//IoObject_freeIfUnreferenced(target);

			// Here we are saying use the result from the chain so far as the
			// target on the next iteration.  So for instance if you said
			// a b c() we're going to use the result of (a b) as target for c().
			target = result;

            // STOP_STATUS_NORMAL means we are going forward as normal,
            // and not breaking, continuing, returning, etc.
            // So stopStatus != normal means exit the loop.
			if (state->stopStatus != MESSAGE_STOP_STATUS_NORMAL)
			{
			    if (state->stopStatus == MESSAGE_STOP_STATUS_RETURN &&
                    hereStepOut && state->stepMode == StepMode_RunOut)
                    state->stepMode = StepMode_StopOnAnyMessage;

                return state->returnValue;
			}
		}

	} while ((m = md->next));

    // Finished with block of lines, exiting the expression
    // by reaching the ending ")" or last line.
    if (hereStepOut && state->stepMode == StepMode_RunOut)
        state->stepMode = StepMode_StopOnAnyMessage;

	return result;
}