3 * only can be included by userspace compiler
12 #define MAX_INT ((int)(~0U>>1))
15 #define MAX_SIZET ((size_t)(~(size_t)0)-2)
17 #define KTAP_ERRSYNTAX 3
20 * KTAP_IDSIZE gives the maximum size for the description of the source
21 * of a function in debug information.
22 * CHANGE it if you want a different size.
24 #define KTAP_IDSIZE 60
27 #define FIRST_RESERVED 257
30 * maximum depth for nested C calls and syntactical nested non-terminals
31 * in a program. (Value must fit in an unsigned short int.)
33 #define KTAP_MAXCCALLS 200
35 #define KTAP_MULTRET (-1)
38 #define SHRT_MAX UCHAR_MAX
40 #define MAXUPVAL UCHAR_MAX
43 /* maximum stack for a ktap function */
46 #define islalpha(c) (isalpha(c) || (c) == '_')
47 #define islalnum(c) (isalnum(c) || (c) == '_')
49 #define isreserved(s) ((s)->tsv.tt == KTAP_TSHRSTR && (s)->tsv.extra > 0)
51 #define ktap_numeq(a,b) ((a)==(b))
52 #define ktap_numisnan(L,a) (!ktap_numeq((a), (a)))
54 #define ktap_numunm(a) (-(a))
57 * ** Comparison and arithmetic functions
60 #define KTAP_OPADD 0 /* ORDER TM */
74 * WARNING: if you change the order of this enumeration,
75 * grep "ORDER RESERVED"
78 /* terminal symbols denoted by reserved words */
79 TK_TRACE = FIRST_RESERVED, TK_TRACE_END,
80 TK_ARGEVENT, TK_ARGNAME,
82 TK_ARG1, TK_ARG2, TK_ARG3, TK_ARG4, TK_ARG5, TK_ARG6, TK_ARG7, TK_ARG8,
83 TK_ARG9, TK_PROFILE, TK_TICK, TK_AGGR_ASSIGN,
85 TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
86 TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
87 TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
88 /* other terminal symbols */
89 TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_INCR, TK_DBCOLON,
90 TK_EOS, TK_NUMBER, TK_NAME, TK_STRING, TK_KSYM
93 /* number of reserved words */
94 #define NUM_RESERVED ((int)(TK_WHILE-FIRST_RESERVED + 1))
96 #define EOZ (0) /* end of stream */
101 } ktap_seminfo; /* semantics information */
104 typedef struct ktap_token {
106 ktap_seminfo seminfo;
109 typedef struct ktap_mbuffer {
115 #define mbuff_init(buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
116 #define mbuff(buff) ((buff)->buffer)
117 #define mbuff_reset(buff) ((buff)->n = 0, memset((buff)->buffer, 0, (buff)->buffsize))
118 #define mbuff_len(buff) ((buff)->n)
119 #define mbuff_size(buff) ((buff)->buffsize)
121 #define mbuff_resize(buff, size) \
122 (ktapc_realloc((buff)->buffer, (buff)->buffsize, size, char), \
123 (buff)->buffsize = size)
125 #define mbuff_free(buff) mbuff_resize(buff, 0)
129 * state of the lexer plus state of the parser when shared by all
132 typedef struct ktap_lexstate {
133 char *ptr; /* source file reading position */
134 int current; /* current character (charint) */
135 int linenumber; /* input line counter */
136 int lastline; /* line of last token `consumed' */
137 ktap_token t; /* current token */
138 ktap_token lookahead; /* look ahead token */
139 struct ktap_funcstate *fs; /* current function (parser) */
140 ktap_mbuffer *buff; /* buffer for tokens */
141 struct ktap_dyndata *dyd; /* dynamic structures used by the parser */
142 ktap_string *source; /* current source name */
143 ktap_string *envn; /* environment variable name */
144 char decpoint; /* locale decimal point */
150 * Expression descriptor
153 VVOID, /* no value */
157 VK, /* info = index of constant in `k' */
158 VKNUM, /* nval = numerical value */
159 VNONRELOC, /* info = result register */
160 VLOCAL, /* info = local register */
161 VUPVAL, /* info = index of upvalue in 'upvalues' */
162 VINDEXED, /* t = table register/upvalue; idx = index R/K */
163 VJMP, /* info = instruction pc */
164 VRELOCABLE, /* info = instruction pc */
165 VCALL, /* info = instruction pc */
166 VVARARG, /* info = instruction pc */
173 #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED)
174 #define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL)
176 typedef struct ktap_expdesc {
179 struct { /* for indexed variables (VINDEXED) */
180 short idx; /* index (R/K) */
181 u8 t; /* table (register or upvalue) */
182 u8 vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
184 int info; /* for generic use */
185 ktap_number nval; /* for VKNUM */
187 int t; /* patch list of `exit when true' */
188 int f; /* patch list of `exit when false' */
192 typedef struct ktap_vardesc {
193 short idx; /* variable index in stack */
197 /* description of pending goto statements and label statements */
198 typedef struct ktap_labeldesc {
199 ktap_string *name; /* label identifier */
200 int pc; /* position in code */
201 int line; /* line where it appeared */
202 u8 nactvar; /* local level where it appears in current block */
206 /* list of labels or gotos */
207 typedef struct ktap_labellist {
208 ktap_labeldesc *arr; /* array */
209 int n; /* number of entries in use */
210 int size; /* array size */
214 /* dynamic structures used by the parser */
215 typedef struct ktap_dyndata {
216 struct { /* list of active local variables */
221 ktap_labellist gt; /* list of pending gotos */
222 ktap_labellist label; /* list of active labels */
226 /* control of blocks */
227 struct ktap_blockcnt; /* defined in lparser.c */
230 /* state needed to generate code for a given function */
231 typedef struct ktap_funcstate {
232 ktap_proto *f; /* current function header */
233 ktap_tab *h; /* table to find (and reuse) elements in `k' */
234 struct ktap_funcstate *prev; /* enclosing function */
235 struct ktap_lexstate *ls; /* lexical state */
236 struct ktap_blockcnt *bl; /* chain of current blocks */
237 int pc; /* next position to code (equivalent to `ncode') */
238 int lasttarget; /* 'label' of last 'jump label' */
239 int jpc; /* list of pending jumps to `pc' */
240 int nk; /* number of elements in `k' */
241 int np; /* number of elements in `p' */
242 int firstlocal; /* index of first local var (in ktap_dyndata array) */
243 short nlocvars; /* number of elements in 'f->locvars' */
244 u8 nactvar; /* number of active local variables */
245 u8 nups; /* number of upvalues */
246 u8 freereg; /* first free register */
251 * Marks the end of a patch list. It is an invalid value both as an absolute
252 * address, and as a list link (would link an element to itself).
258 * grep "ORDER OPR" if you change these enums (ORDER OP)
260 typedef enum BinOpr {
261 OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
263 OPR_EQ, OPR_LT, OPR_LE,
264 OPR_NE, OPR_GT, OPR_GE,
270 typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
273 #define getcode(fs,e) ((fs)->f->code[(e)->u.info])
275 #define codegen_codeAsBx(fs,o,A,sBx) codegen_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
277 #define codegen_setmultret(fs,e) codegen_setreturns(fs, e, KTAP_MULTRET)
279 #define codegen_jumpto(fs,t) codegen_patchlist(fs, codegen_jump(fs), t)
282 #define ktapc_realloc(v, osize, nsize, t) \
283 ((v) = (t *)ktapc_reallocv(v, osize * sizeof(t), nsize * sizeof(t)))
285 #define ktapc_reallocvector(v,oldn,n,t) ktapc_realloc(v,oldn,n,t)
288 #define ktapc_growvector(v,nelems,size,t,limit,e) \
289 if ((nelems)+1 > (size)) \
290 ((v)=(t *)ktapc_growaux(v,&(size),sizeof(t),limit,e))
294 ktap_string *lex_newstring(ktap_lexstate *ls, const char *str, size_t l);
295 const char *lex_token2str(ktap_lexstate *ls, int token);
296 void lex_syntaxerror(ktap_lexstate *ls, const char *msg);
297 void lex_setinput(ktap_lexstate *ls, char *ptr, ktap_string *source, int firstchar);
298 void lex_next(ktap_lexstate *ls);
299 int lex_lookahead(ktap_lexstate *ls);
300 void lex_read_string_until(ktap_lexstate *ls, int c);
301 ktap_closure *ktapc_parser(char *pos, const char *name);
302 ktap_string *ktapc_ts_new(const char *str);
303 int ktapc_ts_eqstr(ktap_string *a, ktap_string *b);
304 ktap_string *ktapc_ts_newlstr(const char *str, size_t l);
305 ktap_proto *ktapc_newproto();
306 ktap_tab *ktapc_table_new();
307 const ktap_value *ktapc_table_get(ktap_tab *t, const ktap_value *key);
308 void ktapc_table_setvalue(ktap_tab *t, const ktap_value *key, ktap_value *val);
309 ktap_closure *ktapc_newclosure(int n);
310 char *ktapc_sprintf(const char *fmt, ...);
312 void *ktapc_reallocv(void *block, size_t osize, size_t nsize);
313 void *ktapc_growaux(void *block, int *size, size_t size_elems, int limit,
316 void ktapio_exit(void);
317 int ktapio_create(const char *output_filename);
319 ktap_eventdef_info *ktapc_parse_eventdef(const char *eventdef);
320 void cleanup_event_resources(void);
323 #define verbose_printf(...) \
325 printf("[verbose] " __VA_ARGS__);
327 #define ktapc_equalobj(t1, t2) kp_equalobjv(NULL, t1, t2)
329 int codegen_stringK(ktap_funcstate *fs, ktap_string *s);
330 void codegen_indexed(ktap_funcstate *fs, ktap_expdesc *t, ktap_expdesc *k);
331 void codegen_setreturns(ktap_funcstate *fs, ktap_expdesc *e, int nresults);
332 void codegen_reserveregs(ktap_funcstate *fs, int n);
333 void codegen_exp2nextreg(ktap_funcstate *fs, ktap_expdesc *e);
334 void codegen_nil(ktap_funcstate *fs, int from, int n);
335 void codegen_patchlist(ktap_funcstate *fs, int list, int target);
336 void codegen_patchclose(ktap_funcstate *fs, int list, int level);
337 int codegen_jump(ktap_funcstate *fs);
338 void codegen_patchtohere(ktap_funcstate *fs, int list);
339 int codegen_codeABx(ktap_funcstate *fs, OpCode o, int a, unsigned int bc);
340 void codegen_ret(ktap_funcstate *fs, int first, int nret);
341 void codegen_exp2anyregup(ktap_funcstate *fs, ktap_expdesc *e);
342 void codegen_exp2val(ktap_funcstate *fs, ktap_expdesc *e);
343 int codegen_exp2RK(ktap_funcstate *fs, ktap_expdesc *e);
344 int codegen_codeABC(ktap_funcstate *fs, OpCode o, int a, int b, int c);
345 void codegen_setlist(ktap_funcstate *fs, int base, int nelems, int tostore);
346 void codegen_fixline (ktap_funcstate *fs, int line);
347 void codegen_dischargevars(ktap_funcstate *fs, ktap_expdesc *e);
348 void codegen_self(ktap_funcstate *fs, ktap_expdesc *e, ktap_expdesc *key);
349 void codegen_prefix(ktap_funcstate *fs, UnOpr op, ktap_expdesc *e, int line);
350 void codegen_infix(ktap_funcstate *fs, BinOpr op, ktap_expdesc *v);
351 void codegen_posfix(ktap_funcstate *fs, BinOpr op, ktap_expdesc *e1, ktap_expdesc *e2, int line);
352 void codegen_setoneret(ktap_funcstate *fs, ktap_expdesc *e);
353 void codegen_storevar(ktap_funcstate *fs, ktap_expdesc *var, ktap_expdesc *ex);
354 void codegen_storeincr(ktap_funcstate *fs, ktap_expdesc *var, ktap_expdesc *ex);
355 void codegen_store_aggr(ktap_funcstate *fs, ktap_expdesc *var,
357 void codegen_goiftrue(ktap_funcstate *fs, ktap_expdesc *e);
358 int codegen_getlabel(ktap_funcstate *fs);
359 int codegen_codek(ktap_funcstate *fs, int reg, int k);
360 int codegen_numberK(ktap_funcstate *fs, ktap_number r);
361 void codegen_checkstack(ktap_funcstate *fs, int n);
362 void codegen_goiffalse(ktap_funcstate *fs, ktap_expdesc *e);
363 void codegen_concat(ktap_funcstate *fs, int *l1, int l2);
364 int codegen_exp2anyreg(ktap_funcstate *fs, ktap_expdesc *e);
366 typedef int (*ktap_writer)(const void* p, size_t sz, void* ud);
367 int ktapc_dump(const ktap_proto *f, ktap_writer w, void *data, int strip);
369 void ktapc_chunkid(char *out, const char *source, size_t bufflen);
370 int ktapc_str2d(const char *s, size_t len, ktap_number *result);
371 int ktapc_hexavalue(int c);
372 ktap_number ktapc_arith(int op, ktap_number v1, ktap_number v2);
373 int ktapc_int2fb(unsigned int x);
374 bool strglobmatch(const char *str, const char *pat);
375 int kallsyms_parse(void *arg,
376 int(*process_symbol)(void *arg, const char *name,
377 char type, unsigned long start));
379 unsigned long find_kernel_symbol(const char *symbol);
380 void list_available_events(const char *match);
383 #ifdef CONFIG_KTAP_FFI
384 #include "../include/ktap_ffi.h"
386 typedef struct cp_csymbol_state {
387 int cs_nr; /* number of c symbols */
388 int cs_arr_size; /* size of current symbol arrays */
392 cp_csymbol_state *ctype_get_csym_state(void);