fixed a compiler bug that omitted the RETURN_FROM_BLOCK instruction when an empty block is encountered.

added more code for supporting the process stack
This commit is contained in:
hyunghwan.chung
2016-02-12 16:23:26 +00:00
parent 3d937334d8
commit f32e58f4b3
44 changed files with 3932 additions and 2025 deletions

View File

@ -1,7 +1,7 @@
/*
* $Id$
*
Copyright (c) 2014-2015 Chung, Hyung-Hwan. All rights reserved.
Copyright (c) 2014-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@ -146,6 +146,19 @@ enum voca_id_t
};
typedef enum voca_id_t voca_id_t;
#if defined(STIX_DEBUG_COMP_001)
# define DBGOUT_COMP_0(fmt) printf(fmt "\n")
# define DBGOUT_COMP_1(fmt,a1) printf(fmt "\n",a1)
# define DBGOUT_COMP_2(fmt,a1,a2) printf(fmt "\n", a1, a2)
# define DBGOUT_COMP_3(fmt,a1,a2,a3) printf(fmt "\n", a1, a2, a3)
#else
# define DBGOUT_COMP_0(fmt)
# define DBGOUT_COMP_1(fmt,a1)
# define DBGOUT_COMP_2(fmt,a1,a2)
# define DBGOUT_COMP_3(fmt,a1,a2,a3)
#endif
static int compile_block_statement (stix_t* stix);
static int compile_method_statement (stix_t* stix);
static int compile_method_expression (stix_t* stix, int pop);
@ -1780,37 +1793,36 @@ static int emit_push_smint_literal (stix_t* stix, stix_ooi_t i)
switch (i)
{
case -1:
printf ("\tpush negone\n");
DBGOUT_COMP_0("\tpush negone");
return emit_byte_instruction (stix, BCODE_PUSH_NEGONE);
case 0:
printf ("\tpush zero\n");
DBGOUT_COMP_0("\tpush zero");
return emit_byte_instruction (stix, BCODE_PUSH_ZERO);
case 1:
printf ("\tpush one\n");
DBGOUT_COMP_0("\tpush one");
return emit_byte_instruction (stix, BCODE_PUSH_ONE);
case 2:
printf ("\tpush two\n");
DBGOUT_COMP_0("\tpush two");
return emit_byte_instruction (stix, BCODE_PUSH_TWO);
}
if (i >= 0 && i <= MAX_CODE_PARAM)
{
printf ("\tpush intlit %d\n", (int)i);
DBGOUT_COMP_1("\tpush intlit %d", (int)i);
return emit_single_param_instruction(stix, BCODE_PUSH_INTLIT, i);
}
else if (i < 0 && i >= -(stix_ooi_t)MAX_CODE_PARAM)
{
printf ("\tpush negintlit %d\n", (int)i);
DBGOUT_COMP_1("\tpush negintlit %d", (int)i);
return emit_single_param_instruction(stix, BCODE_PUSH_NEGINTLIT, -i);
}
if (add_literal(stix, STIX_SMOOI_TO_OOP(i), &index) <= -1 ||
emit_single_param_instruction(stix, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
printf ("\tpush litral_0 %d\n", (int)index);
DBGOUT_COMP_1("\tpush litral_0 %d", (int)index);
return 0;
}
@ -3035,20 +3047,20 @@ static int compile_block_expression (stix_t* stix)
if (store_tmpr_count_for_block (stix, stix->c->mth.tmpr_count) <= -1) return -1;
#if defined(STIX_USE_MAKE_BLOCK)
printf ("\tmake_block nargs %d ntmprs %d\n", (int)block_arg_count, (int)stix->c->mth.tmpr_count /*block_tmpr_count*/);
DBGOUT_COMP_2 ("\tmake_block nargs %d ntmprs %d", (int)block_arg_count, (int)stix->c->mth.tmpr_count /*block_tmpr_count*/);
if (emit_double_param_instruction(stix, BCODE_MAKE_BLOCK, block_arg_count, stix->c->mth.tmpr_count/*block_tmpr_count*/) <= -1) return -1;
#else
printf ("\tpush_context\n");
printf ("\tpush smint nargs=%d\n", (int)block_arg_count);
printf ("\tpush smint ntmprs=%d\n", (int)stix->c->mth.tmpr_count /*block_tmpr_count*/);
printf ("\tsend_block_copy\n");
DBGOUT_COMP_0("\tpush_context");
DBGOUT_COMP_1("\tpush smint nargs=%d", (int)block_arg_count);
DBGOUT_COMP_1("\tpush smint ntmprs=%d", (int)stix->c->mth.tmpr_count /*block_tmpr_count*/);
DBGOUT_COMP_0("\tsend_block_copy");
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, BCODE_SEND_BLOCK_COPY) <= -1) return -1;
#endif
printf ("\tjump\n");
DBGOUT_COMP_0 ("\tjump_forward_0");
/* insert dummy instructions before replacing them with a jump instruction */
jump_inst_pos = stix->c->mth.code.len;
/* specifying MAX_CODE_JUMP causes emit_single_param_instruction() to
@ -3059,6 +3071,7 @@ printf ("\tjump\n");
if (stix->c->tok.type == STIX_IOTOK_RBRACK)
{
/* the block is empty */
DBGOUT_COMP_0("\tpush_nil");
if (emit_byte_instruction (stix, BCODE_PUSH_NIL) <= -1) return -1;
}
else
@ -3072,6 +3085,7 @@ printf ("\tjump\n");
{
GET_TOKEN (stix);
if (stix->c->tok.type == STIX_IOTOK_RBRACK) break;
DBGOUT_COMP_0("\tpop_stacktop");
if (emit_byte_instruction(stix, BCODE_POP_STACKTOP) <= -1) return -1;
}
else
@ -3080,11 +3094,12 @@ printf ("\tjump\n");
return -1;
}
}
printf ("\treturn_from_block\n");
if (emit_byte_instruction(stix, BCODE_RETURN_FROM_BLOCK) <= -1) return -1;
}
DBGOUT_COMP_0("\treturn_from_block");
if (emit_byte_instruction(stix, BCODE_RETURN_FROM_BLOCK) <= -1) return -1;
block_code_size = stix->c->mth.code.len - jump_inst_pos - (STIX_BCODE_LONG_PARAM_SIZE + 1);
if (block_code_size > MAX_CODE_JUMP * 2)
{
@ -3097,7 +3112,7 @@ printf ("\treturn_from_block\n");
if (block_code_size > MAX_CODE_JUMP)
{
printf ("\tfixed jump to jump2\n");
DBGOUT_COMP_0("\tfixed jump_forward to jump2_forward");
stix->c->mth.code.ptr[jump_inst_pos] = BCODE_JUMP2_FORWARD;
jump_offset = block_code_size - MAX_CODE_JUMP;
}
@ -3106,7 +3121,7 @@ printf ("\tfixed jump to jump2\n");
jump_offset = block_code_size;
}
printf ("\tfixed jump offset to %u\n", (unsigned int)jump_offset);
DBGOUT_COMP_1("\tfixed jump offset to %u", (unsigned int)jump_offset);
#if (STIX_BCODE_LONG_PARAM_SIZE == 2)
stix->c->mth.code.ptr[jump_inst_pos + 1] = jump_offset >> 8;
@ -3331,7 +3346,7 @@ static int compile_byte_array_literal (stix_t* stix)
if (read_byte_array_literal(stix, &lit) <= -1 ||
add_literal(stix, lit, &index) <= -1 ||
emit_single_param_instruction(stix, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
printf ("\tpush_literal byte_array\n");
DBGOUT_COMP_0("\tpush_literal byte_array");
GET_TOKEN (stix);
return 0;
@ -3367,7 +3382,7 @@ static int compile_array_literal (stix_t* stix)
if (read_array_literal(stix, &lit) <= -1 ||
add_literal(stix, lit, &index) <= -1 ||
emit_single_param_instruction(stix, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
printf ("\tpush_literal array\n");
DBGOUT_COMP_0("\tpush_literal array");
GET_TOKEN (stix);
return 0;
@ -3408,7 +3423,7 @@ static int compile_expression_primary (stix_t* stix, const stix_oocs_t* ident, c
{
if (var.pos >= stix->c->mth.blk_tmprcnt[i - 1])
{
printf ("\tpush ctxtempvar %d %d\n", (int)(stix->c->mth.blk_depth - i), (int)(var.pos - stix->c->mth.blk_tmprcnt[i - 1]));
DBGOUT_COMP_2("\tpush ctxtempvar %d %d", (int)(stix->c->mth.blk_depth - i), (int)(var.pos - stix->c->mth.blk_tmprcnt[i - 1]));
if (emit_double_param_instruction(stix, BCODE_PUSH_CTXTEMPVAR_0, stix->c->mth.blk_depth - i, var.pos - stix->c->mth.blk_tmprcnt[i - 1]) <= -1) return -1;
goto temporary_done;
}
@ -3417,7 +3432,7 @@ printf ("\tpush ctxtempvar %d %d\n", (int)(stix->c->mth.blk_depth - i), (int)(va
#endif
if (emit_single_param_instruction(stix, BCODE_PUSH_TEMPVAR_0, var.pos) <= -1) return -1;
printf ("\tpush tempvar %d\n", (int)var.pos);
DBGOUT_COMP_1("\tpush tempvar %d", (int)var.pos);
temporary_done:
break;
}
@ -3425,13 +3440,13 @@ printf ("\tpush tempvar %d\n", (int)var.pos);
case VAR_INSTANCE:
case VAR_CLASSINST:
if (emit_single_param_instruction(stix, BCODE_PUSH_INSTVAR_0, var.pos) <= -1) return -1;
printf ("\tpush instvar %d\n", (int)var.pos);
DBGOUT_COMP_1("\tpush instvar %d", (int)var.pos);
break;
case VAR_CLASS:
if (add_literal(stix, (stix_oop_t)var.cls, &index) <= -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);
DBGOUT_COMP_2("\tpush objvar %d %d", (int)var.pos, (int)index);
break;
case VAR_GLOBAL:
@ -3446,7 +3461,7 @@ printf ("\tpush objvar %d %d\n", (int)var.pos, (int)index);
*/
if (add_literal(stix, (stix_oop_t)var.gbl, &index) <= -1 ||
emit_single_param_instruction(stix, BCODE_PUSH_OBJECT_0, index) <= -1) return -1;
printf ("\tpush object %d\n", (int)index);
DBGOUT_COMP_1("\tpush object %d", (int)index);
break;
default:
@ -3469,38 +3484,38 @@ printf ("\tpush object %d\n", (int)index);
goto handle_ident;
case STIX_IOTOK_SELF:
printf ("\tpush receiver...\n");
DBGOUT_COMP_0("\tpush receiver");
if (emit_byte_instruction(stix, BCODE_PUSH_RECEIVER) <= -1) return -1;
GET_TOKEN (stix);
break;
case STIX_IOTOK_SUPER:
printf ("\tpush receiver(super)...\n");
DBGOUT_COMP_0("\tpush receiver(super)");
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");
DBGOUT_COMP_0("\tpush nil");
if (emit_byte_instruction(stix, BCODE_PUSH_NIL) <= -1) return -1;
GET_TOKEN (stix);
break;
case STIX_IOTOK_TRUE:
printf ("\tpush true...\n");
DBGOUT_COMP_0("\tpush true");
if (emit_byte_instruction(stix, BCODE_PUSH_TRUE) <= -1) return -1;
GET_TOKEN (stix);
break;
case STIX_IOTOK_FALSE:
printf ("\tpush false...\n");
DBGOUT_COMP_0("\tpush false");
if (emit_byte_instruction(stix, BCODE_PUSH_FALSE) <= -1) return -1;
GET_TOKEN (stix);
break;
case STIX_IOTOK_THIS_CONTEXT:
printf ("\tpush context...\n");
DBGOUT_COMP_0("\tpush context");
if (emit_byte_instruction(stix, BCODE_PUSH_CONTEXT) <= -1) return -1;
GET_TOKEN (stix);
break;
@ -3509,21 +3524,21 @@ printf ("\tpush context...\n");
STIX_ASSERT (stix->c->tok.name.len == 1);
if (add_character_literal(stix, stix->c->tok.name.ptr[0], &index) <= -1 ||
emit_single_param_instruction(stix, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
printf ("\tpush character literal %d\n", (int)index);
DBGOUT_COMP_1("\tpush character literal %d", (int)index);
GET_TOKEN (stix);
break;
case STIX_IOTOK_STRLIT:
if (add_string_literal(stix, &stix->c->tok.name, &index) <= -1 ||
emit_single_param_instruction(stix, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
printf ("\tpush string literal %d\n", (int)index);
DBGOUT_COMP_1("\tpush string literal %d", (int)index);
GET_TOKEN (stix);
break;
case STIX_IOTOK_SYMLIT:
if (add_symbol_literal(stix, &stix->c->tok.name, &index) <= -1 ||
emit_single_param_instruction(stix, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
printf ("\tpush symbol literal %d\n", (int)index);
DBGOUT_COMP_1("\tpush symbol literal %d", (int)index);
GET_TOKEN (stix);
break;
@ -3545,7 +3560,7 @@ printf ("\tpush symbol literal %d\n", (int)index);
{
if (add_literal(stix, tmp, &index) <= -1 ||
emit_single_param_instruction(stix, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
printf ("\tpush_literal_0 %d\n", (int)index);
DBGOUT_COMP_1("\tpush_literal_0 %d", (int)index);
}
GET_TOKEN (stix);
@ -3822,7 +3837,7 @@ 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");
DBGOUT_COMP_0("\tdup_stacktop for cascading");
stix->c->mth.code.ptr[noop_pos] = BCODE_DUP_STACKTOP;
if (emit_byte_instruction(stix, BCODE_POP_STACKTOP) <= -1) return -1;
GET_TOKEN(stix);
@ -3946,7 +3961,7 @@ printf ("\n");
{
if (var.pos >= stix->c->mth.blk_tmprcnt[i - 1])
{
printf ("\t%s_into_ctxtempvar %d %d\n", (pop? "pop":"store"), (int)(stix->c->mth.blk_depth - i), (int)(var.pos - stix->c->mth.blk_tmprcnt[i - 1]));
DBGOUT_COMP_3("\t%s_into_ctxtempvar %d %d", (pop? "pop":"store"), (int)(stix->c->mth.blk_depth - i), (int)(var.pos - stix->c->mth.blk_tmprcnt[i - 1]));
if (emit_double_param_instruction(stix, (pop? BCODE_POP_INTO_CTXTEMPVAR_0: BCODE_STORE_INTO_CTXTEMPVAR_0), stix->c->mth.blk_depth - i, var.pos - stix->c->mth.blk_tmprcnt[i - 1]) <= -1) return -1;
goto temporary_done;
}
@ -3954,7 +3969,7 @@ printf ("\t%s_into_ctxtempvar %d %d\n", (pop? "pop":"store"), (int)(stix->c->mth
}
#endif
printf ("\t%s_into_tempvar %d\n", (pop? "pop":"store"), (int)var.pos);
DBGOUT_COMP_2("\t%s_into_tempvar %d", (pop? "pop":"store"), (int)var.pos);
if (emit_single_param_instruction (stix, (pop? BCODE_POP_INTO_TEMPVAR_0: BCODE_STORE_INTO_TEMPVAR_0), var.pos) <= -1) goto oops;
temporary_done:
@ -3964,7 +3979,7 @@ printf ("\t%s_into_tempvar %d\n", (pop? "pop":"store"), (int)var.pos);
case VAR_INSTANCE:
case VAR_CLASSINST:
printf ("\t%s_into_instvar %d\n", (pop? "pop":"store"), (int)var.pos);
DBGOUT_COMP_2("\t%s_into_instvar %d", (pop? "pop":"store"), (int)var.pos);
if (emit_single_param_instruction (stix, (pop? BCODE_POP_INTO_INSTVAR_0: BCODE_STORE_INTO_INSTVAR_0), var.pos) <= -1) goto oops;
ret = pop;
break;
@ -3972,14 +3987,14 @@ printf ("\t%s_into_instvar %d\n", (pop? "pop":"store"), (int)var.pos);
case VAR_CLASS:
if (add_literal (stix, (stix_oop_t)var.cls, &index) <= -1 ||
emit_double_param_instruction (stix, (pop? BCODE_POP_INTO_OBJVAR_0: BCODE_STORE_INTO_OBJVAR_0), var.pos, index) <= -1) goto oops;
printf ("\t%s_into_objvar %d %d\n", (pop? "pop":"store"), (int)var.pos, (int)index);
DBGOUT_COMP_3("\t%s_into_objvar %d %d", (pop? "pop":"store"), (int)var.pos, (int)index);
ret = pop;
break;
case VAR_GLOBAL:
if (add_literal(stix, (stix_oop_t)var.gbl, &index) <= -1 ||
emit_single_param_instruction(stix, (pop? BCODE_POP_INTO_OBJECT_0: BCODE_STORE_INTO_OBJECT_0), index) <= -1) return -1;
printf ("\t%s_into_object %d\n", (pop? "pop":"store"), (int)index);
DBGOUT_COMP_2("\t%s_into_object %d", (pop? "pop":"store"), (int)index);
ret = pop;
break;
@ -4021,7 +4036,7 @@ static int compile_block_statement (stix_t* stix)
/* handle the return statement */
GET_TOKEN (stix);
if (compile_method_expression(stix, 0) <= -1) return -1;
printf ("\treturn_stacktop\n");
DBGOUT_COMP_0("\treturn_stacktop");
return emit_byte_instruction (stix, BCODE_RETURN_STACKTOP);
}
else
@ -4042,7 +4057,7 @@ static int compile_method_statement (stix_t* stix)
/* handle the return statement */
GET_TOKEN (stix);
if (compile_method_expression(stix, 0) <= -1) return -1;
printf ("\treturn_stacktop\n");
DBGOUT_COMP_0("\treturn_stacktop");
return emit_byte_instruction (stix, BCODE_RETURN_STACKTOP);
}
else
@ -4059,8 +4074,13 @@ printf ("\treturn_stacktop\n");
if (n <= -1) return -1;
/* if n is 1, no stack popping is required */
if (n == 0) printf ("\tpop_stacktop\n");
return (n == 0)? emit_byte_instruction (stix, BCODE_POP_STACKTOP): 0;
if (n == 0)
{
DBGOUT_COMP_0("\tpop_stacktop");
return emit_byte_instruction (stix, BCODE_POP_STACKTOP);
}
return 0;
}
}