Mercurial > hg-old > index.cgi
diff src/lwasm.c @ 77:a338d496350e
Checkpointing conversion to allow object target
author | lost |
---|---|
date | Fri, 09 Jan 2009 04:23:00 +0000 |
parents | 2fe5fd7d65a3 |
children | 121bf4a588ea |
line wrap: on
line diff
--- a/src/lwasm.c Thu Jan 08 02:57:24 2009 +0000 +++ b/src/lwasm.c Fri Jan 09 04:23:00 2009 +0000 @@ -216,7 +216,10 @@ se = lwasm_find_symbol(st -> as, sym, -1); debug_message(3, "lwasm_expr_lookup_symbol(): got '%p'", se); if (!se) + { + register_error(st -> as, st -> l, 2, "Undefined symbol '%s'", sym); return NULL; + } if (st -> as -> outformat != OUTPUT_OBJ || se -> sect == NULL || se -> sect == st -> as -> csect) { // global symbol, intrasegment reference, or not an object target @@ -258,6 +261,17 @@ return(lwasm_expr_eval(inp, outp, lwasm_expr_lookup_symbol, &st)); } + +int lwasm_reevaluate_expr(asmstate_t *as, lwasm_line_t *l, lwasm_expr_stack_t *s) +{ + struct symstateinfo st; + + st.as = as; + st.l = l; + + return(lwasm_expr_reval(s, lwasm_expr_lookup_symbol, &st)); +} + // return 1 if no undefined symbols (externals and incompletes are okay) // return 0 if there are undefined symbols int lwasm_expr_result_ckconst(asmstate_t *as, lwasm_expr_stack_t *s) @@ -265,6 +279,14 @@ lwasm_expr_stack_node_t *n; lwasm_symbol_ent_t *se; + if (as -> outformat != OUTPUT_OBJ) + { + if (lwasm_expr_is_constant(s)) + return 1; + else + return 0; + } + for (n = s -> head; n; n = n -> next) { if (n -> term -> term_type == LWASM_TERM_SYM) @@ -289,7 +311,13 @@ - a symbol defined in another section will remain unresolved - external references will also remain unresolved +EXPR_PASS2PASS will cause the result from pass 1 along with the offset to +the end of the expression to be stored in the line data. There can only be +one such expression per source line. In this case, the expression is parsed +and evaluated on pass 1 but the intermediate representation is re-evaluated +on pass 2. */ +/* int lwasm_expr_result(asmstate_t *as, lwasm_line_t *l, char **inp, int flag, int *val) { lwasm_expr_stack_t *s; @@ -305,22 +333,40 @@ } *inp = (char *)ep; - if (flag & EXPR_PASS1CONST && as -> passnum == 1 && !lwasm_expr_is_constant(s)) + if (flag & EXPR_PASS1CONST && as -> passnum == 1 && !lwasm_expr_result_ckconst(as, s)) { - register_error(as, l, 1, "Illegal incomplete reference (pass 1)"); + register_error(as, l, 1, "Undefined reference (pass 1)"); + *val = 0; + lwasm_expr_stack_free(s); + return -1; + } + if (flag & EXPR_PASS2CONST && as -> passnum == 2 && !lwasm_expr_result_ckconst(as, s)) + { + register_error(as, l, 2, "Undefined reference (pass 2)"); *val = 0; lwasm_expr_stack_free(s); return -1; } - if (flag & EXPR_PASS2CONST && as -> passnum == 2 && !lwasm_expr_is_constant(s)) + if (flag & EXPR_NOINTERSECT && !lwasm_expr_is_constant(s)) { - register_error(as, l, 2, "Incomplete reference (pass 2)"); - *val = 0; - lwasm_expr_stack_free(s); - return -1; + register_error(as, l, 2, "Invalid inter-section reference"); } *val = lwasm_expr_get_value(s); - lwasm_expr_stack_free(s); + if (l -> expr) + { + lwasm_expr_stack_free(l -> expr); + l -> expr = NULL; + } + if (lwasm_is_constant(s)) + { + // fully resolved value here + lwasm_expr_stack_free(s); + } + else + { + // incomplete reference here + l -> expr = s; + } if (flag & EXPR_BYTE && as -> passnum == 2 && (*val < -128 || *val > 255)) { @@ -335,6 +381,50 @@ return 0; } +*/ +int lwasm_expr_result2(asmstate_t *as, lwasm_line_t *l, char **inp, int flag, int *val, int slot) +{ + lwasm_expr_stack_t *s; + const char *ep; + int rval; + + if (as -> passnum == 1) + { + s = lwasm_evaluate_expr(as, l, *inp, &ep); + l -> exprs[slot] = s; + if (!s) + { + register_error(as, l, 1, "Bad expression"); + *val = 0; + return -1; + } + *inp = (char *)ep; + l -> exprends[slot] = *inp; + l -> exprvals[slot] = lwasm_expr_get_value(s); + } + else if (l -> exprs[slot]) + { + s = l -> exprs[slot]; + *inp = l -> exprends[slot]; + lwasm_reevaluate_expr(as, l, s); + l -> exprvals[slot] = lwasm_expr_get_value(s); + } + + if (s && lwasm_expr_is_constant(s)) + { + lwasm_expr_stack_free(s); + l -> exprs[slot] = NULL; + s = NULL; + } + + if (!s) + { + *val = l -> exprvals[slot]; + return 0; + } + + return 1; +} void debug_message(int level, const char *fmt, ...) {