added stix_invoke()

This commit is contained in:
hyunghwan.chung
2015-06-06 07:24:35 +00:00
parent 7a751d7cc0
commit 5da9a789cd
4 changed files with 139 additions and 39 deletions

View File

@ -54,15 +54,36 @@ static int activate_new_method (stix_t* stix, stix_oop_method_t mth)
ctx->sender = (stix_oop_t)stix->active_context;
ctx->ip = 0;
/* the stack front has temporary variables including arguments */
/* the stack front has temporary variables including arguments.
*
* Context
*
* +---------------------+
* | fixed part |
* | |
* | |
* | |
* +---------------------+
* | tmp1 (arg1) | slot[0]
* | tmp2 (arg2) | slot[1]
* | .... | slot[1]
* | tmpX | slot[1] <-- initial sp
* | | slot[1]
* | | slot[1]
* | | slot[1]
* | | slot[stack_size - 1]
* +---------------------+
*
* if no temporaries exist, the initial sp is -1.
*/
ctx->sp = STIX_OOP_FROM_SMINT(ntmprs - 1);
ctx->method = mth;
/*
* This message sending expression is compiled to
* Assume this message sending expression:
* obj1 do: #this with: #that with: #it
*
* the logical byte-code sequences shown below:
* It would be compiled to these logical byte-code sequences shown below:
* push obj1
* push #this
* push #that
@ -80,12 +101,13 @@ static int activate_new_method (stix_t* stix, stix_oop_method_t mth)
* the receiver. When the stack is empty, sp is -1.
*/
j = sp - nargs;
ctx->receiver = stix->active_context->slot[j++];
ctx->receiver = stix->active_context->slot[j];
for (i = 0; i < nargs; i++)
{
/* copy an argument */
/* copy an argument*/
ctx->slot[i] = stix->active_context->slot[++j];
}
printf ("j = %d, sp = %d\n", (int)j, (int)sp);
STIX_ASSERT (j == sp);
/* TODO: store the contennts of internal registers to stix->active_context */
@ -99,15 +121,39 @@ static int activate_new_method (stix_t* stix, stix_oop_method_t mth)
static stix_oop_method_t find_method (stix_t* stix, stix_oop_t obj, const stix_ucs_t* mthname)
{
stix_oop_class_t cls;
stix_oop_association_t ass;
stix_oop_t c;
stix_oop_set_t mthdic;
int dic_no;
cls = (stix_oop_class_t)STIX_CLASSOF(stix, obj);
if (cls == stix->_class)
if ((stix_oop_t)cls == stix->_class)
{
}
/* obj is a class object */
c = obj;
dic_no = STIX_CLASS_MTHDIC_CLASS;
printf ("going to lookup class method dictioanry...\n");
}
else
{
c = (stix_oop_t)cls;
dic_no = STIX_CLASS_MTHDIC_INSTANCE;
printf ("going to lookup class instance dictioanry...\n");
}
while (c != stix->_nil)
{
mthdic = ((stix_oop_class_t)c)->mthdic[dic_no];
STIX_ASSERT (STIX_CLASSOF(stix, mthdic) == stix->_method_dictionary);
dump_dictionary (stix, mthdic, "Method dictionary");
ass = (stix_oop_association_t)stix_lookupdic (stix, mthdic, mthname);
if (ass)
{
STIX_ASSERT (STIX_CLASSOF(stix, ass->value) == stix->_method);
return (stix_oop_method_t)ass->value;
}
c = ((stix_oop_class_t)c)->superclass;
}
stix->errnum = STIX_ENOENT;
@ -117,25 +163,40 @@ static stix_oop_method_t find_method (stix_t* stix, stix_oop_t obj, const stix_u
static int activate_initial_context (stix_t* stix, const stix_ucs_t* objname, const stix_ucs_t* mthname)
{
/* the initial context is a fake context */
stix_oow_t stack_size;
stix_oop_context_t ctx;
stix_oop_association_t ass;
stix_oop_method_t mth;
stack_size = 1; /* grow it if you want to pass arguments */
ctx = (stix_oop_context_t)stix_instantiate (stix, stix->_context, STIX_NULL, stack_size);
if (!ctx) return -1;
stix_ooi_t sp;
ass = stix_lookupsysdic (stix, objname);
if (!ass) return -1;
printf ("found object...\n");
mth = find_method (stix, ass->value, mthname);
if (!mth) return -1;
printf ("found method...\n");
if (STIX_OOP_TO_SMINT(mth->tmpr_nargs) > 0)
{
/* this method expects more than 0 arguments.
* i can't use it as a start-up method.
TODO: overcome this problem
*/
stix->errnum = STIX_EINVAL;
return -1;
}
/* the initial context starts the life of the entire VM
* and is not really worked on except that it is used to call the
* initial method. so it doesn't really require any extra stack space.
* TODO: verify my theory above is true */
sp = 1 + STIX_OOP_TO_SMINT(mth->tmpr_count);
ctx = (stix_oop_context_t)stix_instantiate (stix, stix->_context, STIX_NULL, sp);
if (!ctx) return -1;
ctx->slot[0] = ass->value;
ctx->sp = STIX_OOP_FROM_SMINT(1);
ctx->sp = STIX_OOP_FROM_SMINT(sp);
stix->active_context = ctx;
return activate_new_method (stix, mth);
@ -158,13 +219,30 @@ static stix_oop_process_t make_process (stix_t* stix, stix_oop_context_t ctx)
int stix_execute (stix_t* stix)
{
stix_oop_method_t mth;
stix_oop_byte_t code;
stix_ooi_t ip;
stix_byte_t bc;
STIX_ASSERT (stix->active_context != STIX_NULL);
mth = stix->active_context->method;
ip = STIX_OOP_TO_SMINT(stix->active_context->ip);
code = mth->code;
while (1)
{
bc = code->slot[ip++];
cmd = bc >> 4;
if (cmd == CMD_EXTEND)
{
cmd = bc & 0xF;
}
}
return 0;
return -1;
}
int stix_invoke (stix_t* stix, const stix_ucs_t* objname, const stix_ucs_t* mthname)