diff options
Diffstat (limited to 'contrib/bc/src/vm.c')
-rw-r--r-- | contrib/bc/src/vm.c | 126 |
1 files changed, 92 insertions, 34 deletions
diff --git a/contrib/bc/src/vm.c b/contrib/bc/src/vm.c index e15b1398734e..3922b088414f 100644 --- a/contrib/bc/src/vm.c +++ b/contrib/bc/src/vm.c @@ -56,13 +56,15 @@ #endif // _WIN32 -#include <status.h> #include <vector.h> #include <args.h> #include <vm.h> #include <read.h> #include <bc.h> +char output_bufs[BC_VM_BUF_SIZE]; +BcVm vm; + #if BC_DEBUG_CODE BC_NORETURN void bc_vm_jmp(const char* f) { #else // BC_DEBUG_CODE @@ -84,12 +86,14 @@ BC_NORETURN void bc_vm_jmp(void) { assert(vm.jmp_bufs.len - (size_t) vm.sig_pop); #endif // NDEBUG + if (vm.jmp_bufs.len == 0) abort(); if (vm.sig_pop) bc_vec_pop(&vm.jmp_bufs); else vm.sig_pop = 1; siglongjmp(*((sigjmp_buf*) bc_vec_top(&vm.jmp_bufs)), 1); } +#if !BC_ENABLE_LIBRARY static void bc_vm_sig(int sig) { // There is already a signal in flight. @@ -132,8 +136,28 @@ void bc_vm_info(const char* const help) { bc_file_flush(&vm.fout); } +#endif // !BC_ENABLE_LIBRARY + +#if BC_ENABLE_LIBRARY +void bc_vm_handleError(BcErr e) { + + assert(e < BC_ERR_NELEMS); + assert(!vm.sig_pop); + + BC_SIG_LOCK; -void bc_vm_error(BcError e, size_t line, ...) { + if (e <= BC_ERR_MATH_DIVIDE_BY_ZERO) { + vm.err = (BclError) (e - BC_ERR_MATH_NEGATIVE + + BCL_ERROR_MATH_NEGATIVE); + } + else if (vm.abrt) abort(); + else if (e == BC_ERR_FATAL_ALLOC_ERR) vm.err = BCL_ERROR_FATAL_ALLOC_ERR; + else vm.err = BCL_ERROR_FATAL_UNKNOWN_ERR; + + BC_VM_JMP; +} +#else // BC_ENABLE_LIBRARY +void bc_vm_handleError(BcErr e, size_t line, ...) { BcStatus s; va_list args; @@ -141,11 +165,11 @@ void bc_vm_error(BcError e, size_t line, ...) { const char* err_type = vm.err_ids[id]; sig_atomic_t lock; - assert(e < BC_ERROR_NELEMS); + assert(e < BC_ERR_NELEMS); assert(!vm.sig_pop); #if BC_ENABLED - if (!BC_S && e >= BC_ERROR_POSIX_START) { + if (!BC_S && e >= BC_ERR_POSIX_START) { if (BC_W) { // Make sure to not return an error. id = UCHAR_MAX; @@ -261,7 +285,7 @@ static void bc_vm_envArgs(const char* const env_args_name) { buf += 1; start = buf; } - else if (instr) bc_vm_error(BC_ERROR_FATAL_OPTION, 0, start); + else if (instr) bc_vm_error(BC_ERR_FATAL_OPTION, 0, start); } else buf += 1; } @@ -293,6 +317,7 @@ static size_t bc_vm_envLen(const char *var) { return len; } +#endif // BC_ENABLE_LIBRARY void bc_vm_shutdown(void) { @@ -308,6 +333,7 @@ void bc_vm_shutdown(void) { #endif // BC_ENABLE_HISTORY #ifndef NDEBUG +#if !BC_ENABLE_LIBRARY bc_vec_free(&vm.env_args); free(vm.env_args_buffer); bc_vec_free(&vm.files); @@ -315,31 +341,40 @@ void bc_vm_shutdown(void) { bc_program_free(&vm.prog); bc_parse_free(&vm.prs); +#endif // !BC_ENABLE_LIBRARY - { - size_t i; - for (i = 0; i < vm.temps.len; ++i) - free(((BcNum*) bc_vec_item(&vm.temps, i))->num); - - bc_vec_free(&vm.temps); - } + bc_vm_freeTemps(); + bc_vec_free(&vm.temps); #endif // NDEBUG +#if !BC_ENABLE_LIBRARY bc_file_free(&vm.fout); bc_file_free(&vm.ferr); +#endif // !BC_ENABLE_LIBRARY } +#if !defined(NDEBUG) || BC_ENABLE_LIBRARY +void bc_vm_freeTemps(void) { + + size_t i; + + for (i = 0; i < vm.temps.len; ++i) { + free(((BcNum*) bc_vec_item(&vm.temps, i))->num); + } +} +#endif // !defined(NDEBUG) || BC_ENABLE_LIBRARY + inline size_t bc_vm_arraySize(size_t n, size_t size) { size_t res = n * size; if (BC_ERR(res >= SIZE_MAX || (n != 0 && res / n != size))) - bc_vm_err(BC_ERROR_FATAL_ALLOC_ERR); + bc_vm_err(BC_ERR_FATAL_ALLOC_ERR); return res; } inline size_t bc_vm_growSize(size_t a, size_t b) { size_t res = a + b; if (BC_ERR(res >= SIZE_MAX || res < a || res < b)) - bc_vm_err(BC_ERROR_FATAL_ALLOC_ERR); + bc_vm_err(BC_ERR_FATAL_ALLOC_ERR); return res; } @@ -351,7 +386,7 @@ void* bc_vm_malloc(size_t n) { ptr = malloc(n); - if (BC_ERR(ptr == NULL)) bc_vm_err(BC_ERROR_FATAL_ALLOC_ERR); + if (BC_ERR(ptr == NULL)) bc_vm_err(BC_ERR_FATAL_ALLOC_ERR); return ptr; } @@ -364,7 +399,7 @@ void* bc_vm_realloc(void *ptr, size_t n) { temp = realloc(ptr, n); - if (BC_ERR(temp == NULL)) bc_vm_err(BC_ERROR_FATAL_ALLOC_ERR); + if (BC_ERR(temp == NULL)) bc_vm_err(BC_ERR_FATAL_ALLOC_ERR); return temp; } @@ -377,11 +412,12 @@ char* bc_vm_strdup(const char *str) { s = strdup(str); - if (BC_ERR(!s)) bc_vm_err(BC_ERROR_FATAL_ALLOC_ERR); + if (BC_ERR(!s)) bc_vm_err(BC_ERR_FATAL_ALLOC_ERR); return s; } +#if !BC_ENABLE_LIBRARY void bc_vm_printf(const char *fmt, ...) { va_list args; @@ -396,12 +432,18 @@ void bc_vm_printf(const char *fmt, ...) { BC_SIG_UNLOCK; } +#endif // !BC_ENABLE_LIBRARY void bc_vm_putchar(int c) { +#if BC_ENABLE_LIBRARY + bc_vec_pushByte(&vm.out, (uchar) c); +#else // BC_ENABLE_LIBRARY bc_file_putchar(&vm.fout, (uchar) c); vm.nchars = (c == '\n' ? 0 : vm.nchars + 1); +#endif // BC_ENABLE_LIBRARY } +#if !BC_ENABLE_LIBRARY static void bc_vm_clean(void) { BcVec *fns = &vm.prog.fns; @@ -491,7 +533,7 @@ static void bc_vm_endif(void) { if (good) { while (BC_PARSE_IF_END(&vm.prs)) bc_vm_process("else {}"); } - else bc_parse_err(&vm.prs, BC_ERROR_PARSE_BLOCK); + else bc_parse_err(&vm.prs, BC_ERR_PARSE_BLOCK); } #endif // BC_ENABLED @@ -604,9 +646,9 @@ restart: if (!BC_STATUS_IS_ERROR(s)) { if (BC_ERR(comment)) - bc_parse_err(&vm.prs, BC_ERROR_PARSE_COMMENT); + bc_parse_err(&vm.prs, BC_ERR_PARSE_COMMENT); else if (BC_ERR(string)) - bc_parse_err(&vm.prs, BC_ERROR_PARSE_STRING); + bc_parse_err(&vm.prs, BC_ERR_PARSE_STRING); #if BC_ENABLED else if (BC_IS_BC) bc_vm_endif(); #endif // BC_ENABLED @@ -652,7 +694,7 @@ static void bc_vm_defaultMsgs(void) { for (i = 0; i < BC_ERR_IDX_NELEMS + BC_ENABLED; ++i) vm.err_ids[i] = bc_errs[i]; - for (i = 0; i < BC_ERROR_NELEMS; ++i) vm.err_msgs[i] = bc_err_msgs[i]; + for (i = 0; i < BC_ERR_NELEMS; ++i) vm.err_msgs[i] = bc_err_msgs[i]; } static void bc_vm_gettext(void) { @@ -683,7 +725,7 @@ static void bc_vm_gettext(void) { i = 0; id = bc_err_ids[i]; - for (set = id + 3, msg = 1; i < BC_ERROR_NELEMS; ++i, ++msg) { + for (set = id + 3, msg = 1; i < BC_ERR_NELEMS; ++i, ++msg) { if (id != bc_err_ids[i]) { msg = 1; @@ -775,8 +817,8 @@ err: #endif // NDEBUG } -void bc_vm_boot(int argc, char *argv[], const char *env_len, - const char* const env_args) +void bc_vm_boot(int argc, char *argv[], const char *env_len, + const char* const env_args) { int ttyin, ttyout, ttyerr; struct sigaction sa; @@ -803,10 +845,7 @@ void bc_vm_boot(int argc, char *argv[], const char *env_len, if (BC_TTY) sigaction(SIGHUP, &sa, NULL); #endif // BC_ENABLE_HISTORY - memcpy(vm.max_num, bc_num_bigdigMax, - bc_num_bigdigMax_size * sizeof(BcDig)); - bc_num_setup(&vm.max, vm.max_num, BC_NUM_BIGDIG_LOG10); - vm.max.len = bc_num_bigdigMax_size; + bc_vm_init(); vm.file = NULL; @@ -822,8 +861,6 @@ void bc_vm_boot(int argc, char *argv[], const char *env_len, bc_vec_clear(&vm.files); bc_vec_clear(&vm.exprs); - bc_vec_init(&vm.temps, sizeof(BcNum), NULL); - bc_program_init(&vm.prog); bc_parse_init(&vm.prs, &vm.prog, BC_PROG_MAIN); @@ -842,6 +879,27 @@ void bc_vm_boot(int argc, char *argv[], const char *env_len, if (BC_IS_POSIX) vm.flags &= ~(BC_FLAG_G); #endif // BC_ENABLED + BC_SIG_UNLOCK; + + bc_vm_exec(); +} +#endif // !BC_ENABLE_LIBRARY + +void bc_vm_init(void) { + + BC_SIG_ASSERT_LOCKED; + + memcpy(vm.max_num, bc_num_bigdigMax, + bc_num_bigdigMax_size * sizeof(BcDig)); + memcpy(vm.max2_num, bc_num_bigdigMax2, + bc_num_bigdigMax2_size * sizeof(BcDig)); + bc_num_setup(&vm.max, vm.max_num, BC_NUM_BIGDIG_LOG10); + bc_num_setup(&vm.max2, vm.max2_num, BC_NUM_BIGDIG_LOG10); + vm.max.len = bc_num_bigdigMax_size; + vm.max2.len = bc_num_bigdigMax2_size; + + bc_vec_init(&vm.temps, sizeof(BcNum), NULL); + vm.maxes[BC_PROG_GLOBALS_IBASE] = BC_NUM_MAX_POSIX_IBASE; vm.maxes[BC_PROG_GLOBALS_OBASE] = BC_MAX_OBASE; vm.maxes[BC_PROG_GLOBALS_SCALE] = BC_MAX_SCALE; @@ -851,11 +909,11 @@ void bc_vm_boot(int argc, char *argv[], const char *env_len, #endif // BC_ENABLE_EXTRA_MATH && BC_ENABLE_RAND #if BC_ENABLED +#if !BC_ENABLE_LIBRARY if (BC_IS_BC && !BC_IS_POSIX) +#endif // !BC_ENABLE_LIBRARY + { vm.maxes[BC_PROG_GLOBALS_IBASE] = BC_NUM_MAX_IBASE; + } #endif // BC_ENABLED - - BC_SIG_UNLOCK; - - bc_vm_exec(); } |