diff options
author | Denys Vlasenko | 2018-12-21 20:29:34 +0100 |
---|---|---|
committer | Denys Vlasenko | 2018-12-21 20:29:34 +0100 |
commit | 19eee8ed7cf32de37afa53ce56c62376c880a5a8 (patch) | |
tree | 7a7e952d4f28af8b9ab7361093d40ac3a935c3ba /miscutils/bc.c | |
parent | 5d57bc442dfebefdd7db37c04fe2c9f1343bd08d (diff) | |
download | busybox-19eee8ed7cf32de37afa53ce56c62376c880a5a8.zip busybox-19eee8ed7cf32de37afa53ce56c62376c880a5a8.tar.gz |
bc: fix for() to not leave data on stack
function old new delta
zbc_parse_stmt_possibly_auto 1665 1697 +32
zbc_vm_process 672 701 +29
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 61/0) Total: 61 bytes
text data bss dec hex filename
981656 485 7296 989437 f18fd busybox_old
981748 485 7296 989529 f1959 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'miscutils/bc.c')
-rw-r--r-- | miscutils/bc.c | 48 |
1 files changed, 23 insertions, 25 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 50e5457..441cb04 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -170,6 +170,8 @@ #define DEBUG_LEXER 0 #define DEBUG_COMPILE 0 #define DEBUG_EXEC 0 +// This can be left enabled for production as well: +#define SANITY_CHECKS 1 #if DEBUG_LEXER static uint8_t lex_indent; @@ -1218,8 +1220,6 @@ static char** bc_program_const(size_t idx) IF_DC(return bc_vec_item(&G.prog.consts, idx);) } - - static int bc_id_cmp(const void *e1, const void *e2) { return strcmp(((const BcId *) e1)->name, ((const BcId *) e2)->name); @@ -4227,12 +4227,15 @@ static BC_STATUS zbc_parse_for(BcParse *p) s = zbc_lex_next(&p->l); if (s) RETURN_STATUS(s); - if (p->l.t.t != BC_LEX_SCOLON) + if (p->l.t.t != BC_LEX_SCOLON) { s = zbc_parse_expr(p, 0); - else + bc_parse_push(p, BC_INST_POP); + if (s) RETURN_STATUS(s); + } else { s = bc_POSIX_does_not_allow_empty_X_expression_in_for("init"); + IF_ERROR_RETURN_POSSIBLE(if (s) RETURN_STATUS(s);) + } - if (s) RETURN_STATUS(s); if (p->l.t.t != BC_LEX_SCOLON) RETURN_STATUS(bc_error_bad_token()); s = zbc_lex_next(&p->l); if (s) RETURN_STATUS(s); @@ -4254,8 +4257,8 @@ static BC_STATUS zbc_parse_for(BcParse *p) bc_parse_pushNUM(p); s = bc_POSIX_does_not_allow_empty_X_expression_in_for("condition"); } - if (s) RETURN_STATUS(s); + if (p->l.t.t != BC_LEX_SCOLON) RETURN_STATUS(bc_error_bad_token()); s = zbc_lex_next(&p->l); @@ -4267,12 +4270,14 @@ static BC_STATUS zbc_parse_for(BcParse *p) bc_vec_push(&p->conds, &update_idx); bc_vec_push(&p->func->labels, &p->func->code.len); - if (p->l.t.t != BC_LEX_RPAREN) + if (p->l.t.t != BC_LEX_RPAREN) { s = zbc_parse_expr(p, 0); - else + bc_parse_push(p, BC_INST_POP); + if (s) RETURN_STATUS(s); + } else { s = bc_POSIX_does_not_allow_empty_X_expression_in_for("update"); - - if (s) RETURN_STATUS(s); + IF_ERROR_RETURN_POSSIBLE(if (s) RETURN_STATUS(s);) + } if (p->l.t.t != BC_LEX_RPAREN) RETURN_STATUS(bc_error_bad_token()); bc_parse_pushJUMP(p, cond_idx); @@ -6434,12 +6439,13 @@ static BC_STATUS zbc_program_exec(void) BcFunc *func = bc_program_func(ip->func); char *code = func->code.v; - dbg_exec("func:%zd bytes:%zd ip:%zd", ip->func, func->code.len, ip->idx); + dbg_exec("func:%zd bytes:%zd ip:%zd results.len:%d", + ip->func, func->code.len, ip->idx, G.prog.results.len); while (ip->idx < func->code.len) { BcStatus s = BC_STATUS_SUCCESS; char inst = code[ip->idx++]; - dbg_exec("inst at %zd:%d", ip->idx - 1, inst); + dbg_exec("inst at %zd:%d results.len:%d", ip->idx - 1, inst, G.prog.results.len); switch (inst) { #if ENABLE_BC case BC_INST_JUMP_ZERO: { @@ -6671,7 +6677,6 @@ static BC_STATUS zbc_program_exec(void) } fflush_and_check(); - } RETURN_STATUS(BC_STATUS_SUCCESS); @@ -6723,23 +6728,16 @@ static BC_STATUS zbc_vm_process(const char *text) // storage. if (IS_BC) { BcFunc *f; - BcInstPtr *ip; - - //FIXME: this does not clear up the stack - //for(i=1; i<3; i++) { - // i - // if(i==2) continue - // 77 - //} -// if (G.prog.results.len != 0) -// bb_error_msg_and_die("data stack not empty: %d slots", G.prog.results.len); + BcInstPtr *ip = (void*)G.prog.exestack.v; +#if SANITY_CHECKS + if (G.prog.results.len != 0) + bb_error_msg_and_die("data stack not empty: %d slots", G.prog.results.len); if (G.prog.exestack.len != 1) // should be empty bb_error_msg_and_die("BUG:call stack"); - - ip = (void*)G.prog.exestack.v; if (ip->func != BC_PROG_MAIN) bb_error_msg_and_die("BUG:not MAIN"); +#endif //bb_error_msg("ip->func:%d >idx:%d >len:%d", ip->func, ip->idx, ip->len); f = bc_program_func_BC_PROG_MAIN(); //bb_error_msg("MAIN->code.len:%d >strs.len:%d >consts.len:%d", f->code.len, f->strs.len, f->consts.len); // labels, autos, nparams |