fixed a compiler bug that omitted the RETURN_FROM_BLOCK instruction when an empty block is encountered.
added more code for supporting the process stack
This commit is contained in:
323
stix/lib/exec.c
323
stix/lib/exec.c
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2014-2015 Chung, Hyung-Hwan. All rights reserved.
|
||||
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
@ -33,7 +33,11 @@
|
||||
|
||||
/* TODO: context's stack overflow check in various part of this file */
|
||||
/* TOOD: determine the right stack size */
|
||||
#define CONTEXT_STACK_SIZE 96
|
||||
#if defined(STIX_USE_PROCSTK)
|
||||
# define CONTEXT_STACK_SIZE 0
|
||||
#else
|
||||
# define CONTEXT_STACK_SIZE 96
|
||||
#endif
|
||||
|
||||
#define LOAD_IP(stix, v_ctx) ((stix)->ip = STIX_OOP_TO_SMOOI((v_ctx)->ip))
|
||||
#define STORE_IP(stix, v_ctx) ((v_ctx)->ip = STIX_SMOOI_TO_OOP((stix)->ip))
|
||||
@ -44,53 +48,79 @@
|
||||
#define LOAD_ACTIVE_IP(stix) LOAD_IP(stix, (stix)->active_context)
|
||||
#define STORE_ACTIVE_IP(stix) STORE_IP(stix, (stix)->active_context)
|
||||
|
||||
#define LOAD_ACTIVE_SP(stix) LOAD_SP(stix, (stix)->active_context)
|
||||
#define STORE_ACTIVE_SP(stix) STORE_SP(stix, (stix)->active_context)
|
||||
#if defined(STIX_USE_PROCSTK)
|
||||
#define LOAD_ACTIVE_SP(stix) LOAD_SP(stix, (stix)->processor->active)
|
||||
#define STORE_ACTIVE_SP(stix) STORE_SP(stix, (stix)->processor->active)
|
||||
|
||||
#define ACTIVE_STACK_PUSH(stix,v) \
|
||||
do { \
|
||||
(stix)->sp = (stix)->sp + 1; \
|
||||
(stix)->processor->active->slot[(stix)->sp] = v; \
|
||||
} while (0)
|
||||
|
||||
#define ACTIVE_STACK_PUSH(stix,v) \
|
||||
do { \
|
||||
(stix)->sp = (stix)->sp + 1; \
|
||||
(stix)->active_context->slot[(stix)->sp] = v; \
|
||||
} while (0)
|
||||
#define ACTIVE_STACK_GET(stix,v_sp) ((stix)->processor->active->slot[v_sp])
|
||||
#define ACTIVE_STACK_SET(stix,v_sp,v_obj) ((stix)->processor->active->slot[v_sp] = v_obj)
|
||||
|
||||
#else
|
||||
#define LOAD_ACTIVE_SP(stix) LOAD_SP(stix, (stix)->active_context)
|
||||
#define STORE_ACTIVE_SP(stix) STORE_SP(stix, (stix)->active_context)
|
||||
|
||||
#define ACTIVE_STACK_PUSH(stix,v) \
|
||||
do { \
|
||||
(stix)->sp = (stix)->sp + 1; \
|
||||
(stix)->active_context->slot[(stix)->sp] = v; \
|
||||
} while (0)
|
||||
|
||||
#define ACTIVE_STACK_GET(stix,v_sp) ((stix)->active_context->slot[v_sp])
|
||||
#define ACTIVE_STACK_SET(stix,v_sp,v_obj) ((stix)->active_context->slot[v_sp] = v_obj)
|
||||
#endif
|
||||
|
||||
#define ACTIVE_STACK_GETTOP(stix) ACTIVE_STACK_GET(stix, (stix)->sp)
|
||||
#define ACTIVE_STACK_SETTOP(stix,v_obj) ACTIVE_STACK_SET(stix, (stix)->sp, v_obj)
|
||||
|
||||
#define ACTIVE_STACK_POP(stix) ((stix)->sp = (stix)->sp - 1)
|
||||
#define ACTIVE_STACK_UNPOP(stix) ((stix)->sp = (stix)->sp + 1)
|
||||
#define ACTIVE_STACK_POPS(stix,count) ((stix)->sp = (stix)->sp - (count))
|
||||
|
||||
#define ACTIVE_STACK_GET(stix,v_sp) ((stix)->active_context->slot[v_sp])
|
||||
#define ACTIVE_STACK_SET(stix,v_sp,v_obj) ((stix)->active_context->slot[v_sp] = v_obj)
|
||||
#define ACTIVE_STACK_GETTOP(stix) ACTIVE_STACK_GET(stix, (stix)->sp)
|
||||
#define ACTIVE_STACK_SETTOP(stix,v_obj) ACTIVE_STACK_SET(stix, (stix)->sp, v_obj)
|
||||
|
||||
#define ACTIVE_STACK_ISEMPTY(stix) ((stix)->sp <= -1)
|
||||
|
||||
#define SWITCH_ACTIVE_CONTEXT(stix,v_ctx) \
|
||||
do \
|
||||
{ \
|
||||
STORE_ACTIVE_IP (stix); \
|
||||
STORE_ACTIVE_SP (stix); \
|
||||
(stix)->active_context = (v_ctx); \
|
||||
(stix)->active_method = (stix_oop_method_t)(stix)->active_context->origin->method_or_nargs; \
|
||||
SET_ACTIVE_METHOD_CODE(stix); \
|
||||
LOAD_ACTIVE_IP (stix); \
|
||||
LOAD_ACTIVE_SP (stix); \
|
||||
} while (0) \
|
||||
#if defined(STIX_USE_PROCSTK)
|
||||
#define SWITCH_ACTIVE_CONTEXT(stix,v_ctx) \
|
||||
do \
|
||||
{ \
|
||||
STORE_ACTIVE_IP (stix); \
|
||||
(stix)->active_context = (v_ctx); \
|
||||
(stix)->active_method = (stix_oop_method_t)(stix)->active_context->origin->method_or_nargs; \
|
||||
SET_ACTIVE_METHOD_CODE(stix); \
|
||||
LOAD_ACTIVE_IP (stix); \
|
||||
} while (0)
|
||||
#else
|
||||
#define SWITCH_ACTIVE_CONTEXT(stix,v_ctx) \
|
||||
do \
|
||||
{ \
|
||||
STORE_ACTIVE_IP (stix); \
|
||||
STORE_ACTIVE_SP (stix); \
|
||||
(stix)->active_context = (v_ctx); \
|
||||
(stix)->active_method = (stix_oop_method_t)(stix)->active_context->origin->method_or_nargs; \
|
||||
SET_ACTIVE_METHOD_CODE(stix); \
|
||||
LOAD_ACTIVE_IP (stix); \
|
||||
LOAD_ACTIVE_SP (stix); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define FETCH_BYTE_CODE(stix) ((stix)->active_code[(stix)->ip++])
|
||||
#define FETCH_BYTE_CODE_TO(stix, v_ooi) (v_ooi = FETCH_BYTE_CODE(stix))
|
||||
#if (STIX_BCODE_LONG_PARAM_SIZE == 2)
|
||||
#define FETCH_PARAM_CODE_TO(stix, v_ooi) \
|
||||
do { \
|
||||
v_ooi = FETCH_BYTE_CODE(stix); \
|
||||
v_ooi = (v_ooi << 8) | FETCH_BYTE_CODE(stix); \
|
||||
} while (0)
|
||||
# define FETCH_PARAM_CODE_TO(stix, v_ooi) \
|
||||
do { \
|
||||
v_ooi = FETCH_BYTE_CODE(stix); \
|
||||
v_ooi = (v_ooi << 8) | FETCH_BYTE_CODE(stix); \
|
||||
} while (0)
|
||||
#else
|
||||
#define FETCH_PARAM_CODE_TO(stix, v_ooi) (v_ooi = FETCH_BYTE_CODE(stix))
|
||||
# define FETCH_PARAM_CODE_TO(stix, v_ooi) (v_ooi = FETCH_BYTE_CODE(stix))
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(STIX_DEBUG_EXEC)
|
||||
#if defined(STIX_DEBUG_EXEC_001)
|
||||
# define DBGOUT_EXEC_0(fmt) printf(fmt "\n")
|
||||
# define DBGOUT_EXEC_1(fmt,a1) printf(fmt "\n",a1)
|
||||
# define DBGOUT_EXEC_2(fmt,a1,a2) printf(fmt "\n", a1, a2)
|
||||
@ -115,6 +145,9 @@ static stix_oop_process_t make_process (stix_t* stix, stix_oop_context_t c)
|
||||
proc->initial_context = c;
|
||||
proc->sp = STIX_SMOOI_TO_OOP(-1);
|
||||
|
||||
#if defined(STIX_DEBUG_PROCESSOR)
|
||||
printf ("PROCESS %p SIZE => %ld\n", proc, (long int)STIX_OBJ_GET_SIZE(proc));
|
||||
#endif
|
||||
return proc;
|
||||
}
|
||||
|
||||
@ -126,16 +159,32 @@ static void switch_process (stix_t* stix, stix_oop_process_t proc)
|
||||
printf ("ACTUAL PROCESS SWITCHING BF...%d %p\n", (int)stix->ip, stix->active_context);
|
||||
#endif
|
||||
|
||||
/* store the active context to the active process */
|
||||
STIX_ASSERT ((stix_oop_t)stix->processor->active != stix->_nil);
|
||||
stix->processor->active->active_context = stix->active_context;
|
||||
#if defined(STIX_USE_PROCSTK)
|
||||
STORE_ACTIVE_SP(stix);
|
||||
#else
|
||||
/* nothing special */
|
||||
#endif
|
||||
|
||||
/* store the active context to the active process */
|
||||
STIX_ASSERT ((stix_oop_t)stix->processor->active != stix->_nil);
|
||||
stix->processor->active->active_context = stix->active_context;
|
||||
|
||||
/* switch the active process */
|
||||
/*TODO: set the state to RUNNING */
|
||||
stix->processor->active = proc;
|
||||
|
||||
#if defined(STIX_USE_PROCSTK)
|
||||
LOAD_ACTIVE_SP(stix);
|
||||
#else
|
||||
/* nothing special */
|
||||
#endif
|
||||
|
||||
/* switch the active context */
|
||||
SWITCH_ACTIVE_CONTEXT (stix, proc->active_context);
|
||||
|
||||
#if defined(STIX_DEBUG_PROCESSOR)
|
||||
printf ("ACTUAL PROCESS SWITCHING AF...%d %p\n", (int)stix->ip, stix->active_context);
|
||||
#endif
|
||||
/*TODO: set the state to RUNNING */
|
||||
stix->processor->active = proc;
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,11 +223,13 @@ static STIX_INLINE int register_new_process (stix_t* stix, stix_oop_process_t pr
|
||||
{
|
||||
/* the process schedule has no process.
|
||||
* it is the first process */
|
||||
STIX_ASSERT (stix->processor->active == stix->nil_process);
|
||||
|
||||
stix->processor->head = proc;
|
||||
stix->processor->tail = proc;
|
||||
stix->processor->tally = STIX_SMOOI_TO_OOP(1);
|
||||
stix->processor->tally = STIX_SMOOI_TO_OOP(1);
|
||||
#if defined(STIX_DEBUG_PROCESSOR)
|
||||
printf ("ADD NEW PROCESS X - %d\n", (int)1);
|
||||
printf ("ADDED FIRST NEW PROCESS - %d\n", (int)1);
|
||||
#endif
|
||||
}
|
||||
else if (tally >= STIX_SMOOI_MAX)
|
||||
@ -196,7 +247,7 @@ printf ("TOO MANY PROCESS\n");
|
||||
stix->processor->head = proc;
|
||||
stix->processor->tally = STIX_SMOOI_TO_OOP(tally + 1);
|
||||
#if defined(STIX_DEBUG_PROCESSOR)
|
||||
printf ("ADD NEW PROCESS Y - %d\n", (int)tally + 1);
|
||||
printf ("ADDED NEW PROCESS - %d\n", (int)tally + 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -222,35 +273,27 @@ static int schedule_process (stix_t* stix, stix_oop_process_t proc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static stix_oop_process_t start_new_process (stix_t* stix, stix_oop_context_t c)
|
||||
{
|
||||
stix_oop_process_t proc;
|
||||
|
||||
proc = make_process (stix, c);
|
||||
if (!proc) return STIX_NULL;
|
||||
|
||||
if (schedule_process (stix, proc) <= -1) return STIX_NULL;
|
||||
return proc;
|
||||
}
|
||||
#endif
|
||||
|
||||
static stix_oop_process_t start_initial_process (stix_t* stix, stix_oop_context_t c)
|
||||
{
|
||||
stix_oop_process_t proc;
|
||||
|
||||
/* there must be no active process when this function is called */
|
||||
STIX_ASSERT (stix->processor->tally == STIX_SMOOI_TO_OOP(0));
|
||||
STIX_ASSERT (stix->processor->active == stix->nil_process);
|
||||
|
||||
proc = make_process (stix, c);
|
||||
if (!proc) return STIX_NULL;
|
||||
|
||||
if (register_new_process (stix, proc) <= -1) return STIX_NULL;
|
||||
|
||||
/*TODO: set the state to RUNNING */
|
||||
stix->processor->active = proc;
|
||||
|
||||
/* do somthing that schedule_process() would do with less overhead */
|
||||
STIX_ASSERT ((stix_oop_t)proc->active_context != stix->_nil);
|
||||
STIX_ASSERT (proc->active_context == proc->initial_context);
|
||||
SWITCH_ACTIVE_CONTEXT (stix, proc->active_context);
|
||||
/*TODO: set the state to RUNNING */
|
||||
stix->processor->active = proc;
|
||||
|
||||
|
||||
return proc;
|
||||
}
|
||||
|
||||
@ -287,11 +330,15 @@ static STIX_INLINE int activate_new_method (stix_t* stix, stix_oop_method_t mth)
|
||||
|
||||
STIX_ASSERT (ntmprs >= 0);
|
||||
STIX_ASSERT (nargs <= ntmprs);
|
||||
#if defined(STIX_USE_PROCSTK)
|
||||
/* nothing special */
|
||||
#else
|
||||
STIX_ASSERT (stix->sp >= 0);
|
||||
STIX_ASSERT (stix->sp >= nargs);
|
||||
#endif
|
||||
|
||||
stix_pushtmp (stix, (stix_oop_t*)&mth);
|
||||
ctx = (stix_oop_context_t)stix_instantiate (stix, stix->_method_context, STIX_NULL, CONTEXT_STACK_SIZE);
|
||||
ctx = (stix_oop_context_t)stix_instantiate (stix, stix->_method_context, STIX_NULL, ntmprs + CONTEXT_STACK_SIZE);
|
||||
stix_poptmp (stix);
|
||||
if (!ctx) return -1;
|
||||
|
||||
@ -359,53 +406,13 @@ static STIX_INLINE int activate_new_method (stix_t* stix, stix_oop_method_t mth)
|
||||
|
||||
STIX_ASSERT (stix->sp >= -1);
|
||||
|
||||
/* swtich the active context */
|
||||
/* switch the active context */
|
||||
SWITCH_ACTIVE_CONTEXT (stix, ctx);
|
||||
|
||||
#if defined(STIX_DEBUG_EXEC)
|
||||
#if defined(STIX_DEBUG_EXEC_001)
|
||||
printf ("<<ENTERING>> SP=%d\n", (int)stix->sp);
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
#if 0
|
||||
reuse_context:
|
||||
/* force the class to become a method context */
|
||||
ctx->_class = stix->_method_context;
|
||||
|
||||
ctx->receiver_or_source = ACTIVE_STACK_GET(stix, stix->sp - nargs);
|
||||
#if defined(STIX_DEBUG_EXEC)
|
||||
printf ("####### REUSING CONTEXT INSTEAD OF <<ENTERING>> WITH RECEIVER ");
|
||||
print_object (stix, ctx->receiver_or_source);
|
||||
printf ("\n");
|
||||
#endif
|
||||
|
||||
for (i = 0; i < nargs; i++)
|
||||
{
|
||||
ctx->slot[i] = ACTIVE_STACK_GET (stix, stix->sp - nargs + i + 1);
|
||||
#if defined(STIX_DEBUG_EXEC)
|
||||
printf ("REUSING ARGUMENT %d - ", (int)i);
|
||||
print_object (stix, ctx->slot[i]);
|
||||
printf ("\n");
|
||||
#endif
|
||||
}
|
||||
for (; i <= stix->sp; i++) ctx->slot[i] = stix->_nil;
|
||||
/* keep the sender
|
||||
ctx->sender =
|
||||
*/
|
||||
|
||||
ctx->ntmprs = STIX_SMOOI_TO_OOP(ntmprs);
|
||||
ctx->method_or_nargs = (stix_oop_t)mth;
|
||||
ctx->home = stix->_nil;
|
||||
ctx->origin = ctx;
|
||||
|
||||
/* let SWITCH_ACTIVE_CONTEXT() fill 'ctx->ip' and 'ctx->sp' by putting
|
||||
* the values to stix->ip and stix->sp */
|
||||
stix->ip = 0;
|
||||
stix->sp = ntmprs - 1;
|
||||
SWITCH_ACTIVE_CONTEXT (stix, ctx);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static stix_oop_method_t find_method (stix_t* stix, stix_oop_t receiver, const stix_oocs_t* message, int super)
|
||||
@ -417,7 +424,7 @@ static stix_oop_method_t find_method (stix_t* stix, stix_oop_t receiver, const s
|
||||
int dic_no;
|
||||
/* TODO: implement method lookup cache */
|
||||
|
||||
#if defined(STIX_DEBUG_EXEC)
|
||||
#if defined(STIX_DEBUG_EXEC_002)
|
||||
printf ("==== FINDING METHOD FOR %p [", receiver);
|
||||
print_oocs (message);
|
||||
printf ("] in ");
|
||||
@ -429,7 +436,7 @@ printf ("] in ");
|
||||
/* receiver is a class object */
|
||||
c = receiver;
|
||||
dic_no = STIX_CLASS_MTHDIC_CLASS;
|
||||
#if defined(STIX_DEBUG_EXEC)
|
||||
#if defined(STIX_DEBUG_EXEC_002)
|
||||
printf ("class method dictioanry of ");
|
||||
print_object(stix, (stix_oop_t)((stix_oop_class_t)c)->name);
|
||||
printf ("\n");
|
||||
@ -439,7 +446,7 @@ printf ("\n");
|
||||
{
|
||||
c = (stix_oop_t)cls;
|
||||
dic_no = STIX_CLASS_MTHDIC_INSTANCE;
|
||||
#if defined(STIX_DEBUG_EXEC)
|
||||
#if defined(STIX_DEBUG_EXEC_002)
|
||||
printf ("instance method dictioanry of ");
|
||||
print_object(stix, (stix_oop_t)((stix_oop_class_t)c)->name);
|
||||
printf ("\n");
|
||||
@ -478,7 +485,7 @@ not_found:
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
static int activate_initial_context (stix_t* stix, const stix_oocs_t* objname, const stix_oocs_t* mthname)
|
||||
static int start_initial_process_and_context (stix_t* stix, const stix_oocs_t* objname, const stix_oocs_t* mthname)
|
||||
{
|
||||
/* the initial context is a fake context. if objname is 'Stix' and
|
||||
* mthname is 'main', this function emulates message sending 'Stix main'.
|
||||
@ -521,6 +528,8 @@ TODO: overcome this problem
|
||||
stix->ip = 0;
|
||||
stix->sp = -1;
|
||||
|
||||
ctx->ip = STIX_SMOOI_TO_OOP(0); /* point to the beginning */
|
||||
ctx->sp = STIX_SMOOI_TO_OOP(-1); /* pointer to -1 below the bottom */
|
||||
ctx->origin = ctx; /* point to self */
|
||||
ctx->method_or_nargs = (stix_oop_t)mth; /* fake. help SWITCH_ACTIVE_CONTEXT() not fail*/
|
||||
|
||||
@ -530,21 +539,35 @@ TODO: overcome this problem
|
||||
* the main execution loop for breaking out of the loop */
|
||||
|
||||
STIX_ASSERT (stix->active_context == STIX_NULL);
|
||||
/* i can't use SWITCH_ACTIVE_CONTEXT() macro as there is no active
|
||||
* context before switching. let's force set active_context to ctx
|
||||
* directly. */
|
||||
STIX_ASSERT (stix->active_method == STIX_NULL);
|
||||
|
||||
/* stix_gc() uses stix->processor when stix->active_context
|
||||
* is not NULL. at this poinst, stix->processor should point to
|
||||
* an instance of ProcessScheduler. */
|
||||
STIX_ASSERT ((stix_oop_t)stix->processor != stix->_nil);
|
||||
STIX_ASSERT (stix->processor->tally == STIX_SMOOI_TO_OOP(0));
|
||||
|
||||
/* start_initial_process() calls the SWITCH_ACTIVE_CONTEXT() macro.
|
||||
* the macro assumes a non-null value in stix->active_context.
|
||||
* let's force set active_context to ctx directly. */
|
||||
stix->active_context = ctx;
|
||||
ACTIVE_STACK_PUSH (stix, ass->value); /* push the receiver */
|
||||
|
||||
STORE_ACTIVE_IP (stix); /* stix->active_context->ip = STIX_SMOOI_TO_OOP(stix->ip) */
|
||||
STORE_ACTIVE_SP (stix); /* stix->active_context->sp = STIX_SMOOI_TO_OOP(stix->sp) */
|
||||
|
||||
stix_pushtmp (stix, (stix_oop_t*)&ctx);
|
||||
stix_pushtmp (stix, (stix_oop_t*)&mth);
|
||||
/* call start_initial_process() instead of start_new_process() */
|
||||
stix_pushtmp (stix, (stix_oop_t*)&ass);
|
||||
proc = start_initial_process (stix, ctx);
|
||||
stix_poptmp (stix);
|
||||
stix_poptmps (stix, 3);
|
||||
if (!proc) return -1;
|
||||
|
||||
ACTIVE_STACK_PUSH (stix, ass->value); /* push the receiver */
|
||||
STORE_ACTIVE_SP (stix); /* stix->active_context->sp = STIX_SMOOI_TO_OOP(stix->sp) */
|
||||
|
||||
STIX_ASSERT (stix->processor->active == proc);
|
||||
STIX_ASSERT (stix->processor->active->initial_context == ctx);
|
||||
STIX_ASSERT (stix->processor->active->active_context == ctx);
|
||||
STIX_ASSERT (stix->active_context == ctx);
|
||||
|
||||
/* emulate the message sending */
|
||||
return activate_new_method (stix, mth);
|
||||
}
|
||||
|
||||
@ -907,7 +930,6 @@ static int __block_value (stix_t* stix, stix_ooi_t nargs, stix_ooi_t num_first_a
|
||||
stix_ooi_t local_ntmprs, i;
|
||||
stix_ooi_t actual_arg_count;
|
||||
|
||||
|
||||
actual_arg_count = (num_first_arg_elems > 0)? num_first_arg_elems: nargs;
|
||||
|
||||
/* TODO: find a better way to support a reentrant block context. */
|
||||
@ -924,7 +946,7 @@ static int __block_value (stix_t* stix, stix_ooi_t nargs, stix_ooi_t num_first_a
|
||||
if (STIX_CLASSOF(stix, org_blkctx) != stix->_block_context)
|
||||
{
|
||||
/* the receiver must be a block context */
|
||||
#if defined(STIX_DEBUG_EXEC)
|
||||
#if defined(STIX_DEBUG_EXEC_001)
|
||||
printf ("PRIMITVE VALUE RECEIVER IS NOT A BLOCK CONTEXT\n");
|
||||
#endif
|
||||
return 0;
|
||||
@ -938,7 +960,7 @@ printf ("PRIMITVE VALUE RECEIVER IS NOT A BLOCK CONTEXT\n");
|
||||
* For example, [thisContext value] value.
|
||||
*/
|
||||
STIX_ASSERT (STIX_OBJ_GET_SIZE(org_blkctx) > STIX_CONTEXT_NAMED_INSTVARS);
|
||||
#if defined(STIX_DEBUG_EXEC)
|
||||
#if defined(STIX_DEBUG_EXEC_001)
|
||||
printf ("PRIM REVALUING AN BLOCKCONTEXT\n");
|
||||
#endif
|
||||
return 0;
|
||||
@ -948,15 +970,22 @@ printf ("PRIM REVALUING AN BLOCKCONTEXT\n");
|
||||
if (STIX_OOP_TO_SMOOI(org_blkctx->method_or_nargs) != actual_arg_count /* nargs */)
|
||||
{
|
||||
/* the number of argument doesn't match */
|
||||
#if defined(STIX_DEBUG_EXEC)
|
||||
#if defined(STIX_DEBUG_EXEC_001)
|
||||
/* TODO: better handling of primitive failure */
|
||||
printf ("PRIM BlockContext value FAIL - NARGS MISMATCH\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the number of temporaries stored in the block context
|
||||
* accumulates the number of temporaries starting from the origin.
|
||||
* simple calculation is needed to find the number of local temporaries */
|
||||
local_ntmprs = STIX_OOP_TO_SMOOI(org_blkctx->ntmprs) -
|
||||
STIX_OOP_TO_SMOOI(((stix_oop_context_t)org_blkctx->home)->ntmprs);
|
||||
STIX_ASSERT (local_ntmprs >= actual_arg_count);
|
||||
|
||||
/* create a new block context to clone org_blkctx */
|
||||
blkctx = (stix_oop_context_t) stix_instantiate (stix, stix->_block_context, STIX_NULL, CONTEXT_STACK_SIZE);
|
||||
blkctx = (stix_oop_context_t) stix_instantiate (stix, stix->_block_context, STIX_NULL, local_ntmprs + CONTEXT_STACK_SIZE);
|
||||
if (!blkctx) return -1;
|
||||
|
||||
/* get org_blkctx again to be GC-safe for stix_instantiate() above */
|
||||
@ -976,9 +1005,6 @@ printf ("PRIM BlockContext value FAIL - NARGS MISMATCH\n");
|
||||
blkctx->receiver_or_source = (stix_oop_t)org_blkctx;
|
||||
blkctx->home = org_blkctx->home;
|
||||
blkctx->origin = org_blkctx->origin;
|
||||
#if defined(STIX_DEBUG_EXEC)
|
||||
printf ("~~~~~~~~~~ BLOCK VALUING %p TO NEW BLOCK %p\n", org_blkctx, blkctx);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* TODO: check the stack size of a block context to see if it's large enough to hold arguments */
|
||||
@ -1005,18 +1031,9 @@ printf ("~~~~~~~~~~ BLOCK VALUING %p TO NEW BLOCK %p\n", org_blkctx, blkctx);
|
||||
}
|
||||
}
|
||||
ACTIVE_STACK_POPS (stix, nargs + 1); /* pop arguments and receiver */
|
||||
|
||||
|
||||
STIX_ASSERT (blkctx->home != stix->_nil);
|
||||
|
||||
/* the number of temporaries stored in the block context
|
||||
* accumulates the number of temporaries starting from the origin.
|
||||
* simple calculation is needed to find the number of local temporaries */
|
||||
local_ntmprs = STIX_OOP_TO_SMOOI(blkctx->ntmprs) -
|
||||
STIX_OOP_TO_SMOOI(((stix_oop_context_t)blkctx->home)->ntmprs);
|
||||
STIX_ASSERT (local_ntmprs >= nargs);
|
||||
|
||||
blkctx->sp = STIX_SMOOI_TO_OOP(local_ntmprs);
|
||||
blkctx->sp = STIX_SMOOI_TO_OOP(local_ntmprs - 1);
|
||||
blkctx->sender = (stix_oop_t)stix->active_context;
|
||||
|
||||
*pblkctx = blkctx;
|
||||
@ -1031,8 +1048,8 @@ static int prim_block_value (stix_t* stix, stix_ooi_t nargs)
|
||||
x = __block_value (stix, nargs, 0, &blkctx);
|
||||
if (x <= 0) return x; /* hard failure and soft failure */
|
||||
|
||||
#if defined(STIX_DEBUG_EXEC)
|
||||
printf ("<<ENTERING BLOCK>>\n");
|
||||
#if defined(STIX_DEBUG_EXEC_001)
|
||||
printf ("<<ENTERING BLOCK>> SP=%ld\n", (long int)stix->sp);
|
||||
#endif
|
||||
SWITCH_ACTIVE_CONTEXT (stix, (stix_oop_context_t)blkctx);
|
||||
return 1;
|
||||
@ -2007,7 +2024,8 @@ static int send_message (stix_t* stix, stix_oop_char_t selector, int to_super, s
|
||||
STIX_ASSERT (STIX_CLASSOF(stix, selector) == stix->_symbol);
|
||||
|
||||
receiver = ACTIVE_STACK_GET(stix, stix->sp - nargs);
|
||||
#if defined(STIX_DEBUG_EXEC)
|
||||
|
||||
#if defined(STIX_DEBUG_EXEC_001)
|
||||
printf (" RECEIVER = ");
|
||||
print_object(stix, receiver);
|
||||
printf ("\n");
|
||||
@ -2687,7 +2705,7 @@ printf ("\n");
|
||||
/* get the selector from the literal frame */
|
||||
selector = (stix_oop_char_t)stix->active_method->slot[b2];
|
||||
|
||||
#if defined(STIX_DEBUG_EXEC)
|
||||
#if defined(STIX_DEBUG_EXEC_001)
|
||||
printf ("SEND_MESSAGE%s TO RECEIVER AT STACKPOS=%d NARGS=%d SELECTOR=", (((bcode >> 2) & 1)? "_TO_SUPER": ""), (int)(stix->sp - b1), (int)b1);
|
||||
print_object (stix, (stix_oop_t)selector);
|
||||
fflush (stdout);
|
||||
@ -2784,7 +2802,7 @@ fflush (stdout);
|
||||
return_value = stix->active_context->origin->receiver_or_source;
|
||||
|
||||
handle_return:
|
||||
#if defined(STIX_DEBUG_EXEC)
|
||||
#if defined(STIX_DEBUG_EXEC_001)
|
||||
printf ("<<LEAVING>> SP=%d\n", (int)stix->sp);
|
||||
#endif
|
||||
|
||||
@ -2847,10 +2865,16 @@ printf ("TERMINATING XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n");
|
||||
/* the sending context of the intial context has been set to nil.
|
||||
* use this fact to tell an initial context from a normal context. */
|
||||
STIX_ASSERT (stix->active_context->receiver_or_source == stix->_nil);
|
||||
#if defined(STIX_DEBUG_EXEC)
|
||||
#if defined(STIX_DEBUG_EXEC_001)
|
||||
printf ("<<<RETURNIGN TO THE INITIAL CONTEXT>>>\n");
|
||||
#endif
|
||||
|
||||
printf ("TERMINATING SP.... %ld\n", (long int)stix->sp);
|
||||
#if defined(STIX_USE_PROCSTK)
|
||||
/* nothing special */
|
||||
#else
|
||||
STIX_ASSERT (stix->sp == 0);
|
||||
#endif
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -2864,15 +2888,28 @@ printf ("<<<RETURNIGN TO THE INITIAL CONTEXT>>>\n");
|
||||
|
||||
if (stix->active_context == stix->processor->active->initial_context)
|
||||
{
|
||||
/* TODO: terminate the process */
|
||||
/* TODO: terminate the process. can this happen? */
|
||||
printf ("TERMINATE A PROCESS............\n");
|
||||
/* **************************************** */
|
||||
}
|
||||
else
|
||||
{
|
||||
return_value = ACTIVE_STACK_GETTOP(stix);
|
||||
#if defined(STIX_DEBUG_EXEC_001)
|
||||
printf ("<<LEAVING BLOCK>>\n");
|
||||
#endif
|
||||
#if defined(STIX_USE_PROCSTK)
|
||||
/* the process stack is shared. the return value
|
||||
* doesn't need to get moved. */
|
||||
SWITCH_ACTIVE_CONTEXT (stix, (stix_oop_context_t)stix->active_context->sender);
|
||||
ACTIVE_STACK_PUSH (stix, return_value);
|
||||
#else
|
||||
/* NOTE: GC must not performed between here and */
|
||||
return_value = ACTIVE_STACK_GETTOP(stix);
|
||||
ACTIVE_STACK_POP (stix); /* pop off the return value */
|
||||
|
||||
SWITCH_ACTIVE_CONTEXT (stix, (stix_oop_context_t)stix->active_context->sender);
|
||||
ACTIVE_STACK_PUSH (stix, return_value); /* push it to the sender */
|
||||
/* NOTE: here. if so, return_value will point to a garbage. */
|
||||
#endif
|
||||
}
|
||||
|
||||
break;
|
||||
@ -3048,7 +3085,11 @@ oops:
|
||||
|
||||
int stix_invoke (stix_t* stix, const stix_oocs_t* objname, const stix_oocs_t* mthname)
|
||||
{
|
||||
if (activate_initial_context (stix, objname, mthname) <= -1) return -1;
|
||||
if (start_initial_process_and_context (stix, objname, mthname) <= -1) return -1;
|
||||
return stix_execute (stix);
|
||||
/* TODO: reset stix->active_context & stix->active_method to STIX_NULL
|
||||
*
|
||||
* TODO: remove the process. set processor->tally to zero. processor->active to nil_process...
|
||||
*/
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user