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

@ -2393,7 +2393,7 @@ static int add_compiled_method (stix_t* stix)
{ {
stix_oop_t name; /* selector */ stix_oop_t name; /* selector */
stix_oop_method_t mth; /* method */ stix_oop_method_t mth; /* method */
stix_oop_t code; stix_oop_byte_t code;
stix_size_t tmp_count = 0; stix_size_t tmp_count = 0;
stix_size_t i; stix_size_t i;
@ -2411,9 +2411,9 @@ static int add_compiled_method (stix_t* stix)
} }
stix_pushtmp (stix, (stix_oop_t*)&mth); tmp_count++; stix_pushtmp (stix, (stix_oop_t*)&mth); tmp_count++;
code = stix_instantiate (stix, stix->_byte_array, stix->c->mth.code.ptr, stix->c->mth.code.len); code = (stix_oop_byte_t)stix_instantiate (stix, stix->_byte_array, stix->c->mth.code.ptr, stix->c->mth.code.len);
if (!code) goto oops; if (!code) goto oops;
stix_pushtmp (stix, &code); tmp_count++; stix_pushtmp (stix, (stix_oop_t*)&code); tmp_count++;
mth->owner = stix->c->cls.self_oop; mth->owner = stix->c->cls.self_oop;
mth->tmpr_count = STIX_OOP_FROM_SMINT(stix->c->mth.tmpr_count); mth->tmpr_count = STIX_OOP_FROM_SMINT(stix->c->mth.tmpr_count);
@ -2837,8 +2837,8 @@ printf ("\n");
} }
/* use the method dictionary of an existing class object */ /* use the method dictionary of an existing class object */
stix->c->cls.mthdic_oop[MTH_INSTANCE] = stix->c->cls.self_oop->instmths; stix->c->cls.mthdic_oop[MTH_INSTANCE] = stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_INSTANCE];
stix->c->cls.mthdic_oop[MTH_CLASS] = stix->c->cls.self_oop->classmths; stix->c->cls.mthdic_oop[MTH_CLASS] = stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_CLASS];
} }
else else
{ {
@ -2871,8 +2871,8 @@ printf ("\n");
if (!(stix->c->cls.flags & CLASS_EXTENDED)) if (!(stix->c->cls.flags & CLASS_EXTENDED))
{ {
/* TODO: anything else to set? */ /* TODO: anything else to set? */
stix->c->cls.self_oop->instmths = stix->c->cls.mthdic_oop[MTH_INSTANCE]; stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_INSTANCE] = stix->c->cls.mthdic_oop[MTH_INSTANCE];
stix->c->cls.self_oop->classmths = stix->c->cls.mthdic_oop[MTH_CLASS]; stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_CLASS] = stix->c->cls.mthdic_oop[MTH_CLASS];
} }
GET_TOKEN (stix); GET_TOKEN (stix);

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->sender = (stix_oop_t)stix->active_context;
ctx->ip = 0; 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->sp = STIX_OOP_FROM_SMINT(ntmprs - 1);
ctx->method = mth; ctx->method = mth;
/* /*
* This message sending expression is compiled to * Assume this message sending expression:
* obj1 do: #this with: #that with: #it * 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 obj1
* push #this * push #this
* push #that * 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. * the receiver. When the stack is empty, sp is -1.
*/ */
j = sp - nargs; j = sp - nargs;
ctx->receiver = stix->active_context->slot[j++]; ctx->receiver = stix->active_context->slot[j];
for (i = 0; i < nargs; i++) for (i = 0; i < nargs; i++)
{ {
/* copy an argument */ /* copy an argument*/
ctx->slot[i] = stix->active_context->slot[++j]; ctx->slot[i] = stix->active_context->slot[++j];
} }
printf ("j = %d, sp = %d\n", (int)j, (int)sp);
STIX_ASSERT (j == sp); STIX_ASSERT (j == sp);
/* TODO: store the contennts of internal registers to stix->active_context */ /* 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) 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_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); 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 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; 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) 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 */ /* the initial context is a fake context */
stix_oow_t stack_size;
stix_oop_context_t ctx; stix_oop_context_t ctx;
stix_oop_association_t ass; stix_oop_association_t ass;
stix_oop_method_t mth; stix_oop_method_t mth;
stix_ooi_t sp;
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;
ass = stix_lookupsysdic (stix, objname); ass = stix_lookupsysdic (stix, objname);
if (!ass) return -1; if (!ass) return -1;
printf ("found object...\n");
mth = find_method (stix, ass->value, mthname); mth = find_method (stix, ass->value, mthname);
if (!mth) return -1; 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->slot[0] = ass->value;
ctx->sp = STIX_OOP_FROM_SMINT(1); ctx->sp = STIX_OOP_FROM_SMINT(sp);
stix->active_context = ctx; stix->active_context = ctx;
return activate_new_method (stix, mth); 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) 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) 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) int stix_invoke (stix_t* stix, const stix_ucs_t* objname, const stix_ucs_t* mthname)

View File

