added stix_invoke()
This commit is contained in:
parent
7a751d7cc0
commit
5da9a789cd
@ -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);
|
||||
|
110
stix/lib/exec.c
110
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)
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user