# HG changeset patch # User lost # Date 1231571354 0 # Node ID d0ce3f5f6797faa94aebb99649a0ca598d3d2777 # Parent 121bf4a588ea5061fa1d8e7f66cfc8b20b2d88bb Checkpointing deployment of non-constant expression handling diff -r 121bf4a588ea -r d0ce3f5f6797 src/lwasm.c --- a/src/lwasm.c Sat Jan 10 05:00:42 2009 +0000 +++ b/src/lwasm.c Sat Jan 10 07:09:14 2009 +0000 @@ -384,14 +384,15 @@ */ int lwasm_expr_result2(asmstate_t *as, lwasm_line_t *l, char **inp, int flag, int *val, int slot) { - lwasm_expr_stack_t *s; + lwasm_expr_stack_t *s = NULL; const char *ep; int rval; - if (as -> passnum == 1) + if (as -> passnum == 1 || slot < 0) { s = lwasm_evaluate_expr(as, l, *inp, &ep); - l -> exprs[slot] = s; + if (slot >= 0) + l -> exprs[slot] = s; if (!s) { register_error(as, l, 1, "Bad expression"); @@ -399,8 +400,11 @@ return -1; } *inp = (char *)ep; - l -> exprends[slot] = *inp; - l -> exprvals[slot] = lwasm_expr_get_value(s); + if (slot >= 0) + { + l -> exprends[slot] = *inp; + l -> exprvals[slot] = lwasm_expr_get_value(s); + } } else if (l -> exprs[slot]) { @@ -417,21 +421,28 @@ s = NULL; } - if (!s) + if (!s && slot >= 0) { *val = l -> exprvals[slot]; return 0; } + else if (!s) + { + *val = 0; + return 0; + } // was a constant result on pass 1 requested? // that means we must have a constant on either pass if (flag & EXPR_PASS1CONST) { *val = 0; - l -> exprvals[slot] = 0; + if (slot >= 0) + l -> exprvals[slot] = 0; register_error(as, l, 1, "Illegal forward, external, or inter-section reference"); lwasm_expr_stack_free(s); - l -> exprs[slot] = NULL; + if (slot >= 0) + l -> exprs[slot] = NULL; return -1; } diff -r 121bf4a588ea -r d0ce3f5f6797 src/pseudo.c --- a/src/pseudo.c Sat Jan 10 05:00:42 2009 +0000 +++ b/src/pseudo.c Sat Jan 10 07:09:14 2009 +0000 @@ -288,12 +288,14 @@ l -> symaddr = v & 0xFFFF; l -> addrset = 2; + // note: we need to do this because the symbol might have resolved + // to a constant! lwasm_register_symbol(as, l, l -> sym, v, (r > 0 ? SYMBOL_COMPLEX: SYMBOL_NORM) | SYMBOL_FORCE); } OPFUNC(pseudo_set) { - int rval; + int r, v; // set MUST run on both passes as the symbol value changes! @@ -303,27 +305,41 @@ return; } - if (lwasm_expr_result(as, l, p, EXPR_PASS1CONST | EXPR_PASS2CONST, &rval) < 0) - rval = 0; + r = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v, 0); + if (r < 0) + v = 0; - l -> symaddr = rval & 0xFFFF; + l -> symaddr = v & 0xFFFF; l -> addrset = 2; - lwasm_register_symbol(as, l, l -> sym, rval, SYMBOL_SET); + lwasm_register_symbol(as, l, l -> sym, v, (r > 0 ? SYMBOL_COMPLEX: SYMBOL_NORM) | SYMBOL_SET); } OPFUNC(pseudo_setdp) { - int rval; + int r, v; - // setdp is needed on both passes - if (lwasm_expr_result(as, l, p, EXPR_PASS1CONST | EXPR_PASS2CONST | EXPR_BYTE, &rval) < 0) - rval = 0; + if (as -> outformat == OUTPUT_OBJ) + { + register_error(as, l, 1, "SETDP not permitted with OBJ target"); + return; + } + + // setdp is needed on both passes; must resolve to a constant on pass 1 + r = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v, 0); + if (r != 0) + return; - l -> symaddr = rval & 0xFF; + if (v < -127 || v > 255) + { + register_error(as, l, 1, "Byte overflow"); + return; + } + + l -> symaddr = v & 0xFF; l -> addrset = 2; - as -> dpval = rval & 0xFF; + as -> dpval = v & 0xFF; } OPFUNC(pseudo_fcc) @@ -391,15 +407,28 @@ lwasm_emit(as, l, 0); } +// FIXME: handle external, etc., references in a useful manner OPFUNC(pseudo_fcb) { - int v1; + int r, v; fcb_again: - if (lwasm_expr_result(as, l, p, EXPR_PASS2CONST | EXPR_BYTE, &v1) < 0) + r = lwasm_expr_result2(as, l, p, 0, &v, -1); + if (r < 0) return; + + if (r > 0) + { + register_error(as, l, 2, "Illegal external or inter-segment reference"); + v = 0; + } + + if (v < -127 || v > 255) + { + register_error(as, l, 1, "Byte overflow"); + } - lwasm_emit(as, l, v1); + lwasm_emit(as, l, v); if (**p == ',') { (*p)++; @@ -407,16 +436,24 @@ } } +// FIXME: handle external references in an intelligent way OPFUNC(pseudo_fdb) { - int v1; + int r, v; fdb_again: - if (lwasm_expr_result(as, l, p, EXPR_PASS2CONST, &v1) < 0) + r = lwasm_expr_result2(as, l, p, 0, &v, -1); + if (r < 0) return; - - lwasm_emit(as, l, v1 >> 8); - lwasm_emit(as, l, v1 & 0xff); + + if (r > 0) + { + register_error(as, l, 2, "Illegal external or inter-segment reference"); + v = 0; + } + + lwasm_emit(as, l, v >> 8); + lwasm_emit(as, l, v & 0xff); if (**p == ',') { (*p)++; @@ -424,18 +461,26 @@ } } +// FIXME: handle external references in a sensible way OPFUNC(pseudo_fqb) { - int v1; + int r, v; fqb_again: - if (lwasm_expr_result(as, l, p, EXPR_PASS2CONST, &v1) < 0) + r = lwasm_expr_result2(as, l, p, 0, &v, -1); + if (r < 0) return; - - lwasm_emit(as, l, v1 >> 24); - lwasm_emit(as, l, v1 >> 16); - lwasm_emit(as, l, v1 >> 8); - lwasm_emit(as, l, v1 & 0xff); + + if (r > 0) + { + register_error(as, l, 2, "Illegal external or inter-segment reference"); + v = 0; + } + + lwasm_emit(as, l, v >> 24); + lwasm_emit(as, l, v >> 16); + lwasm_emit(as, l, v >> 8); + lwasm_emit(as, l, v & 0xff); if (**p == ',') { (*p)++; @@ -488,8 +533,8 @@ return; } - rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1); - if (rval < 0) + rval = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v1, 0); + if (rval != 0) return; if (!v1) { @@ -509,8 +554,8 @@ return; } - rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1); - if (rval < 0) + rval = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v1, 0); + if (rval != 0) return; if (v1) { @@ -530,8 +575,8 @@ return; } - rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1); - if (rval < 0) + rval = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v1, 0); + if (rval != 0) return; if (v1 >= 0) { @@ -551,8 +596,8 @@ return; } - rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1); - if (rval < 0) + rval = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v1, 0); + if (rval != 0) return; if (v1 > 0) { @@ -572,8 +617,8 @@ return; } - rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1); - if (rval < 0) + rval = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v1, 0); + if (rval != 0) return; if (v1 <= 0) { @@ -593,8 +638,8 @@ return; } - rval = lwasm_expr_result(as, l, p, EXPR_PASS1CONST, &v1); - if (rval < 0) + rval = lwasm_expr_result2(as, l, p, EXPR_PASS1CONST, &v1, 0); + if (rval != 0) return; if (v1 < 0) { diff -r 121bf4a588ea -r d0ce3f5f6797 src/symbol.c --- a/src/symbol.c Sat Jan 10 05:00:42 2009 +0000 +++ b/src/symbol.c Sat Jan 10 07:09:14 2009 +0000 @@ -92,6 +92,11 @@ se = lwasm_find_symbol(as, sym, scontext); if (se) { + if (flags & SYMBOL_FORCE && as -> passnum != 2) + { + register_error(as, l, 1, "Multiply defined symbol: %s", sym); + return -1; + } if (!(flags & SYMBOL_SET) || (flags & SYMBOL_SET && !(se -> flags & SYMBOL_SET))) { register_error(as, l, 1, "Mulitply defined symbol: %s", sym); @@ -105,6 +110,10 @@ { se -> expr = l -> exprs[0]; } + else + { + se -> expr = NULL; + } return; }