1 /* Byte code fragment construction functions */ 2 3 typedef struct frag Frag; 4 5 struct frag { 6 unsigned char *start; 7 ptrdiff_t len; 8 ptrdiff_t size; 9 ptrdiff_t align; 10 }; 11 12 /* Initialize a fragment: 'alignment' sets the natural alignment of 13 * the fragment. After any emit or fetch function is called, the 14 * fragment is filled to the next multiple of 'alignment'. 15 */ 16 17 void iz_frag(Frag *, ptrdiff_t alignmnet); 18 19 void clr_frag(Frag *); 20 21 /* Generate byte offset you need to add to p so that 22 * it is an exact multiple of size (which is a power of 2). 23 */ 24 25 #define align_o(p, size) (((size) - 1) & -(ptrdiff_t)(p)) 26 27 /* Align frag to next multiple of n */ 28 29 void align_frag(Frag *f, ptrdiff_t n); 30 31 /* Append data to a fragment: return byte offset to data. 32 * These do two alignments: one before and one after the emit. Before, 33 * it fills the fragment until its size is a multiple of the size of 34 * the emitted data. After the emit, it fills the fragment until its 35 * size is a multiple of the natural alignment specified in iz_frag. 36 */ 37 38 39 ptrdiff_t emitb_noalign(Frag *f, char c); 40 ptrdiff_t emitb(Frag *f, char c); 41 ptrdiff_t emith(Frag *f, short n); 42 ptrdiff_t emiti(Frag *f, int n); 43 ptrdiff_t emitd(Frag *f, double d); 44 ptrdiff_t emitp(Frag *f, void *p); 45 ptrdiff_t emits(Frag *f, unsigned char *s, int len); 46 47 ptrdiff_t emit_branch(Frag *f, ptrdiff_t target); 48 void fixup_branch(Frag *f, ptrdiff_t pos); 49 void frag_link(Frag *f, ptrdiff_t chain); 50 51 /* Access data in a fragment */ 52 53 #define fragc(f, ofst) (*((f)->start + (ofst))) 54 #define fragh(f, ofst) (*(short *)((f)->start + (ofst))) 55 #define fragi(f, ofst) (*(int *)((f)->start + (ofst))) 56 #define fragd(f, ofst) (*(double *)((f)->start + (ofst))) 57 #define fragp(f, ofst) (*(void **)((f)->start + (ofst))) 58 59 /* Fetch an datum from a fragment and advance the "PC" */ 60 61 int fetchi(Frag *f, ptrdiff_t *pc); 62 short fetchh(Frag *f, ptrdiff_t *pc); 63 void *fetchp(Frag *f, ptrdiff_t *pc); 64 void fin_code(Frag *f); 65