aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-19 12:35:27 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-19 12:35:27 +0100
commitb80d7aad1b001479942c314690e6979d8290bdfb (patch)
tree45e53f1aca73e38b6bfc42e803e310906a163065
parentd6e24bd795d5d1d00c2414efe2e5d9e1152c5f5b (diff)
downloadbusybox-w32-b80d7aad1b001479942c314690e6979d8290bdfb.tar.gz
busybox-w32-b80d7aad1b001479942c314690e6979d8290bdfb.tar.bz2
busybox-w32-b80d7aad1b001479942c314690e6979d8290bdfb.zip
bc: in execution loop, reload stack only after insts which can change it
Only these functions affect G.prog.exestack: zbc_program_read zbc_program_call zbc_program_return zbc_program_nquit zbc_program_execStr function old new delta zbc_program_exec 3995 4093 +98 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/0 up/down: 98/0) Total: 98 bytes text data bss dec hex filename 981364 485 7296 989145 f17d9 busybox_old 981462 485 7296 989243 f183b busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/bc.c77
1 files changed, 44 insertions, 33 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 7ddae341f..92bf1df57 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -167,8 +167,9 @@
167# include "dc.c" 167# include "dc.c"
168#else 168#else
169 169
170#define DEBUG_LEXER 0 170#define DEBUG_LEXER 0
171#define DEBUG_EXEC 0 171#define DEBUG_COMPILE 0
172#define DEBUG_EXEC 0
172 173
173#if DEBUG_LEXER 174#if DEBUG_LEXER
174static uint8_t lex_indent; 175static uint8_t lex_indent;
@@ -193,6 +194,12 @@ static uint8_t lex_indent;
193# define dbg_lex_done(...) ((void)0) 194# define dbg_lex_done(...) ((void)0)
194#endif 195#endif
195 196
197#if DEBUG_COMPILE
198# define dbg_compile(...) bb_error_msg(__VA_ARGS__)
199#else
200# define dbg_compile(...) ((void)0)
201#endif
202
196#if DEBUG_EXEC 203#if DEBUG_EXEC
197# define dbg_exec(...) bb_error_msg(__VA_ARGS__) 204# define dbg_exec(...) bb_error_msg(__VA_ARGS__)
198#else 205#else
@@ -683,7 +690,7 @@ typedef struct BcProgram {
683#endif 690#endif
684 691
685 BcVec results; 692 BcVec results;
686 BcVec stack; 693 BcVec exestack;
687 694
688 BcVec fns; 695 BcVec fns;
689 BcVec fn_map; 696 BcVec fn_map;
@@ -3448,7 +3455,7 @@ static void bc_parse_addFunc(BcParse *p, char *name, size_t *idx)
3448 3455
3449static void bc_parse_push(BcParse *p, char i) 3456static void bc_parse_push(BcParse *p, char i)
3450{ 3457{
3451 dbg_lex("%s:%d pushing opcode %d", __func__, __LINE__, i); 3458 dbg_compile("%s:%d pushing bytecode %zd:%d", __func__, __LINE__, p->func->code.len, i);
3452 bc_vec_pushByte(&p->func->code, i); 3459 bc_vec_pushByte(&p->func->code, i);
3453} 3460}
3454 3461
@@ -3537,11 +3544,11 @@ static void bc_program_reset(void)
3537 BcFunc *f; 3544 BcFunc *f;
3538 BcInstPtr *ip; 3545 BcInstPtr *ip;
3539 3546
3540 bc_vec_npop(&G.prog.stack, G.prog.stack.len - 1); 3547 bc_vec_npop(&G.prog.exestack, G.prog.exestack.len - 1);
3541 bc_vec_pop_all(&G.prog.results); 3548 bc_vec_pop_all(&G.prog.results);
3542 3549
3543 f = bc_program_func(0); 3550 f = bc_program_func(0);
3544 ip = bc_vec_top(&G.prog.stack); 3551 ip = bc_vec_top(&G.prog.exestack);
3545 ip->idx = f->code.len; 3552 ip->idx = f->code.len;
3546} 3553}
3547 3554
@@ -5145,7 +5152,7 @@ static BC_STATUS zbc_program_read(void)
5145 f = bc_program_func(BC_PROG_READ); 5152 f = bc_program_func(BC_PROG_READ);
5146 5153
5147 bc_vec_pushByte(&f->code, BC_INST_POP_EXEC); 5154 bc_vec_pushByte(&f->code, BC_INST_POP_EXEC);
5148 bc_vec_push(&G.prog.stack, &ip); 5155 bc_vec_push(&G.prog.exestack, &ip);
5149 exec_err: 5156 exec_err:
5150 bc_parse_free(&parse); 5157 bc_parse_free(&parse);
5151 G.in_read = 0; 5158 G.in_read = 0;
@@ -5824,12 +5831,13 @@ static BC_STATUS zbc_program_incdec(char inst)
5824static BC_STATUS zbc_program_call(char *code, size_t *idx) 5831static BC_STATUS zbc_program_call(char *code, size_t *idx)
5825{ 5832{
5826 BcInstPtr ip; 5833 BcInstPtr ip;
5827 size_t i, nparams = bc_program_index(code, idx); 5834 size_t i, nparams;
5828 BcFunc *func; 5835 BcFunc *func;
5829 BcId *a; 5836 BcId *a;
5830 BcResultData param; 5837 BcResultData param;
5831 BcResult *arg; 5838 BcResult *arg;
5832 5839
5840 nparams = bc_program_index(code, idx);
5833 ip.idx = 0; 5841 ip.idx = 0;
5834 ip.func = bc_program_index(code, idx); 5842 ip.func = bc_program_index(code, idx);
5835 func = bc_program_func(ip.func); 5843 func = bc_program_func(ip.func);
@@ -5870,7 +5878,7 @@ static BC_STATUS zbc_program_call(char *code, size_t *idx)
5870 } 5878 }
5871 } 5879 }
5872 5880
5873 bc_vec_push(&G.prog.stack, &ip); 5881 bc_vec_push(&G.prog.exestack, &ip);
5874 5882
5875 RETURN_STATUS(BC_STATUS_SUCCESS); 5883 RETURN_STATUS(BC_STATUS_SUCCESS);
5876} 5884}
@@ -5881,7 +5889,7 @@ static BC_STATUS zbc_program_return(char inst)
5881 BcResult res; 5889 BcResult res;
5882 BcFunc *f; 5890 BcFunc *f;
5883 size_t i; 5891 size_t i;
5884 BcInstPtr *ip = bc_vec_top(&G.prog.stack); 5892 BcInstPtr *ip = bc_vec_top(&G.prog.exestack);
5885 5893
5886 if (!BC_PROG_STACK(&G.prog.results, ip->len + inst == BC_INST_RET)) 5894 if (!BC_PROG_STACK(&G.prog.results, ip->len + inst == BC_INST_RET))
5887 RETURN_STATUS(bc_error_stack_has_too_few_elements()); 5895 RETURN_STATUS(bc_error_stack_has_too_few_elements());
@@ -5914,7 +5922,7 @@ static BC_STATUS zbc_program_return(char inst)
5914 5922
5915 bc_vec_npop(&G.prog.results, G.prog.results.len - ip->len); 5923 bc_vec_npop(&G.prog.results, G.prog.results.len - ip->len);
5916 bc_vec_push(&G.prog.results, &res); 5924 bc_vec_push(&G.prog.results, &res);
5917 bc_vec_pop(&G.prog.stack); 5925 bc_vec_pop(&G.prog.exestack);
5918 5926
5919 RETURN_STATUS(BC_STATUS_SUCCESS); 5927 RETURN_STATUS(BC_STATUS_SUCCESS);
5920} 5928}
@@ -6184,13 +6192,13 @@ static BC_STATUS zbc_program_nquit(void)
6184 6192
6185 bc_vec_pop(&G.prog.results); 6193 bc_vec_pop(&G.prog.results);
6186 6194
6187 if (G.prog.stack.len < val) 6195 if (G.prog.exestack.len < val)
6188 RETURN_STATUS(bc_error_stack_has_too_few_elements()); 6196 RETURN_STATUS(bc_error_stack_has_too_few_elements());
6189 if (G.prog.stack.len == val) { 6197 if (G.prog.exestack.len == val) {
6190 QUIT_OR_RETURN_TO_MAIN; 6198 QUIT_OR_RETURN_TO_MAIN;
6191 } 6199 }
6192 6200
6193 bc_vec_npop(&G.prog.stack, val); 6201 bc_vec_npop(&G.prog.exestack, val);
6194 6202
6195 RETURN_STATUS(s); 6203 RETURN_STATUS(s);
6196} 6204}
@@ -6283,7 +6291,7 @@ static BC_STATUS zbc_program_execStr(char *code, size_t *bgn, bool cond)
6283 ip.func = fidx; 6291 ip.func = fidx;
6284 6292
6285 bc_vec_pop(&G.prog.results); 6293 bc_vec_pop(&G.prog.results);
6286 bc_vec_push(&G.prog.stack, &ip); 6294 bc_vec_push(&G.prog.exestack, &ip);
6287 6295
6288 RETURN_STATUS(BC_STATUS_SUCCESS); 6296 RETURN_STATUS(BC_STATUS_SUCCESS);
6289 err: 6297 err:
@@ -6348,15 +6356,16 @@ static BC_STATUS zbc_program_exec(void)
6348{ 6356{
6349 BcResult r, *ptr; 6357 BcResult r, *ptr;
6350 BcNum *num; 6358 BcNum *num;
6351 BcInstPtr *ip = bc_vec_top(&G.prog.stack); 6359 BcInstPtr *ip = bc_vec_top(&G.prog.exestack);
6352 BcFunc *func = bc_program_func(ip->func); 6360 BcFunc *func = bc_program_func(ip->func);
6353 char *code = func->code.v; 6361 char *code = func->code.v;
6354 6362
6363 dbg_exec("func:%zd bytes:%zd ip:%zd", ip->func, func->code.len, ip->idx);
6355 while (ip->idx < func->code.len) { 6364 while (ip->idx < func->code.len) {
6356 BcStatus s = BC_STATUS_SUCCESS; 6365 BcStatus s = BC_STATUS_SUCCESS;
6357 char inst = code[(ip->idx)++]; 6366 char inst = code[ip->idx++];
6358 6367
6359 dbg_exec("inst:%d", inst); 6368 dbg_exec("inst at %zd:%d", ip->idx - 1, inst);
6360 switch (inst) { 6369 switch (inst) {
6361#if ENABLE_BC 6370#if ENABLE_BC
6362 case BC_INST_JUMP_ZERO: { 6371 case BC_INST_JUMP_ZERO: {
@@ -6382,7 +6391,7 @@ static BC_STATUS zbc_program_exec(void)
6382 case BC_INST_CALL: 6391 case BC_INST_CALL:
6383 dbg_exec("BC_INST_CALL:"); 6392 dbg_exec("BC_INST_CALL:");
6384 s = zbc_program_call(code, &ip->idx); 6393 s = zbc_program_call(code, &ip->idx);
6385 break; 6394 goto read_updated_ip;
6386 case BC_INST_INC_PRE: 6395 case BC_INST_INC_PRE:
6387 case BC_INST_DEC_PRE: 6396 case BC_INST_DEC_PRE:
6388 case BC_INST_INC_POST: 6397 case BC_INST_INC_POST:
@@ -6398,7 +6407,7 @@ static BC_STATUS zbc_program_exec(void)
6398 case BC_INST_RET0: 6407 case BC_INST_RET0:
6399 dbg_exec("BC_INST_RET[0]:"); 6408 dbg_exec("BC_INST_RET[0]:");
6400 s = zbc_program_return(inst); 6409 s = zbc_program_return(inst);
6401 break; 6410 goto read_updated_ip;
6402 case BC_INST_BOOL_OR: 6411 case BC_INST_BOOL_OR:
6403 case BC_INST_BOOL_AND: 6412 case BC_INST_BOOL_AND:
6404#endif // ENABLE_BC 6413#endif // ENABLE_BC
@@ -6414,7 +6423,7 @@ static BC_STATUS zbc_program_exec(void)
6414 case BC_INST_READ: 6423 case BC_INST_READ:
6415 dbg_exec("BC_INST_READ:"); 6424 dbg_exec("BC_INST_READ:");
6416 s = zbc_program_read(); 6425 s = zbc_program_read();
6417 break; 6426 goto read_updated_ip;
6418 case BC_INST_VAR: 6427 case BC_INST_VAR:
6419 dbg_exec("BC_INST_VAR:"); 6428 dbg_exec("BC_INST_VAR:");
6420 s = zbc_program_pushVar(code, &ip->idx, false, false); 6429 s = zbc_program_pushVar(code, &ip->idx, false, false);
@@ -6454,7 +6463,7 @@ static BC_STATUS zbc_program_exec(void)
6454 break; 6463 break;
6455 case BC_INST_POP_EXEC: 6464 case BC_INST_POP_EXEC:
6456 dbg_exec("BC_INST_POP_EXEC:"); 6465 dbg_exec("BC_INST_POP_EXEC:");
6457 bc_vec_pop(&G.prog.stack); 6466 bc_vec_pop(&G.prog.exestack);
6458 break; 6467 break;
6459 case BC_INST_PRINT: 6468 case BC_INST_PRINT:
6460 case BC_INST_PRINT_POP: 6469 case BC_INST_PRINT_POP:
@@ -6513,7 +6522,7 @@ static BC_STATUS zbc_program_exec(void)
6513 case BC_INST_EXECUTE: 6522 case BC_INST_EXECUTE:
6514 case BC_INST_EXEC_COND: 6523 case BC_INST_EXEC_COND:
6515 s = zbc_program_execStr(code, &ip->idx, inst == BC_INST_EXEC_COND); 6524 s = zbc_program_execStr(code, &ip->idx, inst == BC_INST_EXEC_COND);
6516 break; 6525 goto read_updated_ip;
6517 case BC_INST_PRINT_STACK: { 6526 case BC_INST_PRINT_STACK: {
6518 size_t idx; 6527 size_t idx;
6519 for (idx = 0; idx < G.prog.results.len; ++idx) { 6528 for (idx = 0; idx < G.prog.results.len; ++idx) {
@@ -6566,14 +6575,20 @@ static BC_STATUS zbc_program_exec(void)
6566 } 6575 }
6567 case BC_INST_QUIT: 6576 case BC_INST_QUIT:
6568 dbg_exec("BC_INST_NEG:"); 6577 dbg_exec("BC_INST_NEG:");
6569 if (G.prog.stack.len <= 2) 6578 if (G.prog.exestack.len <= 2)
6570 QUIT_OR_RETURN_TO_MAIN; 6579 QUIT_OR_RETURN_TO_MAIN;
6571 bc_vec_npop(&G.prog.stack, 2); 6580 bc_vec_npop(&G.prog.exestack, 2);
6572 break; 6581 break;
6573 case BC_INST_NQUIT: 6582 case BC_INST_NQUIT:
6574 s = zbc_program_nquit(); 6583 s = zbc_program_nquit();
6575 break; 6584 //goto read_updated_ip; - just fall through to it
6576#endif // ENABLE_DC 6585#endif // ENABLE_DC
6586 read_updated_ip:
6587 // Instruction stack has changed, read new pointers
6588 ip = bc_vec_top(&G.prog.exestack);
6589 func = bc_program_func(ip->func);
6590 code = func->code.v;
6591 dbg_exec("func:%zd bytes:%zd ip:%zd", ip->func, func->code.len, ip->idx);
6577 } 6592 }
6578 6593
6579 if (s || G_interrupt) { 6594 if (s || G_interrupt) {
@@ -6583,10 +6598,6 @@ static BC_STATUS zbc_program_exec(void)
6583 6598
6584 fflush_and_check(); 6599 fflush_and_check();
6585 6600
6586 // If the stack has changed, pointers may be invalid.
6587 ip = bc_vec_top(&G.prog.stack);
6588 func = bc_program_func(ip->func);
6589 code = func->code.v;
6590 } 6601 }
6591 6602
6592 RETURN_STATUS(BC_STATUS_SUCCESS); 6603 RETURN_STATUS(BC_STATUS_SUCCESS);
@@ -6957,7 +6968,7 @@ static void bc_program_free(void)
6957 bc_vec_free(&G.prog.strs); 6968 bc_vec_free(&G.prog.strs);
6958 bc_vec_free(&G.prog.consts); 6969 bc_vec_free(&G.prog.consts);
6959 bc_vec_free(&G.prog.results); 6970 bc_vec_free(&G.prog.results);
6960 bc_vec_free(&G.prog.stack); 6971 bc_vec_free(&G.prog.exestack);
6961 bc_num_free(&G.prog.last); 6972 bc_num_free(&G.prog.last);
6962 bc_num_free(&G.prog.zero); 6973 bc_num_free(&G.prog.zero);
6963 bc_num_free(&G.prog.one); 6974 bc_num_free(&G.prog.one);
@@ -7009,8 +7020,8 @@ static void bc_program_init(void)
7009 bc_vec_init(&G.prog.strs, sizeof(char *), bc_string_free); 7020 bc_vec_init(&G.prog.strs, sizeof(char *), bc_string_free);
7010 bc_vec_init(&G.prog.consts, sizeof(char *), bc_string_free); 7021 bc_vec_init(&G.prog.consts, sizeof(char *), bc_string_free);
7011 bc_vec_init(&G.prog.results, sizeof(BcResult), bc_result_free); 7022 bc_vec_init(&G.prog.results, sizeof(BcResult), bc_result_free);
7012 bc_vec_init(&G.prog.stack, sizeof(BcInstPtr), NULL); 7023 bc_vec_init(&G.prog.exestack, sizeof(BcInstPtr), NULL);
7013 bc_vec_push(&G.prog.stack, &ip); 7024 bc_vec_push(&G.prog.exestack, &ip);
7014 7025
7015 bc_char_vec_init(&G.input_buffer); 7026 bc_char_vec_init(&G.input_buffer);
7016} 7027}