added CMD_PUSH_OBJVAR and CMD_STORE_INTO_OBJVAR
This commit is contained in:
parent
2982d4118d
commit
c052501f0c
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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",
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user