@ -182,18 +182,18 @@ static void dump_symbol_table (stix_t* stix)
printf ("--------------------------------------------\n"); printf ("--------------------------------------------\n");
} }
void dump_system_dictionary (stix_t* stix) void dump_dictionary (stix_t* stix, stix_oop_set_t dic, const char* title)
{ {
stix_oow_t i, j; stix_oow_t i, j;
stix_oop_association_t ass; stix_oop_association_t ass;
printf ("--------------------------------------------\n"); printf ("--------------------------------------------\n");
printf ("Stix System Dictionary %lu\n", (unsigned long int)STIX_OBJ_GET_SIZE(stix->sysdic->bucket)); printf ("%s %lu\n", title, (unsigned long int)STIX_OBJ_GET_SIZE(dic->bucket));
printf ("--------------------------------------------\n"); printf ("--------------------------------------------\n");
for (i = 0; i < STIX_OBJ_GET_SIZE(stix->sysdic->bucket); i++) for (i = 0; i < STIX_OBJ_GET_SIZE(dic->bucket); i++)
{ {
ass = (stix_oop_association_t)stix->sysdic->bucket->slot[i]; ass = (stix_oop_association_t)dic->bucket->slot[i];
if ((stix_oop_t)ass != stix->_nil) if ((stix_oop_t)ass != stix->_nil)
{ {
printf (" %lu [", (unsigned long int)i); printf (" %lu [", (unsigned long int)i);
@ -252,10 +252,15 @@ static char* syntax_error_msg[] =
"wrong primitive number" "wrong primitive number"
}; };
stix_uch_t str_stix[] = { 'S', 't', 'i', 'x' };
stix_uch_t str_main[] = { 'm', 'a', 'i', 'n' };
int main (int argc, char* argv[]) int main (int argc, char* argv[])
{ {
stix_t* stix; stix_t* stix;
xtn_t* xtn; xtn_t* xtn;
stix_ucs_t objname;
stix_ucs_t mthname;
printf ("Stix 1.0.0 - max named %lu max indexed %lu max class %lu max classinst %lu\n", printf ("Stix 1.0.0 - max named %lu max indexed %lu max class %lu max classinst %lu\n",
(unsigned long int)STIX_MAX_NAMED_INSTVARS, (unsigned long int)STIX_MAX_NAMED_INSTVARS,
@ -344,7 +349,7 @@ printf ("%p\n", a);
dump_symbol_table (stix); dump_symbol_table (stix);
dump_system_dictionary (stix); dump_dictionary (stix, stix->sysdic, "System dictionary");
} }
xtn = stix_getxtn (stix); xtn = stix_getxtn (stix);
@ -400,15 +405,19 @@ printf ("%p\n", a);
} }
/* objname.ptr = str_stix;
if (stix_execute (stix) <= -1) objname.len = 4;
mthname.ptr = str_main;
mthname.len = 4;
if (stix_invoke (stix, &objname, &mthname) <= -1)
{ {
printf ("ERROR: cannot execute code - %d\n", stix_geterrnum(stix)); printf ("ERROR: cannot execute code - %d\n", stix_geterrnum(stix));
stix_close (stix); stix_close (stix);
return -1; return -1;
} }
*/
dump_system_dictionary(stix);
dump_dictionary (stix, stix->sysdic, "System dictionary");
stix_close (stix); stix_close (stix);

View File

@ -534,12 +534,15 @@ struct stix_class_t
stix_oop_char_t classinstvars; /* String */ stix_oop_char_t classinstvars; /* String */
/* == NEVER CHANGE THE ORDER OF 3 ITEMS ABOVE == */ /* == NEVER CHANGE THE ORDER OF 3 ITEMS ABOVE == */
stix_oop_set_t instmths; /* instance methods, MethodDictionary */ /* [0] - instance methods, MethodDictionary
stix_oop_set_t classmths; /* class methods, MethodDictionary */ * [1] - class methods, MethodDictionary */
stix_oop_set_t mthdic[2];
/* indexed part afterwards */ /* indexed part afterwards */
stix_oop_t slot[1]; /* class instance variables and class variables. */ stix_oop_t slot[1]; /* class instance variables and class variables. */
}; };
#define STIX_CLASS_MTHDIC_INSTANCE 0
#define STIX_CLASS_MTHDIC_CLASS 1
#define STIX_ASSOCIATION_NAMED_INSTVARS 2 #define STIX_ASSOCIATION_NAMED_INSTVARS 2
typedef struct stix_association_t stix_association_t; typedef struct stix_association_t stix_association_t;
@ -565,7 +568,7 @@ struct stix_method_t
/* number of arguments in temporaries */ /* number of arguments in temporaries */
stix_oop_t tmpr_nargs; /* SmallInteger */ stix_oop_t tmpr_nargs; /* SmallInteger */
stix_oop_t code; /* ByteArray */ stix_oop_byte_t code; /* ByteArray */
stix_oop_t source; /* TODO: what should I put? */ stix_oop_t source; /* TODO: what should I put? */
/* variable indexed part */ /* variable indexed part */
@ -851,12 +854,22 @@ STIX_EXPORT int stix_ignite (
/** /**
* The stix_executes() function creates key initial objects. * The stix_executes() function XXXXXXXXXXXXXX
*/ */
STIX_EXPORT int stix_execute ( STIX_EXPORT int stix_execute (
stix_t* stix stix_t* stix
); );
/**
* The stix_invoke() function sends a message named \a mthname to an object
* named \a objname.
*/
STIX_EXPORT int stix_invoke (
stix_t* stix,
const stix_ucs_t* objname,
const stix_ucs_t* mthname
);
/* Temporary OOP management */ /* Temporary OOP management */
STIX_EXPORT void stix_pushtmp ( STIX_EXPORT void stix_pushtmp (
stix_t* stix, stix_t* stix,