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