diff --git a/stix/lib/comp.c b/stix/lib/comp.c index 81653f6..6693e32 100644 --- a/stix/lib/comp.c +++ b/stix/lib/comp.c @@ -1465,73 +1465,120 @@ static STIX_INLINE int emit_byte_instruction (stix_t* stix, stix_byte_t code) 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_ASSERT (index <= MAX_CODE_INDEX); + stix_byte_t bc; - if (index > 0xF) + switch (cmd) { - #if (STIX_CODE_EXTEND_SIZE == 2) - if (emit_byte_instruction(stix, MAKE_CODE(CMD_EXTEND, cmd)) <= -1 || - emit_byte_instruction(stix, index >> 8) <= -1 || - emit_byte_instruction(stix, index & 0xFF) <= -1) return -1; + case BCODE_PUSH_INSTVAR_0: + case BCODE_STORE_INTO_INSTVAR_0: + case BCODE_POP_INTO_INSTVAR_0: + case BCODE_PUSH_TEMPVAR_0: + case BCODE_STORE_INTO_TEMPVAR_0: + case BCODE_POP_INTO_TEMPVAR_0: + case BCODE_PUSH_LITERAL_0: + if (param_1 < 8) + { + bc = (stix_byte_t)(cmd & 0xF8) | (stix_byte_t)param_1; + goto write_short; + } + else + { + /* 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, MAKE_CODE(CMD_EXTEND, cmd)) <= -1 || - emit_byte_instruction(stix, index) <= -1) return -1; + if (emit_byte_instruction(stix, bc) <= -1 || + emit_byte_instruction(stix, param_1) <= -1) return -1; #endif - } - else - { - if (emit_byte_instruction(stix, MAKE_CODE(cmd, index)) <= -1) return -1; - } - return 0; } -static int emit_double_positional_instruction (stix_t* stix, int cmd, stix_size_t index_1, stix_size_t index_2) + +static int emit_double_param_instruction (stix_t* stix, int cmd, stix_size_t param_1, stix_size_t param_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_byte_t bc; - STIX_ASSERT (cmd <= 0xF); - STIX_ASSERT (index_1 <= MAX_CODE_NARGS); - STIX_ASSERT (index_2 <= MAX_CODE_INDEX); - - if (index_1 > 0xF || index_2 > 0xFF) + switch (cmd) { - #if (STIX_CODE_EXTEND_SIZE == 2) - if (emit_byte_instruction(stix, MAKE_CODE(CMD_EXTEND, cmd)) <= -1 || - emit_byte_instruction(stix, index_1 >> 8) <= -1 || - emit_byte_instruction(stix, index_1 & 0xFF) <= -1 || - emit_byte_instruction(stix, index_2 >> 8) <= -1 || - emit_byte_instruction(stix, index_2 & 0xFF) <= -1) return -1; + case BCODE_STORE_INTO_CTXTEMPVAR_0: + case BCODE_POP_INTO_CTXTEMPVAR_0: + case BCODE_PUSH_CTXTEMPVAR_0: + case BCODE_PUSH_OBJVAR_0: + case BCODE_STORE_INTO_OBJVAR_0: + case BCODE_POP_INTO_OBJVAR_0: + 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 + { + /* 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 || + 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, MAKE_CODE(CMD_EXTEND, cmd)) <= -1 || - emit_byte_instruction(stix, index_1) <= -1 || - emit_byte_instruction(stix, index_2) <= -1) return -1; + if (emit_byte_instruction(stix, bc) <= -1 || + emit_byte_instruction(stix, param_1) <= -1 || + emit_byte_instruction(stix, param_2) return -1; #endif - } - else - { - if (emit_byte_instruction(stix, MAKE_CODE(cmd, index_1)) <= -1 || - emit_byte_instruction(stix, index_2) <= -1) return -1; - } - return 0; } @@ -1542,20 +1589,23 @@ static int emit_push_smint_literal (stix_t* stix, stix_ooi_t i) switch (i) { case -1: - return emit_byte_instruction (stix, CODE_PUSH_NEGONE); + return emit_byte_instruction (stix, BCODE_PUSH_NEGONE); case 0: - return emit_byte_instruction (stix, CODE_PUSH_ZERO); + return emit_byte_instruction (stix, BCODE_PUSH_ZERO); 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 || - 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; } @@ -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)stix->c->mth.tmpr_count /*block_tmpr_count*/); 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, 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"); /* insert dummy instructions before replacing them with a jump instruction */ jump_inst_pos = stix->c->mth.code.len; -#if (STIX_CODE_EXTEND_SIZE == 2) - if (emit_byte_instruction(stix, MAKE_CODE(CMD_EXTEND, CMD_JUMP)) <= -1 || +#if (STIX_BCODE_LONG_PARAM_SIZE == 2) + if (emit_byte_instruction(stix, BCODE_JUMP_FORWARD_X) <= -1 || emit_byte_instruction(stix, 0) <= -1 || emit_byte_instruction(stix, 0) <= -1) return -1; #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; #endif @@ -2398,7 +2448,7 @@ printf ("\tjump\n"); if (stix->c->tok.type == STIX_IOTOK_RBRACK) { /* 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); } else @@ -2412,7 +2462,7 @@ printf ("\tjump\n"); { GET_TOKEN (stix); 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 { @@ -2422,20 +2472,20 @@ printf ("\tjump\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) { +/* 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); 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 */ - 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); /* restore the temporary count */ @@ -2662,7 +2712,7 @@ static int compile_byte_array_literal (stix_t* stix) printf ("\tpush_literal byte_array\n"); 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); return 0; @@ -2682,7 +2732,7 @@ static int compile_array_literal (stix_t* stix) printf ("\tpush_literal array\n"); 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); 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_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); break; case VAR_INSTANCE: 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); break; case VAR_CLASS: 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); break; @@ -2752,59 +2802,59 @@ printf ("GLOBAL NOT IMPLMENTED.... \n"); case STIX_IOTOK_SELF: 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); break; case STIX_IOTOK_SUPER: 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); *to_super = 1; break; case STIX_IOTOK_NIL: 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); break; case STIX_IOTOK_TRUE: 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); break; case STIX_IOTOK_FALSE: 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); break; case STIX_IOTOK_THIS_CONTEXT: 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); break; case STIX_IOTOK_CHARLIT: STIX_ASSERT (stix->c->tok.name.len == 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); GET_TOKEN (stix); break; case STIX_IOTOK_STRLIT: 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); GET_TOKEN (stix); break; case STIX_IOTOK_SYMLIT: 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); GET_TOKEN (stix); break; @@ -2875,8 +2925,8 @@ printf ("\tpush int literal\n"); static stix_byte_t send_message_cmd[] = { - CMD_SEND_MESSAGE, - CMD_SEND_MESSAGE_TO_SUPER + BCODE_SEND_MESSAGE_0, + BCODE_SEND_MESSAGE_TO_SUPER_0 }; 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 { 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); print_ucs (&stix->c->tok.name); 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 (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); print_ucs (&binsel); 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; 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); 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 * cascaded message */ 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; @@ -3039,7 +3089,7 @@ static int compile_message_expression (stix_t* stix, int to_super) 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 (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--; 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; } break; case STIX_IOTOK_BINSEL: 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 (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--; 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; } @@ -3074,7 +3124,7 @@ static int compile_message_expression (stix_t* stix, int to_super) case STIX_IOTOK_KEYWORD: 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; break; @@ -3087,8 +3137,8 @@ static int compile_message_expression (stix_t* stix, int to_super) if (stix->c->tok.type == STIX_IOTOK_SEMICOLON) { printf ("\tdup_stacktop for cascading\n"); - stix->c->mth.code.ptr[noop_pos] = CODE_DUP_STACKTOP; - if (emit_byte_instruction(stix, CODE_POP_STACKTOP) <= -1) return -1; + stix->c->mth.code.ptr[noop_pos] = BCODE_DUP_STACKTOP; + if (emit_byte_instruction(stix, BCODE_POP_STACKTOP) <= -1) return -1; GET_TOKEN(stix); } else @@ -3185,25 +3235,25 @@ printf ("\n"); case VAR_TEMPORARY: 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; */ - 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; case VAR_INSTANCE: case VAR_CLASSINST: 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; */ - 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; case VAR_CLASS: /* TODO is this correct? */ 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); break; @@ -3247,7 +3297,7 @@ static int compile_block_statement (stix_t* stix) GET_TOKEN (stix); if (compile_method_expression(stix, 0) <= -1) return -1; printf ("\treturn_stacktop\n"); - return emit_byte_instruction (stix, CODE_RETURN_STACKTOP); + return emit_byte_instruction (stix, BCODE_RETURN_STACKTOP); } else { @@ -3268,7 +3318,7 @@ static int compile_method_statement (stix_t* stix) GET_TOKEN (stix); if (compile_method_expression(stix, 0) <= -1) return -1; printf ("\treturn_stacktop\n"); - return emit_byte_instruction (stix, CODE_RETURN_STACKTOP); + return emit_byte_instruction (stix, BCODE_RETURN_STACKTOP); } else { @@ -3285,7 +3335,7 @@ printf ("\treturn_stacktop\n"); /* if n is 1, no stack popping is required */ 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 * the end of the method without explicit return */ 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) @@ -3368,41 +3418,36 @@ static int add_compiled_method (stix_t* stix) } 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; } else if (stix->c->mth.code.len >= 2 && - stix->c->mth.code.ptr[0] == CODE_PUSH_RECEIVER && - stix->c->mth.code.ptr[1] == CODE_RETURN_STACKTOP) + stix->c->mth.code.ptr[0] == BCODE_PUSH_RECEIVER && + stix->c->mth.code.ptr[1] == BCODE_RETURN_STACKTOP) { preamble_code = STIX_METHOD_PREAMBLE_RETURN_RECEIVER; } else { /* check if the method begins with 'return instavar' instruction */ - int index_size; - stix_byte_t cmd; - - 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) + if (stix->c->mth.code.ptr[0] >= BCODE_PUSH_INSTVAR_0 && + stix->c->mth.code.ptr[0] <= BCODE_PUSH_INSTVAR_7 && + stix->c->mth.code.ptr[1] == BCODE_RETURN_STACKTOP) { preamble_code = STIX_METHOD_PREAMBLE_RETURN_INSTVAR; - - 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 preamble_index = stix->c->mth.code.ptr[0] & 0xF; + preamble_index = stix->c->mth.code.ptr[0] & 0x7; /* low 3 bits */ + } + else if (stix->c->mth.code.ptr[0] == BCODE_PUSH_INSTVAR_X && + stix->c->mth.code.ptr[STIX_BCODE_LONG_PARAM_SIZE + 1] == BCODE_RETURN_STACKTOP) + { + int i; + 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]; + } } } } diff --git a/stix/lib/exec.c b/stix/lib/exec.c index f98d371..c8da48f 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -73,7 +73,7 @@ LOAD_ACTIVE_SP (stix); \ } 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_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 >= 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); ctx = (stix_oop_context_t)stix_instantiate (stix, stix->_method_context, STIX_NULL, CONTEXT_STACK_SIZE); stix_poptmp (stix); @@ -366,7 +340,7 @@ TODO: overcome this problem STORE_ACTIVE_IP (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) @@ -838,33 +812,30 @@ static primitive_t primitives[] = #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 { \ v_ooi = (stix)->active_code->slot[(stix)->ip++]; \ v_ooi = (v_ooi << 8) | (stix)->active_code->slot[stix->ip++]; \ } while (0) -#define FETCH_SIGNED_CODE_TO(stix, v_ooi) \ - 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_BCODE_LONG_PARAM_SIZE == 2 */ -#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++]) -#define FETCH_SIGNED_CODE_TO(stix, v_ooi) (v_ooi = (stix_int8_t)(stix)->active_code->slot[(stix)->ip++]) +#endif /* STIX_BCODE_LONG_PARAM_SIZE == 2 */ -#endif /* STIX_CODE_EXTEND_SIZE == 2 */ int stix_execute (stix_t* stix) { - stix_byte_t bc, cmd; - stix_ooi_t b1, b2; + stix_byte_t bcode; + 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; STIX_ASSERT (stix->active_context != STIX_NULL); @@ -872,82 +843,119 @@ int stix_execute (stix_t* stix) while (1) { + #if 0 printf ("IP => %d ", (int)stix->ip); #endif - FETCH_BYTE_CODE_TO (stix, bc); - while (bc == CODE_NOOP) FETCH_BYTE_CODE_TO (stix, bc); + FETCH_BYTE_CODE_TO (stix, bcode); + /*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 -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 - 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); 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]); 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) { /*TODO: improve this slow temporary access */ /* this code assumes that the method context and * the block context place 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; @@ -969,125 +977,267 @@ fflush(stdout); } while (1); -print_object (stix, ctx->slot[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]); + bx = b1 - home_ntmprs; } else { -print_object (stix, ACTIVE_STACK_GET(stix, b1)); -printf ("\n"); - -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)); + ctx = stix->active_context; + bx = 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; - 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); print_object (stix, stix->active_method->slot[b1]); printf ("\n"); ACTIVE_STACK_PUSH (stix, stix->active_method->slot[b1]); break; - case CMD_STORE_INTO_INSTVAR: -printf ("STORE_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_PUSH_OBJECT_X: + case BCODE_STORE_INTO_OBJECT_X: + case BCODE_POP_INTO_OBJECT_X: + FETCH_PARAM_CODE_TO (stix, b1); + goto handle_object; - case CMD_STORE_INTO_TEMPVAR: -printf ("STORE_TEMPVAR idx=%d - ", (int)b1); -print_object (stix, ACTIVE_STACK_GETTOP(stix)); -printf ("\n"); - if (stix->active_context->home != stix->_nil) + case BCODE_PUSH_OBJECT_0: + case BCODE_PUSH_OBJECT_1: + case BCODE_PUSH_OBJECT_2: + case BCODE_PUSH_OBJECT_3: + 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 */ - /* this code assuments that the method context and - * 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 + /* store or pop */ + if ((bcode >> 2) & 1) { - home_ntmprs = STIX_OOP_TO_SMINT(((stix_oop_context_t)home)->ntmprs); - 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; - } + /* pop */ } - 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 { -printf (" YYCTX %p STACK TEMPVAR PTR=>%p ADJOFF=%d\n", stix->active_context, &stix->active_context->slot[b1], (int)b1); - ACTIVE_STACK_SET (stix, b1, ACTIVE_STACK_GETTOP(stix)); + /* push */ } break; - /* -------------------------------------------------------- */ + /* -------------------------------------------------------- */ -/* TODO: CMD_JUMP_IF_FALSE */ - case CMD_JUMP: -printf ("JUMP %d\n", (int)b1); + case BCODE_JUMP_FORWARD_X: + FETCH_PARAM_CODE_TO (stix, b1); +printf ("JUMP_FORWARD %d\n", (int)b1); stix->ip += b1; 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 CMD_PUSH_OBJVAR: - { + 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 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. * 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; -printf ("PUSH 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)); + handle_objvar: +printf ("XXXXXXXXXXXXXXXXXXXXX [%d]\n", (int)b2); + t1 = (stix_oop_oop_t)stix->active_method->slot[b2]; + STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(t1) == STIX_OBJ_TYPE_OOP); + STIX_ASSERT (b1 < STIX_OBJ_GET_SIZE(t1)); -print_object (stix, obj->slot[b1]); + if ((bcode >> 3) & 1) + { + /* store or pop */ + + t1->slot[b1] = ACTIVE_STACK_GETTOP(stix); + + if ((bcode >> 2) & 1) + { + /* 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"); - ACTIVE_STACK_PUSH (stix, obj->slot[b1]); break; - } - case CMD_STORE_INTO_OBJVAR: + /* -------------------------------------------------------- */ + case BCODE_SEND_MESSAGE_X: + case BCODE_SEND_MESSAGE_TO_SUPER_X: + FETCH_PARAM_CODE_TO (stix, b1); + 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: { - stix_oop_oop_t obj; -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)); -printf ("\n"); - obj->slot[b1] = ACTIVE_STACK_GETTOP(stix); - break; - } - - /* -------------------------------------------------------- */ - case CMD_SEND_MESSAGE: - case CMD_SEND_MESSAGE_TO_SUPER: - { -/* TODO: tail call optimization */ - /* b1 -> number of arguments * b2 -> index to the selector stored in the literal frame */ @@ -1096,15 +1246,17 @@ printf ("\n"); stix_oop_method_t newmth; stix_oop_char_t selector; 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 */ 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); -else -printf ("SEND_MESSAGE_TO_SUPER 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); print_object (stix, (stix_oop_t)selector); fflush (stdout); STIX_ASSERT (STIX_CLASSOF(stix, selector) == stix->_symbol); @@ -1115,7 +1267,7 @@ print_object(stix, newrcv); printf ("\n"); mthname.ptr = selector->slot; 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) { /* TODO: implement doesNotUnderstand: XXXXX instead of returning -1. */ @@ -1188,273 +1340,260 @@ printf ("RETURN INSTVAR AT PREAMBLE\n"); } default: -/* TOOD: remove it only in the instructions that requires reading ahead */ - /* 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; + if (activate_new_method (stix, newmth) <= -1) goto oops; break; } break; /* CMD_SEND_MESSAGE */ } - /* -------------------------------------------------------- */ + /* -------------------------------------------------------- */ - case CMD_PUSH_SPECIAL: - switch (b1) - { - case SUBCMD_PUSH_RECEIVER: + case BCODE_PUSH_RECEIVER: 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); - break; + ACTIVE_STACK_PUSH (stix, stix->active_context->origin->receiver_or_source); + break; - case SUBCMD_PUSH_NIL: + case BCODE_PUSH_NIL: printf ("PUSH_NIL\n"); - ACTIVE_STACK_PUSH (stix, stix->_nil); - break; + ACTIVE_STACK_PUSH (stix, stix->_nil); + break; - case SUBCMD_PUSH_TRUE: + case BCODE_PUSH_TRUE: printf ("PUSH_TRUE\n"); - ACTIVE_STACK_PUSH (stix, stix->_true); - break; + ACTIVE_STACK_PUSH (stix, stix->_true); + break; - case SUBCMD_PUSH_FALSE: + case BCODE_PUSH_FALSE: printf ("PUSH_FALSE\n"); - ACTIVE_STACK_PUSH (stix, stix->_false); - break; + ACTIVE_STACK_PUSH (stix, stix->_false); + break; - case SUBCMD_PUSH_CONTEXT: + case BCODE_PUSH_CONTEXT: printf ("PUSH_CONTEXT\n"); - ACTIVE_STACK_PUSH (stix, (stix_oop_t)stix->active_context); - break; + ACTIVE_STACK_PUSH (stix, (stix_oop_t)stix->active_context); + break; - case SUBCMD_PUSH_NEGONE: + case BCODE_PUSH_NEGONE: printf ("PUSH_NEGONE\n"); - ACTIVE_STACK_PUSH (stix, STIX_OOP_FROM_SMINT(-1)); - break; + ACTIVE_STACK_PUSH (stix, STIX_OOP_FROM_SMINT(-1)); + break; - case SUBCMD_PUSH_ZERO: + case BCODE_PUSH_ZERO: printf ("PUSH_ZERO\n"); - ACTIVE_STACK_PUSH (stix, STIX_OOP_FROM_SMINT(0)); - break; + ACTIVE_STACK_PUSH (stix, STIX_OOP_FROM_SMINT(0)); + break; - case SUBCMD_PUSH_ONE: -printf ("PUSH_SMINT\n"); - ACTIVE_STACK_PUSH (stix, STIX_OOP_FROM_SMINT(1)); - break; - } - break; /* CMD_PUSH_SPECIAL */ + case BCODE_PUSH_ONE: +printf ("PUSH_ONE\n"); + ACTIVE_STACK_PUSH (stix, STIX_OOP_FROM_SMINT(1)); + break; - /* -------------------------------------------------------- */ + 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; - - switch (b1) - { - case SUBCMD_DUP_STACKTOP: - { - stix_oop_t tmp; + stix_oop_t t; printf ("DUP_STACKTOP SP=%d\n", (int)stix->sp); - STIX_ASSERT (!ACTIVE_STACK_ISEMPTY(stix)); - tmp = ACTIVE_STACK_GETTOP(stix); - ACTIVE_STACK_PUSH (stix, tmp); - break; - } + STIX_ASSERT (!ACTIVE_STACK_ISEMPTY(stix)); + t = ACTIVE_STACK_GETTOP(stix); + ACTIVE_STACK_PUSH (stix, t); + break; + } - case SUBCMD_POP_STACKTOP: + case BCODE_POP_STACKTOP: printf ("POP_STACKTOP\n"); - STIX_ASSERT (!ACTIVE_STACK_ISEMPTY(stix)); - ACTIVE_STACK_POP (stix); - break; + STIX_ASSERT (!ACTIVE_STACK_ISEMPTY(stix)); + ACTIVE_STACK_POP (stix); + break; - case SUBCMD_RETURN_STACKTOP: + case BCODE_RETURN_STACKTOP: printf ("RETURN_STACKTOP\n"); - return_value = ACTIVE_STACK_GETTOP(stix); - ACTIVE_STACK_POP (stix); - goto handle_return; + return_value = ACTIVE_STACK_GETTOP(stix); + ACTIVE_STACK_POP (stix); + goto handle_return; - case SUBCMD_RETURN_RECEIVER: + case BCODE_RETURN_RECEIVER: printf ("RETURN_RECEIVER\n"); - 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: - + return_value = stix->active_context->origin->receiver_or_source; + handle_return: printf ("<> SP=%d\n", (int)stix->sp); - /* put the instruction pointer back to the return - * instruction (RETURN_RECEIVER or RETURN_RECEIVER) - * if a context returns into this context again, - * it'll be able to return as well again. - * - * Consider a program like this: - * - * #class MyObject(Object) - * { - * #declare(#classinst) t1 t2. - * #method(#class) xxxx - * { - * | g1 g2 | - * t1 dump. - * t2 := [ g1 := 50. g2 := 100. ^g1 + g2 ]. - * (t1 < 100) ifFalse: [ ^self ]. - * t1 := t1 + 1. - * ^self xxxx. - * } - * #method(#class) main - * { - * t1 := 1. - * self xxxx. - * t2 := t2 value. - * t2 dump. - * } - * } - * - * the 'xxxx' method invoked by 'self xxxx' has - * returned even before 't2 value' is executed. - * the '^' operator makes the active context to - * switch to its 'origin->sender' which is the - * method context of 'xxxx' itself. placing its - * instruction pointer at the 'return' instruction - * helps execute another return when the switching - * occurs. - * - * TODO: verify if this really works - * - */ - stix->ip--; + /* put the instruction pointer back to the return + * instruction (RETURN_RECEIVER or RETURN_RECEIVER) + * if a context returns into this context again, + * it'll be able to return as well again. + * + * Consider a program like this: + * + * #class MyObject(Object) + * { + * #declare(#classinst) t1 t2. + * #method(#class) xxxx + * { + * | g1 g2 | + * t1 dump. + * t2 := [ g1 := 50. g2 := 100. ^g1 + g2 ]. + * (t1 < 100) ifFalse: [ ^self ]. + * t1 := t1 + 1. + * ^self xxxx. + * } + * #method(#class) main + * { + * t1 := 1. + * self xxxx. + * t2 := t2 value. + * t2 dump. + * } + * } + * + * the 'xxxx' method invoked by 'self xxxx' has + * returned even before 't2 value' is executed. + * the '^' operator makes the active context to + * switch to its 'origin->sender' which is the + * method context of 'xxxx' itself. placing its + * instruction pointer at the 'return' instruction + * helps execute another return when the switching + * occurs. + * + * TODO: verify if this really works + * + */ + stix->ip--; - SWITCH_ACTIVE_CONTEXT (stix, (stix_oop_context_t)stix->active_context->origin->sender); + SWITCH_ACTIVE_CONTEXT (stix, (stix_oop_context_t)stix->active_context->origin->sender); - /* push the return value to the stack of the new active context */ - ACTIVE_STACK_PUSH (stix, return_value); + /* push the return value to the stack of the new active context */ + ACTIVE_STACK_PUSH (stix, return_value); - if (stix->active_context->sender == stix->_nil) - { - /* the sending context of the intial context has been set to nil. - * use this fact to tell an initial context from a normal context. */ - STIX_ASSERT (stix->active_context->receiver_or_source == stix->_nil); + if (stix->active_context->sender == stix->_nil) + { + /* the sending context of the intial context has been set to nil. + * use this fact to tell an initial context from a normal context. */ + STIX_ASSERT (stix->active_context->receiver_or_source == stix->_nil); printf ("<<>>\n"); - STIX_ASSERT (stix->sp == 0); - goto done; - } - - break; + STIX_ASSERT (stix->sp == 0); + goto done; } - break; /* CMD_DO_SPECIAL */ + + 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; + } + 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; + } } diff --git a/stix/lib/main.c b/stix/lib/main.c index f3484bf..9eb3869 100644 --- a/stix/lib/main.c +++ b/stix/lib/main.c @@ -282,7 +282,7 @@ printf ("%ld\n", (long int)STIX_OOP_TO_SMINT(k)); { int trait = 0; - /*trait |= STIX_NOTCO;*/ + /*trait |= STIX_NOGC;*/ stix_setoption (stix, STIX_TRAIT, &trait); } diff --git a/stix/lib/stix-prv.h b/stix/lib/stix-prv.h index 04dcb40..c255f25 100644 --- a/stix/lib/stix-prv.h +++ b/stix/lib/stix-prv.h @@ -30,7 +30,7 @@ #include "stix.h" /* 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 * while stix has not been fully initialized when this is defined*/ @@ -460,195 +460,301 @@ struct stix_compiler_t #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_NTMPRS (0xFFu) # define MAX_CODE_NARGS (0xFFu) # define MAX_CODE_NBLKARGS (0xFFu) # define MAX_CODE_NBLKTMPRS (0xFFu) # define MAX_CODE_PRIMNO (0xFFFFu) -# define MIN_CODE_JUMP (-0x80) -# define MAX_CODE_JUMP (0x7F) -#elif defined(STIX_CODE_EXTEND_SIZE) && (STIX_CODE_EXTEND_SIZE == 2) +# define MAX_CODE_JUMP (0xFF) +#elif defined(STIX_BCODE_LONG_PARAM_SIZE) && (STIX_BCODE_LONG_PARAM_SIZE == 2) # define MAX_CODE_INDEX (0xFFFFu) # define MAX_CODE_NTMPRS (0xFFFFu) # define MAX_CODE_NARGS (0xFFFFu) # define MAX_CODE_NBLKARGS (0xFFFFu) # define MAX_CODE_NBLKTMPRS (0xFFFFu) # define MAX_CODE_PRIMNO (0xFFFFu) -# define MIN_CODE_JUMP (-0x8000) -# define MAX_CODE_JUMP (0x7FFF) +# define MAX_CODE_JUMP (0xFFFF) #else -# error Unsupported STIX_CODE_EXTEND_SIZE +# error Unsupported STIX_BCODE_LONG_PARAM_SIZE #endif #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 - 1 000001XX PUSH_TEMPVAR - 2 000010XX PUSH_LITERAL - 3 000011XX STORE_INTO_INSTVAR - 4 000100XX STORE_INTO_TEMPVAR - 5 000101XX POP_INTO_INSTVAR - 6 000110XX POP_INTO_TEMPVAR + v v +24-27 0001 10XX PUSH_TEMPVAR 152 1001 1000 XXXXXXXX PUSH_TEMPVAR_X (bit 4 on) +28-31 0001 11XX PUSH_TEMPVAR +32-35 0010 00XX STORE_INTO_TEMPVAR 160 1010 0000 XXXXXXXX STORE_INTO_TEMPVAR_X (bit 4 off, bit 3 off) +36-39 0010 01XX STORE_INTO_TEMPVAR +40-43 0010 10XX POP_INTO_TEMPVAR 168 1010 1000 XXXXXXXX POP_INTO_TEMPVAR_X (bit 4 off, bit 3 on) +44-47 0010 11XX POP_INTO_TEMPVAR - 7 000111XX JUMP_FORWARD - 8 001000XX JUMP_BACKWARD - 9 001001XX JUMP_IF_TRUE - 10 001010XX JUMP_IF_FALSE +48-51 0011 00XX PUSH_LITERAL 176 1011 0000 XXXXXXXX PUSH_LITERAL_X +52-55 0011 01XX PUSH_LITERAL - 11 001011XX - 12 001100XX - 13 001101XX - 14 001110XX - 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 - -------------------------------------- + vv +56-59 0011 10XX STORE_INTO_OBJECT 184 1011 1000 XXXXXXXX STORE_INTO_OBJECT (bit 3 on, bit 2 off) +60-63 0011 11XX POP_INTO_OBJECT 188 1011 1100 XXXXXXXX POP_INTO_OBJECT (bit 3 on, bit 2 on) +64-67 0100 00XX PUSH_OBJECT 192 1100 0000 XXXXXXXX PUSH_OBJECT (bit 3 off) +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) -{ - case XXX: - case YYY: + 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 - default: - { - cmd = binst >> 2; + 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 - switch (cmd) - { - case PUSH_INSTVAR: - - case PUSHX_INSTVAR: - - - - default: - treated as no op??? - } - } -} +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_cmdcode_t +enum stix_bcode_t { - CMD_EXTEND = 0x0, + BCODE_STORE_INTO_INSTVAR_0 = 0x00, + BCODE_STORE_INTO_INSTVAR_1 = 0x01, + BCODE_STORE_INTO_INSTVAR_2 = 0x02, + BCODE_STORE_INTO_INSTVAR_3 = 0x03, - /* 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, + BCODE_STORE_INTO_INSTVAR_4 = 0x04, + BCODE_STORE_INTO_INSTVAR_5 = 0x05, + BCODE_STORE_INTO_INSTVAR_6 = 0x06, + BCODE_STORE_INTO_INSTVAR_7 = 0x07, -/* - 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, + BCODE_POP_INTO_INSTVAR_0 = 0x08, + BCODE_POP_INTO_INSTVAR_1 = 0x09, + BCODE_POP_INTO_INSTVAR_2 = 0x0A, + BCODE_POP_INTO_INSTVAR_3 = 0x0B, - /* - * 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, + BCODE_POP_INTO_INSTVAR_4 = 0x0C, + BCODE_POP_INTO_INSTVAR_5 = 0x0D, + BCODE_POP_INTO_INSTVAR_6 = 0x0E, + BCODE_POP_INTO_INSTVAR_7 = 0x0F, - /* - * Single byte instructions - */ - CMD_PUSH_SPECIAL = 0xE, - CMD_DO_SPECIAL = 0xF, + BCODE_PUSH_INSTVAR_0 = 0x10, + BCODE_PUSH_INSTVAR_1 = 0x11, + BCODE_PUSH_INSTVAR_2 = 0x12, + BCODE_PUSH_INSTVAR_3 = 0x13, - /* 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, + BCODE_PUSH_INSTVAR_4 = 0x14, + BCODE_PUSH_INSTVAR_5 = 0x15, + BCODE_PUSH_INSTVAR_6 = 0x16, + BCODE_PUSH_INSTVAR_7 = 0x17, - /* 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 + 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, + + + BCODE_SEND_MESSAGE_0 = 0x70, + BCODE_SEND_MESSAGE_1 = 0x71, + BCODE_SEND_MESSAGE_2 = 0x72, + BCODE_SEND_MESSAGE_3 = 0x73, + + BCODE_SEND_MESSAGE_TO_SUPER_0 = 0x74, + BCODE_SEND_MESSAGE_TO_SUPER_1 = 0x75, + BCODE_SEND_MESSAGE_TO_SUPER_2 = 0x76, + BCODE_SEND_MESSAGE_TO_SUPER_3 = 0x77, + + /* 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, + + /* UNUSED 0xE8 - 0xF8 */ + + BCODE_DUP_STACKTOP = 0xF9, + BCODE_POP_STACKTOP = 0xFA, + BCODE_RETURN_STACKTOP = 0xFB, /* ^something */ + BCODE_RETURN_RECEIVER = 0xFC, /* ^self */ + BCODE_RETURN_FROM_BLOCK = 0xFD, /* return the stack top from a block */ + BCODE_SEND_BLOCK_COPY = 0xFE, + BCODE_NOOP = 0xFF }; -/* ---------------------------------- */ -#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) extern "C" { #endif diff --git a/stix/lib/stix.h b/stix/lib/stix.h index 8f20b6e..cf0ae76 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -301,10 +301,7 @@ enum stix_trait_t { /* perform no garbage collection when the heap is full. * you still can use stix_gc() explicitly. */ - STIX_NOGC = (1 << 0), - - /* no tail call optimization */ - STIX_NOTCO = (1 << 1), + STIX_NOGC = (1 << 0) }; typedef enum stix_trait_t stix_trait_t; diff --git a/stix/lib/test-005.st b/stix/lib/test-005.st index a5ffb47..0225187 100644 --- a/stix/lib/test-005.st +++ b/stix/lib/test-005.st @@ -563,7 +563,7 @@ #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 value: 5) dump.