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_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);
|
||||||
|
116
stix/lib/exec.c
116
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->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)
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user