diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-05-07 21:43:43 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-05-07 21:43:43 +0300 |
commit | 615b68377fcf7f7e70bfa0f31aea917fe1cf0903 (patch) | |
tree | b39a17a079580066bfc1f7eb67875f3eb7e77901 | |
parent | 2a963ce202911085c98dac7628150f4a56ee1295 (diff) | |
download | mailfromd-615b68377fcf7f7e70bfa0f31aea917fe1cf0903.tar.gz mailfromd-615b68377fcf7f7e70bfa0f31aea917fe1cf0903.tar.bz2 |
Fix exception handling code (saveex/restex).
* mfd/drivers.c (code_type_funcdecl): Exmask handling
and jump fixups are handled within codegen.
(code_type_progdecl): Update call to codegen.
* mfd/gram.y (codegen): Take an extra argument specifying
the exception mask to handle. Unless it is zero, code
saveex/restex pair around the main code. This makes sure
local allocations do not disturb exception handling code.
Also, take care of jump fixup here.
(mailfromd_test): Fix bug in numeric argument passing.
* mfd/prog.c (instr_saveex): Provide additional debugging
diagnostics (temporary).
(dump_saveex): Fix retrieving of the exmask (seftover
from earlier version).
(instr_memstk, instr_xmemstk, instr_deref)
(instr_ston, instr_ntos, instr_cmp)
(instr_logand, instr_logor, instr_logxor)
(instr_add, instr_sub, instr_mul)
(instr_div, instr_regex, instr_regcomp)
(instr_funcall): Make sure PC and stack adjustments
occur after outputting trace info.
-rw-r--r-- | mfd/drivers.c | 19 | ||||
-rw-r--r-- | mfd/gram.y | 52 | ||||
-rw-r--r-- | mfd/prog.c | 62 |
3 files changed, 77 insertions, 56 deletions
diff --git a/mfd/drivers.c b/mfd/drivers.c index bb6d9e09..d8dfb4b2 100644 --- a/mfd/drivers.c +++ b/mfd/drivers.c @@ -2312,17 +2312,4 @@ code_type_funcdecl(NODE *node, struct locus **old_locus) - /* Entry code */ - if (func->exmask) { - code_op(opcode_saveex); - code_immediate((void*)func->exmask); - } - - if (codegen(&pc, node->v.funcdecl.tree, 0, - node->v.funcdecl.auto_count) == 0) { - jump_fixup(jump_pc, code_get_counter()); - - /* Exit code */ - if (func->exmask) - code_op(opcode_restex); - code_op(opcode_return); - } + codegen(&pc, node->v.funcdecl.tree, func->exmask, 0, + node->v.funcdecl.auto_count); } @@ -2361,3 +2348,3 @@ code_type_progdecl(NODE *node, struct locus **old_locus) if (codegen(&entry_point[tag], - node->v.progdecl.tree, 1, + node->v.progdecl.tree, 0, 1, node->v.progdecl.auto_count) == 0) @@ -35,4 +35,4 @@ static void free_node(NODE *node); static void set_poll_arg(struct poll_data *poll, int kw, NODE *expr); -static int codegen(prog_counter_t *pc, NODE *node, int finalize, - size_t nautos); +static int codegen(prog_counter_t *pc, NODE *node, unsigned exmask, + int finalize, size_t nautos); static void mark(NODE *node); @@ -2617,16 +2617,30 @@ mark(NODE *node) static int -codegen(prog_counter_t *pc, NODE *node, int finalize, size_t nautos) +codegen(prog_counter_t *pc, NODE *node, unsigned exmask, + int finalize, size_t nautos) { - if (error_count == 0) { - *pc = code_get_counter(); - jump_pc = 0; - if (nautos) { - code_op(opcode_stkalloc); - code_immediate((void*)nautos); - } - traverse_tree(node); - if (finalize) - code_op(opcode_nil); + if (error_count) + return 1; + + *pc = code_get_counter(); + jump_pc = 0; + if (nautos) { + code_op(opcode_stkalloc); + code_immediate((void*)nautos); } - return error_count; + if (exmask) { + code_op(opcode_saveex); + code_immediate((void*) exmask); + } + traverse_tree(node); + + jump_fixup(jump_pc, code_get_counter()); + if (exmask) + code_op(opcode_restex); + + if (finalize) + code_op(opcode_nil); + else + code_op(opcode_return); + + return 0; } @@ -3136,5 +3150,9 @@ mailfromd_test(int argc, char **argv) case dtype_number: - n = strtol(p, &end, 0); - if (*end) - mu_error(_("$%d is not a number"), i+1); + if (args[i]) { + n = strtol(args[i], &end, 0); + if (*end) + mu_error(_("$%d is not a number"), + i+1); + } else + n = 0; env_push_number(env, n); @@ -756,3 +756,3 @@ instr_memstk(eval_environ_t env) size_t val = env_base(env, frame) + off; - advance_pc(env, 2); + if (PROG_TRACE_ENGINE) @@ -761,2 +761,3 @@ instr_memstk(eval_environ_t env) (unsigned long) val); + advance_pc(env, 2); push(env, (STKVAL) val); @@ -776,3 +777,3 @@ instr_xmemstk(eval_environ_t env) size_t val = env_base(env, frame) + off; - adjust_stack(env, 2); + if (PROG_TRACE_ENGINE) @@ -781,2 +782,3 @@ instr_xmemstk(eval_environ_t env) (unsigned long) val); + adjust_stack(env, 2); push(env, (STKVAL) val); @@ -789,3 +791,3 @@ instr_deref(eval_environ_t env) STKVAL val = env->dataseg[off]; - adjust_stack(env, 1); + if (PROG_TRACE_ENGINE) @@ -794,2 +796,3 @@ instr_deref(eval_environ_t env) (unsigned long) val, val); + adjust_stack(env, 1); push(env, val); @@ -874,5 +877,5 @@ instr_ston(eval_environ_t env) - adjust_stack(env, 1); if (PROG_TRACE_ENGINE) prog_trace(env, "STON %s", s); + adjust_stack(env, 1); if (*p) @@ -891,5 +894,5 @@ instr_ntos(eval_environ_t env) - adjust_stack(env, 1); if (PROG_TRACE_ENGINE) prog_trace(env, "NTOS %ld", v); + adjust_stack(env, 1); @@ -905,5 +908,6 @@ instr_cmp(eval_environ_t env) long r = (long) get_arg(env, 0); - adjust_stack(env, 2); + if (PROG_TRACE_ENGINE) prog_trace(env, "CMP %ld %ld", l, r); + adjust_stack(env, 2); push(env, (STKVAL) (l == r)); @@ -1146,5 +1150,5 @@ instr_logand(eval_environ_t env) unsigned long b = (unsigned long) get_arg(env, 0); - adjust_stack(env, 2); if (PROG_TRACE_ENGINE) prog_trace(env, "LOGAND %lu %lu", a, b); + adjust_stack(env, 2); push(env, (STKVAL) (a & b)); @@ -1157,5 +1161,5 @@ instr_logor(eval_environ_t env) unsigned long b = (unsigned long) get_arg(env, 0); - adjust_stack(env, 2); if (PROG_TRACE_ENGINE) prog_trace(env, "LOGOR %lu %lu", a, b); + adjust_stack(env, 2); push(env, (STKVAL) (a | b)); @@ -1168,5 +1172,5 @@ instr_logxor(eval_environ_t env) unsigned long b = (unsigned long) get_arg(env, 0); - adjust_stack(env, 2); if (PROG_TRACE_ENGINE) prog_trace(env, "LOGXOR %lu %lu", a, b); + adjust_stack(env, 2); push(env, (STKVAL) (a ^ b)); @@ -1190,5 +1194,5 @@ instr_add(eval_environ_t env) long b = (long) get_arg(env, 0); - adjust_stack(env, 2); if (PROG_TRACE_ENGINE) prog_trace(env, "ADD %ld %ld", a, b); + adjust_stack(env, 2); push(env, (STKVAL) (a + b)); @@ -1201,5 +1205,5 @@ instr_sub(eval_environ_t env) long b = (long) get_arg(env, 0); - adjust_stack(env, 2); if (PROG_TRACE_ENGINE) prog_trace(env, "SUB %ld %ld", a, b); + adjust_stack(env, 2); push(env, (STKVAL) (a - b)); @@ -1212,5 +1216,5 @@ instr_mul(eval_environ_t env) long b = (long) get_arg(env, 0); - adjust_stack(env, 2); if (PROG_TRACE_ENGINE) prog_trace(env, "MUL %ld %ld", a, b); + adjust_stack(env, 2); push(env, (STKVAL) (a * b)); @@ -1223,5 +1227,5 @@ instr_div(eval_environ_t env) long b = (long) get_arg(env, 0); - adjust_stack(env, 2); if (PROG_TRACE_ENGINE) prog_trace(env, "DIV %ld %ld", a, b); + adjust_stack(env, 2); if (b == 0) @@ -1251,3 +1255,3 @@ instr_regex(eval_environ_t env) size_t index = (size_t) get_immediate(env, 0); - advance_pc(env, 1); + if (PROG_TRACE_ENGINE) @@ -1258,2 +1262,3 @@ instr_regex(eval_environ_t env) (char*) env_data_ref(env, regtab[index].expr)); + advance_pc(env, 1); push(env, (STKVAL) index); @@ -1316,5 +1321,2 @@ instr_regcomp(eval_environ_t env) - advance_pc(env, 1); - adjust_stack(env, 1); - if (PROG_TRACE_ENGINE) @@ -1324,2 +1326,6 @@ instr_regcomp(eval_environ_t env) expr); + + advance_pc(env, 1); + adjust_stack(env, 1); + if (rtx->compiled) { @@ -1673,9 +1679,15 @@ instr_saveex(eval_environ_t env) int i; - advance_pc(env, 1); + if (PROG_TRACE_ENGINE) prog_trace(env, "SAVEEX %x", exmask); - push(env, (STKVAL) exmask); + + advance_pc(env, 1); for (i = 0; i < mf_exception_count; i++) - if (EXMASK(i) & exmask) + if (EXMASK(i) & exmask) { + debug3(101, "Push Exception: %d %lu <- %lu", + i, (unsigned long) env->tos, + (unsigned long) env->catch[i]); push(env, (STKVAL) env->catch[i]); + } + push(env, (STKVAL) exmask); } @@ -1691,3 +1703,3 @@ instr_restex(eval_environ_t env) { - unsigned exmask = (unsigned)env->dataseg[env->base]; + unsigned exmask = (unsigned) pop(env); int i; @@ -1697,4 +1709,8 @@ instr_restex(eval_environ_t env) for (i = mf_exception_count-1; i >= 0; i--) - if (EXMASK(i) & exmask) + if (EXMASK(i) & exmask) { env->catch[i] = (prog_counter_t) pop(env); + debug3(102, "Pop Exception: %d %lu -> %lu", + i, (unsigned long) env->tos, + (unsigned long) env->catch[i]); + } } @@ -1733,5 +1749,5 @@ instr_funcall(eval_environ_t env) get_literal(env, 0, &name); - advance_pc(env, 2); if (PROG_TRACE_ENGINE) prog_trace(env, "FUNCALL %s (%lu)", name, (unsigned long)pc); + advance_pc(env, 2); env_make_frame(env); |