diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-19 12:35:27 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-19 12:35:27 +0100 |
| commit | b80d7aad1b001479942c314690e6979d8290bdfb (patch) | |
| tree | 45e53f1aca73e38b6bfc42e803e310906a163065 /miscutils | |
| parent | d6e24bd795d5d1d00c2414efe2e5d9e1152c5f5b (diff) | |
| download | busybox-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>
Diffstat (limited to 'miscutils')
| -rw-r--r-- | miscutils/bc.c | 77 |
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 |
| 174 | static uint8_t lex_indent; | 175 | static 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 | ||
| 3449 | static void bc_parse_push(BcParse *p, char i) | 3456 | static 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) | |||
| 5824 | static BC_STATUS zbc_program_call(char *code, size_t *idx) | 5831 | static 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 | } |
