/* * Copyright (C) 2003, 2004, 2005, 2006 Filip Pizlo. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY FILIP PIZLO ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FILIP PIZLO OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef FP_GPC_INTERNAL_H #define FP_GPC_INTERNAL_H #include "tsf_internal.h" #include "gpc.h" /* stupid stuff */ void gpc_unlink_free(char *name); void gpc_rmdir_free(char *name); void gpc_rmdashrf_free(char *name); /* debugging stuff */ void gpc_dyncc_code_gen_debug(const char *type, const char *src_filename); /* figure out the stack height for each cell inside of an intable. * also gives you the maximum stack height. returns a hashtable * that maps the instruction cell address to the stack height. * the max stack height is stored in *max_height if max_height!=NULL. * also note that the stack height at a cell is the height that the * stack would have had when you were entering into that instruction, * not exiting it. * * NOTE: we represent heights using intptr_t because: * 1) we need signed, since stack effects can be negative, and * 2) we need it to be pointer-size, since we use it as a value to the * hashtable, and hashtable values are void*. */ tsf_st_table *gpc_intable_get_stack_heights(gpc_intable_t *prog, intptr_t *max_height); /* code generation thingies */ #define gpc_read_bitvector_to_array(nbytes) \ uint32_t len;\ uint32_t size;\ uint32_t i;\ \ copy_ntohc_incsrc_bc(&ui8_tmp,cur,end,bounds_error);\ if (ui8_tmp==255) {\ copy_ntohl_incsrc_bc((uint8_t*)&len,cur,\ end,bounds_error);\ } else {\ len = ui8_tmp;\ }\ \ array->len=len;\ size=((len+7)>>3);\ \ if (cur + size > end) {\ goto bounds_error;\ }\ \ array->data=tsf_region_alloc(region,len*nbytes);\ if (array->data==NULL) {\ tsf_set_errno("Could not tsf_region_alloc()");\ INT_FAILURE();\ }\ \ for (i=7;idata[i-7]=((bits>>0)&1);\ array->data[i-6]=((bits>>1)&1);\ array->data[i-5]=((bits>>2)&1);\ array->data[i-4]=((bits>>3)&1);\ array->data[i-3]=((bits>>4)&1);\ array->data[i-2]=((bits>>5)&1);\ array->data[i-1]=((bits>>6)&1);\ array->data[i-0]=((bits>>7)&1);\ cur++;\ }\ i=len&~7;\ if (idata[i++]=((bits>>0)&1);\ if (idata[i++]=((bits>>1)&1);\ if (idata[i++]=((bits>>2)&1);\ if (idata[i++]=((bits>>3)&1);\ if (idata[i++]=((bits>>4)&1);\ if (idata[i++]=((bits>>5)&1);\ if (idata[i++]=((bits>>6)&1);\ if (idata[i++]=((bits>>7)&1);\ }\ }\ }\ }\ }\ }\ }\ cur++;\ } #define gpc_read_array_to_bitvector(kcode,tmpname,nbitbytes) \ uint32_t size;\ uint32_t len;\ uint8_t *bvcur;\ uint32_t nbytes;\ uint32_t overflow;\ uint32_t i;\ \ copy_ntohc_incsrc_bc(&ui8_tmp,cur,end,bounds_error);\ if (ui8_tmp==255) {\ copy_ntohl_incsrc_bc((uint8_t*)&bitvector->num_bits,cur,\ end,bounds_error);\ } else {\ bitvector->num_bits = ui8_tmp;\ }\ \ len=bitvector->num_bits;\ size=((bitvector->num_bits + 7)>>3);\ \ if (cur + len*nbitbytes > end) {\ goto bounds_error;\ }\ \ bitvector->bits=tsf_region_alloc(region,size);\ if (bitvector->bits==NULL) {\ tsf_set_errno("Could not tsf_region_alloc()");\ INT_FAILURE();\ }\ \ bvcur=bitvector->bits;\ nbytes=len>>3;\ \ while (nbytes-->0) {\ uint8_t bits=0;\ for (i=0;i<8;++i) {\ copy_ntoh##kcode##_incsrc((uint8_t*)&tmpname,cur);\ if (tmpname) bits|=(1<0) {\ uint8_t bits=0;\ for (i=0;inum_bits, cur,\ end, bounds_error);\ } else {\ bitvector->num_bits = ui8_tmp;\ }\ \ len = bitvector->num_bits;\ \ bitvector->bits = tsf_region_alloc(region, (len + 7) >> 3);\ if (bitvector->bits == NULL) {\ tsf_set_errno("Could not tsf_region_alloc()");\ INT_FAILURE();\ }\ \ for (i = 0; i < len; ++i) {\ tsf_##integer_type##_t integer;\ read_tsf_##integer_type##_incsrc(&integer, cur, end, bounds_error);\ if (integer) {\ bitvector->bits[i >> 3] |= (1 << (i & 7));\ } else {\ bitvector->bits[i >> 3] &= ~(1 << (i & 7));\ }\ } #define gpc_copy_array_to_bitvector() \ uint8_t *dest_cur;\ uint32_t i,j;\ uint8_t cur_bits;\ \ dest->num_bits=src->len;\ \ dest->bits=tsf_region_alloc(region,(dest->num_bits+7)>>3);\ if (dest->bits==NULL) {\ tsf_set_errno("Could not allocate bitvector from region");\ INT_FAILURE();\ }\ \ dest_cur=dest->bits;\ src_cur=src->data;\ for (i=dest->num_bits>>3;i-->0;) {\ cur_bits=0;\ for (j=0;j<8;++j) {\ if (*src_cur++) {\ cur_bits|=(1<num_bits&~7)num_bits) {\ cur_bits=0;\ for (i=(dest->num_bits&~7),j=0;inum_bits;++i,++j) {\ if (*src_cur++) {\ cur_bits|=(1<len=src->num_bits;\ dest->data=tsf_region_alloc(region,dest->len*nbitbytes);\ if (dest->data==NULL) {\ tsf_set_errno("Could not allocate array");\ INT_FAILURE();\ }\ \ dest_cur=dest->data;\ \ n=dest->len>>3;\ for (i=0;ibits[i];\ *dest_cur++=((bits>>0)&1);\ *dest_cur++=((bits>>1)&1);\ *dest_cur++=((bits>>2)&1);\ *dest_cur++=((bits>>3)&1);\ *dest_cur++=((bits>>4)&1);\ *dest_cur++=((bits>>5)&1);\ *dest_cur++=((bits>>6)&1);\ *dest_cur++=((bits>>7)&1);\ }\ if ((dest->len&~7)len) {\ bits=src->bits[(dest->len-1)>>3];\ for (i=(dest->len&~7);ilen;++i) {\ *dest_cur++=bits&1;\ bits>>=1;\ }\ } #endif