renumbered byte codes and removed fragile code handling tail-call optimization
This commit is contained in:
parent
c233bb95a7
commit
51d7db9b96
295
stix/lib/comp.c
295
stix/lib/comp.c
@ -1465,73 +1465,120 @@ static STIX_INLINE int emit_byte_instruction (stix_t* stix, stix_byte_t code)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int emit_positional_instruction (stix_t* stix, int cmd, stix_oow_t index)
|
static int emit_single_param_instruction (stix_t* stix, int cmd, stix_oow_t param_1)
|
||||||
{
|
{
|
||||||
STIX_ASSERT (cmd <= 0xF);
|
stix_byte_t bc;
|
||||||
STIX_ASSERT (index <= MAX_CODE_INDEX);
|
|
||||||
|
|
||||||
if (index > 0xF)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
#if (STIX_CODE_EXTEND_SIZE == 2)
|
case BCODE_PUSH_INSTVAR_0:
|
||||||
if (emit_byte_instruction(stix, MAKE_CODE(CMD_EXTEND, cmd)) <= -1 ||
|
case BCODE_STORE_INTO_INSTVAR_0:
|
||||||
emit_byte_instruction(stix, index >> 8) <= -1 ||
|
case BCODE_POP_INTO_INSTVAR_0:
|
||||||
emit_byte_instruction(stix, index & 0xFF) <= -1) return -1;
|
case BCODE_PUSH_TEMPVAR_0:
|
||||||
#else
|
case BCODE_STORE_INTO_TEMPVAR_0:
|
||||||
if (emit_byte_instruction(stix, MAKE_CODE(CMD_EXTEND, cmd)) <= -1 ||
|
case BCODE_POP_INTO_TEMPVAR_0:
|
||||||
emit_byte_instruction(stix, index) <= -1) return -1;
|
case BCODE_PUSH_LITERAL_0:
|
||||||
#endif
|
if (param_1 < 8)
|
||||||
|
{
|
||||||
|
bc = (stix_byte_t)(cmd & 0xF8) | (stix_byte_t)param_1;
|
||||||
|
goto write_short;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (emit_byte_instruction(stix, MAKE_CODE(cmd, index)) <= -1) return -1;
|
/* convert the code to a long version */
|
||||||
|
bc = cmd | 0x80;
|
||||||
|
goto write_long;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case BCODE_PUSH_OBJECT_0:
|
||||||
|
case BCODE_STORE_INTO_OBJECT_0:
|
||||||
|
case BCODE_POP_INTO_OBJECT_0:
|
||||||
|
case BCODE_JUMP_FORWARD_0:
|
||||||
|
case BCODE_JUMP_BACKWARD_0:
|
||||||
|
case BCODE_JUMP_IF_TRUE_0:
|
||||||
|
case BCODE_JUMP_IF_FALSE_0:
|
||||||
|
case BCODE_JUMP_BY_OFFSET_0:
|
||||||
|
if (param_1 < 4)
|
||||||
|
{
|
||||||
|
bc = (stix_byte_t)(cmd & 0xFC) | (stix_byte_t)param_1;
|
||||||
|
goto write_short;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* convert the code to a long version */
|
||||||
|
bc = cmd | 0x80;
|
||||||
|
goto write_long;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stix->errnum = STIX_EINVAL;
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
write_short:
|
||||||
|
if (emit_byte_instruction(stix, bc) <= -1) return -1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
write_long:
|
||||||
|
#if (STIX_BCODE_LONG_PARAM_SIZE == 2)
|
||||||
|
if (emit_byte_instruction(stix, bc) <= -1 ||
|
||||||
|
emit_byte_instruction(stix, param_1 >> 8) <= -1 ||
|
||||||
|
emit_byte_instruction(stix, param_1 & 0xFF) <= -1) return -1;
|
||||||
|
#else
|
||||||
|
if (emit_byte_instruction(stix, bc) <= -1 ||
|
||||||
|
emit_byte_instruction(stix, param_1) <= -1) return -1;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int emit_double_positional_instruction (stix_t* stix, int cmd, stix_size_t index_1, stix_size_t index_2)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* 1010JJJJ KKKKKKKK Send literal index_2 K with J arguments to self
|
|
||||||
* 1011JJJJ KKKKKKKK Send literal index_2 K with J arguments to super
|
|
||||||
* 00001010 JJJJJJJJ KKKKKKKK
|
|
||||||
* 00001011 JJJJJJJJ KKKKKKKK
|
|
||||||
* 00001010 JJJJJJJJ JJJJJJJJ KKKKKKKK KKKKKKKK
|
|
||||||
* 00001011 JJJJJJJJ JJJJJJJJ KKKKKKKK KKKKKKKK
|
|
||||||
*
|
|
||||||
* Send:
|
|
||||||
* index_1 nargs JJJJ
|
|
||||||
* index_2 seletor-index-in-literal-frame KKKKKKKK
|
|
||||||
*
|
|
||||||
* Objvar:
|
|
||||||
* index_1 variable-index JJJJ
|
|
||||||
* index_2 object-index-in-literal-frame KKKKKKKK
|
|
||||||
*/
|
|
||||||
|
|
||||||
STIX_ASSERT (cmd <= 0xF);
|
static int emit_double_param_instruction (stix_t* stix, int cmd, stix_size_t param_1, stix_size_t param_2)
|
||||||
STIX_ASSERT (index_1 <= MAX_CODE_NARGS);
|
|
||||||
STIX_ASSERT (index_2 <= MAX_CODE_INDEX);
|
|
||||||
|
|
||||||
if (index_1 > 0xF || index_2 > 0xFF)
|
|
||||||
{
|
{
|
||||||
#if (STIX_CODE_EXTEND_SIZE == 2)
|
stix_byte_t bc;
|
||||||
if (emit_byte_instruction(stix, MAKE_CODE(CMD_EXTEND, cmd)) <= -1 ||
|
|
||||||
emit_byte_instruction(stix, index_1 >> 8) <= -1 ||
|
switch (cmd)
|
||||||
emit_byte_instruction(stix, index_1 & 0xFF) <= -1 ||
|
{
|
||||||
emit_byte_instruction(stix, index_2 >> 8) <= -1 ||
|
case BCODE_STORE_INTO_CTXTEMPVAR_0:
|
||||||
emit_byte_instruction(stix, index_2 & 0xFF) <= -1) return -1;
|
case BCODE_POP_INTO_CTXTEMPVAR_0:
|
||||||
#else
|
case BCODE_PUSH_CTXTEMPVAR_0:
|
||||||
if (emit_byte_instruction(stix, MAKE_CODE(CMD_EXTEND, cmd)) <= -1 ||
|
case BCODE_PUSH_OBJVAR_0:
|
||||||
emit_byte_instruction(stix, index_1) <= -1 ||
|
case BCODE_STORE_INTO_OBJVAR_0:
|
||||||
emit_byte_instruction(stix, index_2) <= -1) return -1;
|
case BCODE_POP_INTO_OBJVAR_0:
|
||||||
#endif
|
case BCODE_SEND_MESSAGE_0:
|
||||||
|
case BCODE_SEND_MESSAGE_TO_SUPER_0:
|
||||||
|
if (param_1 < 8 && param_2 < 0xFF)
|
||||||
|
{
|
||||||
|
/* low 2 bits of the instruction code is the first parameter */
|
||||||
|
bc = (stix_byte_t)(cmd & 0xFC) | (stix_byte_t)param_1;
|
||||||
|
goto write_short;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (emit_byte_instruction(stix, MAKE_CODE(cmd, index_1)) <= -1 ||
|
/* convert the code to a long version */
|
||||||
emit_byte_instruction(stix, index_2) <= -1) return -1;
|
bc = cmd | 0x80;
|
||||||
|
goto write_long;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stix->errnum = STIX_EINVAL;
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
write_short:
|
||||||
|
if (emit_byte_instruction(stix, bc) <= -1 ||
|
||||||
|
emit_byte_instruction(stix, param_2) <= -1) return -1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
write_long:
|
||||||
|
#if (STIX_BCODE_LONG_PARAM_SIZE == 2)
|
||||||
|
if (emit_byte_instruction(stix, bc) <= -1 ||
|
||||||
|
emit_byte_instruction(stix, param_1 >> 8) <= -1 ||
|
||||||
|
emit_byte_instruction(stix, param_1 & 0xFF) <= -1 ||
|
||||||
|
emit_byte_instruction(stix, param_2 >> 8) <= -1 ||
|
||||||
|
emit_byte_instruction(stix, param_2 & 0xFF) <= -1) return -1;
|
||||||
|
#else
|
||||||
|
if (emit_byte_instruction(stix, bc) <= -1 ||
|
||||||
|
emit_byte_instruction(stix, param_1) <= -1 ||
|
||||||
|
emit_byte_instruction(stix, param_2) return -1;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1542,20 +1589,23 @@ static int emit_push_smint_literal (stix_t* stix, stix_ooi_t i)
|
|||||||
switch (i)
|
switch (i)
|
||||||
{
|
{
|
||||||
case -1:
|
case -1:
|
||||||
return emit_byte_instruction (stix, CODE_PUSH_NEGONE);
|
return emit_byte_instruction (stix, BCODE_PUSH_NEGONE);
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
return emit_byte_instruction (stix, CODE_PUSH_ZERO);
|
return emit_byte_instruction (stix, BCODE_PUSH_ZERO);
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
return emit_byte_instruction (stix, CODE_PUSH_ONE);
|
return emit_byte_instruction (stix, BCODE_PUSH_ONE);
|
||||||
|
|
||||||
/* TODO: include some other numbers? like 2 */
|
case 2:
|
||||||
|
return emit_byte_instruction (stix, BCODE_PUSH_TWO);
|
||||||
|
|
||||||
|
/* TODO: include some other numbers? like 3 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (add_literal(stix, STIX_OOP_FROM_SMINT(i), &index) <= -1 ||
|
if (add_literal(stix, STIX_OOP_FROM_SMINT(i), &index) <= -1 ||
|
||||||
emit_positional_instruction(stix, CMD_PUSH_LITERAL, index) <= -1) return -1;
|
emit_single_param_instruction(stix, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2377,20 +2427,20 @@ printf ("\tpush_context nargs %d ntmprs %d\n", (int)block_arg_count, (int)stix->
|
|||||||
printf ("\tpush smint %d\n", (int)block_arg_count);
|
printf ("\tpush smint %d\n", (int)block_arg_count);
|
||||||
printf ("\tpush smint %d\n", (int)stix->c->mth.tmpr_count /*block_tmpr_count*/);
|
printf ("\tpush smint %d\n", (int)stix->c->mth.tmpr_count /*block_tmpr_count*/);
|
||||||
printf ("\tsend_block_copy\n");
|
printf ("\tsend_block_copy\n");
|
||||||
if (emit_byte_instruction(stix, CODE_PUSH_CONTEXT) <= -1 ||
|
if (emit_byte_instruction(stix, BCODE_PUSH_CONTEXT) <= -1 ||
|
||||||
emit_push_smint_literal(stix, block_arg_count) <= -1 ||
|
emit_push_smint_literal(stix, block_arg_count) <= -1 ||
|
||||||
emit_push_smint_literal(stix, stix->c->mth.tmpr_count/*block_tmpr_count*/) <= -1 ||
|
emit_push_smint_literal(stix, stix->c->mth.tmpr_count/*block_tmpr_count*/) <= -1 ||
|
||||||
emit_byte_instruction(stix, CODE_SEND_BLOCK_COPY) <= -1) return -1;
|
emit_byte_instruction(stix, BCODE_SEND_BLOCK_COPY) <= -1) return -1;
|
||||||
|
|
||||||
printf ("\tjump\n");
|
printf ("\tjump\n");
|
||||||
/* insert dummy instructions before replacing them with a jump instruction */
|
/* insert dummy instructions before replacing them with a jump instruction */
|
||||||
jump_inst_pos = stix->c->mth.code.len;
|
jump_inst_pos = stix->c->mth.code.len;
|
||||||
#if (STIX_CODE_EXTEND_SIZE == 2)
|
#if (STIX_BCODE_LONG_PARAM_SIZE == 2)
|
||||||
if (emit_byte_instruction(stix, MAKE_CODE(CMD_EXTEND, CMD_JUMP)) <= -1 ||
|
if (emit_byte_instruction(stix, BCODE_JUMP_FORWARD_X) <= -1 ||
|
||||||
emit_byte_instruction(stix, 0) <= -1 ||
|
emit_byte_instruction(stix, 0) <= -1 ||
|
||||||
emit_byte_instruction(stix, 0) <= -1) return -1;
|
emit_byte_instruction(stix, 0) <= -1) return -1;
|
||||||
#else
|
#else
|
||||||
if (emit_byte_instruction(stix, MAKE_CODE(CMD_EXTEND, CMD_JUMP)) <= -1 ||
|
if (emit_byte_instruction(stix, BCODE_JUMP_FORWARD_X) <= -1 ||
|
||||||
emit_byte_instruction(stix, 0) <= -1) return -1;
|
emit_byte_instruction(stix, 0) <= -1) return -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2398,7 +2448,7 @@ printf ("\tjump\n");
|
|||||||
if (stix->c->tok.type == STIX_IOTOK_RBRACK)
|
if (stix->c->tok.type == STIX_IOTOK_RBRACK)
|
||||||
{
|
{
|
||||||
/* the block is empty */
|
/* the block is empty */
|
||||||
if (emit_byte_instruction (stix, CODE_PUSH_NIL) <= -1) return -1;
|
if (emit_byte_instruction (stix, BCODE_PUSH_NIL) <= -1) return -1;
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2412,7 +2462,7 @@ printf ("\tjump\n");
|
|||||||
{
|
{
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
if (stix->c->tok.type == STIX_IOTOK_RBRACK) break;
|
if (stix->c->tok.type == STIX_IOTOK_RBRACK) break;
|
||||||
if (emit_byte_instruction(stix, CODE_POP_STACKTOP) <= -1) return -1;
|
if (emit_byte_instruction(stix, BCODE_POP_STACKTOP) <= -1) return -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2422,20 +2472,20 @@ printf ("\tjump\n");
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf ("\treturn_from_block\n");
|
printf ("\treturn_from_block\n");
|
||||||
if (emit_byte_instruction(stix,CODE_RETURN_FROM_BLOCK) <= -1) return -1;
|
if (emit_byte_instruction(stix, BCODE_RETURN_FROM_BLOCK) <= -1) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
block_code_size = stix->c->mth.code.len - jump_inst_pos - 3; /* -3 to exclude JUMP code */
|
block_code_size = stix->c->mth.code.len - jump_inst_pos - (STIX_BCODE_LONG_PARAM_SIZE + 1);
|
||||||
if (block_code_size > MAX_CODE_BLKCODE)
|
if (block_code_size > MAX_CODE_BLKCODE)
|
||||||
{
|
{
|
||||||
|
/* TOOD: increate the max block code size and
|
||||||
|
* if it exceedes the limit for BCODE_JUMP_FORWARD_X, switch to BECODE_JUMP_BY_OFFSET */
|
||||||
set_syntax_error (stix, STIX_SYNERR_BLKFLOOD, &block_loc, STIX_NULL);
|
set_syntax_error (stix, STIX_SYNERR_BLKFLOOD, &block_loc, STIX_NULL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: use CMD_EXTEND if block_code_size is > 127 or < -128 and shift code by 1 after having eliminated 1 byte.
|
|
||||||
stix->c->mth.code.ptr[jump_inst_pos + 1] = (stix_int8_t)block_code_size & 0xFF;*/
|
|
||||||
/* note that the jump offset is a signed number */
|
/* note that the jump offset is a signed number */
|
||||||
stix->c->mth.code.ptr[jump_inst_pos + 1] = ((stix_int16_t)block_code_size) >> 8;
|
stix->c->mth.code.ptr[jump_inst_pos + 1] = block_code_size >> 8;
|
||||||
stix->c->mth.code.ptr[jump_inst_pos + 2] = ((stix_int16_t)block_code_size & 0xFF);
|
stix->c->mth.code.ptr[jump_inst_pos + 2] = ((stix_int16_t)block_code_size & 0xFF);
|
||||||
|
|
||||||
/* restore the temporary count */
|
/* restore the temporary count */
|
||||||
@ -2662,7 +2712,7 @@ static int compile_byte_array_literal (stix_t* stix)
|
|||||||
|
|
||||||
printf ("\tpush_literal byte_array\n");
|
printf ("\tpush_literal byte_array\n");
|
||||||
if (add_literal (stix, lit, &index) <= -1 ||
|
if (add_literal (stix, lit, &index) <= -1 ||
|
||||||
emit_positional_instruction (stix, CMD_PUSH_LITERAL, index) <= -1) return -1;
|
emit_single_param_instruction (stix, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
|
||||||
|
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
return 0;
|
return 0;
|
||||||
@ -2682,7 +2732,7 @@ static int compile_array_literal (stix_t* stix)
|
|||||||
|
|
||||||
printf ("\tpush_literal array\n");
|
printf ("\tpush_literal array\n");
|
||||||
if (add_literal (stix, lit, &index) <= -1 ||
|
if (add_literal (stix, lit, &index) <= -1 ||
|
||||||
emit_positional_instruction (stix, CMD_PUSH_LITERAL, index) <= -1) return -1;
|
emit_single_param_instruction (stix, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
|
||||||
|
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
return 0;
|
return 0;
|
||||||
@ -2711,19 +2761,19 @@ static int compile_expression_primary (stix_t* stix, const stix_ucs_t* ident, co
|
|||||||
{
|
{
|
||||||
case VAR_ARGUMENT:
|
case VAR_ARGUMENT:
|
||||||
case VAR_TEMPORARY:
|
case VAR_TEMPORARY:
|
||||||
if (emit_positional_instruction(stix, CMD_PUSH_TEMPVAR, var.pos) <= -1) return -1;
|
if (emit_single_param_instruction(stix, BCODE_PUSH_TEMPVAR_0, var.pos) <= -1) return -1;
|
||||||
printf ("\tpush tempvar %d\n", (int)var.pos);
|
printf ("\tpush tempvar %d\n", (int)var.pos);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VAR_INSTANCE:
|
case VAR_INSTANCE:
|
||||||
case VAR_CLASSINST:
|
case VAR_CLASSINST:
|
||||||
if (emit_positional_instruction(stix, CMD_PUSH_INSTVAR, var.pos) <= -1) return -1;
|
if (emit_single_param_instruction(stix, BCODE_PUSH_INSTVAR_0, var.pos) <= -1) return -1;
|
||||||
printf ("\tpush instvar %d\n", (int)var.pos);
|
printf ("\tpush instvar %d\n", (int)var.pos);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VAR_CLASS:
|
case VAR_CLASS:
|
||||||
if (add_literal(stix, (stix_oop_t)var.cls, &index) <= -1 ||
|
if (add_literal(stix, (stix_oop_t)var.cls, &index) <= -1 ||
|
||||||
emit_double_positional_instruction(stix, CMD_PUSH_OBJVAR, var.pos, index) <= -1) return -1;
|
emit_double_param_instruction(stix, BCODE_PUSH_OBJVAR_0, var.pos, index) <= -1) return -1;
|
||||||
printf ("\tpush objvar %d %d\n", (int)var.pos, (int)index);
|
printf ("\tpush objvar %d %d\n", (int)var.pos, (int)index);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2752,59 +2802,59 @@ printf ("GLOBAL NOT IMPLMENTED.... \n");
|
|||||||
|
|
||||||
case STIX_IOTOK_SELF:
|
case STIX_IOTOK_SELF:
|
||||||
printf ("\tpush receiver...\n");
|
printf ("\tpush receiver...\n");
|
||||||
if (emit_byte_instruction(stix, CODE_PUSH_RECEIVER) <= -1) return -1;
|
if (emit_byte_instruction(stix, BCODE_PUSH_RECEIVER) <= -1) return -1;
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STIX_IOTOK_SUPER:
|
case STIX_IOTOK_SUPER:
|
||||||
printf ("\tpush receiver(super)...\n");
|
printf ("\tpush receiver(super)...\n");
|
||||||
if (emit_byte_instruction(stix, CODE_PUSH_RECEIVER) <= -1) return -1;
|
if (emit_byte_instruction(stix, BCODE_PUSH_RECEIVER) <= -1) return -1;
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
*to_super = 1;
|
*to_super = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STIX_IOTOK_NIL:
|
case STIX_IOTOK_NIL:
|
||||||
printf ("\tpush nil...\n");
|
printf ("\tpush nil...\n");
|
||||||
if (emit_byte_instruction(stix, CODE_PUSH_NIL) <= -1) return -1;
|
if (emit_byte_instruction(stix, BCODE_PUSH_NIL) <= -1) return -1;
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STIX_IOTOK_TRUE:
|
case STIX_IOTOK_TRUE:
|
||||||
printf ("\tpush true...\n");
|
printf ("\tpush true...\n");
|
||||||
if (emit_byte_instruction(stix, CODE_PUSH_TRUE) <= -1) return -1;
|
if (emit_byte_instruction(stix, BCODE_PUSH_TRUE) <= -1) return -1;
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STIX_IOTOK_FALSE:
|
case STIX_IOTOK_FALSE:
|
||||||
printf ("\tpush false...\n");
|
printf ("\tpush false...\n");
|
||||||
if (emit_byte_instruction(stix, CODE_PUSH_FALSE) <= -1) return -1;
|
if (emit_byte_instruction(stix, BCODE_PUSH_FALSE) <= -1) return -1;
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STIX_IOTOK_THIS_CONTEXT:
|
case STIX_IOTOK_THIS_CONTEXT:
|
||||||
printf ("\tpush context...\n");
|
printf ("\tpush context...\n");
|
||||||
if (emit_byte_instruction(stix, CODE_PUSH_CONTEXT) <= -1) return -1;
|
if (emit_byte_instruction(stix, BCODE_PUSH_CONTEXT) <= -1) return -1;
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STIX_IOTOK_CHARLIT:
|
case STIX_IOTOK_CHARLIT:
|
||||||
STIX_ASSERT (stix->c->tok.name.len == 1);
|
STIX_ASSERT (stix->c->tok.name.len == 1);
|
||||||
if (add_character_literal(stix, stix->c->tok.name.ptr[0], &index) <= -1 ||
|
if (add_character_literal(stix, stix->c->tok.name.ptr[0], &index) <= -1 ||
|
||||||
emit_positional_instruction(stix, CMD_PUSH_LITERAL, index) <= -1) return -1;
|
emit_single_param_instruction(stix, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
|
||||||
printf ("\tpush character literal %d\n", (int)index);
|
printf ("\tpush character literal %d\n", (int)index);
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STIX_IOTOK_STRLIT:
|
case STIX_IOTOK_STRLIT:
|
||||||
if (add_string_literal(stix, &stix->c->tok.name, &index) <= -1 ||
|
if (add_string_literal(stix, &stix->c->tok.name, &index) <= -1 ||
|
||||||
emit_positional_instruction(stix, CMD_PUSH_LITERAL, index) <= -1) return -1;
|
emit_single_param_instruction(stix, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
|
||||||
printf ("\tpush string literal %d\n", (int)index);
|
printf ("\tpush string literal %d\n", (int)index);
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STIX_IOTOK_SYMLIT:
|
case STIX_IOTOK_SYMLIT:
|
||||||
if (add_symbol_literal(stix, &stix->c->tok.name, &index) <= -1 ||
|
if (add_symbol_literal(stix, &stix->c->tok.name, &index) <= -1 ||
|
||||||
emit_positional_instruction(stix, CMD_PUSH_LITERAL, index) <= -1) return -1;
|
emit_single_param_instruction(stix, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
|
||||||
printf ("\tpush symbol literal %d\n", (int)index);
|
printf ("\tpush symbol literal %d\n", (int)index);
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
break;
|
break;
|
||||||
@ -2875,8 +2925,8 @@ printf ("\tpush int literal\n");
|
|||||||
|
|
||||||
static stix_byte_t send_message_cmd[] =
|
static stix_byte_t send_message_cmd[] =
|
||||||
{
|
{
|
||||||
CMD_SEND_MESSAGE,
|
BCODE_SEND_MESSAGE_0,
|
||||||
CMD_SEND_MESSAGE_TO_SUPER
|
BCODE_SEND_MESSAGE_TO_SUPER_0
|
||||||
};
|
};
|
||||||
|
|
||||||
static int compile_unary_message (stix_t* stix, int to_super)
|
static int compile_unary_message (stix_t* stix, int to_super)
|
||||||
@ -2888,7 +2938,7 @@ static int compile_unary_message (stix_t* stix, int to_super)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (add_symbol_literal(stix, &stix->c->tok.name, &index) <= -1 ||
|
if (add_symbol_literal(stix, &stix->c->tok.name, &index) <= -1 ||
|
||||||
emit_double_positional_instruction(stix, send_message_cmd[to_super], 0, index) <= -1) return -1;
|
emit_double_param_instruction(stix, send_message_cmd[to_super], 0, index) <= -1) return -1;
|
||||||
printf ("\tsend unary message %d [", (int)index);
|
printf ("\tsend unary message %d [", (int)index);
|
||||||
print_ucs (&stix->c->tok.name);
|
print_ucs (&stix->c->tok.name);
|
||||||
printf ("] with 0 arguments %s\n", (to_super? " to super": ""));
|
printf ("] with 0 arguments %s\n", (to_super? " to super": ""));
|
||||||
@ -2927,7 +2977,7 @@ static int compile_binary_message (stix_t* stix, int to_super)
|
|||||||
if (stix->c->tok.type == STIX_IOTOK_IDENT && compile_unary_message(stix, to_super2) <= -1) goto oops;
|
if (stix->c->tok.type == STIX_IOTOK_IDENT && compile_unary_message(stix, to_super2) <= -1) goto oops;
|
||||||
|
|
||||||
if (add_symbol_literal(stix, &binsel, &index) <= -1 ||
|
if (add_symbol_literal(stix, &binsel, &index) <= -1 ||
|
||||||
emit_double_positional_instruction(stix, send_message_cmd[to_super], 1, index) <= -1) goto oops;
|
emit_double_param_instruction(stix, send_message_cmd[to_super], 1, index) <= -1) goto oops;
|
||||||
printf ("\tsend binary message %d [", (int)index);
|
printf ("\tsend binary message %d [", (int)index);
|
||||||
print_ucs (&binsel);
|
print_ucs (&binsel);
|
||||||
printf ("] with 1 arguments %s\n", (to_super? " to super": ""));
|
printf ("] with 1 arguments %s\n", (to_super? " to super": ""));
|
||||||
@ -2989,7 +3039,7 @@ static int compile_keyword_message (stix_t* stix, int to_super)
|
|||||||
kwsel.len = stix->c->mth.kwsels.len - saved_kwsel_len;
|
kwsel.len = stix->c->mth.kwsels.len - saved_kwsel_len;
|
||||||
|
|
||||||
if (add_symbol_literal(stix, &kwsel, &index) <= -1 ||
|
if (add_symbol_literal(stix, &kwsel, &index) <= -1 ||
|
||||||
emit_double_positional_instruction(stix, send_message_cmd[to_super], nargs, index) <= -1) goto oops;
|
emit_double_param_instruction(stix, send_message_cmd[to_super], nargs, index) <= -1) goto oops;
|
||||||
|
|
||||||
printf ("\tsend keyword message %d [", (int)index);
|
printf ("\tsend keyword message %d [", (int)index);
|
||||||
print_ucs (&kwsel);
|
print_ucs (&kwsel);
|
||||||
@ -3028,7 +3078,7 @@ static int compile_message_expression (stix_t* stix, int to_super)
|
|||||||
/* insert NOOP to change to DUP_STACKTOP if there is a
|
/* insert NOOP to change to DUP_STACKTOP if there is a
|
||||||
* cascaded message */
|
* cascaded message */
|
||||||
noop_pos = stix->c->mth.code.len;
|
noop_pos = stix->c->mth.code.len;
|
||||||
if (emit_byte_instruction(stix, CODE_NOOP) <= -1) return -1;
|
if (emit_byte_instruction(stix, BCODE_NOOP) <= -1) return -1;
|
||||||
|
|
||||||
if (compile_unary_message(stix, to_super) <= -1) return -1;
|
if (compile_unary_message(stix, to_super) <= -1) return -1;
|
||||||
|
|
||||||
@ -3039,7 +3089,7 @@ static int compile_message_expression (stix_t* stix, int to_super)
|
|||||||
stix->c->mth.code.len--;
|
stix->c->mth.code.len--;
|
||||||
|
|
||||||
noop_pos = stix->c->mth.code.len;
|
noop_pos = stix->c->mth.code.len;
|
||||||
if (emit_byte_instruction(stix, CODE_NOOP) <= -1) return -1;
|
if (emit_byte_instruction(stix, BCODE_NOOP) <= -1) return -1;
|
||||||
if (compile_binary_message(stix, to_super) <= -1) return -1;
|
if (compile_binary_message(stix, to_super) <= -1) return -1;
|
||||||
}
|
}
|
||||||
if (stix->c->tok.type == STIX_IOTOK_KEYWORD)
|
if (stix->c->tok.type == STIX_IOTOK_KEYWORD)
|
||||||
@ -3049,14 +3099,14 @@ static int compile_message_expression (stix_t* stix, int to_super)
|
|||||||
stix->c->mth.code.len--;
|
stix->c->mth.code.len--;
|
||||||
|
|
||||||
noop_pos = stix->c->mth.code.len;
|
noop_pos = stix->c->mth.code.len;
|
||||||
if (emit_byte_instruction(stix, CODE_NOOP) <= -1) return -1;
|
if (emit_byte_instruction(stix, BCODE_NOOP) <= -1) return -1;
|
||||||
if (compile_keyword_message(stix, to_super) <= -1) return -1;
|
if (compile_keyword_message(stix, to_super) <= -1) return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STIX_IOTOK_BINSEL:
|
case STIX_IOTOK_BINSEL:
|
||||||
noop_pos = stix->c->mth.code.len;
|
noop_pos = stix->c->mth.code.len;
|
||||||
if (emit_byte_instruction(stix, CODE_NOOP) <= -1) return -1;
|
if (emit_byte_instruction(stix, BCODE_NOOP) <= -1) return -1;
|
||||||
|
|
||||||
if (compile_binary_message(stix, to_super) <= -1) return -1;
|
if (compile_binary_message(stix, to_super) <= -1) return -1;
|
||||||
if (stix->c->tok.type == STIX_IOTOK_KEYWORD)
|
if (stix->c->tok.type == STIX_IOTOK_KEYWORD)
|
||||||
@ -3066,7 +3116,7 @@ static int compile_message_expression (stix_t* stix, int to_super)
|
|||||||
stix->c->mth.code.len--;
|
stix->c->mth.code.len--;
|
||||||
|
|
||||||
noop_pos = stix->c->mth.code.len;
|
noop_pos = stix->c->mth.code.len;
|
||||||
if (emit_byte_instruction(stix, CODE_NOOP) <= -1) return -1;
|
if (emit_byte_instruction(stix, BCODE_NOOP) <= -1) return -1;
|
||||||
|
|
||||||
if (compile_keyword_message(stix, to_super) <= -1) return -1;
|
if (compile_keyword_message(stix, to_super) <= -1) return -1;
|
||||||
}
|
}
|
||||||
@ -3074,7 +3124,7 @@ static int compile_message_expression (stix_t* stix, int to_super)
|
|||||||
|
|
||||||
case STIX_IOTOK_KEYWORD:
|
case STIX_IOTOK_KEYWORD:
|
||||||
noop_pos = stix->c->mth.code.len;
|
noop_pos = stix->c->mth.code.len;
|
||||||
if (emit_byte_instruction(stix, CODE_NOOP) <= -1) return -1;
|
if (emit_byte_instruction(stix, BCODE_NOOP) <= -1) return -1;
|
||||||
|
|
||||||
if (compile_keyword_message(stix, to_super) <= -1) return -1;
|
if (compile_keyword_message(stix, to_super) <= -1) return -1;
|
||||||
break;
|
break;
|
||||||
@ -3087,8 +3137,8 @@ static int compile_message_expression (stix_t* stix, int to_super)
|
|||||||
if (stix->c->tok.type == STIX_IOTOK_SEMICOLON)
|
if (stix->c->tok.type == STIX_IOTOK_SEMICOLON)
|
||||||
{
|
{
|
||||||
printf ("\tdup_stacktop for cascading\n");
|
printf ("\tdup_stacktop for cascading\n");
|
||||||
stix->c->mth.code.ptr[noop_pos] = CODE_DUP_STACKTOP;
|
stix->c->mth.code.ptr[noop_pos] = BCODE_DUP_STACKTOP;
|
||||||
if (emit_byte_instruction(stix, CODE_POP_STACKTOP) <= -1) return -1;
|
if (emit_byte_instruction(stix, BCODE_POP_STACKTOP) <= -1) return -1;
|
||||||
GET_TOKEN(stix);
|
GET_TOKEN(stix);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3185,25 +3235,25 @@ printf ("\n");
|
|||||||
|
|
||||||
case VAR_TEMPORARY:
|
case VAR_TEMPORARY:
|
||||||
printf ("\tstore_into_tempvar %d\n", (int)var.pos);
|
printf ("\tstore_into_tempvar %d\n", (int)var.pos);
|
||||||
/* TODO: if pop is 1, emit CMD_POP_INTO_TEMPVAR.
|
/* TODO: if pop is 1, emit BCODE_POP_INTO_TEMPVAR.
|
||||||
ret = pop;
|
ret = pop;
|
||||||
*/
|
*/
|
||||||
if (emit_positional_instruction (stix, CMD_STORE_INTO_TEMPVAR, var.pos) <= -1) goto oops;
|
if (emit_single_param_instruction (stix, BCODE_STORE_INTO_TEMPVAR_0, var.pos) <= -1) goto oops;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VAR_INSTANCE:
|
case VAR_INSTANCE:
|
||||||
case VAR_CLASSINST:
|
case VAR_CLASSINST:
|
||||||
printf ("\tstore_into_instvar %d\n", (int)var.pos);
|
printf ("\tstore_into_instvar %d\n", (int)var.pos);
|
||||||
/* TODO: if pop is 1, emit CMD_POP_INTO_INSTVAR
|
/* TODO: if pop is 1, emit BCODE_POP_INTO_INSTVAR
|
||||||
ret = pop;
|
ret = pop;
|
||||||
*/
|
*/
|
||||||
if (emit_positional_instruction (stix, CMD_STORE_INTO_INSTVAR, var.pos) <= -1) goto oops;
|
if (emit_single_param_instruction (stix, BCODE_STORE_INTO_INSTVAR_0, var.pos) <= -1) goto oops;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VAR_CLASS:
|
case VAR_CLASS:
|
||||||
/* TODO is this correct? */
|
/* TODO is this correct? */
|
||||||
if (add_literal (stix, (stix_oop_t)var.cls, &index) <= -1 ||
|
if (add_literal (stix, (stix_oop_t)var.cls, &index) <= -1 ||
|
||||||
emit_double_positional_instruction (stix, CMD_STORE_INTO_OBJVAR, var.pos, index) <= -1) goto oops;
|
emit_double_param_instruction (stix, BCODE_STORE_INTO_OBJVAR_0, var.pos, index) <= -1) goto oops;
|
||||||
printf ("\tstore_into_objvar %d %d\n", (int)var.pos, (int)index);
|
printf ("\tstore_into_objvar %d %d\n", (int)var.pos, (int)index);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3247,7 +3297,7 @@ static int compile_block_statement (stix_t* stix)
|
|||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
if (compile_method_expression(stix, 0) <= -1) return -1;
|
if (compile_method_expression(stix, 0) <= -1) return -1;
|
||||||
printf ("\treturn_stacktop\n");
|
printf ("\treturn_stacktop\n");
|
||||||
return emit_byte_instruction (stix, CODE_RETURN_STACKTOP);
|
return emit_byte_instruction (stix, BCODE_RETURN_STACKTOP);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3268,7 +3318,7 @@ static int compile_method_statement (stix_t* stix)
|
|||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
if (compile_method_expression(stix, 0) <= -1) return -1;
|
if (compile_method_expression(stix, 0) <= -1) return -1;
|
||||||
printf ("\treturn_stacktop\n");
|
printf ("\treturn_stacktop\n");
|
||||||
return emit_byte_instruction (stix, CODE_RETURN_STACKTOP);
|
return emit_byte_instruction (stix, BCODE_RETURN_STACKTOP);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3285,7 +3335,7 @@ printf ("\treturn_stacktop\n");
|
|||||||
|
|
||||||
/* if n is 1, no stack popping is required */
|
/* if n is 1, no stack popping is required */
|
||||||
if (n == 0) printf ("\tpop_stacktop\n");
|
if (n == 0) printf ("\tpop_stacktop\n");
|
||||||
return (n == 0)? emit_byte_instruction (stix, CODE_POP_STACKTOP): 0;
|
return (n == 0)? emit_byte_instruction (stix, BCODE_POP_STACKTOP): 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3327,7 +3377,7 @@ static int compile_method_statements (stix_t* stix)
|
|||||||
/* arrange to return the receiver if execution reached
|
/* arrange to return the receiver if execution reached
|
||||||
* the end of the method without explicit return */
|
* the end of the method without explicit return */
|
||||||
printf ("\treturn_receiver\n");
|
printf ("\treturn_receiver\n");
|
||||||
return emit_byte_instruction (stix, CODE_RETURN_RECEIVER);
|
return emit_byte_instruction (stix, BCODE_RETURN_RECEIVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_compiled_method (stix_t* stix)
|
static int add_compiled_method (stix_t* stix)
|
||||||
@ -3368,41 +3418,36 @@ static int add_compiled_method (stix_t* stix)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (stix->c->mth.code.ptr[0] == CODE_RETURN_RECEIVER)
|
if (stix->c->mth.code.ptr[0] == BCODE_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] == BCODE_PUSH_RECEIVER &&
|
||||||
stix->c->mth.code.ptr[1] == CODE_RETURN_STACKTOP)
|
stix->c->mth.code.ptr[1] == BCODE_RETURN_STACKTOP)
|
||||||
{
|
{
|
||||||
preamble_code = STIX_METHOD_PREAMBLE_RETURN_RECEIVER;
|
preamble_code = STIX_METHOD_PREAMBLE_RETURN_RECEIVER;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* check if the method begins with 'return instavar' instruction */
|
/* check if the method begins with 'return instavar' instruction */
|
||||||
int index_size;
|
if (stix->c->mth.code.ptr[0] >= BCODE_PUSH_INSTVAR_0 &&
|
||||||
stix_byte_t cmd;
|
stix->c->mth.code.ptr[0] <= BCODE_PUSH_INSTVAR_7 &&
|
||||||
|
stix->c->mth.code.ptr[1] == BCODE_RETURN_STACKTOP)
|
||||||
cmd = stix->c->mth.code.ptr[0] >> 4;
|
|
||||||
if (cmd == CMD_EXTEND)
|
|
||||||
{
|
|
||||||
cmd = stix->c->mth.code.ptr[0] & 0xF;
|
|
||||||
index_size = STIX_CODE_EXTEND_SIZE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
index_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd == CMD_PUSH_INSTVAR &&
|
|
||||||
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;
|
||||||
|
preamble_index = stix->c->mth.code.ptr[0] & 0x7; /* low 3 bits */
|
||||||
if (index_size == 1) preamble_index = stix->c->mth.code.ptr[1];
|
}
|
||||||
else if (index_size == 2) preamble_index = ((stix_ooi_t)stix->c->mth.code.ptr[1] << 8) | stix->c->mth.code.ptr[2];
|
else if (stix->c->mth.code.ptr[0] == BCODE_PUSH_INSTVAR_X &&
|
||||||
else preamble_index = stix->c->mth.code.ptr[0] & 0xF;
|
stix->c->mth.code.ptr[STIX_BCODE_LONG_PARAM_SIZE + 1] == BCODE_RETURN_STACKTOP)
|
||||||
|
{
|
||||||
|
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];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
791
stix/lib/exec.c
791
stix/lib/exec.c
@ -73,7 +73,7 @@
|
|||||||
LOAD_ACTIVE_SP (stix); \
|
LOAD_ACTIVE_SP (stix); \
|
||||||
} while (0) \
|
} while (0) \
|
||||||
|
|
||||||
static STIX_INLINE int activate_new_method (stix_t* stix, stix_oop_method_t mth, stix_uint16_t next_inst)
|
static STIX_INLINE int activate_new_method (stix_t* stix, stix_oop_method_t mth)
|
||||||
{
|
{
|
||||||
stix_oop_context_t ctx;
|
stix_oop_context_t ctx;
|
||||||
stix_ooi_t i;
|
stix_ooi_t i;
|
||||||
@ -109,32 +109,6 @@ static STIX_INLINE int activate_new_method (stix_t* stix, stix_oop_method_t mth,
|
|||||||
STIX_ASSERT (stix->sp >= 0);
|
STIX_ASSERT (stix->sp >= 0);
|
||||||
STIX_ASSERT (stix->sp >= nargs);
|
STIX_ASSERT (stix->sp >= nargs);
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (!(stix->option.trait & STIX_NOTCO))
|
|
||||||
{
|
|
||||||
if (stix->active_context->home == stix->_nil)
|
|
||||||
{
|
|
||||||
/* method context */
|
|
||||||
STIX_ASSERT (STIX_CLASSOF(stix, stix->active_context) == stix->_method_context);
|
|
||||||
|
|
||||||
if (next_inst == ((CODE_POP_STACKTOP << 8) | CODE_RETURN_STACKTOP) ||
|
|
||||||
next_inst == ((CODE_POP_STACKTOP << 8) | CODE_RETURN_RECEIVER) ||
|
|
||||||
next_inst == CODE_RETURN_STACKTOP ||
|
|
||||||
next_inst == CODE_RETURN_RECEIVER)
|
|
||||||
{
|
|
||||||
/* don't allocate a new method context. reuse the active context.
|
|
||||||
*
|
|
||||||
* [NOTE]
|
|
||||||
* a context stored into a variable by way of 'thisContext' may
|
|
||||||
* present a different context from the original after this reuse.
|
|
||||||
*/
|
|
||||||
ctx = stix->active_context;
|
|
||||||
goto reuse_context;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
stix_pushtmp (stix, (stix_oop_t*)&mth);
|
stix_pushtmp (stix, (stix_oop_t*)&mth);
|
||||||
ctx = (stix_oop_context_t)stix_instantiate (stix, stix->_method_context, STIX_NULL, CONTEXT_STACK_SIZE);
|
ctx = (stix_oop_context_t)stix_instantiate (stix, stix->_method_context, STIX_NULL, CONTEXT_STACK_SIZE);
|
||||||
stix_poptmp (stix);
|
stix_poptmp (stix);
|
||||||
@ -366,7 +340,7 @@ TODO: overcome this problem
|
|||||||
STORE_ACTIVE_IP (stix);
|
STORE_ACTIVE_IP (stix);
|
||||||
STORE_ACTIVE_SP (stix);
|
STORE_ACTIVE_SP (stix);
|
||||||
|
|
||||||
return activate_new_method (stix, mth, CODE_NOOP);
|
return activate_new_method (stix, mth);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int primitive_dump (stix_t* stix, stix_ooi_t nargs)
|
static int primitive_dump (stix_t* stix, stix_ooi_t nargs)
|
||||||
@ -838,31 +812,28 @@ static primitive_t primitives[] =
|
|||||||
|
|
||||||
#define FETCH_BYTE_CODE_TO(stix, v_ooi) (v_ooi = (stix)->active_code->slot[(stix)->ip++])
|
#define FETCH_BYTE_CODE_TO(stix, v_ooi) (v_ooi = (stix)->active_code->slot[(stix)->ip++])
|
||||||
|
|
||||||
#if (STIX_CODE_EXTEND_SIZE == 2)
|
#if (STIX_BCODE_LONG_PARAM_SIZE == 2)
|
||||||
|
|
||||||
#define FETCH_UNSIGNED_CODE_TO(stix, v_ooi) \
|
#define FETCH_PARAM_CODE_TO(stix, v_ooi) \
|
||||||
do { \
|
do { \
|
||||||
v_ooi = (stix)->active_code->slot[(stix)->ip++]; \
|
v_ooi = (stix)->active_code->slot[(stix)->ip++]; \
|
||||||
v_ooi = (v_ooi << 8) | (stix)->active_code->slot[stix->ip++]; \
|
v_ooi = (v_ooi << 8) | (stix)->active_code->slot[stix->ip++]; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define FETCH_SIGNED_CODE_TO(stix, v_ooi) \
|
#else /* STIX_BCODE_LONG_PARAM_SIZE == 2 */
|
||||||
do { \
|
|
||||||
v_ooi = (stix)->active_code->slot[(stix)->ip++]; \
|
|
||||||
v_ooi = (stix_int16_t)((v_ooi << 8) | (stix)->active_code->slot[stix->ip++]); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#else /* STIX_CODE_EXTEND_SIZE == 2 */
|
#define FETCH_PARAM_CODE_TO(stix, v_ooi) (v_ooi = (stix)->active_code->slot[(stix)->ip++])
|
||||||
|
|
||||||
#define FETCH_UNSIGNED_CODE_TO(stix, v_ooi) (v_ooi = (stix)->active_code->slot[(stix)->ip++])
|
#endif /* STIX_BCODE_LONG_PARAM_SIZE == 2 */
|
||||||
#define FETCH_SIGNED_CODE_TO(stix, v_ooi) (v_ooi = (stix_int8_t)(stix)->active_code->slot[(stix)->ip++])
|
|
||||||
|
|
||||||
#endif /* STIX_CODE_EXTEND_SIZE == 2 */
|
|
||||||
|
|
||||||
int stix_execute (stix_t* stix)
|
int stix_execute (stix_t* stix)
|
||||||
{
|
{
|
||||||
stix_byte_t bc, cmd;
|
stix_byte_t bcode;
|
||||||
stix_ooi_t b1, b2;
|
stix_ooi_t b1, b2, bx;
|
||||||
|
stix_oop_context_t ctx;
|
||||||
|
stix_oop_oop_t t1;
|
||||||
|
stix_oop_t return_value;
|
||||||
|
|
||||||
stix_size_t inst_counter;
|
stix_size_t inst_counter;
|
||||||
|
|
||||||
@ -872,82 +843,119 @@ int stix_execute (stix_t* stix)
|
|||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf ("IP => %d ", (int)stix->ip);
|
printf ("IP => %d ", (int)stix->ip);
|
||||||
#endif
|
#endif
|
||||||
FETCH_BYTE_CODE_TO (stix, bc);
|
FETCH_BYTE_CODE_TO (stix, bcode);
|
||||||
while (bc == CODE_NOOP) FETCH_BYTE_CODE_TO (stix, bc);
|
/*while (bcode == BCODE_NOOP) FETCH_BYTE_CODE_TO (stix, bcode);*/
|
||||||
|
|
||||||
cmd = bc >> 4;
|
|
||||||
if (cmd == CMD_EXTEND)
|
|
||||||
{
|
|
||||||
cmd = bc & 0xF;
|
|
||||||
switch (cmd)
|
|
||||||
{
|
|
||||||
case CMD_JUMP:
|
|
||||||
case CMD_JUMP_IF_FALSE:
|
|
||||||
FETCH_SIGNED_CODE_TO (stix, b1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CMD_PUSH_OBJVAR:
|
|
||||||
case CMD_STORE_INTO_OBJVAR:
|
|
||||||
case CMD_SEND_MESSAGE:
|
|
||||||
case CMD_SEND_MESSAGE_TO_SUPER:
|
|
||||||
FETCH_UNSIGNED_CODE_TO (stix, b1);
|
|
||||||
FETCH_UNSIGNED_CODE_TO (stix, b2);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
FETCH_UNSIGNED_CODE_TO (stix, b1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (cmd)
|
|
||||||
{
|
|
||||||
case CMD_JUMP:
|
|
||||||
case CMD_JUMP_IF_FALSE:
|
|
||||||
b1 = bc & 0xF; /* the short jump offset is unsigned */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CMD_PUSH_OBJVAR:
|
|
||||||
case CMD_STORE_INTO_OBJVAR:
|
|
||||||
case CMD_SEND_MESSAGE:
|
|
||||||
case CMD_SEND_MESSAGE_TO_SUPER:
|
|
||||||
b1 = bc & 0xF;
|
|
||||||
FETCH_BYTE_CODE_TO (stix, b2);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
b1 = bc & 0xF;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inst_counter++;
|
|
||||||
#if 0
|
#if 0
|
||||||
printf ("CMD => %d, B1 = %d, SP = %d, IP AFTER INC %d\n", (int)cmd, (int)b1, (int)stix->sp, (int)stix->ip);
|
printf ("BCODE = %x\n", bcode);
|
||||||
#endif
|
#endif
|
||||||
switch (cmd)
|
inst_counter++;
|
||||||
{
|
|
||||||
|
|
||||||
case CMD_PUSH_INSTVAR:
|
switch (bcode)
|
||||||
|
{
|
||||||
|
/* ------------------------------------------------- */
|
||||||
|
|
||||||
|
case BCODE_PUSH_INSTVAR_X:
|
||||||
|
FETCH_PARAM_CODE_TO (stix, b1);
|
||||||
|
goto push_instvar;
|
||||||
|
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:
|
||||||
|
b1 = bcode & 0x7; /* low 3 bits */
|
||||||
|
push_instvar:
|
||||||
printf ("PUSH_INSTVAR %d\n", (int)b1);
|
printf ("PUSH_INSTVAR %d\n", (int)b1);
|
||||||
STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(stix->active_context->origin->receiver_or_source) == STIX_OBJ_TYPE_OOP);
|
STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(stix->active_context->origin->receiver_or_source) == STIX_OBJ_TYPE_OOP);
|
||||||
ACTIVE_STACK_PUSH (stix, ((stix_oop_oop_t)stix->active_context->origin->receiver_or_source)->slot[b1]);
|
ACTIVE_STACK_PUSH (stix, ((stix_oop_oop_t)stix->active_context->origin->receiver_or_source)->slot[b1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_PUSH_TEMPVAR:
|
/* ------------------------------------------------- */
|
||||||
printf ("PUSH_TEMPVAR idx=%d - ", (int)b1);
|
|
||||||
fflush(stdout);
|
case BCODE_STORE_INTO_INSTVAR_X:
|
||||||
|
FETCH_PARAM_CODE_TO (stix, b1);
|
||||||
|
goto store_instvar;
|
||||||
|
case BCODE_STORE_INTO_INSTVAR_0:
|
||||||
|
case BCODE_STORE_INTO_INSTVAR_1:
|
||||||
|
case BCODE_STORE_INTO_INSTVAR_2:
|
||||||
|
case BCODE_STORE_INTO_INSTVAR_3:
|
||||||
|
case BCODE_STORE_INTO_INSTVAR_4:
|
||||||
|
case BCODE_STORE_INTO_INSTVAR_5:
|
||||||
|
case BCODE_STORE_INTO_INSTVAR_6:
|
||||||
|
case BCODE_STORE_INTO_INSTVAR_7:
|
||||||
|
b1 = bcode & 0x7; /* low 3 bits */
|
||||||
|
store_instvar:
|
||||||
|
printf ("STORE_INTO_INSTVAR %d\n", (int)b1);
|
||||||
|
STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(stix->active_context->receiver_or_source) == STIX_OBJ_TYPE_OOP);
|
||||||
|
((stix_oop_oop_t)stix->active_context->origin->receiver_or_source)->slot[b1] = ACTIVE_STACK_GETTOP(stix);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* ------------------------------------------------- */
|
||||||
|
case BCODE_POP_INTO_INSTVAR_X:
|
||||||
|
FETCH_PARAM_CODE_TO (stix, b1);
|
||||||
|
goto pop_into_instvar;
|
||||||
|
case BCODE_POP_INTO_INSTVAR_0:
|
||||||
|
case BCODE_POP_INTO_INSTVAR_1:
|
||||||
|
case BCODE_POP_INTO_INSTVAR_2:
|
||||||
|
case BCODE_POP_INTO_INSTVAR_3:
|
||||||
|
case BCODE_POP_INTO_INSTVAR_4:
|
||||||
|
case BCODE_POP_INTO_INSTVAR_5:
|
||||||
|
case BCODE_POP_INTO_INSTVAR_6:
|
||||||
|
case BCODE_POP_INTO_INSTVAR_7:
|
||||||
|
b1 = bcode & 0x7; /* low 3 bits */
|
||||||
|
pop_into_instvar:
|
||||||
|
printf ("POP_INTO_INSTVAR %d\n", (int)b1);
|
||||||
|
STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(stix->active_context->receiver_or_source) == STIX_OBJ_TYPE_OOP);
|
||||||
|
((stix_oop_oop_t)stix->active_context->origin->receiver_or_source)->slot[b1] = ACTIVE_STACK_GETTOP(stix);
|
||||||
|
ACTIVE_STACK_POP (stix);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* ------------------------------------------------- */
|
||||||
|
case BCODE_PUSH_TEMPVAR_X:
|
||||||
|
case BCODE_STORE_INTO_TEMPVAR_X:
|
||||||
|
case BCODE_POP_INTO_TEMPVAR_X:
|
||||||
|
FETCH_PARAM_CODE_TO (stix, b1);
|
||||||
|
goto handle_tempvar;
|
||||||
|
|
||||||
|
case BCODE_PUSH_TEMPVAR_0:
|
||||||
|
case BCODE_PUSH_TEMPVAR_1:
|
||||||
|
case BCODE_PUSH_TEMPVAR_2:
|
||||||
|
case BCODE_PUSH_TEMPVAR_3:
|
||||||
|
case BCODE_PUSH_TEMPVAR_4:
|
||||||
|
case BCODE_PUSH_TEMPVAR_5:
|
||||||
|
case BCODE_PUSH_TEMPVAR_6:
|
||||||
|
case BCODE_PUSH_TEMPVAR_7:
|
||||||
|
case BCODE_STORE_INTO_TEMPVAR_0:
|
||||||
|
case BCODE_STORE_INTO_TEMPVAR_1:
|
||||||
|
case BCODE_STORE_INTO_TEMPVAR_2:
|
||||||
|
case BCODE_STORE_INTO_TEMPVAR_3:
|
||||||
|
case BCODE_STORE_INTO_TEMPVAR_4:
|
||||||
|
case BCODE_STORE_INTO_TEMPVAR_5:
|
||||||
|
case BCODE_STORE_INTO_TEMPVAR_6:
|
||||||
|
case BCODE_STORE_INTO_TEMPVAR_7:
|
||||||
|
case BCODE_POP_INTO_TEMPVAR_0:
|
||||||
|
case BCODE_POP_INTO_TEMPVAR_1:
|
||||||
|
case BCODE_POP_INTO_TEMPVAR_2:
|
||||||
|
case BCODE_POP_INTO_TEMPVAR_3:
|
||||||
|
case BCODE_POP_INTO_TEMPVAR_4:
|
||||||
|
case BCODE_POP_INTO_TEMPVAR_5:
|
||||||
|
case BCODE_POP_INTO_TEMPVAR_6:
|
||||||
|
case BCODE_POP_INTO_TEMPVAR_7:
|
||||||
|
b1 = bcode & 0x7; /* low 3 bits */
|
||||||
|
handle_tempvar:
|
||||||
if (stix->active_context->home != stix->_nil)
|
if (stix->active_context->home != stix->_nil)
|
||||||
{
|
{
|
||||||
/*TODO: improve this slow temporary access */
|
/*TODO: improve this slow temporary access */
|
||||||
/* this code assumes that the method context and
|
/* this code assumes that the method context and
|
||||||
* the block context place some key fields in the
|
* the block context place some key fields in the
|
||||||
* same offset. such fields include 'home', 'ntmprs' */
|
* same offset. such fields include 'home', 'ntmprs' */
|
||||||
stix_oop_context_t ctx;
|
|
||||||
stix_oop_t home;
|
stix_oop_t home;
|
||||||
stix_ooi_t home_ntmprs;
|
stix_ooi_t home_ntmprs;
|
||||||
|
|
||||||
@ -969,125 +977,267 @@ fflush(stdout);
|
|||||||
}
|
}
|
||||||
while (1);
|
while (1);
|
||||||
|
|
||||||
print_object (stix, ctx->slot[b1 - home_ntmprs]);
|
bx = b1 - home_ntmprs;
|
||||||
printf ("\n");
|
|
||||||
|
|
||||||
printf (" XXCTX %p STACK TEMPVAR PTR=>%p ADJOFF=%d B1=%d HOME_NTMPRS=%d\n", ctx, &ctx->slot[b1-home_ntmprs], (int)(b1 - home_ntmprs), (int)b1, (int)home_ntmprs);
|
|
||||||
ACTIVE_STACK_PUSH (stix, ctx->slot[b1 - home_ntmprs]);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
print_object (stix, ACTIVE_STACK_GET(stix, b1));
|
ctx = stix->active_context;
|
||||||
printf ("\n");
|
bx = b1;
|
||||||
|
|
||||||
printf (" YYCTX %p STACK TEMPVAR PTR=>%p ADJOFF=%d\n", stix->active_context, &stix->active_context->slot[b1], (int)b1);
|
|
||||||
ACTIVE_STACK_PUSH (stix, ACTIVE_STACK_GET(stix, b1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((bcode >> 4) & 1)
|
||||||
|
{
|
||||||
|
/* push - bit 4 on*/
|
||||||
|
printf ("PUSH_TEMPVAR %d - ", (int)b1);
|
||||||
|
|
||||||
|
ACTIVE_STACK_PUSH (stix, ctx->slot[bx]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* store or pop - bit 5 off */
|
||||||
|
ctx->slot[bx] = ACTIVE_STACK_GETTOP(stix);
|
||||||
|
|
||||||
|
if ((bcode >> 3) & 1)
|
||||||
|
{
|
||||||
|
/* pop - bit 3 on */
|
||||||
|
ACTIVE_STACK_POP (stix);
|
||||||
|
printf ("POP_INTO_TEMPVAR %d - ", (int)b1);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf ("STORE_INTO_TEMPVAR %d - ", (int)b1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print_object (stix, ctx->slot[bx]);
|
||||||
|
printf ("\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_PUSH_LITERAL:
|
/* ------------------------------------------------- */
|
||||||
|
case BCODE_PUSH_LITERAL_X:
|
||||||
|
FETCH_PARAM_CODE_TO (stix, b1);
|
||||||
|
goto push_literal;
|
||||||
|
|
||||||
|
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:
|
||||||
|
b1 = bcode & 0x7; /* low 3 bits */
|
||||||
|
push_literal:
|
||||||
printf ("PUSH_LITERAL idx=%d - ", (int)b1);
|
printf ("PUSH_LITERAL idx=%d - ", (int)b1);
|
||||||
print_object (stix, stix->active_method->slot[b1]);
|
print_object (stix, stix->active_method->slot[b1]);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
ACTIVE_STACK_PUSH (stix, stix->active_method->slot[b1]);
|
ACTIVE_STACK_PUSH (stix, stix->active_method->slot[b1]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_STORE_INTO_INSTVAR:
|
/* ------------------------------------------------- */
|
||||||
printf ("STORE_INSTVAR %d\n", (int)b1);
|
case BCODE_PUSH_OBJECT_X:
|
||||||
STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(stix->active_context->receiver_or_source) == STIX_OBJ_TYPE_OOP);
|
case BCODE_STORE_INTO_OBJECT_X:
|
||||||
((stix_oop_oop_t)stix->active_context->origin->receiver_or_source)->slot[b1] = ACTIVE_STACK_GETTOP(stix);
|
case BCODE_POP_INTO_OBJECT_X:
|
||||||
break;
|
FETCH_PARAM_CODE_TO (stix, b1);
|
||||||
|
goto handle_object;
|
||||||
|
|
||||||
case CMD_STORE_INTO_TEMPVAR:
|
case BCODE_PUSH_OBJECT_0:
|
||||||
printf ("STORE_TEMPVAR idx=%d - ", (int)b1);
|
case BCODE_PUSH_OBJECT_1:
|
||||||
print_object (stix, ACTIVE_STACK_GETTOP(stix));
|
case BCODE_PUSH_OBJECT_2:
|
||||||
printf ("\n");
|
case BCODE_PUSH_OBJECT_3:
|
||||||
if (stix->active_context->home != stix->_nil)
|
case BCODE_STORE_INTO_OBJECT_0:
|
||||||
|
case BCODE_STORE_INTO_OBJECT_1:
|
||||||
|
case BCODE_STORE_INTO_OBJECT_2:
|
||||||
|
case BCODE_STORE_INTO_OBJECT_3:
|
||||||
|
case BCODE_POP_INTO_OBJECT_0:
|
||||||
|
case BCODE_POP_INTO_OBJECT_1:
|
||||||
|
case BCODE_POP_INTO_OBJECT_2:
|
||||||
|
case BCODE_POP_INTO_OBJECT_3:
|
||||||
|
b1 = bcode & 0x3; /* low 2 bits */
|
||||||
|
handle_object:
|
||||||
|
printf ("<<<<<<<<<<<<<< XXXXX_OBJECT NOT IMPLEMENTED YET >>>>>>>>>>>> \n");
|
||||||
|
stix->errnum = STIX_ENOIMPL;
|
||||||
|
return -1;
|
||||||
|
if ((bcode >> 3) & 1)
|
||||||
{
|
{
|
||||||
/*TODO: improve this slow temporary access */
|
/* store or pop */
|
||||||
/* this code assuments that the method context and
|
if ((bcode >> 2) & 1)
|
||||||
* the block context places some key fields in the
|
|
||||||
* same offset. such fields include 'home', 'ntmprs' */
|
|
||||||
stix_oop_context_t ctx;
|
|
||||||
stix_oop_t home;
|
|
||||||
stix_ooi_t home_ntmprs;
|
|
||||||
|
|
||||||
ctx = stix->active_context;
|
|
||||||
home = ctx->home;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
home_ntmprs = STIX_OOP_TO_SMINT(((stix_oop_context_t)home)->ntmprs);
|
/* pop */
|
||||||
if (b1 >= home_ntmprs) break;
|
|
||||||
|
|
||||||
ctx = (stix_oop_context_t)home;
|
|
||||||
home = ((stix_oop_context_t)home)->home;
|
|
||||||
if (home == stix->_nil)
|
|
||||||
{
|
|
||||||
home_ntmprs = 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (1);
|
|
||||||
|
|
||||||
printf (" XXCTX %p STACK TEMPVAR PTR=>%p ADJOFF=%d B1=%d HOME_NTMPRS=%d\n", ctx, &ctx->slot[b1-home_ntmprs], (int)(b1 - home_ntmprs), (int)b1, (int)home_ntmprs);
|
|
||||||
ctx->slot[b1 - home_ntmprs] = ACTIVE_STACK_GETTOP(stix);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf (" YYCTX %p STACK TEMPVAR PTR=>%p ADJOFF=%d\n", stix->active_context, &stix->active_context->slot[b1], (int)b1);
|
/* push */
|
||||||
ACTIVE_STACK_SET (stix, b1, ACTIVE_STACK_GETTOP(stix));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* -------------------------------------------------------- */
|
/* -------------------------------------------------------- */
|
||||||
|
|
||||||
/* TODO: CMD_JUMP_IF_FALSE */
|
case BCODE_JUMP_FORWARD_X:
|
||||||
case CMD_JUMP:
|
FETCH_PARAM_CODE_TO (stix, b1);
|
||||||
printf ("JUMP %d\n", (int)b1);
|
printf ("JUMP_FORWARD %d\n", (int)b1);
|
||||||
stix->ip += b1;
|
stix->ip += b1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BCODE_JUMP_FORWARD_0:
|
||||||
|
case BCODE_JUMP_FORWARD_1:
|
||||||
|
case BCODE_JUMP_FORWARD_2:
|
||||||
|
case BCODE_JUMP_FORWARD_3:
|
||||||
|
printf ("JUMP_FORWARD %d\n", (int)(bcode & 0x3));
|
||||||
|
stix->ip += (bcode & 0x3); /* low 2 bits */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BCODE_JUMP_BACKWARD_X:
|
||||||
|
FETCH_PARAM_CODE_TO (stix, b1);
|
||||||
|
printf ("JUMP_BACKWARD %d\n", (int)b1);
|
||||||
|
stix->ip += b1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BCODE_JUMP_BACKWARD_0:
|
||||||
|
case BCODE_JUMP_BACKWARD_1:
|
||||||
|
case BCODE_JUMP_BACKWARD_2:
|
||||||
|
case BCODE_JUMP_BACKWARD_3:
|
||||||
|
printf ("JUMP_BACKWARD %d\n", (int)(bcode & 0x3));
|
||||||
|
stix->ip -= (bcode & 0x3); /* low 2 bits */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BCODE_JUMP_IF_TRUE_X:
|
||||||
|
case BCODE_JUMP_IF_FALSE_X:
|
||||||
|
case BCODE_JUMP_BY_OFFSET_X:
|
||||||
|
case BCODE_JUMP_IF_TRUE_0:
|
||||||
|
case BCODE_JUMP_IF_TRUE_1:
|
||||||
|
case BCODE_JUMP_IF_TRUE_2:
|
||||||
|
case BCODE_JUMP_IF_TRUE_3:
|
||||||
|
case BCODE_JUMP_IF_FALSE_0:
|
||||||
|
case BCODE_JUMP_IF_FALSE_1:
|
||||||
|
case BCODE_JUMP_IF_FALSE_2:
|
||||||
|
case BCODE_JUMP_IF_FALSE_3:
|
||||||
|
case BCODE_JUMP_BY_OFFSET_0:
|
||||||
|
case BCODE_JUMP_BY_OFFSET_1:
|
||||||
|
case BCODE_JUMP_BY_OFFSET_2:
|
||||||
|
case BCODE_JUMP_BY_OFFSET_3:
|
||||||
|
printf ("<<<<<<<<<<<<<< JUMP NOT IMPLEMENTED YET >>>>>>>>>>>> \n");
|
||||||
|
stix->errnum = STIX_ENOIMPL;
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
|
||||||
/* -------------------------------------------------------- */
|
/* -------------------------------------------------------- */
|
||||||
|
|
||||||
case CMD_PUSH_OBJVAR:
|
case BCODE_PUSH_CTXTEMPVAR_X:
|
||||||
|
case BCODE_STORE_INTO_CTXTEMPVAR_X:
|
||||||
|
case BCODE_POP_INTO_CTXTEMPVAR_X:
|
||||||
|
FETCH_PARAM_CODE_TO (stix, b1);
|
||||||
|
FETCH_PARAM_CODE_TO (stix, b2);
|
||||||
|
goto handle_ctxtempvar;
|
||||||
|
case BCODE_PUSH_CTXTEMPVAR_0:
|
||||||
|
case BCODE_PUSH_CTXTEMPVAR_1:
|
||||||
|
case BCODE_PUSH_CTXTEMPVAR_2:
|
||||||
|
case BCODE_PUSH_CTXTEMPVAR_3:
|
||||||
|
case BCODE_STORE_INTO_CTXTEMPVAR_0:
|
||||||
|
case BCODE_STORE_INTO_CTXTEMPVAR_1:
|
||||||
|
case BCODE_STORE_INTO_CTXTEMPVAR_2:
|
||||||
|
case BCODE_STORE_INTO_CTXTEMPVAR_3:
|
||||||
|
case BCODE_POP_INTO_CTXTEMPVAR_0:
|
||||||
|
case BCODE_POP_INTO_CTXTEMPVAR_1:
|
||||||
|
case BCODE_POP_INTO_CTXTEMPVAR_2:
|
||||||
|
case BCODE_POP_INTO_CTXTEMPVAR_3:
|
||||||
|
b1 = bcode & 0x3; /* low 2 bits */
|
||||||
|
FETCH_BYTE_CODE_TO (stix, b2);
|
||||||
|
handle_ctxtempvar:
|
||||||
|
printf ("<<<<<<<<<<<<<< XXXXX_CTXTEMPVAR NOT IMPLEMENTED YET >>>>>>>>>>>> \n");
|
||||||
|
stix->errnum = STIX_ENOIMPL;
|
||||||
|
return -1;
|
||||||
|
if ((bcode >> 3) & 1)
|
||||||
{
|
{
|
||||||
|
/* store or pop */
|
||||||
|
if ((bcode >> 2) & 1)
|
||||||
|
{
|
||||||
|
/* pop */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* push */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
/* -------------------------------------------------------- */
|
||||||
|
|
||||||
|
case BCODE_PUSH_OBJVAR_X:
|
||||||
|
case BCODE_STORE_INTO_OBJVAR_X:
|
||||||
|
case BCODE_POP_INTO_OBJVAR_X:
|
||||||
|
FETCH_PARAM_CODE_TO (stix, b1);
|
||||||
|
FETCH_PARAM_CODE_TO (stix, b2);
|
||||||
|
goto handle_objvar;
|
||||||
|
|
||||||
|
case BCODE_PUSH_OBJVAR_0:
|
||||||
|
case BCODE_PUSH_OBJVAR_1:
|
||||||
|
case BCODE_PUSH_OBJVAR_2:
|
||||||
|
case BCODE_PUSH_OBJVAR_3:
|
||||||
|
case BCODE_STORE_INTO_OBJVAR_0:
|
||||||
|
case BCODE_STORE_INTO_OBJVAR_1:
|
||||||
|
case BCODE_STORE_INTO_OBJVAR_2:
|
||||||
|
case BCODE_STORE_INTO_OBJVAR_3:
|
||||||
|
case BCODE_POP_INTO_OBJVAR_0:
|
||||||
|
case BCODE_POP_INTO_OBJVAR_1:
|
||||||
|
case BCODE_POP_INTO_OBJVAR_2:
|
||||||
|
case BCODE_POP_INTO_OBJVAR_3:
|
||||||
/* b1 -> variable index to the object indicated by b2.
|
/* b1 -> variable index to the object indicated by b2.
|
||||||
* b2 -> object index stored in the literal frame. */
|
* b2 -> object index stored in the literal frame. */
|
||||||
|
b1 = bcode & 0x3; /* low 2 bits */
|
||||||
|
FETCH_BYTE_CODE_TO (stix, b2);
|
||||||
|
|
||||||
stix_oop_oop_t obj;
|
handle_objvar:
|
||||||
printf ("PUSH OBJVAR index=%d object_index_in_literal_frame=%d - ", (int)b1, (int)b2);
|
printf ("XXXXXXXXXXXXXXXXXXXXX [%d]\n", (int)b2);
|
||||||
obj = (stix_oop_oop_t)stix->active_method->slot[b2];
|
t1 = (stix_oop_oop_t)stix->active_method->slot[b2];
|
||||||
STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(obj) == STIX_OBJ_TYPE_OOP);
|
STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(t1) == STIX_OBJ_TYPE_OOP);
|
||||||
STIX_ASSERT (b1 < STIX_OBJ_GET_SIZE(obj));
|
STIX_ASSERT (b1 < STIX_OBJ_GET_SIZE(t1));
|
||||||
|
|
||||||
print_object (stix, obj->slot[b1]);
|
if ((bcode >> 3) & 1)
|
||||||
printf ("\n");
|
|
||||||
ACTIVE_STACK_PUSH (stix, obj->slot[b1]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case CMD_STORE_INTO_OBJVAR:
|
|
||||||
{
|
{
|
||||||
stix_oop_oop_t obj;
|
/* store or pop */
|
||||||
printf ("STORE OBJVAR index=%d object_index_in_literal_frame=%d - ", (int)b1, (int)b2);
|
|
||||||
obj = (stix_oop_oop_t)stix->active_method->slot[b2];
|
|
||||||
STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(obj) == STIX_OBJ_TYPE_OOP);
|
|
||||||
STIX_ASSERT (b1 < STIX_OBJ_GET_SIZE(obj));
|
|
||||||
|
|
||||||
print_object (stix, ACTIVE_STACK_GETTOP(stix));
|
t1->slot[b1] = ACTIVE_STACK_GETTOP(stix);
|
||||||
printf ("\n");
|
|
||||||
obj->slot[b1] = ACTIVE_STACK_GETTOP(stix);
|
if ((bcode >> 2) & 1)
|
||||||
break;
|
{
|
||||||
|
/* pop */
|
||||||
|
ACTIVE_STACK_POP (stix);
|
||||||
|
printf ("POP_INTO_OBJVAR %d %d - ", (int)b1, (int)b2);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf ("STORE_INTO_OBJVAR %d %d - ", (int)b1, (int)b2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* push */
|
||||||
|
printf ("PUSH_OBJVAR %d %d - ", (int)b1, (int)b2);
|
||||||
|
ACTIVE_STACK_PUSH (stix, t1->slot[b1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
print_object (stix, t1->slot[b1]);
|
||||||
|
printf ("\n");
|
||||||
|
break;
|
||||||
|
|
||||||
/* -------------------------------------------------------- */
|
/* -------------------------------------------------------- */
|
||||||
case CMD_SEND_MESSAGE:
|
case BCODE_SEND_MESSAGE_X:
|
||||||
case CMD_SEND_MESSAGE_TO_SUPER:
|
case BCODE_SEND_MESSAGE_TO_SUPER_X:
|
||||||
{
|
FETCH_PARAM_CODE_TO (stix, b1);
|
||||||
/* TODO: tail call optimization */
|
FETCH_PARAM_CODE_TO (stix, b2);
|
||||||
|
goto handle_send_message;
|
||||||
|
|
||||||
|
case BCODE_SEND_MESSAGE_0:
|
||||||
|
case BCODE_SEND_MESSAGE_1:
|
||||||
|
case BCODE_SEND_MESSAGE_2:
|
||||||
|
case BCODE_SEND_MESSAGE_3:
|
||||||
|
case BCODE_SEND_MESSAGE_TO_SUPER_0:
|
||||||
|
case BCODE_SEND_MESSAGE_TO_SUPER_1:
|
||||||
|
case BCODE_SEND_MESSAGE_TO_SUPER_2:
|
||||||
|
case BCODE_SEND_MESSAGE_TO_SUPER_3:
|
||||||
|
{
|
||||||
/* b1 -> number of arguments
|
/* b1 -> number of arguments
|
||||||
* b2 -> index to the selector stored in the literal frame
|
* b2 -> index to the selector stored in the literal frame
|
||||||
*/
|
*/
|
||||||
@ -1096,15 +1246,17 @@ printf ("\n");
|
|||||||
stix_oop_method_t newmth;
|
stix_oop_method_t newmth;
|
||||||
stix_oop_char_t selector;
|
stix_oop_char_t selector;
|
||||||
stix_ooi_t preamble;
|
stix_ooi_t preamble;
|
||||||
stix_uint16_t next_inst;
|
|
||||||
|
|
||||||
|
handle_send_message:
|
||||||
|
b1 = bcode & 0x3; /* low 2 bits */
|
||||||
|
FETCH_BYTE_CODE_TO (stix, b2);
|
||||||
|
|
||||||
/* get the selector from the literal frame */
|
/* get the selector from the literal frame */
|
||||||
selector = (stix_oop_char_t)stix->active_method->slot[b2];
|
selector = (stix_oop_char_t)stix->active_method->slot[b2];
|
||||||
|
|
||||||
if (cmd == CMD_SEND_MESSAGE)
|
|
||||||
printf ("SEND_MESSAGE TO RECEIVER AT STACKPOS=%d NARGS=%d SELECTOR=", (int)(stix->sp - b1), (int)b1);
|
printf ("SEND_MESSAGE%s TO RECEIVER AT STACKPOS=%d NARGS=%d SELECTOR=", (((bcode >> 2) & 1)? "_TO_SUPER": ""), (int)(stix->sp - b1), (int)b1);
|
||||||
else
|
|
||||||
printf ("SEND_MESSAGE_TO_SUPER TO RECEIVER AT STACKPOS=%d NARGS=%d SELECTOR=", (int)(stix->sp - b1), (int)b1);
|
|
||||||
print_object (stix, (stix_oop_t)selector);
|
print_object (stix, (stix_oop_t)selector);
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
STIX_ASSERT (STIX_CLASSOF(stix, selector) == stix->_symbol);
|
STIX_ASSERT (STIX_CLASSOF(stix, selector) == stix->_symbol);
|
||||||
@ -1115,7 +1267,7 @@ print_object(stix, newrcv);
|
|||||||
printf ("\n");
|
printf ("\n");
|
||||||
mthname.ptr = selector->slot;
|
mthname.ptr = selector->slot;
|
||||||
mthname.len = STIX_OBJ_GET_SIZE(selector);
|
mthname.len = STIX_OBJ_GET_SIZE(selector);
|
||||||
newmth = find_method (stix, newrcv, &mthname, (cmd == CMD_SEND_MESSAGE_TO_SUPER));
|
newmth = find_method (stix, newrcv, &mthname, ((bcode >> 2) & 1));
|
||||||
if (!newmth)
|
if (!newmth)
|
||||||
{
|
{
|
||||||
/* TODO: implement doesNotUnderstand: XXXXX instead of returning -1. */
|
/* TODO: implement doesNotUnderstand: XXXXX instead of returning -1. */
|
||||||
@ -1188,13 +1340,7 @@ printf ("RETURN INSTVAR AT PREAMBLE\n");
|
|||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* TOOD: remove it only in the instructions that requires reading ahead */
|
if (activate_new_method (stix, newmth) <= -1) goto oops;
|
||||||
/* read ahead the next instruction for tail-call optimization */
|
|
||||||
next_inst = stix->active_code->slot[stix->ip];
|
|
||||||
if (next_inst == CODE_POP_STACKTOP)
|
|
||||||
next_inst |= (next_inst << 8) + stix->active_code->slot[stix->ip + 1];
|
|
||||||
|
|
||||||
if (activate_new_method (stix, newmth, next_inst) <= -1) goto oops;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1203,193 +1349,79 @@ printf ("RETURN INSTVAR AT PREAMBLE\n");
|
|||||||
|
|
||||||
/* -------------------------------------------------------- */
|
/* -------------------------------------------------------- */
|
||||||
|
|
||||||
case CMD_PUSH_SPECIAL:
|
case BCODE_PUSH_RECEIVER:
|
||||||
switch (b1)
|
|
||||||
{
|
|
||||||
case SUBCMD_PUSH_RECEIVER:
|
|
||||||
printf ("PUSH_RECEIVER %p TO STACK INDEX %d\n", stix->active_context->origin->receiver_or_source, (int)stix->sp);
|
printf ("PUSH_RECEIVER %p TO STACK INDEX %d\n", stix->active_context->origin->receiver_or_source, (int)stix->sp);
|
||||||
ACTIVE_STACK_PUSH (stix, stix->active_context->origin->receiver_or_source);
|
ACTIVE_STACK_PUSH (stix, stix->active_context->origin->receiver_or_source);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBCMD_PUSH_NIL:
|
case BCODE_PUSH_NIL:
|
||||||
printf ("PUSH_NIL\n");
|
printf ("PUSH_NIL\n");
|
||||||
ACTIVE_STACK_PUSH (stix, stix->_nil);
|
ACTIVE_STACK_PUSH (stix, stix->_nil);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBCMD_PUSH_TRUE:
|
case BCODE_PUSH_TRUE:
|
||||||
printf ("PUSH_TRUE\n");
|
printf ("PUSH_TRUE\n");
|
||||||
ACTIVE_STACK_PUSH (stix, stix->_true);
|
ACTIVE_STACK_PUSH (stix, stix->_true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBCMD_PUSH_FALSE:
|
case BCODE_PUSH_FALSE:
|
||||||
printf ("PUSH_FALSE\n");
|
printf ("PUSH_FALSE\n");
|
||||||
ACTIVE_STACK_PUSH (stix, stix->_false);
|
ACTIVE_STACK_PUSH (stix, stix->_false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBCMD_PUSH_CONTEXT:
|
case BCODE_PUSH_CONTEXT:
|
||||||
printf ("PUSH_CONTEXT\n");
|
printf ("PUSH_CONTEXT\n");
|
||||||
ACTIVE_STACK_PUSH (stix, (stix_oop_t)stix->active_context);
|
ACTIVE_STACK_PUSH (stix, (stix_oop_t)stix->active_context);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBCMD_PUSH_NEGONE:
|
case BCODE_PUSH_NEGONE:
|
||||||
printf ("PUSH_NEGONE\n");
|
printf ("PUSH_NEGONE\n");
|
||||||
ACTIVE_STACK_PUSH (stix, STIX_OOP_FROM_SMINT(-1));
|
ACTIVE_STACK_PUSH (stix, STIX_OOP_FROM_SMINT(-1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBCMD_PUSH_ZERO:
|
case BCODE_PUSH_ZERO:
|
||||||
printf ("PUSH_ZERO\n");
|
printf ("PUSH_ZERO\n");
|
||||||
ACTIVE_STACK_PUSH (stix, STIX_OOP_FROM_SMINT(0));
|
ACTIVE_STACK_PUSH (stix, STIX_OOP_FROM_SMINT(0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBCMD_PUSH_ONE:
|
case BCODE_PUSH_ONE:
|
||||||
printf ("PUSH_SMINT\n");
|
printf ("PUSH_ONE\n");
|
||||||
ACTIVE_STACK_PUSH (stix, STIX_OOP_FROM_SMINT(1));
|
ACTIVE_STACK_PUSH (stix, STIX_OOP_FROM_SMINT(1));
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
break; /* CMD_PUSH_SPECIAL */
|
case BCODE_PUSH_TWO:
|
||||||
|
printf ("PUSH_TWO\n");
|
||||||
|
ACTIVE_STACK_PUSH (stix, STIX_OOP_FROM_SMINT(2));
|
||||||
|
break;
|
||||||
|
|
||||||
/* -------------------------------------------------------- */
|
/* -------------------------------------------------------- */
|
||||||
|
|
||||||
case CMD_DO_SPECIAL:
|
case BCODE_DUP_STACKTOP:
|
||||||
{
|
{
|
||||||
stix_oop_t return_value;
|
stix_oop_t t;
|
||||||
|
|
||||||
switch (b1)
|
|
||||||
{
|
|
||||||
case SUBCMD_DUP_STACKTOP:
|
|
||||||
{
|
|
||||||
stix_oop_t tmp;
|
|
||||||
printf ("DUP_STACKTOP SP=%d\n", (int)stix->sp);
|
printf ("DUP_STACKTOP SP=%d\n", (int)stix->sp);
|
||||||
STIX_ASSERT (!ACTIVE_STACK_ISEMPTY(stix));
|
STIX_ASSERT (!ACTIVE_STACK_ISEMPTY(stix));
|
||||||
tmp = ACTIVE_STACK_GETTOP(stix);
|
t = ACTIVE_STACK_GETTOP(stix);
|
||||||
ACTIVE_STACK_PUSH (stix, tmp);
|
ACTIVE_STACK_PUSH (stix, t);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SUBCMD_POP_STACKTOP:
|
case BCODE_POP_STACKTOP:
|
||||||
printf ("POP_STACKTOP\n");
|
printf ("POP_STACKTOP\n");
|
||||||
STIX_ASSERT (!ACTIVE_STACK_ISEMPTY(stix));
|
STIX_ASSERT (!ACTIVE_STACK_ISEMPTY(stix));
|
||||||
ACTIVE_STACK_POP (stix);
|
ACTIVE_STACK_POP (stix);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBCMD_RETURN_STACKTOP:
|
case BCODE_RETURN_STACKTOP:
|
||||||
printf ("RETURN_STACKTOP\n");
|
printf ("RETURN_STACKTOP\n");
|
||||||
return_value = ACTIVE_STACK_GETTOP(stix);
|
return_value = ACTIVE_STACK_GETTOP(stix);
|
||||||
ACTIVE_STACK_POP (stix);
|
ACTIVE_STACK_POP (stix);
|
||||||
goto handle_return;
|
goto handle_return;
|
||||||
|
|
||||||
case SUBCMD_RETURN_RECEIVER:
|
case BCODE_RETURN_RECEIVER:
|
||||||
printf ("RETURN_RECEIVER\n");
|
printf ("RETURN_RECEIVER\n");
|
||||||
return_value = stix->active_context->origin->receiver_or_source;
|
return_value = stix->active_context->origin->receiver_or_source;
|
||||||
goto handle_return;
|
|
||||||
|
|
||||||
case SUBCMD_RETURN_FROM_BLOCK:
|
|
||||||
printf ("LEAVING_BLOCK\n");
|
|
||||||
STIX_ASSERT(STIX_CLASSOF(stix, stix->active_context) == stix->_block_context);
|
|
||||||
|
|
||||||
return_value = ACTIVE_STACK_GETTOP(stix);
|
|
||||||
SWITCH_ACTIVE_CONTEXT (stix, (stix_oop_context_t)stix->active_context->sender);
|
|
||||||
ACTIVE_STACK_PUSH (stix, return_value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SUBCMD_SEND_BLOCK_COPY:
|
|
||||||
{
|
|
||||||
stix_ooi_t nargs, ntmprs;
|
|
||||||
stix_oop_context_t rctx;
|
|
||||||
stix_oop_context_t blkctx;
|
|
||||||
printf ("SEND_BLOCK_COPY\n");
|
|
||||||
/* it emulates thisContext blockCopy: nargs ofTmprCount: ntmprs */
|
|
||||||
STIX_ASSERT (stix->sp >= 2);
|
|
||||||
|
|
||||||
STIX_ASSERT (STIX_CLASSOF(stix, ACTIVE_STACK_GETTOP(stix)) == stix->_small_integer);
|
|
||||||
ntmprs = STIX_OOP_TO_SMINT(ACTIVE_STACK_GETTOP(stix));
|
|
||||||
ACTIVE_STACK_POP (stix);
|
|
||||||
|
|
||||||
STIX_ASSERT (STIX_CLASSOF(stix, ACTIVE_STACK_GETTOP(stix)) == stix->_small_integer);
|
|
||||||
nargs = STIX_OOP_TO_SMINT(ACTIVE_STACK_GETTOP(stix));
|
|
||||||
ACTIVE_STACK_POP (stix);
|
|
||||||
|
|
||||||
STIX_ASSERT (nargs >= 0);
|
|
||||||
STIX_ASSERT (ntmprs >= nargs);
|
|
||||||
|
|
||||||
/* the block context object created here is used
|
|
||||||
* as a base object for block context activation.
|
|
||||||
* primitive_block_context_value() clones a block
|
|
||||||
* context and activates the cloned context.
|
|
||||||
* this base block context is created with no
|
|
||||||
* stack for this reason. */
|
|
||||||
blkctx = (stix_oop_context_t)stix_instantiate (stix, stix->_block_context, STIX_NULL, 0);
|
|
||||||
if (!blkctx) return -1;
|
|
||||||
|
|
||||||
/* get the receiver to the block copy message after block context instantiation
|
|
||||||
* not to get affected by potential GC */
|
|
||||||
rctx = (stix_oop_context_t)ACTIVE_STACK_GETTOP(stix);
|
|
||||||
|
|
||||||
/* [NOTE]
|
|
||||||
* blkctx->caller is left to nil. it is set to the
|
|
||||||
* active context before it gets activated. see
|
|
||||||
* primitive_block_context_value().
|
|
||||||
*
|
|
||||||
* blkctx->home is set here to the active context.
|
|
||||||
* it's redundant to have them pushed to the stack
|
|
||||||
* though it is to emulate the message sending of
|
|
||||||
* blockCopy:withNtmprs:.
|
|
||||||
* TODO: devise a new byte code to eliminate stack pushing.
|
|
||||||
*
|
|
||||||
* blkctx->origin is set here by copying the origin
|
|
||||||
* of the active context.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* the extended jump instruction has the format of
|
|
||||||
* 0000XXXX KKKKKKKK or 0000XXXX KKKKKKKK KKKKKKKK
|
|
||||||
* depending on STIX_CODE_EXTEND_SIZE. change 'ip' to point to
|
|
||||||
* the instruction after the jump. */
|
|
||||||
blkctx->ip = STIX_OOP_FROM_SMINT(stix->ip + STIX_CODE_EXTEND_SIZE + 1);
|
|
||||||
blkctx->sp = STIX_OOP_FROM_SMINT(-1);
|
|
||||||
/* the number of arguments for a block context is local to the block */
|
|
||||||
blkctx->method_or_nargs = STIX_OOP_FROM_SMINT(nargs);
|
|
||||||
/* the number of temporaries here is an accumulated count including
|
|
||||||
* the number of temporaries of a home context */
|
|
||||||
blkctx->ntmprs = STIX_OOP_FROM_SMINT(ntmprs);
|
|
||||||
|
|
||||||
blkctx->home = (stix_oop_t)rctx;
|
|
||||||
blkctx->receiver_or_source = stix->_nil;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (rctx->home == stix->_nil)
|
|
||||||
{
|
|
||||||
/* the context that receives the blockCopy message is a method context */
|
|
||||||
STIX_ASSERT (STIX_CLASSOF(stix, rctx) == stix->_method_context);
|
|
||||||
STIX_ASSERT (rctx == (stix_oop_t)stix->active_context);
|
|
||||||
blkctx->origin = (stix_oop_context_t)rctx;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* a block context is active */
|
|
||||||
STIX_ASSERT (STIX_CLASSOF(stix, rctx) == stix->_block_context);
|
|
||||||
blkctx->origin = ((stix_oop_block_context_t)rctx)->origin;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* [NOTE]
|
|
||||||
* the origin of a method context is set to itself
|
|
||||||
* when it's created. so it's safe to simply copy
|
|
||||||
* the origin field this way.
|
|
||||||
*/
|
|
||||||
blkctx->origin = rctx->origin;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ACTIVE_STACK_SETTOP (stix, (stix_oop_t)blkctx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
stix->errnum = STIX_EINTERN;
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
handle_return:
|
handle_return:
|
||||||
|
|
||||||
printf ("<<LEAVING>> SP=%d\n", (int)stix->sp);
|
printf ("<<LEAVING>> SP=%d\n", (int)stix->sp);
|
||||||
|
|
||||||
/* put the instruction pointer back to the return
|
/* put the instruction pointer back to the return
|
||||||
@ -1451,9 +1483,116 @@ printf ("<<<RETURNIGN TO THE INITIAL CONTEXT>>>\n");
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BCODE_RETURN_FROM_BLOCK:
|
||||||
|
printf ("LEAVING_BLOCK\n");
|
||||||
|
STIX_ASSERT(STIX_CLASSOF(stix, stix->active_context) == stix->_block_context);
|
||||||
|
|
||||||
|
return_value = ACTIVE_STACK_GETTOP(stix);
|
||||||
|
SWITCH_ACTIVE_CONTEXT (stix, (stix_oop_context_t)stix->active_context->sender);
|
||||||
|
ACTIVE_STACK_PUSH (stix, return_value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BCODE_SEND_BLOCK_COPY:
|
||||||
|
{
|
||||||
|
stix_ooi_t nargs, ntmprs;
|
||||||
|
stix_oop_context_t rctx;
|
||||||
|
stix_oop_context_t blkctx;
|
||||||
|
printf ("SEND_BLOCK_COPY\n");
|
||||||
|
/* it emulates thisContext blockCopy: nargs ofTmprCount: ntmprs */
|
||||||
|
STIX_ASSERT (stix->sp >= 2);
|
||||||
|
|
||||||
|
STIX_ASSERT (STIX_CLASSOF(stix, ACTIVE_STACK_GETTOP(stix)) == stix->_small_integer);
|
||||||
|
ntmprs = STIX_OOP_TO_SMINT(ACTIVE_STACK_GETTOP(stix));
|
||||||
|
ACTIVE_STACK_POP (stix);
|
||||||
|
|
||||||
|
STIX_ASSERT (STIX_CLASSOF(stix, ACTIVE_STACK_GETTOP(stix)) == stix->_small_integer);
|
||||||
|
nargs = STIX_OOP_TO_SMINT(ACTIVE_STACK_GETTOP(stix));
|
||||||
|
ACTIVE_STACK_POP (stix);
|
||||||
|
|
||||||
|
STIX_ASSERT (nargs >= 0);
|
||||||
|
STIX_ASSERT (ntmprs >= nargs);
|
||||||
|
|
||||||
|
/* the block context object created here is used
|
||||||
|
* as a base object for block context activation.
|
||||||
|
* primitive_block_context_value() clones a block
|
||||||
|
* context and activates the cloned context.
|
||||||
|
* this base block context is created with no
|
||||||
|
* stack for this reason. */
|
||||||
|
blkctx = (stix_oop_context_t)stix_instantiate (stix, stix->_block_context, STIX_NULL, 0);
|
||||||
|
if (!blkctx) return -1;
|
||||||
|
|
||||||
|
/* get the receiver to the block copy message after block context instantiation
|
||||||
|
* not to get affected by potential GC */
|
||||||
|
rctx = (stix_oop_context_t)ACTIVE_STACK_GETTOP(stix);
|
||||||
|
|
||||||
|
/* [NOTE]
|
||||||
|
* blkctx->caller is left to nil. it is set to the
|
||||||
|
* active context before it gets activated. see
|
||||||
|
* primitive_block_context_value().
|
||||||
|
*
|
||||||
|
* blkctx->home is set here to the active context.
|
||||||
|
* it's redundant to have them pushed to the stack
|
||||||
|
* though it is to emulate the message sending of
|
||||||
|
* blockCopy:withNtmprs:.
|
||||||
|
* TODO: devise a new byte code to eliminate stack pushing.
|
||||||
|
*
|
||||||
|
* blkctx->origin is set here by copying the origin
|
||||||
|
* of the active context.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* the extended jump instruction has the format of
|
||||||
|
* 0000XXXX KKKKKKKK or 0000XXXX KKKKKKKK KKKKKKKK
|
||||||
|
* depending on STIX_BCODE_LONG_PARAM_SIZE. change 'ip' to point to
|
||||||
|
* the instruction after the jump. */
|
||||||
|
blkctx->ip = STIX_OOP_FROM_SMINT(stix->ip + STIX_BCODE_LONG_PARAM_SIZE + 1);
|
||||||
|
blkctx->sp = STIX_OOP_FROM_SMINT(-1);
|
||||||
|
/* the number of arguments for a block context is local to the block */
|
||||||
|
blkctx->method_or_nargs = STIX_OOP_FROM_SMINT(nargs);
|
||||||
|
/* the number of temporaries here is an accumulated count including
|
||||||
|
* the number of temporaries of a home context */
|
||||||
|
blkctx->ntmprs = STIX_OOP_FROM_SMINT(ntmprs);
|
||||||
|
|
||||||
|
blkctx->home = (stix_oop_t)rctx;
|
||||||
|
blkctx->receiver_or_source = stix->_nil;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (rctx->home == stix->_nil)
|
||||||
|
{
|
||||||
|
/* the context that receives the blockCopy message is a method context */
|
||||||
|
STIX_ASSERT (STIX_CLASSOF(stix, rctx) == stix->_method_context);
|
||||||
|
STIX_ASSERT (rctx == (stix_oop_t)stix->active_context);
|
||||||
|
blkctx->origin = (stix_oop_context_t)rctx;
|
||||||
}
|
}
|
||||||
break; /* CMD_DO_SPECIAL */
|
else
|
||||||
|
{
|
||||||
|
/* a block context is active */
|
||||||
|
STIX_ASSERT (STIX_CLASSOF(stix, rctx) == stix->_block_context);
|
||||||
|
blkctx->origin = ((stix_oop_block_context_t)rctx)->origin;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* [NOTE]
|
||||||
|
* the origin of a method context is set to itself
|
||||||
|
* when it's created. so it's safe to simply copy
|
||||||
|
* the origin field this way.
|
||||||
|
*/
|
||||||
|
blkctx->origin = rctx->origin;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ACTIVE_STACK_SETTOP (stix, (stix_oop_t)blkctx);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case BCODE_NOOP:
|
||||||
|
/* do nothing */
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf ("UNKNOWN BYTE CODE ENCOUNTERED %x\n", (int)bcode);
|
||||||
|
stix->errnum = STIX_EINTERN;
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,7 +282,7 @@ printf ("%ld\n", (long int)STIX_OOP_TO_SMINT(k));
|
|||||||
{
|
{
|
||||||
int trait = 0;
|
int trait = 0;
|
||||||
|
|
||||||
/*trait |= STIX_NOTCO;*/
|
/*trait |= STIX_NOGC;*/
|
||||||
stix_setoption (stix, STIX_TRAIT, &trait);
|
stix_setoption (stix, STIX_TRAIT, &trait);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#include "stix.h"
|
#include "stix.h"
|
||||||
|
|
||||||
/* you can define this to either 1 or 2 */
|
/* you can define this to either 1 or 2 */
|
||||||
#define STIX_CODE_EXTEND_SIZE 2
|
#define STIX_BCODE_LONG_PARAM_SIZE 2
|
||||||
|
|
||||||
/* this is useful for debugging. stix_gc() can be called
|
/* this is useful for debugging. stix_gc() can be called
|
||||||
* while stix has not been fully initialized when this is defined*/
|
* while stix has not been fully initialized when this is defined*/
|
||||||
@ -460,195 +460,301 @@ struct stix_compiler_t
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(STIX_CODE_EXTEND_SIZE) && (STIX_CODE_EXTEND_SIZE == 1)
|
#if defined(STIX_BCODE_LONG_PARAM_SIZE) && (STIX_BCODE_LONG_PARAM_SIZE == 1)
|
||||||
# define MAX_CODE_INDEX (0xFFu)
|
# define MAX_CODE_INDEX (0xFFu)
|
||||||
# define MAX_CODE_NTMPRS (0xFFu)
|
# define MAX_CODE_NTMPRS (0xFFu)
|
||||||
# define MAX_CODE_NARGS (0xFFu)
|
# define MAX_CODE_NARGS (0xFFu)
|
||||||
# define MAX_CODE_NBLKARGS (0xFFu)
|
# define MAX_CODE_NBLKARGS (0xFFu)
|
||||||
# define MAX_CODE_NBLKTMPRS (0xFFu)
|
# define MAX_CODE_NBLKTMPRS (0xFFu)
|
||||||
# define MAX_CODE_PRIMNO (0xFFFFu)
|
# define MAX_CODE_PRIMNO (0xFFFFu)
|
||||||
# define MIN_CODE_JUMP (-0x80)
|
# define MAX_CODE_JUMP (0xFF)
|
||||||
# define MAX_CODE_JUMP (0x7F)
|
#elif defined(STIX_BCODE_LONG_PARAM_SIZE) && (STIX_BCODE_LONG_PARAM_SIZE == 2)
|
||||||
#elif defined(STIX_CODE_EXTEND_SIZE) && (STIX_CODE_EXTEND_SIZE == 2)
|
|
||||||
# define MAX_CODE_INDEX (0xFFFFu)
|
# define MAX_CODE_INDEX (0xFFFFu)
|
||||||
# define MAX_CODE_NTMPRS (0xFFFFu)
|
# define MAX_CODE_NTMPRS (0xFFFFu)
|
||||||
# define MAX_CODE_NARGS (0xFFFFu)
|
# define MAX_CODE_NARGS (0xFFFFu)
|
||||||
# define MAX_CODE_NBLKARGS (0xFFFFu)
|
# define MAX_CODE_NBLKARGS (0xFFFFu)
|
||||||
# define MAX_CODE_NBLKTMPRS (0xFFFFu)
|
# define MAX_CODE_NBLKTMPRS (0xFFFFu)
|
||||||
# define MAX_CODE_PRIMNO (0xFFFFu)
|
# define MAX_CODE_PRIMNO (0xFFFFu)
|
||||||
# define MIN_CODE_JUMP (-0x8000)
|
# define MAX_CODE_JUMP (0xFFFF)
|
||||||
# define MAX_CODE_JUMP (0x7FFF)
|
|
||||||
#else
|
#else
|
||||||
# error Unsupported STIX_CODE_EXTEND_SIZE
|
# error Unsupported STIX_BCODE_LONG_PARAM_SIZE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_CODE_BLKCODE MAX_CODE_JUMP
|
#define MAX_CODE_BLKCODE MAX_CODE_JUMP
|
||||||
#define MAKE_CODE(x,y) (((x) << 4) | y)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
--------------------------------------
|
----------------------------------------------------------------------------------------------------------------
|
||||||
|
SHORT INSTRUCTION CODE LONG INSTRUCTION CODE
|
||||||
|
----------------------------------------------------------------------------------------------------------------
|
||||||
|
v v
|
||||||
|
0-3 0000 00XX STORE_INTO_INSTVAR 128 1000 0000 XXXXXXXX STORE_INTO_INSTVAR_X (bit 4 off, bit 3 off)
|
||||||
|
4-7 0000 01XX STORE_INTO_INSTVAR
|
||||||
|
8-11 0000 10XX POP_INTO_INSTVAR 136 1000 1000 XXXXXXXX POP_INTO_INSTVAR_X (bit 4 off, bit 3 on)
|
||||||
|
12-15 0000 11XX POP_INTO_INSTVAR
|
||||||
|
16-19 0001 00XX PUSH_INSTVAR 144 1001 0000 XXXXXXXX PUSH_INSTVAR_X (bit 4 on)
|
||||||
|
20-23 0001 01XX PUSH_INSTVAR
|
||||||
|
|
||||||
0 000000XX PUSH_INSTVAR
|
v v
|
||||||
1 000001XX PUSH_TEMPVAR
|
24-27 0001 10XX PUSH_TEMPVAR 152 1001 1000 XXXXXXXX PUSH_TEMPVAR_X (bit 4 on)
|
||||||
2 000010XX PUSH_LITERAL
|
28-31 0001 11XX PUSH_TEMPVAR
|
||||||
3 000011XX STORE_INTO_INSTVAR
|
32-35 0010 00XX STORE_INTO_TEMPVAR 160 1010 0000 XXXXXXXX STORE_INTO_TEMPVAR_X (bit 4 off, bit 3 off)
|
||||||
4 000100XX STORE_INTO_TEMPVAR
|
36-39 0010 01XX STORE_INTO_TEMPVAR
|
||||||
5 000101XX POP_INTO_INSTVAR
|
40-43 0010 10XX POP_INTO_TEMPVAR 168 1010 1000 XXXXXXXX POP_INTO_TEMPVAR_X (bit 4 off, bit 3 on)
|
||||||
6 000110XX POP_INTO_TEMPVAR
|
44-47 0010 11XX POP_INTO_TEMPVAR
|
||||||
|
|
||||||
7 000111XX JUMP_FORWARD
|
48-51 0011 00XX PUSH_LITERAL 176 1011 0000 XXXXXXXX PUSH_LITERAL_X
|
||||||
8 001000XX JUMP_BACKWARD
|
52-55 0011 01XX PUSH_LITERAL
|
||||||
9 001001XX JUMP_IF_TRUE
|
|
||||||
10 001010XX JUMP_IF_FALSE
|
|
||||||
|
|
||||||
11 001011XX
|
vv
|
||||||
12 001100XX
|
56-59 0011 10XX STORE_INTO_OBJECT 184 1011 1000 XXXXXXXX STORE_INTO_OBJECT (bit 3 on, bit 2 off)
|
||||||
13 001101XX
|
60-63 0011 11XX POP_INTO_OBJECT 188 1011 1100 XXXXXXXX POP_INTO_OBJECT (bit 3 on, bit 2 on)
|
||||||
14 001110XX
|
64-67 0100 00XX PUSH_OBJECT 192 1100 0000 XXXXXXXX PUSH_OBJECT (bit 3 off)
|
||||||
15 001111XX
|
|
||||||
|
|
||||||
---------------------------------------
|
|
||||||
16 010000XX YYYYYYYY PUSH_XTEMPVAR XXXth outer-frame, YYYYYYYY local variable
|
|
||||||
17 010001XX YYYYYYYY STORE_INTO_XTEMPVAR
|
|
||||||
18 010010XX YYYYYYYY POP_INTO_XTEMPVAR
|
|
||||||
|
|
||||||
19 010011XX YYYYYYYY PUSH_OBJVAR
|
|
||||||
20 010100XX YYYYYYYY STORE_INTO_OBJVAR
|
|
||||||
21 010101XX YYYYYYYY POP_INTO_OBJVAR XXXth instance variable of YYYYYYYY object
|
|
||||||
22 010110XX YYYYYYYY SEND_MESSAGE
|
|
||||||
23 010111XX YYYYYYYY SEND_MESSAGE_TO_SUPER XXX args, YYYYYYYY message
|
|
||||||
|
|
||||||
24 011000XX
|
|
||||||
25 011001XX
|
|
||||||
26 011010XX
|
|
||||||
27 011011XX
|
|
||||||
28 011100XX
|
|
||||||
29 011101XX
|
|
||||||
30 011110XX
|
|
||||||
31 011111XX
|
|
||||||
|
|
||||||
-------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
68-71 0100 01XX JUMP_FORWARD 196 1100 0100 XXXXXXXX JUMP_FORWARD_X
|
||||||
|
72-75 0100 10XX JUMP_BACKWARD 200 1100 1000 XXXXXXXX JUMP_BACKWARD_X
|
||||||
|
76-79 0100 11XX JUMP_IF_TRUE 204 1100 1100 XXXXXXXX JUMP_IF_TRUE_X
|
||||||
|
80-83 0101 00XX JUMP_IF_FALSE 208 1101 0000 XXXXXXXX JUMP_IF_FALSE_X
|
||||||
|
84-87 0101 01XX JUMP_BY_OFFSET 212 1101 0100 XXXXXXXX JUMP_BY_OFFSET_X
|
||||||
|
# for JUMP_BY_OFFSET, XX is an index to literal frame pointing to a small integer.
|
||||||
|
|
||||||
switch (binst)
|
vv
|
||||||
|
88-91 0101 10XX YYYYYYYY STORE_INTO_CTXTEMPVAR 216 1101 1000 XXXXXXXX YYYYYYYY STORE_INTO_CTXTEMPVAR_X (bit 3 on, bit 2 off)
|
||||||
|
92-95 0101 11XX YYYYYYYY POP_INTO_CTXTEMPVAR 220 1101 1100 XXXXXXXX YYYYYYYY POP_INTO_CTXTEMPVAR_X (bit 3 on, bit 2 on)
|
||||||
|
96-99 0110 00XX YYYYYYYY PUSH_CTXTEMPVAR 224 1110 0000 XXXXXXXX YYYYYYYY PUSH_CTXTEMPVAR_X (bit 3 off)
|
||||||
|
# XXXth outer-frame, YYYYYYYY local variable
|
||||||
|
|
||||||
|
100-103 0110 01XX YYYYYYYY PUSH_OBJVAR 228 1110 0100 XXXXXXXX YYYYYYYY PUSH_OBJVAR_X (bit 3 off)
|
||||||
|
104-107 0110 10XX YYYYYYYY STORE_INTO_OBJVAR 232 1110 1000 XXXXXXXX YYYYYYYY STORE_INTO_OBJVAR_X (bit 3 on, bit 2 off)
|
||||||
|
108-111 0110 11XX YYYYYYYY POP_INTO_OBJVAR 236 1110 1100 XXXXXXXX YYYYYYYY POP_INTO_OBJVAR_X (bit 3 on, bit 2 on)
|
||||||
|
# XXXth instance variable of YYYYYYYY object
|
||||||
|
|
||||||
|
v
|
||||||
|
112-115 0111 00XX YYYYYYYY SEND_MESSAGE 240 1111 0000 XXXXXXXX YYYYYYYY SEND_MESSAGE_X (bit 2 off)
|
||||||
|
116-119 0111 01XX YYYYYYYY SEND_MESSAGE_TO_SUPER 244 1111 0100 XXXXXXXX YYYYYYYY SEND_MESSAGE_TO_SUPER_X (bit 2 on)
|
||||||
|
# XXX args, YYYYYYYY message
|
||||||
|
|
||||||
|
120-123 0111 10XX UNUSED
|
||||||
|
124-127 0111 11XX UNUSED
|
||||||
|
|
||||||
|
##
|
||||||
|
## "SHORT_CODE_0 | 0x80" becomes "LONG_CODE_X".
|
||||||
|
## A special single byte instruction is assigned an unused number greater than 128.
|
||||||
|
##
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum stix_bcode_t
|
||||||
{
|
{
|
||||||
case XXX:
|
BCODE_STORE_INTO_INSTVAR_0 = 0x00,
|
||||||
case YYY:
|
BCODE_STORE_INTO_INSTVAR_1 = 0x01,
|
||||||
|
BCODE_STORE_INTO_INSTVAR_2 = 0x02,
|
||||||
|
BCODE_STORE_INTO_INSTVAR_3 = 0x03,
|
||||||
|
|
||||||
|
BCODE_STORE_INTO_INSTVAR_4 = 0x04,
|
||||||
|
BCODE_STORE_INTO_INSTVAR_5 = 0x05,
|
||||||
|
BCODE_STORE_INTO_INSTVAR_6 = 0x06,
|
||||||
|
BCODE_STORE_INTO_INSTVAR_7 = 0x07,
|
||||||
|
|
||||||
|
BCODE_POP_INTO_INSTVAR_0 = 0x08,
|
||||||
|
BCODE_POP_INTO_INSTVAR_1 = 0x09,
|
||||||
|
BCODE_POP_INTO_INSTVAR_2 = 0x0A,
|
||||||
|
BCODE_POP_INTO_INSTVAR_3 = 0x0B,
|
||||||
|
|
||||||
|
BCODE_POP_INTO_INSTVAR_4 = 0x0C,
|
||||||
|
BCODE_POP_INTO_INSTVAR_5 = 0x0D,
|
||||||
|
BCODE_POP_INTO_INSTVAR_6 = 0x0E,
|
||||||
|
BCODE_POP_INTO_INSTVAR_7 = 0x0F,
|
||||||
|
|
||||||
|
BCODE_PUSH_INSTVAR_0 = 0x10,
|
||||||
|
BCODE_PUSH_INSTVAR_1 = 0x11,
|
||||||
|
BCODE_PUSH_INSTVAR_2 = 0x12,
|
||||||
|
BCODE_PUSH_INSTVAR_3 = 0x13,
|
||||||
|
|
||||||
|
BCODE_PUSH_INSTVAR_4 = 0x14,
|
||||||
|
BCODE_PUSH_INSTVAR_5 = 0x15,
|
||||||
|
BCODE_PUSH_INSTVAR_6 = 0x16,
|
||||||
|
BCODE_PUSH_INSTVAR_7 = 0x17,
|
||||||
|
|
||||||
|
BCODE_PUSH_TEMPVAR_0 = 0x18,
|
||||||
|
BCODE_PUSH_TEMPVAR_1 = 0x19,
|
||||||
|
BCODE_PUSH_TEMPVAR_2 = 0x1A,
|
||||||
|
BCODE_PUSH_TEMPVAR_3 = 0x1B,
|
||||||
|
|
||||||
|
BCODE_PUSH_TEMPVAR_4 = 0x1C,
|
||||||
|
BCODE_PUSH_TEMPVAR_5 = 0x1D,
|
||||||
|
BCODE_PUSH_TEMPVAR_6 = 0x1E,
|
||||||
|
BCODE_PUSH_TEMPVAR_7 = 0x1F,
|
||||||
|
|
||||||
|
BCODE_STORE_INTO_TEMPVAR_0 = 0x20,
|
||||||
|
BCODE_STORE_INTO_TEMPVAR_1 = 0x21,
|
||||||
|
BCODE_STORE_INTO_TEMPVAR_2 = 0x22,
|
||||||
|
BCODE_STORE_INTO_TEMPVAR_3 = 0x23,
|
||||||
|
|
||||||
|
BCODE_STORE_INTO_TEMPVAR_4 = 0x24,
|
||||||
|
BCODE_STORE_INTO_TEMPVAR_5 = 0x25,
|
||||||
|
BCODE_STORE_INTO_TEMPVAR_6 = 0x26,
|
||||||
|
BCODE_STORE_INTO_TEMPVAR_7 = 0x27,
|
||||||
|
|
||||||
|
BCODE_POP_INTO_TEMPVAR_0 = 0x28,
|
||||||
|
BCODE_POP_INTO_TEMPVAR_1 = 0x29,
|
||||||
|
BCODE_POP_INTO_TEMPVAR_2 = 0x2A,
|
||||||
|
BCODE_POP_INTO_TEMPVAR_3 = 0x2B,
|
||||||
|
|
||||||
|
BCODE_POP_INTO_TEMPVAR_4 = 0x2C,
|
||||||
|
BCODE_POP_INTO_TEMPVAR_5 = 0x2D,
|
||||||
|
BCODE_POP_INTO_TEMPVAR_6 = 0x2E,
|
||||||
|
BCODE_POP_INTO_TEMPVAR_7 = 0x2F,
|
||||||
|
|
||||||
|
BCODE_PUSH_LITERAL_0 = 0x30,
|
||||||
|
BCODE_PUSH_LITERAL_1 = 0x31,
|
||||||
|
BCODE_PUSH_LITERAL_2 = 0x32,
|
||||||
|
BCODE_PUSH_LITERAL_3 = 0x33,
|
||||||
|
|
||||||
|
BCODE_PUSH_LITERAL_4 = 0x34,
|
||||||
|
BCODE_PUSH_LITERAL_5 = 0x35,
|
||||||
|
BCODE_PUSH_LITERAL_6 = 0x36,
|
||||||
|
BCODE_PUSH_LITERAL_7 = 0x37,
|
||||||
|
|
||||||
|
/* -------------------------------------- */
|
||||||
|
|
||||||
|
BCODE_STORE_INTO_OBJECT_0 = 0x38,
|
||||||
|
BCODE_STORE_INTO_OBJECT_1 = 0x39,
|
||||||
|
BCODE_STORE_INTO_OBJECT_2 = 0x3A,
|
||||||
|
BCODE_STORE_INTO_OBJECT_3 = 0x3B,
|
||||||
|
|
||||||
|
BCODE_POP_INTO_OBJECT_0 = 0x3C,
|
||||||
|
BCODE_POP_INTO_OBJECT_1 = 0x3D,
|
||||||
|
BCODE_POP_INTO_OBJECT_2 = 0x3E,
|
||||||
|
BCODE_POP_INTO_OBJECT_3 = 0x3F,
|
||||||
|
|
||||||
|
BCODE_PUSH_OBJECT_0 = 0x40,
|
||||||
|
BCODE_PUSH_OBJECT_1 = 0x41,
|
||||||
|
BCODE_PUSH_OBJECT_2 = 0x42,
|
||||||
|
BCODE_PUSH_OBJECT_3 = 0x43,
|
||||||
|
|
||||||
|
BCODE_JUMP_FORWARD_0 = 0x44, /* 68 */
|
||||||
|
BCODE_JUMP_FORWARD_1 = 0x45, /* 69 */
|
||||||
|
BCODE_JUMP_FORWARD_2 = 0x46, /* 70 */
|
||||||
|
BCODE_JUMP_FORWARD_3 = 0x47, /* 71 */
|
||||||
|
|
||||||
|
BCODE_JUMP_BACKWARD_0 = 0x48,
|
||||||
|
BCODE_JUMP_BACKWARD_1 = 0x49,
|
||||||
|
BCODE_JUMP_BACKWARD_2 = 0x4A,
|
||||||
|
BCODE_JUMP_BACKWARD_3 = 0x4B,
|
||||||
|
|
||||||
|
BCODE_JUMP_IF_TRUE_0 = 0x4C,
|
||||||
|
BCODE_JUMP_IF_TRUE_1 = 0x4D,
|
||||||
|
BCODE_JUMP_IF_TRUE_2 = 0x4E,
|
||||||
|
BCODE_JUMP_IF_TRUE_3 = 0x4F,
|
||||||
|
|
||||||
|
BCODE_JUMP_IF_FALSE_0 = 0x50,
|
||||||
|
BCODE_JUMP_IF_FALSE_1 = 0x51,
|
||||||
|
BCODE_JUMP_IF_FALSE_2 = 0x52,
|
||||||
|
BCODE_JUMP_IF_FALSE_3 = 0x53,
|
||||||
|
|
||||||
|
BCODE_JUMP_BY_OFFSET_0 = 0x54,
|
||||||
|
BCODE_JUMP_BY_OFFSET_1 = 0x55,
|
||||||
|
BCODE_JUMP_BY_OFFSET_2 = 0x56,
|
||||||
|
BCODE_JUMP_BY_OFFSET_3 = 0x57,
|
||||||
|
|
||||||
|
BCODE_PUSH_CTXTEMPVAR_0 = 0x58,
|
||||||
|
BCODE_PUSH_CTXTEMPVAR_1 = 0x59,
|
||||||
|
BCODE_PUSH_CTXTEMPVAR_2 = 0x5A,
|
||||||
|
BCODE_PUSH_CTXTEMPVAR_3 = 0x5B,
|
||||||
|
|
||||||
|
BCODE_STORE_INTO_CTXTEMPVAR_0 = 0x5C,
|
||||||
|
BCODE_STORE_INTO_CTXTEMPVAR_1 = 0x5D,
|
||||||
|
BCODE_STORE_INTO_CTXTEMPVAR_2 = 0x5E,
|
||||||
|
BCODE_STORE_INTO_CTXTEMPVAR_3 = 0x5F,
|
||||||
|
|
||||||
|
BCODE_POP_INTO_CTXTEMPVAR_0 = 0x60,
|
||||||
|
BCODE_POP_INTO_CTXTEMPVAR_1 = 0x61,
|
||||||
|
BCODE_POP_INTO_CTXTEMPVAR_2 = 0x62,
|
||||||
|
BCODE_POP_INTO_CTXTEMPVAR_3 = 0x63,
|
||||||
|
|
||||||
|
BCODE_PUSH_OBJVAR_0 = 0x64,
|
||||||
|
BCODE_PUSH_OBJVAR_1 = 0x65,
|
||||||
|
BCODE_PUSH_OBJVAR_2 = 0x66,
|
||||||
|
BCODE_PUSH_OBJVAR_3 = 0x67,
|
||||||
|
|
||||||
|
BCODE_STORE_INTO_OBJVAR_0 = 0x68,
|
||||||
|
BCODE_STORE_INTO_OBJVAR_1 = 0x69,
|
||||||
|
BCODE_STORE_INTO_OBJVAR_2 = 0x6A,
|
||||||
|
BCODE_STORE_INTO_OBJVAR_3 = 0x6B,
|
||||||
|
|
||||||
|
BCODE_POP_INTO_OBJVAR_0 = 0x6C,
|
||||||
|
BCODE_POP_INTO_OBJVAR_1 = 0x6D,
|
||||||
|
BCODE_POP_INTO_OBJVAR_2 = 0x6E,
|
||||||
|
BCODE_POP_INTO_OBJVAR_3 = 0x6F,
|
||||||
|
|
||||||
|
|
||||||
default:
|
BCODE_SEND_MESSAGE_0 = 0x70,
|
||||||
{
|
BCODE_SEND_MESSAGE_1 = 0x71,
|
||||||
cmd = binst >> 2;
|
BCODE_SEND_MESSAGE_2 = 0x72,
|
||||||
|
BCODE_SEND_MESSAGE_3 = 0x73,
|
||||||
|
|
||||||
switch (cmd)
|
BCODE_SEND_MESSAGE_TO_SUPER_0 = 0x74,
|
||||||
{
|
BCODE_SEND_MESSAGE_TO_SUPER_1 = 0x75,
|
||||||
case PUSH_INSTVAR:
|
BCODE_SEND_MESSAGE_TO_SUPER_2 = 0x76,
|
||||||
|
BCODE_SEND_MESSAGE_TO_SUPER_3 = 0x77,
|
||||||
|
|
||||||
case PUSHX_INSTVAR:
|
/* UNUSED 0x78 - 0x7F */
|
||||||
|
|
||||||
|
BCODE_STORE_INTO_INSTVAR_X = 0x80, /* 128 */
|
||||||
|
BCODE_POP_INTO_INSTVAR_X = 0x88, /* 136 */
|
||||||
|
BCODE_PUSH_INSTVAR_X = 0x90, /* 144 */
|
||||||
|
|
||||||
|
BCODE_PUSH_TEMPVAR_X = 0x98, /* 152 */
|
||||||
|
BCODE_STORE_INTO_TEMPVAR_X = 0xA0, /* 160 */
|
||||||
|
BCODE_POP_INTO_TEMPVAR_X = 0xA8, /* 168 */
|
||||||
|
|
||||||
|
BCODE_PUSH_LITERAL_X = 0xB0, /* 176 */
|
||||||
|
|
||||||
|
BCODE_STORE_INTO_OBJECT_X = 0xB8, /* 184 */
|
||||||
|
BCODE_POP_INTO_OBJECT_X = 0xBC, /* 188 */
|
||||||
|
BCODE_PUSH_OBJECT_X = 0xC0, /* 192 */
|
||||||
|
|
||||||
|
BCODE_JUMP_FORWARD_X = 0xC4, /* 196 */
|
||||||
|
BCODE_JUMP_BACKWARD_X = 0xC8, /* 200 */
|
||||||
|
BCODE_JUMP_IF_TRUE_X = 0xCC, /* 204 */
|
||||||
|
BCODE_JUMP_IF_FALSE_X = 0xD0, /* 208 */
|
||||||
|
BCODE_JUMP_BY_OFFSET_X = 0xD4, /* 212 */
|
||||||
|
|
||||||
|
BCODE_STORE_INTO_CTXTEMPVAR_X = 0xD8, /* 216 */
|
||||||
|
BCODE_POP_INTO_CTXTEMPVAR_X = 0xDC, /* 220 */
|
||||||
|
BCODE_PUSH_CTXTEMPVAR_X = 0xE0, /* 224 */
|
||||||
|
|
||||||
|
BCODE_PUSH_OBJVAR_X = 0xE4, /* 228 */
|
||||||
|
BCODE_STORE_INTO_OBJVAR_X = 0xE8, /* 232 */
|
||||||
|
BCODE_POP_INTO_OBJVAR_X = 0xEC, /* 236 */
|
||||||
|
|
||||||
|
BCODE_SEND_MESSAGE_X = 0xF0, /* 240 */
|
||||||
|
BCODE_SEND_MESSAGE_TO_SUPER_X = 0xF4, /* 244 */
|
||||||
|
|
||||||
|
|
||||||
|
BCODE_PUSH_RECEIVER = 0x81,
|
||||||
|
BCODE_PUSH_NIL = 0x82,
|
||||||
|
BCODE_PUSH_TRUE = 0x83,
|
||||||
|
BCODE_PUSH_FALSE = 0x84,
|
||||||
|
BCODE_PUSH_CONTEXT = 0x85,
|
||||||
|
BCODE_PUSH_NEGONE = 0x86,
|
||||||
|
BCODE_PUSH_ZERO = 0x87,
|
||||||
|
BCODE_PUSH_ONE = 0x89,
|
||||||
|
BCODE_PUSH_TWO = 0x91,
|
||||||
|
|
||||||
default:
|
/* UNUSED 0xE8 - 0xF8 */
|
||||||
treated as no op???
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
BCODE_DUP_STACKTOP = 0xF9,
|
||||||
|
BCODE_POP_STACKTOP = 0xFA,
|
||||||
|
BCODE_RETURN_STACKTOP = 0xFB, /* ^something */
|
||||||
enum stix_cmdcode_t
|
BCODE_RETURN_RECEIVER = 0xFC, /* ^self */
|
||||||
{
|
BCODE_RETURN_FROM_BLOCK = 0xFD, /* return the stack top from a block */
|
||||||
CMD_EXTEND = 0x0,
|
BCODE_SEND_BLOCK_COPY = 0xFE,
|
||||||
|
BCODE_NOOP = 0xFF
|
||||||
/* Single positional instructions
|
|
||||||
*
|
|
||||||
* XXXXJJJJ
|
|
||||||
* 0000XXXX JJJJJJJJ
|
|
||||||
* 0000XXXX JJJJJJJJ JJJJJJJJ
|
|
||||||
*
|
|
||||||
* XXXX is one of the following positional instructions.
|
|
||||||
* JJJJ or JJJJJJJJ is the position.
|
|
||||||
*/
|
|
||||||
CMD_PUSH_INSTVAR = 0x1,
|
|
||||||
CMD_PUSH_TEMPVAR = 0x2,
|
|
||||||
CMD_PUSH_LITERAL = 0x3,
|
|
||||||
CMD_STORE_INTO_INSTVAR = 0x4,
|
|
||||||
CMD_STORE_INTO_TEMPVAR = 0x5,
|
|
||||||
|
|
||||||
/*
|
|
||||||
CMD_POP_INTO_INSTVAR = 0x6,
|
|
||||||
CMD_POP_INTO_TEMPVAR = 0x7,
|
|
||||||
CMD_POP_INTO_OBJVAR = 0xXXX,
|
|
||||||
*/
|
|
||||||
/* Jump is a single positional instructions.
|
|
||||||
* JJJJJJJJ in the extended format is encoded as a signed offset
|
|
||||||
* while JJJJ in the compact format is an unsigned offset. */
|
|
||||||
CMD_JUMP = 0x8,
|
|
||||||
CMD_JUMP_IF_FALSE = 0x9,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Double positional instructions
|
|
||||||
*
|
|
||||||
* XXXXJJJJ KKKKKKKK
|
|
||||||
* 0000XXXX JJJJJJJJ KKKKKKKK
|
|
||||||
* 0000XXXX JJJJJJJJ JJJJJJJJ KKKKKKKK KKKKKKKK
|
|
||||||
*
|
|
||||||
* Access instance variable #JJJJ of an object at literal frame #KKKKKKKK
|
|
||||||
* Send message at literal frame #KKKKKKKK with #JJJJ arguments.
|
|
||||||
*/
|
|
||||||
CMD_PUSH_OBJVAR = 0xA,
|
|
||||||
CMD_STORE_INTO_OBJVAR = 0xB,
|
|
||||||
CMD_SEND_MESSAGE = 0xC,
|
|
||||||
CMD_SEND_MESSAGE_TO_SUPER = 0xD,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Single byte instructions
|
|
||||||
*/
|
|
||||||
CMD_PUSH_SPECIAL = 0xE,
|
|
||||||
CMD_DO_SPECIAL = 0xF,
|
|
||||||
|
|
||||||
/* sub-commands for CMD_PUSH_SPECIAL */
|
|
||||||
SUBCMD_PUSH_RECEIVER = 0x0,
|
|
||||||
SUBCMD_PUSH_NIL = 0x1,
|
|
||||||
SUBCMD_PUSH_TRUE = 0x2,
|
|
||||||
SUBCMD_PUSH_FALSE = 0x3,
|
|
||||||
SUBCMD_PUSH_CONTEXT = 0x4,
|
|
||||||
SUBCMD_PUSH_NEGONE = 0x5,
|
|
||||||
SUBCMD_PUSH_ZERO = 0x6,
|
|
||||||
SUBCMD_PUSH_ONE = 0x7,
|
|
||||||
|
|
||||||
/* sub-commands for CMD_DO_SPECIAL */
|
|
||||||
SUBCMD_DUP_STACKTOP = 0x0,
|
|
||||||
SUBCMD_POP_STACKTOP = 0x1,
|
|
||||||
SUBCMD_RETURN_STACKTOP = 0x2, /* ^something */
|
|
||||||
SUBCMD_RETURN_RECEIVER = 0x3, /* ^self */
|
|
||||||
SUBCMD_RETURN_FROM_BLOCK = 0x4, /* return the stack top from a block */
|
|
||||||
SUBCMD_SEND_BLOCK_COPY = 0xE,
|
|
||||||
SUBCMD_NOOP = 0xF
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ---------------------------------- */
|
|
||||||
#define CODE_PUSH_RECEIVER MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_RECEIVER)
|
|
||||||
#define CODE_PUSH_NIL MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_NIL)
|
|
||||||
#define CODE_PUSH_TRUE MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_TRUE)
|
|
||||||
#define CODE_PUSH_FALSE MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_FALSE)
|
|
||||||
#define CODE_PUSH_CONTEXT MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_CONTEXT)
|
|
||||||
#define CODE_PUSH_NEGONE MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_NEGONE)
|
|
||||||
#define CODE_PUSH_ZERO MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_ZERO)
|
|
||||||
#define CODE_PUSH_ONE MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_ONE)
|
|
||||||
|
|
||||||
/* special code */
|
|
||||||
#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_RETURN_STACKTOP MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_RETURN_STACKTOP)
|
|
||||||
#define CODE_RETURN_RECEIVER MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_RETURN_RECEIVER)
|
|
||||||
#define CODE_RETURN_FROM_BLOCK MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_RETURN_FROM_BLOCK)
|
|
||||||
#define CODE_SEND_BLOCK_COPY MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_SEND_BLOCK_COPY)
|
|
||||||
#define CODE_NOOP MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_NOOP)
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -301,10 +301,7 @@ enum stix_trait_t
|
|||||||
{
|
{
|
||||||
/* perform no garbage collection when the heap is full.
|
/* perform no garbage collection when the heap is full.
|
||||||
* you still can use stix_gc() explicitly. */
|
* you still can use stix_gc() explicitly. */
|
||||||
STIX_NOGC = (1 << 0),
|
STIX_NOGC = (1 << 0)
|
||||||
|
|
||||||
/* no tail call optimization */
|
|
||||||
STIX_NOTCO = (1 << 1),
|
|
||||||
};
|
};
|
||||||
typedef enum stix_trait_t stix_trait_t;
|
typedef enum stix_trait_t stix_trait_t;
|
||||||
|
|
||||||
|
@ -563,7 +563,7 @@
|
|||||||
|
|
||||||
#method(#class) main
|
#method(#class) main
|
||||||
{
|
{
|
||||||
|a b sum |
|
|a b c d e f g h i j k sum |
|
||||||
|
|
||||||
sum := [ :n | (n < 2) ifTrue: [1] ifFalse: [ n + (sum value: (n - 1))] ].
|
sum := [ :n | (n < 2) ifTrue: [1] ifFalse: [ n + (sum value: (n - 1))] ].
|
||||||
(sum value: 5) dump.
|
(sum value: 5) dump.
|
||||||
|
Loading…
Reference in New Issue
Block a user