diff --git a/stix/lib/comp.c b/stix/lib/comp.c index 89c37ea..fc4573e 100644 --- a/stix/lib/comp.c +++ b/stix/lib/comp.c @@ -3569,35 +3569,96 @@ static int add_compiled_method (stix_t* stix) { preamble_code = STIX_METHOD_PREAMBLE_RETURN_RECEIVER; } - else if (stix->c->mth.code.len >= 2 && - stix->c->mth.code.ptr[0] == BCODE_PUSH_RECEIVER && - stix->c->mth.code.ptr[1] == BCODE_RETURN_STACKTOP) + else if (stix->c->mth.code.len >= 2 && stix->c->mth.code.ptr[1] == BCODE_RETURN_STACKTOP) { - preamble_code = STIX_METHOD_PREAMBLE_RETURN_RECEIVER; - } - else - { - /* check if the method begins with 'return instavar' instruction */ - if (stix->c->mth.code.ptr[0] >= BCODE_PUSH_INSTVAR_0 && - stix->c->mth.code.ptr[0] <= BCODE_PUSH_INSTVAR_7 && - stix->c->mth.code.ptr[1] == BCODE_RETURN_STACKTOP) + switch (stix->c->mth.code.ptr[0]) { - preamble_code = STIX_METHOD_PREAMBLE_RETURN_INSTVAR; - preamble_index = stix->c->mth.code.ptr[0] & 0x7; /* low 3 bits */ + case BCODE_PUSH_RECEIVER: + preamble_code = STIX_METHOD_PREAMBLE_RETURN_RECEIVER; + break; + + case BCODE_PUSH_NIL: + preamble_code = STIX_METHOD_PREAMBLE_RETURN_NIL; + break; + + case BCODE_PUSH_TRUE: + preamble_code = STIX_METHOD_PREAMBLE_RETURN_TRUE; + break; + + case BCODE_PUSH_FALSE: + preamble_code = STIX_METHOD_PREAMBLE_RETURN_FALSE; + break; + + case BCODE_PUSH_NEGONE: + preamble_code = STIX_METHOD_PREAMBLE_RETURN_NEGINDEX; + preamble_index = 1; + break; + + case BCODE_PUSH_ZERO: + preamble_code = STIX_METHOD_PREAMBLE_RETURN_INDEX; + preamble_index = 0; + break; + + case BCODE_PUSH_ONE: + preamble_code = STIX_METHOD_PREAMBLE_RETURN_INDEX; + preamble_index = 1; + break; + + case BCODE_PUSH_TWO: + preamble_code = STIX_METHOD_PREAMBLE_RETURN_INDEX; + preamble_index = 2; + break; + +/* + case BCODE_PUSH_LITERAL_0: + case BCODE_PUSH_LITERAL_1: + case BCODE_PUSH_LITERAL_2: + case BCODE_PUSH_LITERAL_3: + case BCODE_PUSH_LITERAL_4: + case BCODE_PUSH_LITERAL_5: + case BCODE_PUSH_LITERAL_6: + case BCODE_PUSH_LITERAL_7: + TODO: check the literal frame. if the value in the literal frame is a small integer within the premable index range, + convert ito to PREAMBEL_RETURN_INDEX or NEGINDEX + break; +*/ + + case BCODE_PUSH_INSTVAR_0: + case BCODE_PUSH_INSTVAR_1: + case BCODE_PUSH_INSTVAR_2: + case BCODE_PUSH_INSTVAR_3: + case BCODE_PUSH_INSTVAR_4: + case BCODE_PUSH_INSTVAR_5: + case BCODE_PUSH_INSTVAR_6: + case BCODE_PUSH_INSTVAR_7: + preamble_code = STIX_METHOD_PREAMBLE_RETURN_INSTVAR; + preamble_index = stix->c->mth.code.ptr[0] & 0x7; /* low 3 bits */ + break; + + } - else if (stix->c->mth.code.ptr[0] == BCODE_PUSH_INSTVAR_X && - stix->c->mth.code.ptr[STIX_BCODE_LONG_PARAM_SIZE + 1] == BCODE_RETURN_STACKTOP) + } + else if (stix->c->mth.code.ptr[0] == BCODE_PUSH_INSTVAR_X && + stix->c->mth.code.ptr[STIX_BCODE_LONG_PARAM_SIZE + 1] == BCODE_RETURN_STACKTOP) + { + int i; + + STIX_ASSERT (stix->c->mth.code.len >= STIX_BCODE_LONG_PARAM_SIZE + 1); + + preamble_code = STIX_METHOD_PREAMBLE_RETURN_INSTVAR; + preamble_index = 0; + for (i = 1; i <= STIX_BCODE_LONG_PARAM_SIZE; i++) { - int i; - preamble_code = STIX_METHOD_PREAMBLE_RETURN_INSTVAR; - preamble_index = stix->c->mth.code.ptr[1]; - for (i = 2; i <= STIX_BCODE_LONG_PARAM_SIZE; i++) + preamble_index = (preamble_index << 8) | stix->c->mth.code.ptr[i]; + if (!STIX_OOI_IN_PREAMBLE_INDEX_RANGE(preamble_index)) { - preamble_index = (preamble_index << 8) | stix->c->mth.code.ptr[i]; + /* the index got out of the range */ + preamble_code = STIX_METHOD_PREAMBLE_NONE; + preamble_index = 0; + break; } } } -/* TODO: check more special cases like 'return true' and encode it to this preamble */ } } else diff --git a/stix/lib/exec.c b/stix/lib/exec.c index a8f00fc..3a196ad 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -1349,7 +1349,7 @@ printf ("\n"); stix_oop_t newrcv; stix_oop_method_t newmth; stix_oop_char_t selector; - stix_ooi_t preamble; + stix_ooi_t preamble, preamble_code; handle_send_message: @@ -1384,13 +1384,54 @@ printf ("]\n"); STIX_ASSERT (STIX_OOP_TO_SMINT(newmth->tmpr_nargs) == b1); preamble = STIX_OOP_TO_SMINT(newmth->preamble); - switch (STIX_METHOD_GET_PREAMBLE_CODE(preamble)) + preamble_code = STIX_METHOD_GET_PREAMBLE_CODE(preamble); + switch (preamble_code) { case STIX_METHOD_PREAMBLE_RETURN_RECEIVER: printf ("RETURN RECEIVER AT PREAMBLE\n"); ACTIVE_STACK_POPS (stix, b1); /* pop arguments only*/ break; + case STIX_METHOD_PREAMBLE_RETURN_NIL: +printf ("RETURN NIL AT PREAMBLE\n"); + ACTIVE_STACK_POPS (stix, b1); + ACTIVE_STACK_SETTOP (stix, stix->_nil); + break; + + case STIX_METHOD_PREAMBLE_RETURN_TRUE: +printf ("RETURN TRUE AT PREAMBLE\n"); + ACTIVE_STACK_POPS (stix, b1); + ACTIVE_STACK_SETTOP (stix, stix->_true); + break; + + case STIX_METHOD_PREAMBLE_RETURN_FALSE: +printf ("RETURN FALSE AT PREAMBLE\n"); + ACTIVE_STACK_POPS (stix, b1); + ACTIVE_STACK_SETTOP (stix, stix->_false); + break; + + case STIX_METHOD_PREAMBLE_RETURN_NEGINDEX: +printf ("RETURN %d AT PREAMBLE\n", (int)-STIX_METHOD_GET_PREAMBLE_INDEX(preamble)); + ACTIVE_STACK_POPS (stix, b1); + ACTIVE_STACK_SETTOP (stix, STIX_OOP_FROM_SMINT(-STIX_METHOD_GET_PREAMBLE_INDEX(preamble))); + break; + + case STIX_METHOD_PREAMBLE_RETURN_INDEX: +printf ("RETURN %d AT PREAMBLE\n", (int)STIX_METHOD_GET_PREAMBLE_INDEX(preamble)); + ACTIVE_STACK_POPS (stix, b1); + ACTIVE_STACK_SETTOP (stix, STIX_OOP_FROM_SMINT(STIX_METHOD_GET_PREAMBLE_INDEX(preamble))); + break; + +#if 0 + case STIX_METHOD_PREAMBLE_RETURN_ZERO: + case STIX_METHOD_PREAMBLE_RETURN_ONE: + case STIX_METHOD_PREAMBLE_RETURN_TWO: +printf ("RETURN %d AT PREAMBLE\n", (int)(preamble_code - STIX_METHOD_PREAMBLE_RETURN_NEGONE - 1)); + ACTIVE_STACK_POPS (stix, b1); + ACTIVE_STACK_SETTOP (stix, STIX_OOP_FROM_SMINT(preamble_code - STIX_METHOD_PREAMBLE_RETURN_NEGONE - 1)); + break; +#endif + case STIX_METHOD_PREAMBLE_RETURN_INSTVAR: { stix_oop_oop_t rcv; diff --git a/stix/lib/stix.h b/stix/lib/stix.h index 91a3cbe..02c0bdd 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -614,8 +614,13 @@ struct stix_method_t * The code can be one of the following values: * 0 - no special action * 1 - return self - * 2 - return instvar[index] - * 3 - do primitive[index] + * 2 - return nil + * 3 - return true + * 4 - return false + * 5 - return -index. + * 6 - return index. + * 7 - return instvar[index] + * 8 - do primitive[index] */ #define STIX_METHOD_MAKE_PREAMBLE(code,index) ((((stix_ooi_t)index) << 8) | ((stix_ooi_t)code)) #define STIX_METHOD_GET_PREAMBLE_CODE(preamble) (((stix_ooi_t)preamble) & 0xFF) @@ -623,8 +628,16 @@ struct stix_method_t #define STIX_METHOD_PREAMBLE_NONE 0 #define STIX_METHOD_PREAMBLE_RETURN_RECEIVER 1 -#define STIX_METHOD_PREAMBLE_RETURN_INSTVAR 2 -#define STIX_METHOD_PREAMBLE_PRIMITIVE 3 +#define STIX_METHOD_PREAMBLE_RETURN_NIL 2 +#define STIX_METHOD_PREAMBLE_RETURN_TRUE 3 +#define STIX_METHOD_PREAMBLE_RETURN_FALSE 4 +#define STIX_METHOD_PREAMBLE_RETURN_NEGINDEX 5 +#define STIX_METHOD_PREAMBLE_RETURN_INDEX 6 +#define STIX_METHOD_PREAMBLE_RETURN_INSTVAR 7 +#define STIX_METHOD_PREAMBLE_PRIMITIVE 8 + +/* the index is an 16-bit unsigned integer. */ +#define STIX_OOI_IN_PREAMBLE_INDEX_RANGE(ooi) ((ooi) >= 0 && (ooi) <= 0xFFFF) #define STIX_CONTEXT_NAMED_INSTVARS 8 typedef struct stix_context_t stix_context_t;