From 5da9a789cd5b3b481829f15df7830d49b5321991 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Sat, 6 Jun 2015 07:24:35 +0000 Subject: [PATCH] added stix_invoke() --- stix/lib/comp.c | 14 +++--- stix/lib/exec.c | 116 ++++++++++++++++++++++++++++++++++++++++-------- stix/lib/main.c | 27 +++++++---- stix/lib/stix.h | 21 +++++++-- 4 files changed, 139 insertions(+), 39 deletions(-) diff --git a/stix/lib/comp.c b/stix/lib/comp.c index 44b1852..6464c82 100644 --- a/stix/lib/comp.c +++ b/stix/lib/comp.c @@ -2393,7 +2393,7 @@ static int add_compiled_method (stix_t* stix) { stix_oop_t name; /* selector */ stix_oop_method_t mth; /* method */ - stix_oop_t code; + stix_oop_byte_t code; stix_size_t tmp_count = 0; 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++; - 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; - stix_pushtmp (stix, &code); tmp_count++; + stix_pushtmp (stix, (stix_oop_t*)&code); tmp_count++; mth->owner = stix->c->cls.self_oop; 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 */ - stix->c->cls.mthdic_oop[MTH_INSTANCE] = stix->c->cls.self_oop->instmths; - stix->c->cls.mthdic_oop[MTH_CLASS] = stix->c->cls.self_oop->classmths; + 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->mthdic[STIX_CLASS_MTHDIC_CLASS]; } else { @@ -2871,8 +2871,8 @@ printf ("\n"); if (!(stix->c->cls.flags & CLASS_EXTENDED)) { /* TODO: anything else to set? */ - stix->c->cls.self_oop->instmths = 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_INSTANCE] = stix->c->cls.mthdic_oop[MTH_INSTANCE]; + stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_CLASS] = stix->c->cls.mthdic_oop[MTH_CLASS]; } GET_TOKEN (stix); diff --git a/stix/lib/exec.c b/stix/lib/exec.c index 95a7d01..7761ae0 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -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) diff --git a/stix/lib/main.c b/stix/lib/main.c index ea62a68..57d1695 100644 --- a/stix/lib/main.c +++ b/stix/lib/main.c @@ -182,18 +182,18 @@ static void dump_symbol_table (stix_t* stix) 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_oop_association_t ass; 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"); - 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) { printf (" %lu [", (unsigned long int)i); @@ -252,10 +252,15 @@ static char* syntax_error_msg[] = "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[]) { stix_t* stix; 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", (unsigned long int)STIX_MAX_NAMED_INSTVARS, @@ -344,7 +349,7 @@ printf ("%p\n", a); dump_symbol_table (stix); - dump_system_dictionary (stix); + dump_dictionary (stix, stix->sysdic, "System dictionary"); } xtn = stix_getxtn (stix); @@ -400,15 +405,19 @@ printf ("%p\n", a); } -/* - if (stix_execute (stix) <= -1) + objname.ptr = str_stix; + 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)); stix_close (stix); return -1; } -*/ -dump_system_dictionary(stix); + + + dump_dictionary (stix, stix->sysdic, "System dictionary"); stix_close (stix); diff --git a/stix/lib/stix.h b/stix/lib/stix.h index 1efe22f..645b30c 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -534,12 +534,15 @@ struct stix_class_t stix_oop_char_t classinstvars; /* String */ /* == NEVER CHANGE THE ORDER OF 3 ITEMS ABOVE == */ - stix_oop_set_t instmths; /* instance methods, MethodDictionary */ - stix_oop_set_t classmths; /* class methods, MethodDictionary */ + /* [0] - instance methods, MethodDictionary + * [1] - class methods, MethodDictionary */ + stix_oop_set_t mthdic[2]; /* indexed part afterwards */ 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 typedef struct stix_association_t stix_association_t; @@ -565,7 +568,7 @@ struct stix_method_t /* number of arguments in temporaries */ 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? */ /* 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_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 */ STIX_EXPORT void stix_pushtmp ( stix_t* stix,