From c052501f0ccc339858ea7f1e8e95268853f6a3c6 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Fri, 12 Jun 2015 13:52:30 +0000 Subject: [PATCH] added CMD_PUSH_OBJVAR and CMD_STORE_INTO_OBJVAR --- stix/lib/comp.c | 94 ++++++++++++++++++++++++++++----------------- stix/lib/exec.c | 66 ++++++++++++++++++++++++++++--- stix/lib/main.c | 4 ++ stix/lib/stix-prv.h | 43 ++++++++++++++------- stix/lib/stix.c | 5 +-- 5 files changed, 153 insertions(+), 59 deletions(-) diff --git a/stix/lib/comp.c b/stix/lib/comp.c index 6fc1997..c7ae0fa 100644 --- a/stix/lib/comp.c +++ b/stix/lib/comp.c @@ -951,6 +951,9 @@ retry: static void clear_io_names (stix_t* stix) { stix_iolink_t* cur; + + STIX_ASSERT (stix->c != STIX_NULL); + while (stix->c->io_names) { cur = stix->c->io_names; @@ -1103,45 +1106,52 @@ static int emit_positional_instruction (stix_t* stix, int cmd, stix_size_t index } -static int emit_send_instruction (stix_t* stix, int cmd, stix_size_t nargs, stix_size_t selector) +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 selector K with J arguments to self - * 1011JJJJ KKKKKKKK Send literal selector K with J arguments to super + * 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 * 00011010 JJJJJJJJ JJJJJJJJ KKKKKKKK KKKKKKKK * 00011011 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); - STIX_ASSERT (nargs <= MAX_CODE_NARGS); - STIX_ASSERT (selector <= MAX_CODE_INDEX); + STIX_ASSERT (index_1 <= MAX_CODE_NARGS); + STIX_ASSERT (index_2 <= MAX_CODE_INDEX); - if (nargs > 0xFF || selector > 0xFF) + if (index_1 > 0xFF || index_2 > 0xFF) { if (emit_byte_instruction(stix, MAKE_CODE(CMD_EXTEND_DOUBLE, cmd)) <= -1 || - emit_byte_instruction(stix, nargs >> 8) <= -1 || - emit_byte_instruction(stix, nargs & 0xFF) <= -1 || - emit_byte_instruction(stix, selector >> 8) <= -1 || - emit_byte_instruction(stix, selector & 0xFF) <= -1) return -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; } - else if (nargs > 0xF) + else if (index_1 > 0xF) { if (emit_byte_instruction(stix, MAKE_CODE(CMD_EXTEND, cmd)) <= -1 || - emit_byte_instruction(stix, nargs) <= -1 || - emit_byte_instruction(stix, selector) <= -1) return -1; + emit_byte_instruction(stix, index_1) <= -1 || + emit_byte_instruction(stix, index_2) <= -1) return -1; } else { - if (emit_byte_instruction(stix, MAKE_CODE(cmd, nargs)) <= -1 || - emit_byte_instruction(stix, selector) <= -1) return -1; + if (emit_byte_instruction(stix, MAKE_CODE(cmd, index_1)) <= -1 || + emit_byte_instruction(stix, index_2) <= -1) return -1; } return 0; } - /* --------------------------------------------------------------------- * Compiler * --------------------------------------------------------------------- */ @@ -1935,6 +1945,7 @@ static int compile_expression_primary (stix_t* stix, const stix_ucs_t* ident, co var_info_t var; int read_next_token = 0; + stix_size_t index; *to_super = 0; @@ -1943,28 +1954,31 @@ static int compile_expression_primary (stix_t* stix, const stix_ucs_t* ident, co /* the caller has read the identifier and the next word */ handle_ident: - if (get_variable_info (stix, ident, ident_loc, &var) <= -1) return -1; + if (get_variable_info(stix, ident, ident_loc, &var) <= -1) return -1; switch (var.type) { case VAR_ARGUMENT: case VAR_TEMPORARY: + if (emit_positional_instruction(stix, CMD_PUSH_TEMPVAR, var.pos) <= -1) return -1; printf ("push tempvar %d\n", (int)var.pos); - if (emit_positional_instruction (stix, CMD_PUSH_TEMPVAR, var.pos) <= -1) return -1; break; case VAR_INSTANCE: case VAR_CLASSINST: + if (emit_positional_instruction(stix, CMD_PUSH_INSTVAR, var.pos) <= -1) return -1; printf ("push instvar %d\n", (int)var.pos); - if (emit_positional_instruction (stix, CMD_PUSH_INSTVAR, var.pos) <= -1) return -1; break; case VAR_CLASS: - /* TODO: what instruction to generate for class variable access... */ - return -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; +printf ("PUSH OBJVAR %d %d\n", (int)var.pos, (int)index); + break; case VAR_GLOBAL: /* TODO: .............................. */ +stix->errnum = STIX_ENOIMPL; return -1; default: @@ -1976,8 +1990,6 @@ printf ("push instvar %d\n", (int)var.pos); } else { - stix_size_t index; - switch (stix->c->tok.type) { case STIX_IOTOK_IDENT: @@ -2107,7 +2119,7 @@ static int compile_unary_message (stix_t* stix, int to_super) while (stix->c->tok.type == STIX_IOTOK_IDENT) { if (add_symbol_literal(stix, &stix->c->tok.name, &index) <= -1 || - emit_send_instruction(stix, send_message_cmd[to_super], 0, index) <= -1) return -1; + emit_double_positional_instruction(stix, send_message_cmd[to_super], 0, index) <= -1) return -1; printf ("send message %d with 0 arguments to %s\n", (int)index, (to_super? "super": "self")); GET_TOKEN (stix); } @@ -2136,7 +2148,7 @@ static int compile_binary_message (stix_t* stix, int to_super) if (compile_expression_primary(stix, STIX_NULL, STIX_NULL, &to_super2) <= -1 || compile_unary_message(stix, to_super2) <= -1 || add_symbol_literal(stix, &binsel, &index) <= -1 || - emit_send_instruction(stix, send_message_cmd[to_super], 2, index) <= -1) + emit_double_positional_instruction(stix, send_message_cmd[to_super], 2, index) <= -1) { stix->c->mth.binsels.len -= binsel.len; return -1; @@ -2192,7 +2204,7 @@ static int compile_keyword_message (stix_t* stix, int to_super) kwsel.len = stix->c->mth.kwsels.len - kwsel_len; if (add_symbol_literal(stix, &kwsel, &index) <= -1 || - emit_send_instruction(stix, send_message_cmd[to_super], nargs, index) <= -1) goto oops; + emit_double_positional_instruction(stix, send_message_cmd[to_super], nargs, index) <= -1) goto oops; printf ("Send message %d [", (int)index); print_ucs (&kwsel); printf ("] with %d arguments to %s\n", (int)nargs, (to_super? "super": "self")); @@ -2265,6 +2277,7 @@ static int compile_method_expression (stix_t* stix, int pop) */ stix_ucs_t assignee; + stix_size_t index; int ret = 0; STIX_ASSERT (pop == 0 || pop == 1); @@ -2320,9 +2333,10 @@ ret = pop; break; case VAR_CLASS: - /* TODO: what instruction to generate for class variable access... */ - - goto oops; +/* 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; + break; case VAR_GLOBAL: /* TODO: .............................. */ @@ -3151,20 +3165,30 @@ int stix_compile (stix_t* stix, stix_ioimpl_t io) stix->c->ilchr_ucs.len = 1; } - stix->c->impl = io; + /* Some IO names could have been stored in earlier calls to this function. + * I clear such names before i begin this function. i don't clear it + * at the end of this function because i may be referenced as an error + * location */ + clear_io_names (stix); + /* initialize some key fields */ + stix->c->impl = io; + stix->c->nungots = 0; + + /* The name field and the includer field are STIX_NULL + * for the main stream */ STIX_MEMSET (&stix->c->arg, 0, STIX_SIZEOF(stix->c->arg)); stix->c->arg.line = 1; stix->c->arg.colm = 1; - stix->c->nungots = 0; - - stix->c->curinp = &stix->c->arg; - clear_io_names (stix); /* open the top-level stream */ - n = stix->c->impl (stix, STIX_IO_OPEN, stix->c->curinp); + n = stix->c->impl (stix, STIX_IO_OPEN, &stix->c->arg); if (n <= -1) return -1; + /* the stream is open. set it as the current input stream */ + stix->c->curinp = &stix->c->arg; + + /* compile the contents of the stream */ if (compile_stream (stix) <= -1) goto oops; /* close the stream */ diff --git a/stix/lib/exec.c b/stix/lib/exec.c index 905dab3..acb46fb 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -40,6 +40,18 @@ (v_ctx)->sp = STIX_OOP_FROM_SMINT(v_sp); \ } while(0) +#define LOAD_SP(v_ctx, v_sp) \ + do \ + { \ + v_sp = STIX_OOP_TO_SMINT((v_ctx)->sp); \ + } while(0) + +#define STORE_SP(v_ctx, v_sp) \ + do \ + { \ + (v_ctx)->sp = STIX_OOP_FROM_SMINT(v_sp); \ + } while(0) + static int activate_new_method (stix_t* stix, stix_oop_method_t mth, stix_ooi_t* xip, stix_ooi_t* xsp) { @@ -274,35 +286,44 @@ TODO: overcome this problem (stix)->active_context->slot[sp] = v; \ } while (0) -static int execute_primitive (stix_t* stix, int prim_no, stix_ooi_t nargs, stix_ooi_t* xsp) +static int execute_primitive (stix_t* stix, int prim_no, stix_ooi_t nargs) { /* a primitive handler must pop off all arguments and the receiver and * push a return value when it's successful. otherwise, it must not touch * the stack. */ + stix_ooi_t sp; + LOAD_SP (stix->active_context, sp); switch (prim_no) { case 0: { stix_ooi_t i; - dump_object (stix, stix->active_context->slot[*xsp - nargs], "receiver"); + dump_object (stix, stix->active_context->slot[sp - nargs], "receiver"); for (i = nargs; i > 0; ) { --i; - dump_object (stix, stix->active_context->slot[*xsp - i], "argument"); + dump_object (stix, stix->active_context->slot[sp - i], "argument"); } - *xsp -= nargs; /* pop off arguments */ - return 1; + sp -= nargs; /* pop off arguments */ + goto success; } default: + /* this is hard failure */ + stix->errnum = STIX_ENOIMPL; return -1; } /* TODO: when it returns 1, it should pop up receiver and argumetns.... * when it returns 0, it should not touch the stack */ + return 0; + +success: + STORE_SP (stix->active_context, sp); + return 1; } @@ -383,6 +404,37 @@ printf ("STORE_TEMPVAR %d\n", (int)b1); /* -------------------------------------------------------- */ + case CMD_PUSH_OBJVAR: + { +/* TODO: HANDLE DOUBLE EXTEND */ + /* b1 -> variable index */ + stix_ooi_t obj_index; + stix_oop_oop_t obj; + obj_index = code->slot[ip++]; + + obj = (stix_oop_oop_t)mth->slot[obj_index]; +printf ("PUSH OBJVAR %d %d\n", (int)b1, (int)obj_index); + STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(obj) == STIX_OBJ_TYPE_OOP); + STIX_ASSERT (obj_index < STIX_OBJ_GET_SIZE(obj)); + PUSH (stix, obj->slot[b1]); + break; + } + + case CMD_STORE_INTO_OBJVAR: + { + stix_ooi_t obj_index; + stix_oop_oop_t obj; + obj_index = code->slot[ip++]; + +printf ("STORE OBJVAR %d %d\n", (int)b1, (int)obj_index); + obj = (stix_oop_oop_t)mth->slot[obj_index]; + STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(obj) == STIX_OBJ_TYPE_OOP); + STIX_ASSERT (obj_index < STIX_OBJ_GET_SIZE(obj)); + obj->slot[b1] = stix->active_context->slot[sp]; + break; + } + + /* -------------------------------------------------------- */ case CMD_SEND_MESSAGE: case CMD_SEND_MESSAGE_TO_SUPER: { @@ -454,7 +506,9 @@ printf ("RETURN INSTVAR AT PREAMBLE\n"); printf ("JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ\n"); stix_pushtmp (stix, (stix_oop_t*)&newmth); - n = execute_primitive (stix, STIX_METHOD_GET_PREAMBLE_INDEX(preamble), b1, &sp); + STORE_SP (stix->active_context, sp); + n = execute_primitive (stix, STIX_METHOD_GET_PREAMBLE_INDEX(preamble), b1); + LOAD_SP (stix->active_context, sp); stix_poptmp (stix); if (n <= -1) goto oops; diff --git a/stix/lib/main.c b/stix/lib/main.c index 271aed3..ea7216b 100644 --- a/stix/lib/main.c +++ b/stix/lib/main.c @@ -341,6 +341,10 @@ printf ("%p\n", a); printf ("%.*s ", (int)bcslen, bcs); } } + else + { + printf ("%s ", xtn->source_path); + } printf ("syntax error at line %lu column %lu - %s", diff --git a/stix/lib/stix-prv.h b/stix/lib/stix-prv.h index cf8bc70..83dcb60 100644 --- a/stix/lib/stix-prv.h +++ b/stix/lib/stix-prv.h @@ -442,7 +442,8 @@ struct stix_compiler_t #define CMD_EXTEND 0x0 #define CMD_EXTEND_DOUBLE 0x1 -/* positional instructions +/* Single positional instructions + * * XXXXJJJJ * 0000XXXX JJJJJJJJ * 0001XXXX JJJJJJJJ JJJJJJJJ @@ -454,32 +455,46 @@ struct stix_compiler_t #define CMD_PUSH_TEMPVAR 0x3 #define CMD_PUSH_LITERAL 0x4 #define CMD_STORE_INTO_INSTVAR 0x5 -#define CMD_STORE_INTO_CLASSVAR 0x6 -#define CMD_STORE_INTO_TEMPVAR 0x7 +#define CMD_STORE_INTO_TEMPVAR 0x6 /* + * Double positional instructions + * * XXXXJJJJ KKKKKKKK * 0000XXXX JJJJJJJJ KKKKKKKK * 0001XXXX JJJJJJJJ JJJJJJJJ KKKKKKKK KKKKKKKK + * + * Access instance variable #JJJJ of an object at literal frame #KKKKKKKK + * Send message at literal frame #KKKKKKKK with #JJJJ arguments. */ +#define CMD_PUSH_OBJVAR 0x8 +#define CMD_STORE_INTO_OBJVAR 0x9 + #define CMD_SEND_MESSAGE 0xA #define CMD_SEND_MESSAGE_TO_SUPER 0xB +/* + * Single byte instructions + */ #define CMD_PUSH_SPECIAL 0xE #define CMD_DO_SPECIAL 0xF +enum stix_subcmd_t +{ + /* 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, -#define SUBCMD_PUSH_RECEIVER 0x0 -#define SUBCMD_PUSH_NIL 0x1 -#define SUBCMD_PUSH_TRUE 0x2 -#define SUBCMD_PUSH_FALSE 0x3 -#define SUBCMD_PUSH_CONTEXT 0x4 - -#define SUBCMD_DUP_STACKTOP 0x0 -#define SUBCMD_POP_STACKTOP 0x1 -#define SUBCMD_RETURN_STACKTOP 0x2 -#define SUBCMD_RETURN_BLOCK_STACKTOP 0x3 -#define SUBCMD_RETURN_RECEIVER 0x4 + /* sub-commands for CMD_DO_SPECIAL */ + SUBCMD_DUP_STACKTOP = 0x0, + SUBCMD_POP_STACKTOP = 0x1, + SUBCMD_RETURN_STACKTOP = 0x2, + SUBCMD_RETURN_BLOCK_STACKTOP = 0x3, + SUBCMD_RETURN_RECEIVER = 0x4 +}; /* ---------------------------------- */ #define CODE_PUSH_RECEIVER MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_RECEIVER) diff --git a/stix/lib/stix.c b/stix/lib/stix.c index de10e81..421b868 100644 --- a/stix/lib/stix.c +++ b/stix/lib/stix.c @@ -42,10 +42,7 @@ stix_t* stix_open (stix_mmgr_t* mmgr, stix_size_t xtnsize, stix_size_t heapsize, } else STIX_MEMSET (stix + 1, 0, xtnsize); } - else if (errnum) - { - *errnum = STIX_ENOMEM; - } + else if (errnum) *errnum = STIX_ENOMEM; return stix; }