2
/********************************************
4
copyright 1991, Michael D. Brennan
6
This is a source file for mawk, an implementation of
7
the AWK programming language.
9
Mawk is distributed without warranty under the terms of
10
the GNU General Public License, version 2, 1991.
11
********************************************/
14
* Revision 1.4 1995/06/18 19:42:19 mike
15
* Remove some redundant declarations and add some prototypes
17
* Revision 1.3 1995/04/21 14:20:16 mike
18
* move_level variable to fix bug in arglist patching of moved code.
20
* Revision 1.2 1993/07/14 13:17:49 mike
21
* rm SIZE_T and run thru indent
23
* Revision 1.1.1.1 1993/07/03 18:58:15 mike
26
* Revision 5.3 1993/01/09 19:03:44 mike
27
* code_pop checks if the resolve_list needs relocation
29
* Revision 5.2 1993/01/07 02:50:33 mike
30
* relative vs absolute code
32
* Revision 5.1 1991/12/05 07:56:10 brennan
37
/* this module deals with back patching jumps, breaks and continues,
38
and with save and restoring code when we move code.
39
There are three stacks. If we encounter a compile error, the
40
stacks are frozen, i.e., we do not attempt error recovery
53
#define error_state (compile_error_count>0)
56
/*---------- back patching jumps ---------------*/
68
code_jmp(jtype, target)
72
if (error_state) return ;
74
/* WARNING: Don't emit any code before using target or
75
relocation might make it invalid */
77
if (target) code2op(jtype, target - (code_ptr + 1)) ;
80
register JMP *p = ZMALLOC(JMP) ;
82
/* stack for back patch */
84
p->source_offset = code_offset - 1 ;
91
patch_jmp(target) /* patch a jump on the jmp_stack */
95
register INST *source ; /* jmp starts here */
100
if (!jmp_top) bozo("jmp stack underflow") ;
103
p = jmp_top ; jmp_top = p->link ;
104
source = p->source_offset + code_base ;
105
source->op = target - source ;
112
/*-- break and continue -------*/
116
struct bc *link ; /* stack as linked list */
117
int type ; /* 'B' or 'C' or mark start with 0 */
118
int source_offset ; /* position of _JMP */
127
BC_new() /* mark the start of a loop */
129
BC_insert(0, (INST *) 0) ;
133
BC_insert(type, address)
134
int type ; INST *address ;
138
if (error_state) return ;
142
compile_error("%s statement outside of loop",
143
type == 'B' ? "break" : "continue") ;
151
p->source_offset = address - code_base ;
158
/* patch all break and continues for one loop */
160
BC_clear(B_address, C_address)
161
INST *B_address, *C_address ;
166
if (error_state) return ;
169
/* pop down to the mark node */
172
source = code_base + p->source_offset ;
173
source->op = (p->type == 'B' ? B_address : C_address)
176
q = p ; p = p->link ; ZFREE(q) ;
178
/* remove the mark node */
183
/*----- moving code --------------------------*/
185
/* a stack to hold some pieces of code while
190
{ /* mc -- move code */
192
INST *code ; /* the save code */
193
unsigned len ; /* its length */
194
int scope ; /* its scope */
195
int move_level ; /* size of this stack when coded */
196
FBLOCK *fbp ; /* if scope FUNCT */
197
int offset ; /* distance from its code base */
202
int code_move_level = 0 ; /* see comment in jmp.h */
205
/* means relocation of resolve list not needed */
208
code_push(code, len, scope, fbp)
225
p->code = (INST *) zmalloc(sizeof(INST) * len) ;
226
memcpy(p->code, code, sizeof(INST) * len) ;
228
if (!resolve_list) p->scope = NO_SCOPE ;
232
p->move_level = code_move_level ;
234
p->offset = code - code_base ;
240
/* copy the code at the top of the mc stack to target.
241
return the number of INSTs moved */
251
if (error_state) return 0 ;
254
if (!mc_top) bozo("mc underflow") ;
257
p = mc_top ; mc_top = p->link ;
260
while (target + len >= code_warn)
262
target_offset = target - code_base ;
264
target = code_base + target_offset ;
269
memcpy(target, p->code, len * sizeof(INST)) ;
270
zfree(p->code, len * sizeof(INST)) ;
273
if (p->scope != NO_SCOPE)
275
target_offset = target - code_base ;
276
relocate_resolve_list(p->scope, p->move_level, p->fbp,
277
p->offset, len, target_offset - p->offset) ;