Logo Search packages:      
Sourcecode: mawk version File versions  Download package

code.c

/********************************************
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 ;
   }
}

Generated by  Doxygen 1.6.0   Back to index