blob: 15da6bc2b53fa69d450c1fd5e82bede98b26e566 [file] [log] [blame]
/*
* 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;i<len;i+=8) {\
uint8_t bits=*cur;\
array->data[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 (i<len) {\
uint8_t bits=*cur;\
array->data[i++]=((bits>>0)&1);\
if (i<len) {\
array->data[i++]=((bits>>1)&1);\
if (i<len) {\
array->data[i++]=((bits>>2)&1);\
if (i<len) {\
array->data[i++]=((bits>>3)&1);\
if (i<len) {\
array->data[i++]=((bits>>4)&1);\
if (i<len) {\
array->data[i++]=((bits>>5)&1);\
if (i<len) {\
array->data[i++]=((bits>>6)&1);\
if (i<len) {\
array->data[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<<i);\
}\
*bvcur++=bits;\
}\
overflow=len&7;\
if (len>0) {\
uint8_t bits=0;\
for (i=0;i<len;++i) {\
copy_ntoh##kcode##_incsrc((uint8_t*)&tmpname,cur);\
if (tmpname) bits|=(1<<i);\
}\
*bvcur=bits;\
}
#define gpc_read_integer_array_to_bitvector(integer_type) \
uint32_t len, 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;\
\
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<<j);\
}\
}\
*dest_cur++=cur_bits;\
}\
if ((dest->num_bits&~7)<dest->num_bits) {\
cur_bits=0;\
for (i=(dest->num_bits&~7),j=0;i<dest->num_bits;++i,++j) {\
if (*src_cur++) {\
cur_bits|=(1<<j);\
}\
}\
*dest_cur=cur_bits;\
}
#define gpc_copy_bitvector_to_array(nbitbytes) \
\
uint32_t i;\
uint32_t n;\
uint8_t bits;\
\
dest->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;i<n;++i) {\
bits=src->bits[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)<dest->len) {\
bits=src->bits[(dest->len-1)>>3];\
for (i=(dest->len&~7);i<dest->len;++i) {\
*dest_cur++=bits&1;\
bits>>=1;\
}\
}
#endif