fixed some bugs related to store and pop

This commit is contained in:
hyunghwan.chung 2015-06-11 09:11:18 +00:00
parent a8a44a1519
commit 469210bd80
6 changed files with 203 additions and 99 deletions

View File

@ -26,10 +26,10 @@
#include "stix-prv.h" #include "stix-prv.h"
#define TOKEN_NAME_ALIGN 256 #define TOKEN_NAME_ALIGN 256
#define CLASS_BUFFER_ALIGN 8 /* 256 */ #define CLASS_BUFFER_ALIGN 8 /* 256 */
#define LITERAL_BUFFER_ALIGN 8 /* 256 */ #define LITERAL_BUFFER_ALIGN 8 /* 256 */
#define CODE_BUFFER_ALIGN 8 /* 256 */ #define CODE_BUFFER_ALIGN 8 /* 256 */
/* initial method dictionary size */ /* initial method dictionary size */
#define INSTANCE_METHOD_DICTIONARY_SIZE 256 /* TODO: choose the right size */ #define INSTANCE_METHOD_DICTIONARY_SIZE 256 /* TODO: choose the right size */
@ -1098,7 +1098,7 @@ static int emit_send_instruction (stix_t* stix, int cmd, stix_size_t nargs, stix
* --------------------------------------------------------------------- */ * --------------------------------------------------------------------- */
static int compile_method_statement (stix_t* stix); static int compile_method_statement (stix_t* stix);
static int compile_method_expression (stix_t* stix); static int compile_method_expression (stix_t* stix, int pop);
static int add_literal (stix_t* stix, stix_oop_t lit, stix_size_t* index) static int add_literal (stix_t* stix, stix_oop_t lit, stix_size_t* index)
{ {
@ -2026,7 +2026,7 @@ printf ("push symbol literal %d\n", (int)index);
case STIX_IOTOK_LPAREN: case STIX_IOTOK_LPAREN:
GET_TOKEN (stix); GET_TOKEN (stix);
if (compile_method_expression(stix) <= -1) return -1; if (compile_method_expression(stix, 0) <= -1) return -1;
if (stix->c->tok.type != STIX_IOTOK_RPAREN) if (stix->c->tok.type != STIX_IOTOK_RPAREN)
{ {
set_syntax_error (stix, STIX_SYNERR_RPAREN, &stix->c->tok.loc, &stix->c->tok.name); set_syntax_error (stix, STIX_SYNERR_RPAREN, &stix->c->tok.loc, &stix->c->tok.name);
@ -2207,16 +2207,17 @@ static int compile_basic_expression (stix_t* stix, const stix_ucs_t* ident, cons
return 0; return 0;
} }
static int compile_method_expression (stix_t* stix) static int compile_method_expression (stix_t* stix, int pop)
{ {
/* /*
* method-expression := method-assignment-expression | basic-expression * method-expression := method-assignment-expression | basic-expression
* method-assignment-expression := identifier ":=" method-expression * method-assignment-expression := identifier ":=" method-expression
*/ */
stix_ucs_t assignee; stix_ucs_t assignee;
int ret = 0;
STIX_ASSERT (pop == 0 || pop == 1);
STIX_MEMSET (&assignee, 0, STIX_SIZEOF(assignee)); STIX_MEMSET (&assignee, 0, STIX_SIZEOF(assignee));
if (stix->c->tok.type == STIX_IOTOK_IDENT) if (stix->c->tok.type == STIX_IOTOK_IDENT)
@ -2237,43 +2238,49 @@ static int compile_method_expression (stix_t* stix)
GET_TOKEN (stix); GET_TOKEN (stix);
printf ("ASSIGNIUNG TO ...."); printf ("ASSIGNIUNG TO ....");
print_ucs (&assignee); print_ucs (&assignee);
printf ("\n"); printf ("\n");
if (compile_method_expression(stix) <= -1 || if (compile_method_expression(stix, 0) <= -1 ||
get_variable_info(stix, &assignee, &assignee_loc, &var) <= -1) return -1; get_variable_info(stix, &assignee, &assignee_loc, &var) <= -1) goto oops;
switch (var.type) switch (var.type)
{ {
case VAR_ARGUMENT: case VAR_ARGUMENT:
/* assigning to an argument is not allowed */ /* assigning to an argument is not allowed */
set_syntax_error (stix, STIX_SYNERR_VARARG, &assignee_loc, &assignee); set_syntax_error (stix, STIX_SYNERR_VARARG, &assignee_loc, &assignee);
return -1; goto oops;
case VAR_TEMPORARY: case VAR_TEMPORARY:
printf ("emit pop and store to tempvar %d\n", (int)var.pos); printf ("<emit> store to tempvar %d\n", (int)var.pos);
if (emit_positional_instruction (stix, CMD_POP_AND_STORE_INTO_TEMPVAR, var.pos) <= -1) return -1; /* TODO: if pop is 1, emit CMD_POP_AND_STORE_INTO_TEMPVAR.
ret = pop;
*/
if (emit_positional_instruction (stix, CMD_STORE_INTO_TEMPVAR, var.pos) <= -1) goto oops;
break; break;
case VAR_INSTANCE: case VAR_INSTANCE:
case VAR_CLASSINST: case VAR_CLASSINST:
printf ("emit pop and store to instvar %d\n", (int)var.pos); printf ("<emit> store to instvar %d\n", (int)var.pos);
if (emit_positional_instruction (stix, CMD_POP_AND_STORE_INTO_INSTVAR, var.pos) <= -1) return -1; /* TODO: if pop is 1, emit CMD_POP_AND_STORE_INTO_INSTVAR
ret = pop;
*/
if (emit_positional_instruction (stix, CMD_STORE_INTO_INSTVAR, var.pos) <= -1) goto oops;
break; break;
case VAR_CLASS: case VAR_CLASS:
/* TODO: what instruction to generate for class variable access... */ /* TODO: what instruction to generate for class variable access... */
return -1; goto oops;
case VAR_GLOBAL: case VAR_GLOBAL:
/* TODO: .............................. */ /* TODO: .............................. */
return -1; goto oops;
default: default:
stix->errnum = STIX_EINTERN; stix->errnum = STIX_EINTERN;
return -1; goto oops;
} }
} }
else else
@ -2288,7 +2295,7 @@ static int compile_method_expression (stix_t* stix)
} }
stix->c->mth.assignees.len -= assignee.len; stix->c->mth.assignees.len -= assignee.len;
return 0; return ret;
oops: oops:
stix->c->mth.assignees.len -= assignee.len; stix->c->mth.assignees.len -= assignee.len;
@ -2306,13 +2313,23 @@ static int compile_method_statement (stix_t* stix)
{ {
/* handle the return statement */ /* handle the return statement */
GET_TOKEN (stix); GET_TOKEN (stix);
if (compile_method_expression(stix) <= -1) return -1; if (compile_method_expression(stix, 0) <= -1) return -1;
printf ("return message stacktop\n"); return emit_byte_instruction (stix, CODE_RETURN_STACKTOP);
return emit_byte_instruction (stix, CODE_RETURN_MESSAGE_STACKTOP);
} }
else else
{ {
return compile_method_expression(stix); /* TODO: optimization. if expresssion is a literal, no push and pop are required */
int n;
/* the second parameter to compile_method_expression() indicates
* that the stack top will eventually be popped off. the compiler
* can optimize some instruction sequencese. for example, two
* consecutive store and pop intructions can be transformed to
* a more specialized single pop-and-store instruction. */
n = compile_method_expression(stix, 1);
if (n <= -1) return -1;
return (n == 0)? emit_byte_instruction (stix, CODE_POP_STACKTOP): 0;
} }
} }
@ -2342,18 +2359,18 @@ static int compile_method_statements (stix_t* stix)
{ {
if (stix->c->tok.type == STIX_IOTOK_EOF || if (stix->c->tok.type == STIX_IOTOK_EOF ||
stix->c->tok.type == STIX_IOTOK_RBRACE) break; stix->c->tok.type == STIX_IOTOK_RBRACE) break;
else
{ /* not a period, EOF, nor } */
set_syntax_error (stix, STIX_SYNERR_PERIOD, &stix->c->tok.loc, &stix->c->tok.name); set_syntax_error (stix, STIX_SYNERR_PERIOD, &stix->c->tok.loc, &stix->c->tok.name);
return -1; return -1;
}
} }
} }
while (1); while (1);
} }
/* TODO: size optimization. emit code_return_receiver only if it's not previously emitted */ /* arrange to return the receiver if execution reached
return emit_byte_instruction (stix, CODE_RETURN_MESSAGE_RECEIVER); * the end of the method without explicit return */
return emit_byte_instruction (stix, CODE_RETURN_RECEIVER);
} }
static int add_compiled_method (stix_t* stix) static int add_compiled_method (stix_t* stix)
@ -2394,13 +2411,13 @@ static int add_compiled_method (stix_t* stix)
} }
else else
{ {
if (stix->c->mth.code.ptr[0] == CODE_RETURN_MESSAGE_RECEIVER) if (stix->c->mth.code.ptr[0] == CODE_RETURN_RECEIVER)
{ {
preamble_code = STIX_METHOD_PREAMBLE_RETURN_RECEIVER; preamble_code = STIX_METHOD_PREAMBLE_RETURN_RECEIVER;
} }
else if (stix->c->mth.code.len >= 2 && else if (stix->c->mth.code.len >= 2 &&
stix->c->mth.code.ptr[0] == CODE_PUSH_RECEIVER && stix->c->mth.code.ptr[0] == CODE_PUSH_RECEIVER &&
stix->c->mth.code.ptr[1] == CODE_RETURN_MESSAGE_STACKTOP) stix->c->mth.code.ptr[1] == CODE_RETURN_STACKTOP)
{ {
preamble_code = STIX_METHOD_PREAMBLE_RETURN_RECEIVER; preamble_code = STIX_METHOD_PREAMBLE_RETURN_RECEIVER;
} }
@ -2427,7 +2444,7 @@ static int add_compiled_method (stix_t* stix)
} }
if (cmd == CMD_PUSH_INSTVAR && if (cmd == CMD_PUSH_INSTVAR &&
stix->c->mth.code.ptr[index_size + 1] == CODE_RETURN_MESSAGE_STACKTOP) stix->c->mth.code.ptr[index_size + 1] == CODE_RETURN_STACKTOP)
{ {
preamble_code = STIX_METHOD_PREAMBLE_RETURN_INSTVAR; preamble_code = STIX_METHOD_PREAMBLE_RETURN_INSTVAR;
@ -2557,6 +2574,8 @@ printf (" instvars %d classvars %d classinstvars %d\n", (int)stix->c->cls.var_co
#endif #endif
if (stix->c->cls.self_oop) if (stix->c->cls.self_oop)
{ {
/* this is an internally created class object being defined. */
STIX_ASSERT (STIX_CLASSOF(stix, stix->c->cls.self_oop) == stix->_class); STIX_ASSERT (STIX_CLASSOF(stix, stix->c->cls.self_oop) == stix->_class);
STIX_ASSERT (STIX_OBJ_GET_FLAGS_KERNEL (stix->c->cls.self_oop) == 1); STIX_ASSERT (STIX_OBJ_GET_FLAGS_KERNEL (stix->c->cls.self_oop) == 1);
@ -2564,8 +2583,6 @@ printf (" instvars %d classvars %d classinstvars %d\n", (int)stix->c->cls.var_co
self_spec != STIX_OOP_TO_SMINT(stix->c->cls.self_oop->selfspec)) self_spec != STIX_OOP_TO_SMINT(stix->c->cls.self_oop->selfspec))
{ {
/* it conflicts with internal definition */ /* it conflicts with internal definition */
#if 0 #if 0
printf (" CONFLICTING CLASS DEFINITION %lu %lu %lu %lu\n", printf (" CONFLICTING CLASS DEFINITION %lu %lu %lu %lu\n",
(unsigned long)spec, (unsigned long)self_spec, (unsigned long)spec, (unsigned long)self_spec,
@ -2583,7 +2600,7 @@ printf (" CONFLICTING CLASS DEFINITION %lu %lu %lu %lu\n",
tmp = stix_instantiate (stix, stix->_class, STIX_NULL, tmp = stix_instantiate (stix, stix->_class, STIX_NULL,
stix->c->cls.var_count[VAR_CLASSINST] + stix->c->cls.var_count[VAR_CLASS]); stix->c->cls.var_count[VAR_CLASSINST] + stix->c->cls.var_count[VAR_CLASS]);
if (!tmp) return -1; if (!tmp) return -1;
just_made = 1; just_made = 1;
stix->c->cls.self_oop = (stix_oop_class_t)tmp; stix->c->cls.self_oop = (stix_oop_class_t)tmp;
@ -2599,6 +2616,8 @@ printf (" CONFLICTING CLASS DEFINITION %lu %lu %lu %lu\n",
*/ */
STIX_OBJ_SET_FLAGS_KERNEL (stix->c->cls.self_oop, 2); STIX_OBJ_SET_FLAGS_KERNEL (stix->c->cls.self_oop, 2);
stix->c->cls.self_oop->superclass = stix->c->cls.super_oop;
tmp = stix_makesymbol (stix, stix->c->cls.name.ptr, stix->c->cls.name.len); tmp = stix_makesymbol (stix, stix->c->cls.name.ptr, stix->c->cls.name.len);
if (!tmp) return -1; if (!tmp) return -1;
stix->c->cls.self_oop->name = (stix_oop_char_t)tmp; stix->c->cls.self_oop->name = (stix_oop_char_t)tmp;

View File

@ -156,6 +156,7 @@ static int activate_new_method (stix_t* stix, stix_oop_method_t mth, stix_ooi_t*
* context */ * context */
LOAD_IP_AND_SP (stix->active_context, *xip, *xsp); LOAD_IP_AND_SP (stix->active_context, *xip, *xsp);
printf ("<<ENTERING>>\n");
return 0; return 0;
} }
@ -168,22 +169,22 @@ static stix_oop_method_t find_method (stix_t* stix, stix_oop_t receiver, const s
int dic_no; int dic_no;
/* TODO: implement method lookup cache */ /* TODO: implement method lookup cache */
printf ("FINDING METHOD FOR %p ", receiver); printf ("==== FINDING METHOD FOR %p [", receiver);
print_ucs (message); print_ucs (message);
printf ("\n"); printf ("] in ");
cls = (stix_oop_class_t)STIX_CLASSOF(stix, receiver); cls = (stix_oop_class_t)STIX_CLASSOF(stix, receiver);
if ((stix_oop_t)cls == stix->_class) if ((stix_oop_t)cls == stix->_class)
{ {
/* receiver is a class receiverect */ /* receiver is a class receiverect */
c = receiver; c = receiver;
dic_no = STIX_CLASS_MTHDIC_CLASS; dic_no = STIX_CLASS_MTHDIC_CLASS;
printf ("going to lookup class method dictioanry...\n"); printf ("class method dictioanry ====\n");
} }
else else
{ {
c = (stix_oop_t)cls; c = (stix_oop_t)cls;
dic_no = STIX_CLASS_MTHDIC_INSTANCE; dic_no = STIX_CLASS_MTHDIC_INSTANCE;
printf ("going to lookup instance method dictioanry...\n"); printf ("instance method dictioanry ====\n");
} }
@ -200,7 +201,7 @@ printf ("going to lookup instance method dictioanry...\n");
mthdic = ((stix_oop_class_t)c)->mthdic[dic_no]; mthdic = ((stix_oop_class_t)c)->mthdic[dic_no];
STIX_ASSERT (STIX_CLASSOF(stix, mthdic) == stix->_method_dictionary); STIX_ASSERT (STIX_CLASSOF(stix, mthdic) == stix->_method_dictionary);
dump_dictionary (stix, mthdic, "Method dictionary"); dump_dictionary (stix, mthdic, "Method dictionary");
ass = (stix_oop_association_t)stix_lookupdic (stix, mthdic, message); ass = (stix_oop_association_t)stix_lookupdic (stix, mthdic, message);
if (ass) if (ass)
{ {
@ -239,11 +240,9 @@ static int activate_initial_context (stix_t* stix, const stix_ucs_t* objname, co
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, 0); mth = find_method (stix, ass->value, mthname, 0);
if (!mth) return -1; if (!mth) return -1;
printf ("found method...\n");
if (STIX_OOP_TO_SMINT(mth->tmpr_nargs) > 0) if (STIX_OOP_TO_SMINT(mth->tmpr_nargs) > 0)
{ {
/* this method expects more than 0 arguments. /* this method expects more than 0 arguments.
@ -269,13 +268,48 @@ TODO: overcome this problem
return activate_new_method (stix, mth, &ip, &sp); return activate_new_method (stix, mth, &ip, &sp);
} }
static int execute_primitive (stix_t* stix, int prim_no, stix_ooi_t nargs, stix_ooi_t* sp) #define PUSH(stix,v) \
do { \
++sp; \
(stix)->active_context->slot[sp] = v; \
} while (0)
static void dump_object (stix_t* stix, stix_oop_t oop, const char* title)
{ {
stix_oop_class_t c;
stix_ucs_t s;
printf ("%s: ", title);
printf ("%p instance of ", oop);
c = STIX_CLASSOF(stix, oop);
s.ptr = ((stix_oop_char_t)c->name)->slot;
s.len = STIX_OBJ_GET_SIZE(c->name);
print_ucs (&s);
printf ("\n");
}
static int execute_primitive (stix_t* stix, int prim_no, stix_ooi_t nargs, stix_ooi_t* xsp)
{
/* a primitive handler must pop off all arguments and the receiver and
* push a return value when it's successful. otherwise, it must not touch
* the stack. */
switch (prim_no) switch (prim_no)
{ {
case 0: case 0:
/*dump_object (stix->active_context->slot[sp], nargs);*/ {
stix_ooi_t i;
dump_object (stix, stix->active_context->slot[*xsp - nargs], "receiver");
for (i = nargs; i > 0; )
{
--i;
dump_object (stix, stix->active_context->slot[*xsp - i], "argument");
}
*xsp -= nargs; /* pop off arguments */
return 1; return 1;
}
default: default:
return -1; return -1;
@ -285,6 +319,7 @@ static int execute_primitive (stix_t* stix, int prim_no, stix_ooi_t nargs, stix_
* when it returns 0, it should not touch the stack */ * when it returns 0, it should not touch the stack */
} }
int stix_execute (stix_t* stix) int stix_execute (stix_t* stix)
{ {
stix_oop_method_t mth; stix_oop_method_t mth;
@ -298,6 +333,14 @@ int stix_execute (stix_t* stix)
ip = STIX_OOP_TO_SMINT(stix->active_context->ip); ip = STIX_OOP_TO_SMINT(stix->active_context->ip);
sp = STIX_OOP_TO_SMINT(stix->active_context->sp); sp = STIX_OOP_TO_SMINT(stix->active_context->sp);
/* store the address of the stack pointer variable.
* this address is used to update the sp of the active context
* before actual garbage collection is collected. */
stix->active_context_sp = &sp;
/* TODO: stack popping requires the elelement to be reset to nil or smallinteger.
* otherwide, the element beyond the stack top (sp) won't be GCed.
*/
while (1) while (1)
{ {
mth = stix->active_context->method; mth = stix->active_context->method;
@ -322,30 +365,30 @@ printf ("CMD => %d, B1 = %d, SP = %d, IP AFTER INC %d\n", (int)cmd, (int)b1, (in
{ {
case CMD_PUSH_INSTVAR: case CMD_PUSH_INSTVAR:
printf ("PUSHING INSTVAR %d\n", (int)b1); printf ("PUSH_INSTVAR %d\n", (int)b1);
STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(stix->active_context->receiver) == STIX_OBJ_TYPE_OOP); STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(stix->active_context->receiver) == STIX_OBJ_TYPE_OOP);
stix->active_context->slot[++sp] = ((stix_oop_oop_t)stix->active_context->receiver)->slot[b1]; PUSH (stix, ((stix_oop_oop_t)stix->active_context->receiver)->slot[b1]);
break; break;
case CMD_PUSH_TEMPVAR: case CMD_PUSH_TEMPVAR:
printf ("PUSHING TEMPVAR %d\n", (int)b1); printf ("PUSH_TEMPVAR %d\n", (int)b1);
stix->active_context->slot[++sp] = stix->active_context->slot[b1]; PUSH (stix, stix->active_context->slot[b1]);
break; break;
case CMD_PUSH_LITERAL: case CMD_PUSH_LITERAL:
printf ("PUSHING LITERAL %d\n", (int)b1); printf ("PUSH_LITERAL %d\n", (int)b1);
stix->active_context->slot[++sp] = mth->slot[b1]; PUSH (stix, mth->slot[b1]);
break; break;
case CMD_POP_AND_STORE_INTO_INSTVAR: case CMD_STORE_INTO_INSTVAR:
printf ("STORING INSTVAR %d\n", (int)b1); printf ("STORE_INSTVAR %d\n", (int)b1);
STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(stix->active_context->receiver) == STIX_OBJ_TYPE_OOP); STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(stix->active_context->receiver) == STIX_OBJ_TYPE_OOP);
((stix_oop_oop_t)stix->active_context->receiver)->slot[b1] = stix->active_context->slot[sp--]; ((stix_oop_oop_t)stix->active_context->receiver)->slot[b1] = stix->active_context->slot[sp];
break; break;
case CMD_POP_AND_STORE_INTO_TEMPVAR: case CMD_STORE_INTO_TEMPVAR:
printf ("STORING TEMPVAR %d\n", (int)b1); printf ("STORE_TEMPVAR %d\n", (int)b1);
stix->active_context->slot[b1] = stix->active_context->slot[sp--]; stix->active_context->slot[b1] = stix->active_context->slot[sp];
break; break;
/* /*
@ -367,7 +410,7 @@ TODO: handle double extension
stix_ooi_t selector_index; stix_ooi_t selector_index;
stix_ooi_t preamble; stix_ooi_t preamble;
printf ("SENDING MESSAGE \n");
/* the next byte is the message selector index to the /* the next byte is the message selector index to the
* literal frame. */ * literal frame. */
selector_index = code->slot[ip++]; selector_index = code->slot[ip++];
@ -375,8 +418,11 @@ printf ("SENDING MESSAGE \n");
/* get the selector from the literal frame */ /* get the selector from the literal frame */
selector = (stix_oop_char_t)mth->slot[selector_index]; selector = (stix_oop_char_t)mth->slot[selector_index];
if (cmd == CMD_SEND_MESSAGE)
printf ("SEND_MESSAGE TO RECEIVER AT %d\n", (int)(sp - b1));
else
printf ("SEND_MESSAGE_TO_SUPER TO RECEIVER AT %d\n", (int)(sp - b1));
STIX_ASSERT (STIX_CLASSOF(stix, selector) == stix->_symbol); STIX_ASSERT (STIX_CLASSOF(stix, selector) == stix->_symbol);
printf ("RECEIVER INDEX %d\n", (int)(sp - b1));
newrcv = stix->active_context->slot[sp - b1]; newrcv = stix->active_context->slot[sp - b1];
mthname.ptr = selector->slot; mthname.ptr = selector->slot;
@ -388,7 +434,7 @@ printf ("RECEIVER INDEX %d\n", (int)(sp - b1));
printf ("no such method .........["); printf ("no such method .........[");
print_ucs (&mthname); print_ucs (&mthname);
printf ("]\n"); printf ("]\n");
return -1; goto oops;
} }
STIX_ASSERT (STIX_OOP_TO_SMINT(newmth->tmpr_nargs) == b1); STIX_ASSERT (STIX_OOP_TO_SMINT(newmth->tmpr_nargs) == b1);
@ -397,6 +443,7 @@ printf ("]\n");
switch (STIX_METHOD_GET_PREAMBLE_CODE(preamble)) switch (STIX_METHOD_GET_PREAMBLE_CODE(preamble))
{ {
case STIX_METHOD_PREAMBLE_RETURN_RECEIVER: case STIX_METHOD_PREAMBLE_RETURN_RECEIVER:
printf ("RETURN RECEIVER AT PREAMBLE\n");
sp = sp - b1; /* pop arguments */ sp = sp - b1; /* pop arguments */
break; break;
@ -406,7 +453,7 @@ printf ("]\n");
sp = sp - b1; /* pop arguments */ sp = sp - b1; /* pop arguments */
printf ("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx SIMPLE RETURN INSTVAR VERIFY THIS\n"); printf ("RETURN INSTVAR AT PREAMBLE\n");
/* replace the receiver by an instance variable of the receiver */ /* replace the receiver by an instance variable of the receiver */
receiver = (stix_oop_oop_t)stix->active_context->slot[sp]; receiver = (stix_oop_oop_t)stix->active_context->slot[sp];
STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(receiver) == STIX_OBJ_TYPE_OOP); STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(receiver) == STIX_OBJ_TYPE_OOP);
@ -424,13 +471,13 @@ printf ("JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ\n"
n = execute_primitive (stix, STIX_METHOD_GET_PREAMBLE_INDEX(preamble), b1, &sp); n = execute_primitive (stix, STIX_METHOD_GET_PREAMBLE_INDEX(preamble), b1, &sp);
stix_poptmp (stix); stix_poptmp (stix);
if (n <= -1) return -1; if (n <= -1) goto oops;
if (n >= 1) break; if (n >= 1) break;
/* primitive failed. fall thru */ /* primitive failed. fall thru */
} }
default: default:
if (activate_new_method (stix, newmth, &ip, &sp) <= -1) return -1; if (activate_new_method (stix, newmth, &ip, &sp) <= -1) goto oops;
break; break;
} }
@ -443,28 +490,28 @@ printf ("JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ\n"
switch (b1) switch (b1)
{ {
case SUBCMD_PUSH_RECEIVER: case SUBCMD_PUSH_RECEIVER:
printf ("PUSHING RECEIVER %p TO STACK INDEX %d\n", stix->active_context->receiver, (int)sp); printf ("PUSH_RECEIVER %p TO STACK INDEX %d\n", stix->active_context->receiver, (int)sp);
stix->active_context->slot[++sp] = stix->active_context->receiver; PUSH (stix, stix->active_context->receiver);
break; break;
case SUBCMD_PUSH_NIL: case SUBCMD_PUSH_NIL:
printf ("PUSHING NIL\n"); printf ("PUSH_NIL\n");
stix->active_context->slot[++sp] = stix->_nil; PUSH (stix, stix->_nil);
break; break;
case SUBCMD_PUSH_TRUE: case SUBCMD_PUSH_TRUE:
printf ("PUSHING TRUE\n"); printf ("PUSH_TRUE\n");
stix->active_context->slot[++sp] = stix->_true; PUSH (stix, stix->_true);
break; break;
case SUBCMD_PUSH_FALSE: case SUBCMD_PUSH_FALSE:
printf ("PUSHING FALSE\n"); printf ("PUSH_FALSE\n");
stix->active_context->slot[++sp] = stix->_false; PUSH (stix, stix->_false);
break; break;
case SUBCMD_PUSH_CONTEXT: case SUBCMD_PUSH_CONTEXT:
printf ("PUSHING THIS CONTEXT\n"); printf ("PUSH_CONTEXT\n");
stix->active_context->slot[++sp] = (stix_oop_t)stix->active_context; PUSH (stix, (stix_oop_t)stix->active_context);
break; break;
} }
break; /* CMD_PUSH_SPECIAL */ break; /* CMD_PUSH_SPECIAL */
@ -477,17 +524,24 @@ printf ("PUSHING THIS CONTEXT\n");
switch (b1) switch (b1)
{ {
case SUBCMD_RETURN_MESSAGE_RECEIVER: case SUBCMD_POP_STACKTOP:
printf ("RETURNING. RECEIVER...........\n"); printf ("POP_STACKTOP\n");
return_value = stix->active_context->receiver; STIX_ASSERT (sp > -1);
goto handle_return; sp--;
break;
case SUBCMD_RETURN_MESSAGE_STACKTOP: case SUBCMD_RETURN_STACKTOP:
printf ("RETURNING. RECEIVER...........\n"); printf ("RETURN_STACKTOP\n");
return_value = stix->active_context->slot[sp--]; return_value = stix->active_context->slot[sp--];
goto handle_return; goto handle_return;
case SUBCMD_RETURN_RECEIVER:
printf ("RETURN_RECEIVER\n");
return_value = stix->active_context->receiver;
goto handle_return;
/*case CMD_RETURN_BLOCK_STACKTOP:*/ /*case CMD_RETURN_BLOCK_STACKTOP:*/
/* TODO: */
default: default:
stix->errnum = STIX_EINTERN; stix->errnum = STIX_EINTERN;
@ -505,13 +559,14 @@ printf ("RETURNING. RECEIVER...........\n");
LOAD_IP_AND_SP (stix->active_context, ip, sp); LOAD_IP_AND_SP (stix->active_context, ip, sp);
/* push the return value to the stack of the new active context */ /* push the return value to the stack of the new active context */
stix->active_context->slot[++sp] = return_value; PUSH (stix, return_value);
printf ("<<LEAVING>>\n");
if (stix->active_context->sender == stix->_nil) if (stix->active_context->sender == stix->_nil)
{ {
/* the sending context of the intial context has been set to nil. /* the sending context of the intial context has been set to nil.
* use this fact to tell an initial context from a normal context. */ * use this fact to tell an initial context from a normal context. */
printf ("RETURNIGN TO THE INITIAL CONTEXT.......\n"); printf ("<<<RETURNIGN TO THE INITIAL CONTEXT>>>\n");
STIX_ASSERT (sp == 0); STIX_ASSERT (sp == 0);
goto done; goto done;
} }
@ -525,7 +580,13 @@ printf ("RETURNIGN TO THE INITIAL CONTEXT.......\n");
} }
done: done:
stix->active_context_sp = STIX_NULL;
return 0; return 0;
oops:
stix->active_context_sp = STIX_NULL;
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)
@ -533,5 +594,3 @@ int stix_invoke (stix_t* stix, const stix_ucs_t* objname, const stix_ucs_t* mthn
if (activate_initial_context (stix, objname, mthname) <= -1) return -1; if (activate_initial_context (stix, objname, mthname) <= -1) return -1;
return stix_execute (stix); return stix_execute (stix);
} }

View File

@ -159,14 +159,29 @@ static stix_uint8_t* scan_new_heap (stix_t* stix, stix_uint8_t* ptr)
STIX_OBJ_SET_CLASS (oop, stix_moveoop(stix, STIX_OBJ_GET_CLASS(oop))); STIX_OBJ_SET_CLASS (oop, stix_moveoop(stix, STIX_OBJ_GET_CLASS(oop)));
if (STIX_OBJ_GET_FLAGS_TYPE(oop) == STIX_OBJ_TYPE_OOP) if (STIX_OBJ_GET_FLAGS_TYPE(oop) == STIX_OBJ_TYPE_OOP)
{ {
stix_obj_oop_t* xtmp; stix_oop_oop_t xtmp;
stix_oow_t size;
if (stix->_context && STIX_OBJ_GET_CLASS(oop) == stix->_context)
{
/* TODO: need to do the same for block context?? */
/* the stack in the context object doesn't need to be in
* full. the slots above the stack pointer are garbages. */
size = STIX_CONTEXT_NAMED_INSTVARS +
STIX_OOP_TO_SMINT(((stix_oop_context_t)oop)->sp) + 1;
}
else
{
size = STIX_OBJ_GET_SIZE(oop);
}
xtmp = (stix_oop_oop_t)oop; xtmp = (stix_oop_oop_t)oop;
for (i = 0; i < oop->_size; i++) for (i = 0; i < size; i++)
{ {
if (STIX_OOP_IS_POINTER(xtmp->slot[i])) if (STIX_OOP_IS_POINTER(xtmp->slot[i]))
xtmp->slot[i] = stix_moveoop (stix, xtmp->slot[i]); xtmp->slot[i] = stix_moveoop (stix, xtmp->slot[i]);
} }
} }
/*ptr = ptr + STIX_SIZEOF(stix_obj_t) + nbytes_aligned;*/ /*ptr = ptr + STIX_SIZEOF(stix_obj_t) + nbytes_aligned;*/
@ -191,6 +206,13 @@ void stix_gc (stix_t* stix)
stix_oow_t i; stix_oow_t i;
stix_cb_t* cb; stix_cb_t* cb;
if (stix->active_context_sp && stix->active_context)
{
/* store the stack pointer to the actual active context */
/* TODO: verify if this is correct */
stix->active_context->sp = STIX_OOP_FROM_SMINT(*stix->active_context_sp);
}
/*printf ("STARTING GC curheap base %p ptr %p newheap base %p ptr %p\n", /*printf ("STARTING GC curheap base %p ptr %p newheap base %p ptr %p\n",
stix->curheap->base, stix->curheap->ptr, stix->newheap->base, stix->newheap->ptr);*/ stix->curheap->base, stix->curheap->ptr, stix->newheap->base, stix->newheap->ptr);*/
/* TODO: allocate common objects like _nil and the root dictionary /* TODO: allocate common objects like _nil and the root dictionary

View File

@ -253,6 +253,7 @@ static char* syntax_error_msg[] =
}; };
stix_uch_t str_stix[] = { 'S', 't', 'i', 'x' }; stix_uch_t str_stix[] = { 'S', 't', 'i', 'x' };
stix_uch_t str_my_object[] = { 'M', 'y', 'O', 'b','j','e','c','t' };
stix_uch_t str_main[] = { 'm', 'a', 'i', 'n' }; stix_uch_t str_main[] = { 'm', 'a', 'i', 'n' };
int main (int argc, char* argv[]) int main (int argc, char* argv[])
@ -405,8 +406,10 @@ printf ("%p\n", a);
} }
objname.ptr = str_stix; /* objname.ptr = str_stix;
objname.len = 4; objname.len = 4;*/
objname.ptr = str_my_object;
objname.len = 8;
mthname.ptr = str_main; mthname.ptr = str_main;
mthname.len = 4; mthname.len = 4;
if (stix_invoke (stix, &objname, &mthname) <= -1) if (stix_invoke (stix, &objname, &mthname) <= -1)

View File

@ -452,12 +452,12 @@ struct stix_compiler_t
* XXXX is one of the following positional instructions. * XXXX is one of the following positional instructions.
* JJJJ or JJJJJJJJ is the position. * JJJJ or JJJJJJJJ is the position.
*/ */
#define CMD_PUSH_INSTVAR 0x2 #define CMD_PUSH_INSTVAR 0x2
#define CMD_PUSH_TEMPVAR 0x3 #define CMD_PUSH_TEMPVAR 0x3
#define CMD_PUSH_LITERAL 0x4 #define CMD_PUSH_LITERAL 0x4
#define CMD_POP_AND_STORE_INTO_INSTVAR 0x5 /* pop and store */ #define CMD_STORE_INTO_INSTVAR 0x5
#define CMD_POP_AND_STORE_INTO_CLASSVAR 0x6 /* pop and store */ #define CMD_STORE_INTO_CLASSVAR 0x6
#define CMD_POP_AND_STORE_INTO_TEMPVAR 0x7 /* pop and store */ #define CMD_STORE_INTO_TEMPVAR 0x7
/* /*
* XXXXJJJJ KKKKKKKK * XXXXJJJJ KKKKKKKK
@ -479,9 +479,9 @@ struct stix_compiler_t
#define SUBCMD_DUP_STACKTOP 0x0 #define SUBCMD_DUP_STACKTOP 0x0
#define SUBCMD_POP_STACKTOP 0x1 #define SUBCMD_POP_STACKTOP 0x1
#define SUBCMD_RETURN_MESSAGE_STACKTOP 0x2 #define SUBCMD_RETURN_STACKTOP 0x2
#define SUBCMD_RETURN_BLOCK_STACKTOP 0x3 #define SUBCMD_RETURN_BLOCK_STACKTOP 0x3
#define SUBCMD_RETURN_MESSAGE_RECEIVER 0x4 #define SUBCMD_RETURN_RECEIVER 0x4
/* ---------------------------------- */ /* ---------------------------------- */
#define CODE_PUSH_RECEIVER MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_RECEIVER) #define CODE_PUSH_RECEIVER MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_RECEIVER)
@ -493,9 +493,9 @@ struct stix_compiler_t
/* special code */ /* special code */
#define CODE_DUP_STACKTOP MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_DUP_STACKTOP) #define CODE_DUP_STACKTOP MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_DUP_STACKTOP)
#define CODE_POP_STACKTOP MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_POP_STACKTOP) #define CODE_POP_STACKTOP MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_POP_STACKTOP)
#define CODE_RETURN_MESSAGE_STACKTOP MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_RETURN_MESSAGE_STACKTOP) #define CODE_RETURN_STACKTOP MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_RETURN_STACKTOP)
#define CODE_RETURN_BLOCK_STACKTOP MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_RETURN_BLOCK_STACKTOP) #define CODE_RETURN_BLOCK_STACKTOP MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_RETURN_BLOCK_STACKTOP)
#define CODE_RETURN_MESSAGE_RECEIVER MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_RETURN_MESSAGE_RECEIVER) #define CODE_RETURN_RECEIVER MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_RETURN_RECEIVER)
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {

View File

@ -750,6 +750,7 @@ struct stix_t
/* == EXECUTION REGISTERS == */ /* == EXECUTION REGISTERS == */
stix_oop_context_t active_context; /* TODO: this could be either MethodContext or BlockContext. Some redefintion of stix_oop_context_t might be needed after having removed stix-oop_block-context. */ stix_oop_context_t active_context; /* TODO: this could be either MethodContext or BlockContext. Some redefintion of stix_oop_context_t might be needed after having removed stix-oop_block-context. */
stix_ooi_t* active_context_sp;
/* stix_oop_context_t home_context; */ /* stix_oop_context_t home_context; */
/* == END EXECUTION REGISTERS == */ /* == END EXECUTION REGISTERS == */