Mercurial > hg-old > index.cgi
annotate src/lwasm.c @ 96:7fbccdd1defb
Added doc subdirectory to distribution
author | lost |
---|---|
date | Sat, 17 Jan 2009 07:09:02 +0000 |
parents | 83ba34ed11b3 |
children | 81fc353d4d69 |
rev | line source |
---|---|
0 | 1 /* |
4
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
2 lwasm.c |
55 | 3 Copyright © 2009 William Astle |
4
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
4 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
5 This file is part of LWASM. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
6 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
7 LWASM is free software: you can redistribute it and/or modify it under the |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
8 terms of the GNU General Public License as published by the Free Software |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
9 Foundation, either version 3 of the License, or (at your option) any later |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
10 version. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
11 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
12 This program is distributed in the hope that it will be useful, but WITHOUT |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
15 more details. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
16 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
17 You should have received a copy of the GNU General Public License along with |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
18 this program. If not, see <http://www.gnu.org/licenses/>. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
19 |
26 | 20 |
21 Contains random functions used by the assembler | |
4
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
22 */ |
0 | 23 |
26 | 24 #define __lwasm_c_seen__ |
25 | |
26 #include <stdarg.h> | |
0 | 27 #include <stdlib.h> |
26 | 28 #include <stdio.h> |
29 | |
0 | 30 #include "lwasm.h" |
26 | 31 #include "util.h" |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
32 #include "expr.h" |
0 | 33 |
38 | 34 int debug_level = 0; |
35 | |
26 | 36 int register_error(asmstate_t *as, lwasm_line_t *l, int pass, const char *fmt, ...) |
0 | 37 { |
26 | 38 lwasm_error_t *e; |
39 va_list args; | |
40 char errbuff[1024]; | |
41 int r; | |
0 | 42 |
26 | 43 if (as -> passnum != pass) |
44 return; | |
45 | |
46 va_start(args, fmt); | |
0 | 47 |
26 | 48 e = lwasm_alloc(sizeof(lwasm_error_t)); |
49 | |
50 e -> next = l -> err; | |
51 l -> err = e; | |
0 | 52 |
53 as -> errorcount++; | |
54 | |
26 | 55 r = vsnprintf(errbuff, 1024, fmt, args); |
56 e -> mess = lwasm_strdup(errbuff); | |
0 | 57 |
26 | 58 va_end(args); |
0 | 59 |
26 | 60 return r; |
0 | 61 } |
27
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
62 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
63 void lwasm_emit(asmstate_t *as, lwasm_line_t *l, int b) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
64 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
65 as -> addr += 1; |
58 | 66 as -> addr &= 0xffff; |
67 | |
74 | 68 if (as -> outformat == OUTPUT_OBJ && !(as -> csect)) |
69 { | |
70 register_error(as, l, 1, "Output not allowed outside sections with obj target"); | |
71 return; | |
72 } | |
73 if (as -> outformat == OUTPUT_OBJ && as -> csect -> flags & SECTION_BSS) | |
74 { | |
75 register_error(as, l, 1, "Output not allowed inside BSS sections"); | |
76 return; | |
77 } | |
27
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
78 if (as -> passnum == 1) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
79 return; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
80 |
42 | 81 |
82 if (l -> codelen >= l -> codesize) | |
83 { | |
84 l -> bytes = realloc(l -> bytes, l -> codesize + 16); | |
85 l -> codesize += 16; | |
86 } | |
87 l -> bytes[l -> codelen] = b & 0xff; | |
88 l -> codelen += 1; | |
27
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
89 } |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
90 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
91 void lwasm_emitop(asmstate_t *as, lwasm_line_t *l, int o) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
92 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
93 if (o >= 0x100) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
94 lwasm_emit(as, l, o >> 8); |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
95 lwasm_emit(as, l, o & 0xff); |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
96 } |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
97 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
98 int lwasm_lookupreg2(const char *reglist, char **str) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
99 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
100 int rval = 0; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
101 |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
102 while (*reglist) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
103 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
104 if (toupper(**str) == *reglist) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
105 { |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
106 // first char matches |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
107 if (reglist[1] == ' ' && !isalpha(*(*str + 1))) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
108 break; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
109 if (toupper(*(*str + 1)) == reglist[1]) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
110 break; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
111 } |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
112 reglist += 2; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
113 rval++; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
114 } |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
115 if (!*reglist) |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
116 return -1; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
117 if (reglist[1] == ' ') |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
118 (*str)++; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
119 else |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
120 (*str) += 2; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
121 return rval; |
f736579569b4
Added handlers for inherent and register to register instructions
lost
parents:
26
diff
changeset
|
122 } |
32 | 123 |
124 int lwasm_lookupreg3(const char *rlist, const char **str) | |
125 { | |
126 int rval = 0; | |
127 int f = 0; | |
128 const char *reglist = rlist; | |
129 | |
130 while (*reglist) | |
131 { | |
132 if (toupper(**str) == *reglist) | |
133 { | |
134 // first char matches | |
135 if (reglist[1] == ' ') | |
136 { | |
137 f = 1; | |
138 break; | |
139 } | |
140 if (toupper(*(*str + 1)) == reglist[1]) | |
141 { | |
142 // second char matches | |
143 if (reglist[2] == ' ') | |
144 { | |
145 f = 1; | |
146 break; | |
147 } | |
148 if (toupper(*(*str + 2)) == reglist[2]) | |
149 { | |
150 f = 1; | |
151 break; | |
152 } | |
153 } | |
154 } | |
155 reglist += 3; | |
156 rval++; | |
157 } | |
158 if (f == 0) | |
159 return -1; | |
160 | |
161 | |
162 reglist = rval * 3 + rlist; | |
163 if (reglist[1] == ' ') | |
164 (*str) += 1; | |
165 else if (reglist[2] == ' ') | |
166 (*str) += 2; | |
167 else | |
168 (*str)+=3; | |
169 return rval; | |
170 } | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
171 |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
172 struct symstateinfo |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
173 { |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
174 asmstate_t *as; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
175 lwasm_line_t *l; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
176 }; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
177 |
76 | 178 lwasm_expr_stack_t *lwasm_expr_lookup_symbol(char *sym, void *state) |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
179 { |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
180 lwasm_symbol_ent_t *se; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
181 struct symstateinfo *st; |
76 | 182 lwasm_expr_stack_t *rs; |
183 lwasm_expr_term_t *t; | |
184 lwasm_expr_stack_node_t *n; | |
185 | |
186 int val; | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
187 |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
188 st = state; |
52 | 189 debug_message(3, "lwasm_expr_lookup_symbol(): find '%s' (context=%d)", sym, st -> as -> context); |
190 | |
60 | 191 // check for special symbols first... |
192 if (sym[1] == '\0') | |
193 { | |
194 switch (sym[0]) | |
195 { | |
196 // current line address | |
197 case '*': | |
198 case '.': | |
76 | 199 val = st -> l -> codeaddr; |
200 goto retconst; | |
60 | 201 |
202 case '<': | |
203 // previous branch point | |
204 // not implemented | |
205 break; | |
206 case '>': | |
207 // next branch point | |
208 // not implemented | |
209 break; | |
210 } | |
211 } | |
212 | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
213 // look for local symbol first then global symbol |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
214 se = lwasm_find_symbol(st -> as, sym, st -> as -> context); |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
215 if (!se) |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
216 se = lwasm_find_symbol(st -> as, sym, -1); |
52 | 217 debug_message(3, "lwasm_expr_lookup_symbol(): got '%p'", se); |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
218 if (!se) |
77 | 219 { |
220 register_error(st -> as, st -> l, 2, "Undefined symbol '%s'", sym); | |
76 | 221 return NULL; |
77 | 222 } |
92
ea2cfebef5d0
Make external symbols remain unresolved in expressions and also flag them in the symbol list
lost
parents:
84
diff
changeset
|
223 // external reference - can not resolve it |
ea2cfebef5d0
Make external symbols remain unresolved in expressions and also flag them in the symbol list
lost
parents:
84
diff
changeset
|
224 if (se -> flags & SYMBOL_EXTERN) |
ea2cfebef5d0
Make external symbols remain unresolved in expressions and also flag them in the symbol list
lost
parents:
84
diff
changeset
|
225 { |
ea2cfebef5d0
Make external symbols remain unresolved in expressions and also flag them in the symbol list
lost
parents:
84
diff
changeset
|
226 return NULL; |
ea2cfebef5d0
Make external symbols remain unresolved in expressions and also flag them in the symbol list
lost
parents:
84
diff
changeset
|
227 } |
93
34ca1c6e9550
Fixed symbol resolution to not resolve intra-section references to constants by default
lost
parents:
92
diff
changeset
|
228 if (st -> as -> outformat == OUTPUT_OBJ && se -> sect != NULL) |
34ca1c6e9550
Fixed symbol resolution to not resolve intra-section references to constants by default
lost
parents:
92
diff
changeset
|
229 { |
34ca1c6e9550
Fixed symbol resolution to not resolve intra-section references to constants by default
lost
parents:
92
diff
changeset
|
230 // do not resolve any section symbols in object mode |
34ca1c6e9550
Fixed symbol resolution to not resolve intra-section references to constants by default
lost
parents:
92
diff
changeset
|
231 return NULL; |
34ca1c6e9550
Fixed symbol resolution to not resolve intra-section references to constants by default
lost
parents:
92
diff
changeset
|
232 } |
34ca1c6e9550
Fixed symbol resolution to not resolve intra-section references to constants by default
lost
parents:
92
diff
changeset
|
233 if (st -> as -> outformat != OUTPUT_OBJ || se -> sect == NULL) |
76 | 234 { |
235 // global symbol, intrasegment reference, or not an object target | |
236 val = se -> value; | |
237 goto retconst; | |
238 } | |
239 // an intersegment reference will return as NULL (to be resolved at output/link time) | |
240 // if se -> expr is NULL, it has to be an intersegment reference here | |
241 if (se -> expr == NULL) | |
242 { | |
243 return NULL; | |
244 } | |
245 | |
246 // duplicate the expression for return | |
247 rs = lwasm_expr_stack_create(); | |
248 for (n = se -> expr -> head; n; n = n -> next) | |
249 { | |
250 lwasm_expr_stack_push(rs, n -> term); | |
251 } | |
252 return rs; | |
253 | |
254 retconst: | |
255 rs = lwasm_expr_stack_create(); | |
256 t = lwasm_expr_term_create_int(val); | |
257 lwasm_expr_stack_push(rs, t); | |
258 lwasm_expr_term_free(t); | |
259 return rs; | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
260 } |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
261 |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
262 lwasm_expr_stack_t *lwasm_evaluate_expr(asmstate_t *as, lwasm_line_t *l, const char *inp, const char **outp) |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
263 { |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
264 struct symstateinfo st; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
265 |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
266 st.as = as; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
267 st.l = l; |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
268 |
38 | 269 debug_message(2, "Evaluate expression: %s", inp); |
270 | |
37
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
271 return(lwasm_expr_eval(inp, outp, lwasm_expr_lookup_symbol, &st)); |
538e15927776
Added symbol handling to expression subsystem; adpated instruction handlers to the new scheme; misc fixes
lost
parents:
32
diff
changeset
|
272 } |
38 | 273 |
77 | 274 |
275 int lwasm_reevaluate_expr(asmstate_t *as, lwasm_line_t *l, lwasm_expr_stack_t *s) | |
276 { | |
277 struct symstateinfo st; | |
278 | |
279 st.as = as; | |
280 st.l = l; | |
281 | |
282 return(lwasm_expr_reval(s, lwasm_expr_lookup_symbol, &st)); | |
283 } | |
284 | |
76 | 285 // return 1 if no undefined symbols (externals and incompletes are okay) |
286 // return 0 if there are undefined symbols | |
287 int lwasm_expr_result_ckconst(asmstate_t *as, lwasm_expr_stack_t *s) | |
288 { | |
289 lwasm_expr_stack_node_t *n; | |
290 lwasm_symbol_ent_t *se; | |
291 | |
77 | 292 if (as -> outformat != OUTPUT_OBJ) |
293 { | |
294 if (lwasm_expr_is_constant(s)) | |
295 return 1; | |
296 else | |
297 return 0; | |
298 } | |
299 | |
76 | 300 for (n = s -> head; n; n = n -> next) |
301 { | |
302 if (n -> term -> term_type == LWASM_TERM_SYM) | |
303 { | |
304 se = lwasm_find_symbol(as, n -> term -> symbol, as -> context); | |
305 if (!se) | |
306 se = lwasm_find_symbol(as, n -> term -> symbol, -1); | |
307 if (!se) | |
308 return 0; | |
309 } | |
310 } | |
311 return 1; | |
312 } | |
313 | |
314 /* | |
315 Evaluate an expression according to the flag value. Return 0 if a constant result was | |
316 obtained, 1 if an incomplete result was obtained, and -1 if an error was flagged. | |
317 | |
318 Symbol resolution will be modified for the object target as follows: | |
319 - a symbol which is not defined within a section will evaluate as a constant | |
320 - a symbol which is defined within the same section will evaluate as a constant | |
321 - a symbol defined in another section will remain unresolved | |
322 - external references will also remain unresolved | |
323 | |
77 | 324 EXPR_PASS2PASS will cause the result from pass 1 along with the offset to |
325 the end of the expression to be stored in the line data. There can only be | |
326 one such expression per source line. In this case, the expression is parsed | |
327 and evaluated on pass 1 but the intermediate representation is re-evaluated | |
328 on pass 2. | |
76 | 329 */ |
77 | 330 /* |
55 | 331 int lwasm_expr_result(asmstate_t *as, lwasm_line_t *l, char **inp, int flag, int *val) |
332 { | |
333 lwasm_expr_stack_t *s; | |
58 | 334 const char *ep; |
55 | 335 int rval; |
336 | |
337 s = lwasm_evaluate_expr(as, l, *inp, &ep); | |
338 if (!s) | |
339 { | |
340 register_error(as, l, 1, "Bad expression"); | |
341 *val = 0; | |
342 return -1; | |
343 } | |
58 | 344 *inp = (char *)ep; |
55 | 345 |
77 | 346 if (flag & EXPR_PASS1CONST && as -> passnum == 1 && !lwasm_expr_result_ckconst(as, s)) |
55 | 347 { |
77 | 348 register_error(as, l, 1, "Undefined reference (pass 1)"); |
349 *val = 0; | |
350 lwasm_expr_stack_free(s); | |
351 return -1; | |
352 } | |
353 if (flag & EXPR_PASS2CONST && as -> passnum == 2 && !lwasm_expr_result_ckconst(as, s)) | |
354 { | |
355 register_error(as, l, 2, "Undefined reference (pass 2)"); | |
55 | 356 *val = 0; |
357 lwasm_expr_stack_free(s); | |
358 return -1; | |
359 } | |
77 | 360 if (flag & EXPR_NOINTERSECT && !lwasm_expr_is_constant(s)) |
55 | 361 { |
77 | 362 register_error(as, l, 2, "Invalid inter-section reference"); |
55 | 363 } |
364 *val = lwasm_expr_get_value(s); | |
77 | 365 if (l -> expr) |
366 { | |
367 lwasm_expr_stack_free(l -> expr); | |
368 l -> expr = NULL; | |
369 } | |
370 if (lwasm_is_constant(s)) | |
371 { | |
372 // fully resolved value here | |
373 lwasm_expr_stack_free(s); | |
374 } | |
375 else | |
376 { | |
377 // incomplete reference here | |
378 l -> expr = s; | |
379 } | |
55 | 380 |
381 if (flag & EXPR_BYTE && as -> passnum == 2 && (*val < -128 || *val > 255)) | |
382 { | |
383 register_error(as, l, 2, "Byte overflow"); | |
384 *val &= 0xff; | |
385 return -1; | |
386 } | |
387 if (flag & EXPR_BYTE) | |
388 { | |
389 *val &= 0xff; | |
390 } | |
391 | |
392 return 0; | |
393 } | |
77 | 394 */ |
395 int lwasm_expr_result2(asmstate_t *as, lwasm_line_t *l, char **inp, int flag, int *val, int slot) | |
396 { | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
397 lwasm_expr_stack_t *s = NULL; |
77 | 398 const char *ep; |
399 int rval; | |
400 | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
401 if (as -> passnum == 1 || slot < 0) |
77 | 402 { |
403 s = lwasm_evaluate_expr(as, l, *inp, &ep); | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
404 if (slot >= 0) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
405 l -> exprs[slot] = s; |
77 | 406 if (!s) |
407 { | |
408 register_error(as, l, 1, "Bad expression"); | |
409 *val = 0; | |
410 return -1; | |
411 } | |
412 *inp = (char *)ep; | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
413 if (slot >= 0) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
414 { |
94
83ba34ed11b3
Fixed problem with constant expressions evaluating to 0 when they shouldn't
lost
parents:
93
diff
changeset
|
415 l -> exprends[slot] = (char *)ep; |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
416 l -> exprvals[slot] = lwasm_expr_get_value(s); |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
417 } |
77 | 418 } |
419 else if (l -> exprs[slot]) | |
420 { | |
421 s = l -> exprs[slot]; | |
422 lwasm_reevaluate_expr(as, l, s); | |
423 l -> exprvals[slot] = lwasm_expr_get_value(s); | |
424 } | |
84
e12edcfbebd5
Fixed problem with expression evaluation infrastructure not advancing input pointer on pass 2
lost
parents:
79
diff
changeset
|
425 if (as -> passnum == 2 && slot >= 0) |
e12edcfbebd5
Fixed problem with expression evaluation infrastructure not advancing input pointer on pass 2
lost
parents:
79
diff
changeset
|
426 *inp = l -> exprends[slot]; |
77 | 427 |
428 if (s && lwasm_expr_is_constant(s)) | |
429 { | |
94
83ba34ed11b3
Fixed problem with constant expressions evaluating to 0 when they shouldn't
lost
parents:
93
diff
changeset
|
430 *val = lwasm_expr_get_value(s); |
77 | 431 lwasm_expr_stack_free(s); |
432 l -> exprs[slot] = NULL; | |
433 s = NULL; | |
94
83ba34ed11b3
Fixed problem with constant expressions evaluating to 0 when they shouldn't
lost
parents:
93
diff
changeset
|
434 return 0; |
77 | 435 } |
436 | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
437 if (!s && slot >= 0) |
77 | 438 { |
439 *val = l -> exprvals[slot]; | |
440 return 0; | |
441 } | |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
442 else if (!s) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
443 { |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
444 *val = 0; |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
445 return 0; |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
446 } |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
447 |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
448 // was a constant result on pass 1 requested? |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
449 // that means we must have a constant on either pass |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
450 if (flag & EXPR_PASS1CONST) |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
451 { |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
452 *val = 0; |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
453 if (slot >= 0) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
454 l -> exprvals[slot] = 0; |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
455 register_error(as, l, 1, "Illegal forward, external, or inter-section reference"); |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
456 lwasm_expr_stack_free(s); |
79
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
457 if (slot >= 0) |
d0ce3f5f6797
Checkpointing deployment of non-constant expression handling
lost
parents:
78
diff
changeset
|
458 l -> exprs[slot] = NULL; |
78
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
459 return -1; |
121bf4a588ea
Checkpointing deployment of non-constant expression handling
lost
parents:
77
diff
changeset
|
460 } |
77 | 461 |
462 return 1; | |
463 } | |
55 | 464 |
38 | 465 void debug_message(int level, const char *fmt, ...) |
466 { | |
467 va_list args; | |
468 | |
469 va_start(args, fmt); | |
470 if (debug_level >= level) | |
471 { | |
39 | 472 if (level > 0) |
473 fprintf(stderr, "DEBUG %d: ", level); | |
38 | 474 vfprintf(stderr, fmt, args); |
475 fputc('\n', stderr); | |
476 } | |
477 va_end(args); | |
478 } | |
57 | 479 |
480 int lwasm_next_context(asmstate_t *as) | |
481 { | |
58 | 482 int r; |
483 r = as -> nextcontext; | |
484 as -> nextcontext += 1; | |
485 debug_message(3, "lwasm_next_context(): %d (%d) pass %d", r, as -> nextcontext, as -> passnum); | |
486 return r; | |
57 | 487 } |
488 |