Mercurial > hg-old > index.cgi
diff src/lwasm.c @ 76:2fe5fd7d65a3
Checkpointing object target implementation
author | lost |
---|---|
date | Thu, 08 Jan 2009 02:57:24 +0000 |
parents | c8c772ef5df9 |
children | a338d496350e |
line wrap: on
line diff
--- a/src/lwasm.c Thu Jan 08 01:32:49 2009 +0000 +++ b/src/lwasm.c Thu Jan 08 02:57:24 2009 +0000 @@ -175,10 +175,15 @@ lwasm_line_t *l; }; -int lwasm_expr_lookup_symbol(char *sym, void *state, int *val) +lwasm_expr_stack_t *lwasm_expr_lookup_symbol(char *sym, void *state) { lwasm_symbol_ent_t *se; struct symstateinfo *st; + lwasm_expr_stack_t *rs; + lwasm_expr_term_t *t; + lwasm_expr_stack_node_t *n; + + int val; st = state; debug_message(3, "lwasm_expr_lookup_symbol(): find '%s' (context=%d)", sym, st -> as -> context); @@ -191,8 +196,8 @@ // current line address case '*': case '.': - *val = st -> l -> codeaddr; - return 0; + val = st -> l -> codeaddr; + goto retconst; case '<': // previous branch point @@ -211,9 +216,34 @@ se = lwasm_find_symbol(st -> as, sym, -1); debug_message(3, "lwasm_expr_lookup_symbol(): got '%p'", se); if (!se) - return -1; - *val = se -> value; - return 0; + 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 + val = se -> value; + goto retconst; + } + // an intersegment reference will return as NULL (to be resolved at output/link time) + // if se -> expr is NULL, it has to be an intersegment reference here + if (se -> expr == NULL) + { + return NULL; + } + + // duplicate the expression for return + rs = lwasm_expr_stack_create(); + for (n = se -> expr -> head; n; n = n -> next) + { + lwasm_expr_stack_push(rs, n -> term); + } + return rs; + +retconst: + rs = lwasm_expr_stack_create(); + t = lwasm_expr_term_create_int(val); + lwasm_expr_stack_push(rs, t); + lwasm_expr_term_free(t); + return rs; } lwasm_expr_stack_t *lwasm_evaluate_expr(asmstate_t *as, lwasm_line_t *l, const char *inp, const char **outp) @@ -228,6 +258,38 @@ return(lwasm_expr_eval(inp, outp, 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) +{ + lwasm_expr_stack_node_t *n; + lwasm_symbol_ent_t *se; + + for (n = s -> head; n; n = n -> next) + { + if (n -> term -> term_type == LWASM_TERM_SYM) + { + se = lwasm_find_symbol(as, n -> term -> symbol, as -> context); + if (!se) + se = lwasm_find_symbol(as, n -> term -> symbol, -1); + if (!se) + return 0; + } + } + return 1; +} + +/* +Evaluate an expression according to the flag value. Return 0 if a constant result was +obtained, 1 if an incomplete result was obtained, and -1 if an error was flagged. + +Symbol resolution will be modified for the object target as follows: +- a symbol which is not defined within a section will evaluate as a constant +- a symbol which is defined within the same section will evaluate as a constant +- a symbol defined in another section will remain unresolved +- external references will also remain unresolved + +*/ int lwasm_expr_result(asmstate_t *as, lwasm_line_t *l, char **inp, int flag, int *val) { lwasm_expr_stack_t *s;