/******************************************** code.c copyright 1991-93, Michael D. Brennan This is a source file for mawk, an implementation of the AWK programming language. Mawk is distributed without warranty under the terms of the GNU General Public License, version 2, 1991. ********************************************/ /* $Log: code.c,v $ * Revision 1.6 1995/06/18 19:42:13 mike * Remove some redundant declarations and add some prototypes * * Revision 1.5 1995/06/09 23:21:36 mike * make sure there is an execution block in case user defines function, * but no pattern-action pairs * * Revision 1.4 1995/03/08 00:06:22 mike * add a pointer cast * * Revision 1.3 1994/10/08 19:15:29 mike * remove SM_DOS * * Revision 1.2 1993/07/07 00:07:38 mike * more work on 1.2 * * Revision 1.1.1.1 1993/07/03 18:58:10 mike * move source to cvs * * Revision 5.4 1993/01/14 13:11:11 mike * code2() -> xcode2() * * Revision 5.3 1993/01/09 20:15:35 mike * code_pop checks if the resolve_list needs relocation * * Revision 5.2 1993/01/07 02:50:33 mike * relative vs absolute code * * Revision 5.1 1991/12/05 07:55:43 brennan * 1.1 pre-release * */ /* code.c */ #include "mawk.h" #include "code.h" #include "init.h" #include "jmp.h" #include "field.h" static CODEBLOCK *PROTO(new_code, (void)) ; CODEBLOCK active_code ; CODEBLOCK *main_code_p, *begin_code_p, *end_code_p ; INST *begin_start, *main_start, *end_start ; unsigned begin_size, main_size ; INST *execution_start = 0 ; /* grow the active code */ void code_grow() { unsigned oldsize = code_limit - code_base ; unsigned newsize = PAGESZ + oldsize ; unsigned delta = code_ptr - code_base ; if (code_ptr > code_limit) bozo("CODEWARN is too small") ; code_base = (INST *) zrealloc(code_base, INST_BYTES(oldsize), INST_BYTES(newsize)) ; code_limit = code_base + newsize ; code_warn = code_limit - CODEWARN ; code_ptr = code_base + delta ; } /* shrinks executable code that's done to its final size */ INST * code_shrink(p, sizep) CODEBLOCK *p ; unsigned *sizep ; { unsigned oldsize = INST_BYTES(p->limit - p->base) ; unsigned newsize = INST_BYTES(p->ptr - p->base) ; INST *retval ; *sizep = newsize ; retval = (INST *) zrealloc(p->base, oldsize, newsize) ; ZFREE(p) ; return retval ; } /* code an op and a pointer in the active_code */ void xcode2(op, ptr) int op ; PTR ptr ; { register INST *p = code_ptr + 2 ; if (p >= code_warn) { code_grow() ; p = code_ptr + 2 ; } p[-2].op = op ; p[-1].ptr = ptr ; code_ptr = p ; } /* code two ops in the active_code */ void code2op(x, y) int x, y ; { register INST *p = code_ptr + 2 ; if (p >= code_warn) { code_grow() ; p = code_ptr + 2 ; } p[-2].op = x ; p[-1].op = y ; code_ptr = p ; } void code_init() { main_code_p = new_code() ; active_code = *main_code_p ; code1(_OMAIN) ; } /* final code relocation set_code() as in set concrete */ void set_code() { /* set the main code which is active_code */ if (end_code_p || code_offset > 1) { int gl_offset = code_offset ; extern int NR_flag ; if (NR_flag) code2op(OL_GL_NR, _HALT) ; else code2op(OL_GL, _HALT) ; *main_code_p = active_code ; main_start = code_shrink(main_code_p, &main_size) ; next_label = main_start + gl_offset ; execution_start = main_start ; } else /* only BEGIN */ { zfree(code_base, INST_BYTES(PAGESZ)) ; ZFREE(main_code_p) ; } /* set the END code */ if (end_code_p) { unsigned dummy ; active_code = *end_code_p ; code2op(_EXIT0, _HALT) ; *end_code_p = active_code ; end_start = code_shrink(end_code_p, &dummy) ; } /* set the BEGIN code */ if (begin_code_p) { active_code = *begin_code_p ; if (main_start) code2op(_JMAIN, _HALT) ; else code2op(_EXIT0, _HALT) ; *begin_code_p = active_code ; begin_start = code_shrink(begin_code_p, &begin_size) ; execution_start = begin_start ; } if ( ! execution_start ) { /* program had functions but no pattern-action bodies */ execution_start = begin_start = (INST*) zmalloc(2*sizeof(INST)) ; execution_start[0].op = _EXIT0 ; execution_start[1].op = _HALT ; } } void dump_code() { fdump() ; /* dumps all user functions */ if (begin_start) { fprintf(stdout, "BEGIN\n") ; da(begin_start, stdout) ; } if (end_start) { fprintf(stdout, "END\n") ; da(end_start, stdout) ; } if (main_start) { fprintf(stdout, "MAIN\n") ; da(main_start, stdout) ; } } static CODEBLOCK * new_code() { CODEBLOCK *p = ZMALLOC(CODEBLOCK) ; p->base = (INST *) zmalloc(INST_BYTES(PAGESZ)) ; p->limit = p->base + PAGESZ ; p->warn = p->limit - CODEWARN ; p->ptr = p->base ; return p ; } /* moves the active_code from MAIN to a BEGIN or END */ void be_setup(scope) int scope ; { *main_code_p = active_code ; if (scope == SCOPE_BEGIN) { if (!begin_code_p) begin_code_p = new_code() ; active_code = *begin_code_p ; } else { if (!end_code_p) end_code_p = new_code() ; active_code = *end_code_p ; } }