flush
[m6w6/ext-psi] / src / parser.h
1 #ifndef _PSI_PARSER_H
2 #define _PSI_PARSER_H
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stdarg.h>
7 #include <string.h>
8
9 #include <Zend/zend_types.h>
10 #include <Zend/zend_API.h> /* fcall */
11
12 #include "parser_proc.h"
13
14 #define BSIZE 256
15
16 #define PSI_T_POINTER PSI_T_ASTERISK
17 #define PSI_T_LONG_DOUBLE (PSI_T_DOUBLE << 16)
18
19 typedef int token_t;
20
21 size_t psi_t_alignment(token_t);
22 size_t psi_t_size(token_t);
23
24 typedef struct PSI_Token {
25 token_t type;
26 unsigned size, line, col;
27 char *text, *file;
28 char buf[1];
29 } PSI_Token;
30
31 static inline PSI_Token *PSI_TokenCopy(PSI_Token *src);
32
33 typedef union impl_val {
34 char cval;
35 int8_t i8;
36 uint8_t u8;
37 short sval;
38 int16_t i16;
39 uint16_t u16;
40 int ival;
41 int32_t i32;
42 uint32_t u32;
43 long lval;
44 int64_t i64;
45 uint64_t u64;
46 float fval;
47 double dval;
48 #ifdef HAVE_LONG_DOUBLE
49 long double ldval;
50 #endif
51 union {
52 zend_bool bval;
53 zend_long lval;
54 zend_string *str;
55 struct {
56 zend_fcall_info *fci;
57 zend_fcall_info_cache *fcc;
58 } cb;
59 } zend;
60 void *ptr;
61 uint8_t _dbg[sizeof(void *)];
62 } impl_val;
63
64 typedef struct decl_type {
65 PSI_Token *token;
66 char *name;
67 token_t type;
68 struct decl_type *real;
69 struct decl_struct *strct;
70 struct decl_union *unn;
71 struct decl_enum *enm;
72 struct decl *func;
73 } decl_type;
74
75 static inline decl_type *init_decl_type(token_t type, const char *name) {
76 decl_type *t = calloc(1, sizeof(*t));
77 t->type = type;
78 t->name = strdup(name);
79 return t;
80 }
81
82 static inline decl_type *real_decl_type(decl_type *type) {
83 while (type->real) {
84 type = type->real;
85 }
86 return type;
87 }
88
89 static inline void free_decl(struct decl *decl);
90 static inline void free_decl_type(decl_type *type) {
91 if (type->token) {
92 free(type->token);
93 }
94 if (type->type == PSI_T_FUNCTION) {
95 free_decl(type->func);
96 }
97 free(type->name);
98 free(type);
99 }
100
101 typedef struct decl_var {
102 PSI_Token *token;
103 char *name;
104 unsigned pointer_level;
105 unsigned array_size;
106 struct decl_arg *arg;
107 } decl_var;
108
109 static inline decl_var *init_decl_var(const char *name, unsigned pl, unsigned as) {
110 decl_var *v = calloc(1, sizeof(*v));
111 v->name = (char *) strdup((const char *) name);
112 v->pointer_level = pl;
113 v->array_size = as;
114 return v;
115 }
116
117 static inline decl_var *copy_decl_var(decl_var *src) {
118 decl_var *dest = calloc(1, sizeof(*dest));
119
120 memcpy(dest, src, sizeof(*dest));
121 dest->name = strdup(dest->name);
122 if (dest->token) {
123 dest->token = PSI_TokenCopy(dest->token);
124 }
125 return dest;
126 }
127
128 static inline void free_decl_var(decl_var *var) {
129 if (var->token) {
130 free(var->token);
131 }
132 free(var->name);
133 free(var);
134 }
135
136 typedef struct decl_struct_layout {
137 size_t pos;
138 size_t len;
139 } decl_struct_layout;
140
141 static inline decl_struct_layout *init_decl_struct_layout(size_t pos, size_t len) {
142 decl_struct_layout *l = calloc(1, sizeof(*l));
143 ZEND_ASSERT(pos+len);
144 l->pos = pos;
145 l->len = len;
146 return l;
147 }
148
149 static inline void free_decl_struct_layout(decl_struct_layout *l) {
150 free(l);
151 }
152
153 typedef struct decl_arg {
154 PSI_Token *token;
155 decl_type *type;
156 decl_var *var;
157 decl_struct_layout *layout;
158 struct let_stmt *let;
159 impl_val val;
160 void *ptr;
161 void *mem;
162 } decl_arg;
163
164 static inline decl_arg *init_decl_arg(decl_type *type, decl_var *var) {
165 decl_arg *arg = calloc(1, sizeof(*arg));
166 arg->token = var->token;
167 arg->type = type;
168 arg->var = var;
169 var->arg = arg;
170 arg->ptr = &arg->val;
171 return arg;
172 }
173
174 static inline void free_decl_arg(decl_arg *arg) {
175 if (arg->token && arg->token != arg->var->token) {
176 free(arg->token);
177 }
178 free_decl_type(arg->type);
179 free_decl_var(arg->var);
180 if (arg->layout) {
181 free_decl_struct_layout(arg->layout);
182 }
183 free(arg);
184 }
185
186 typedef struct decl_typedefs {
187 size_t count;
188 decl_arg **list;
189 } decl_typedefs;
190
191 static inline decl_typedefs *add_decl_typedef(decl_typedefs *defs, decl_arg *def) {
192 if (!defs) {
193 defs = calloc(1, sizeof(*defs));
194 }
195 defs->list = realloc(defs->list, ++defs->count * sizeof(*defs->list));
196 defs->list[defs->count-1] = def;
197 return defs;
198 }
199
200 static void free_decl_typedefs(decl_typedefs *defs) {
201 size_t i;
202
203 for (i = 0; i < defs->count; ++i) {
204 free_decl_arg(defs->list[i]);
205 }
206 free(defs->list);
207 free(defs);
208 }
209
210 typedef struct decl_vars {
211 decl_var **vars;
212 size_t count;
213 } decl_vars;
214
215 static inline decl_vars *init_decl_vars(decl_var *var) {
216 decl_vars *vars = calloc(1, sizeof(*vars));
217 if (var) {
218 vars->count = 1;
219 vars->vars = calloc(1, sizeof(*vars->vars));
220 vars->vars[0] = var;
221 }
222 return vars;
223 }
224
225 static inline decl_vars *add_decl_var(decl_vars *vars, decl_var *var) {
226 vars->vars = realloc(vars->vars, ++vars->count * sizeof(*vars->vars));
227 vars->vars[vars->count-1] = var;
228 return vars;
229 }
230
231 static inline void free_decl_vars(decl_vars *vars) {
232 size_t i;
233
234 for (i = 0; i < vars->count; ++i) {
235 free_decl_var(vars->vars[i]);
236 }
237 free(vars->vars);
238 free(vars);
239 }
240
241 typedef struct decl_args {
242 decl_arg **args;
243 size_t count;
244 unsigned varargs:1;
245 } decl_args;
246
247 static inline decl_args *init_decl_args(decl_arg *arg) {
248 decl_args *args = calloc(1, sizeof(*args));
249 if (arg) {
250 args->count = 1;
251 args->args = calloc(1, sizeof(*args->args));
252 args->args[0] = arg;
253 }
254 return args;
255 }
256
257 static inline decl_args *add_decl_arg(decl_args *args, decl_arg *arg) {
258 args->args = realloc(args->args, ++args->count * sizeof(*args->args));
259 args->args[args->count-1] = arg;
260 return args;
261 }
262
263 static inline void free_decl_args(decl_args *args) {
264 size_t i;
265
266 for (i = 0; i < args->count; ++i) {
267 free_decl_arg(args->args[i]);
268 }
269 free(args->args);
270 free(args);
271 }
272
273 typedef struct decl_abi {
274 PSI_Token *token;
275 char *convention;
276 } decl_abi;
277
278 static inline decl_abi *init_decl_abi(const char *convention) {
279 decl_abi *abi = calloc(1, sizeof(*abi));
280 abi->convention = strdup(convention);
281 return abi;
282 }
283
284 static inline void free_decl_abi(decl_abi *abi) {
285 if (abi->token) {
286 free(abi->token);
287 }
288 free(abi->convention);
289 free(abi);
290 }
291
292 typedef struct decl_callinfo {
293 void *sym;
294 void *info;
295 size_t argc;
296 void **args;
297 void **rval;
298 struct {
299 void *data;
300 void (*dtor)(void *data);
301 } closure;
302 } decl_callinfo;
303
304 typedef struct decl {
305 decl_abi *abi;
306 decl_arg *func;
307 decl_args *args;
308 struct impl *impl;
309 decl_callinfo call;
310 } decl;
311
312 static inline decl* init_decl(decl_abi *abi, decl_arg *func, decl_args *args) {
313 decl *d = calloc(1, sizeof(*d));
314 d->abi = abi;
315 d->func = func;
316 d->args = args;
317 return d;
318 }
319
320 static inline void free_decl(decl *d) {
321 free_decl_abi(d->abi);
322 free_decl_arg(d->func);
323 if (d->args) {
324 free_decl_args(d->args);
325 }
326 free(d);
327 }
328
329 typedef struct decls {
330 size_t count;
331 decl **list;
332 } decls;
333
334 static inline decls *add_decl(decls *decls, decl *decl) {
335 if (!decls) {
336 decls = calloc(1, sizeof(*decls));
337 }
338 decls->list = realloc(decls->list, ++decls->count * sizeof(*decls->list));
339 decls->list[decls->count-1] = decl;
340 return decls;
341 }
342
343 static inline void free_decls(decls *decls) {
344 size_t i;
345
346 for (i = 0; i < decls->count; ++i) {
347 free_decl(decls->list[i]);
348 }
349 free(decls->list);
350 free(decls);
351 }
352
353
354 typedef struct decl_struct {
355 PSI_Token *token;
356 char *name;
357 decl_args *args;
358 size_t size;
359 size_t align;
360 struct {
361 void *type;
362 void (*dtor)(void *type);
363 } engine;
364 } decl_struct;
365
366 static inline decl_struct *init_decl_struct(const char *name, decl_args *args) {
367 decl_struct *s = calloc(1, sizeof(*s));
368 s->name = strdup(name);
369 s->args = args;
370 return s;
371 }
372
373 static inline void free_decl_struct(decl_struct *s) {
374 if (s->token) {
375 free(s->token);
376 }
377 if (s->args) {
378 free_decl_args(s->args);
379 }
380 if (s->engine.type && s->engine.dtor) {
381 s->engine.dtor(s->engine.type);
382 }
383 free(s->name);
384 free(s);
385 }
386
387 typedef struct decl_structs {
388 size_t count;
389 decl_struct **list;
390 } decl_structs;
391
392 static inline decl_structs *add_decl_struct(decl_structs *ss, decl_struct *s) {
393 if (!ss) {
394 ss = calloc(1, sizeof(*ss));
395 }
396 ss->list = realloc(ss->list, ++ss->count * sizeof(*ss->list));
397 ss->list[ss->count-1] = s;
398 return ss;
399 }
400
401 static inline void free_decl_structs(decl_structs *ss) {
402 size_t i;
403
404 for (i = 0; i < ss->count; ++i) {
405 free_decl_struct(ss->list[i]);
406 }
407 free(ss->list);
408 free(ss);
409 }
410
411 typedef struct decl_union {
412 PSI_Token *token;
413 char *name;
414 decl_args *args;
415 size_t size;
416 size_t align;
417 } decl_union;
418
419 static inline decl_union *init_decl_union(const char *name, decl_args *args) {
420 decl_union *u = calloc(1, sizeof(*u));
421 u->name = strdup(name);
422 u->args = args;
423 return u;
424 }
425
426 static inline void free_decl_union(decl_union *u) {
427 if (u->token) {
428 free(u->token);
429 }
430 if (u->args) {
431 free_decl_args(u->args);
432 }
433 free(u->name);
434 free(u);
435 }
436
437 typedef struct decl_unions {
438 decl_union **list;
439 size_t count;
440 } decl_unions;
441
442 static inline decl_unions *add_decl_union(decl_unions *uu, decl_union *u) {
443 if (!uu) {
444 uu = calloc(1, sizeof(*uu));
445 }
446 uu->list = realloc(uu->list, ++uu->count * sizeof(*uu->list));
447 uu->list[uu->count-1] = u;
448 return uu;
449 }
450
451 static inline void free_decl_unions(decl_unions *uu) {
452 size_t i;
453
454 for (i = 0; i < uu->count; ++i) {
455 free_decl_union(uu->list[i]);
456 }
457 free(uu->list);
458 free(uu);
459 }
460
461 typedef struct impl_type {
462 char *name;
463 token_t type;
464 } impl_type;
465
466 static inline impl_type *init_impl_type(token_t type, const char *name) {
467 impl_type *t = calloc(1, sizeof(*t));
468
469 t->type = type;
470 t->name = strdup(name);
471 return t;
472 }
473
474 static inline void free_impl_type(impl_type *type) {
475 free(type->name);
476 free(type);
477 }
478
479 typedef struct impl_var {
480 PSI_Token *token;
481 char *name;
482 unsigned reference:1;
483 } impl_var;
484
485 static inline impl_var *init_impl_var(const char *name, int is_reference) {
486 impl_var *var = calloc(1, sizeof(*var));
487 var->name = strdup(name);
488 var->reference = is_reference;
489 return var;
490 }
491
492 static inline void free_impl_var(impl_var *var) {
493 if (var->token) {
494 free(var->token);
495 }
496 free(var->name);
497 free(var);
498 }
499
500 typedef struct impl_def_val {
501 token_t type;
502 char *text;
503 } impl_def_val;
504
505 static inline impl_def_val *init_impl_def_val(token_t t, const char *text) {
506 impl_def_val *def = calloc(1, sizeof(*def));
507 def->type = t;
508 def->text = strdup(text);
509 return def;
510 }
511
512 static inline void free_impl_def_val(impl_def_val *def) {
513 free(def->text);
514 free(def);
515 }
516
517 typedef struct const_type {
518 token_t type;
519 char *name;
520 } const_type;
521
522 static inline const_type *init_const_type(token_t type, const char *name) {
523 const_type *ct = calloc(1, sizeof(*ct));
524 ct->type = type;
525 ct->name = strdup(name);
526 return ct;
527 }
528
529 static inline void free_const_type(const_type *type) {
530 free(type->name);
531 free(type);
532 }
533
534 typedef struct constant {
535 const_type *type;
536 char *name;
537 impl_def_val *val;
538 } constant;
539
540 static inline constant *init_constant(const_type *type, const char *name, impl_def_val *val) {
541 constant *c = calloc(1, sizeof(*c));
542 c->type = type;
543 c->name = strdup(name);
544 c->val = val;
545 return c;
546 }
547
548 static inline void free_constant(constant *constant) {
549 free_const_type(constant->type);
550 free(constant->name);
551 free_impl_def_val(constant->val);
552 free(constant);
553 }
554
555 typedef struct constants {
556 size_t count;
557 constant **list;
558 } constants;
559
560 static inline constants *add_constant(constants *constants, constant *constant) {
561 if (!constants) {
562 constants = calloc(1, sizeof(*constants));
563 }
564 constants->list = realloc(constants->list, ++constants->count * sizeof(*constants->list));
565 constants->list[constants->count-1] = constant;
566 return constants;
567 }
568
569 static inline void free_constants(constants *c) {
570 size_t i;
571
572 for (i = 0; i < c->count; ++i) {
573 free_constant(c->list[i]);
574 }
575 free(c->list);
576 free(c);
577 }
578
579 typedef struct impl_arg {
580 impl_type *type;
581 impl_var *var;
582 impl_def_val *def;
583 impl_val val;
584 zval *_zv;
585 } impl_arg;
586
587 static inline impl_arg *init_impl_arg(impl_type *type, impl_var *var, impl_def_val *def) {
588 impl_arg *arg = calloc(1, sizeof(*arg));
589 arg->type = type;
590 arg->var = var;
591 arg->def = def;
592 return arg;
593 }
594
595 static inline void free_impl_arg(impl_arg *arg) {
596 free_impl_type(arg->type);
597 free_impl_var(arg->var);
598 if (arg->def) {
599 free_impl_def_val(arg->def);
600 }
601 free(arg);
602 }
603
604 typedef struct impl_vararg {
605 impl_arg *name;
606 struct impl_args *args;
607 token_t *types;
608 impl_val *values;
609 void **free_list;
610 } impl_vararg;
611
612 typedef struct impl_args {
613 impl_arg **args;
614 size_t count;
615 impl_vararg vararg;
616 } impl_args;
617
618 static inline impl_args *init_impl_args(impl_arg *arg) {
619 impl_args *args = calloc(1, sizeof(*args));
620 if (arg) {
621 args->count = 1;
622 args->args = calloc(1, sizeof(*args->args));
623 args->args[0] = arg;
624 }
625 return args;
626 }
627
628 static inline impl_args *add_impl_arg(impl_args *args, impl_arg *arg) {
629 args->args = realloc(args->args, ++args->count * sizeof(*args->args));
630 args->args[args->count-1] = arg;
631 return args;
632 }
633
634 static inline void free_impl_args(impl_args *args) {
635 size_t i;
636
637 for (i = 0; i < args->count; ++i) {
638 free_impl_arg(args->args[i]);
639 }
640 if (args->vararg.name) {
641 free_impl_arg(args->vararg.name);
642 }
643 free(args->args);
644 free(args);
645 }
646
647 typedef struct impl_func {
648 PSI_Token *token;
649 char *name;
650 impl_args *args;
651 impl_type *return_type;
652 unsigned return_reference:1;
653 } impl_func;
654
655 static inline impl_func *init_impl_func(char *name, impl_args *args, impl_type *type, int ret_reference) {
656 impl_func *func = calloc(1, sizeof(*func));
657 func->name = strdup(name);
658 func->args = args ? args : init_impl_args(NULL);
659 func->return_type = type;
660 func->return_reference = ret_reference;
661 return func;
662 }
663
664 static inline void free_impl_func(impl_func *f) {
665 if (f->token) {
666 free(f->token);
667 }
668 free_impl_type(f->return_type);
669 free_impl_args(f->args);
670 free(f->name);
671 free(f);
672 }
673
674 typedef struct num_exp {
675 PSI_Token *token;
676 token_t t;
677 union {
678 char *numb;
679 constant *cnst;
680 decl_var *dvar;
681 struct decl_enum_item *enm;
682 } u;
683 token_t operator;
684 int (*calculator)(int t1, impl_val *v1, int t2, impl_val *v2, impl_val *res);
685 struct num_exp *operand;
686 } num_exp;
687
688 static inline num_exp *init_num_exp(token_t t, void *num) {
689 num_exp *exp = calloc(1, sizeof(*exp));
690 switch (exp->t = t) {
691 case PSI_T_NUMBER:
692 case PSI_T_NSNAME:
693 exp->u.numb = strdup(num);
694 break;
695 case PSI_T_NAME:
696 exp->u.dvar = num;
697 break;
698 EMPTY_SWITCH_DEFAULT_CASE();
699 }
700 return exp;
701 }
702
703 static inline num_exp *copy_num_exp(num_exp *exp) {
704 decl_var *dvar;
705 num_exp *num = calloc(1, sizeof(*num));
706
707 memcpy(num, exp, sizeof(*num));
708
709 if (num->token) {
710 num->token = PSI_TokenCopy(num->token);
711 }
712 if (num->operand) {
713 num->operand = copy_num_exp(num->operand);
714 }
715 switch (num->t) {
716 case PSI_T_NUMBER:
717 case PSI_T_NSNAME:
718 num->u.numb = strdup(num->u.numb);
719 break;
720 case PSI_T_NAME:
721 dvar = init_decl_var(num->u.dvar->name, num->u.dvar->pointer_level, num->u.dvar->array_size);
722 dvar->arg = num->u.dvar->arg;
723 if (num->u.dvar->token) {
724 dvar->token = PSI_TokenCopy(num->u.dvar->token);
725 }
726 num->u.dvar = dvar;
727 break;
728 }
729 return num;
730 }
731
732 static inline void free_num_exp(num_exp *exp) {
733 if (exp->token) {
734 free(exp->token);
735 }
736 switch (exp->t) {
737 case PSI_T_NUMBER:
738 free(exp->u.numb);
739 break;
740 case PSI_T_NSNAME:
741 break;
742 case PSI_T_NAME:
743 free_decl_var(exp->u.dvar);
744 break;
745 case PSI_T_ENUM:
746 break;
747 EMPTY_SWITCH_DEFAULT_CASE();
748 }
749 if (exp->operand) {
750 free_num_exp(exp->operand);
751 }
752 free(exp);
753 }
754
755 typedef struct decl_enum_item {
756 PSI_Token *token;
757 char *name;
758 num_exp *num;
759 num_exp inc;
760 struct decl_enum_item *prev;
761 } decl_enum_item;
762
763 static inline decl_enum_item *init_decl_enum_item(const char *name, num_exp *num) {
764 decl_enum_item *i = calloc(1, sizeof(*i));
765
766 i->name = strdup(name);
767 i->num = num;
768 return i;
769 }
770
771 static inline void free_decl_enum_item(decl_enum_item *i) {
772 if (i->token) {
773 free(i->token);
774 }
775 if (i->num && i->num != &i->inc) {
776 free_num_exp(i->num);
777 }
778 free(i->name);
779 free(i);
780 }
781
782 typedef struct decl_enum_items {
783 decl_enum_item **list;
784 size_t count;
785 } decl_enum_items;
786
787 static inline decl_enum_items *init_decl_enum_items(decl_enum_item *i) {
788 decl_enum_items *l = calloc(1, sizeof(*l));
789
790 if (i) {
791 l->count = 1;
792 l->list = calloc(1, sizeof(*l->list));
793 l->list[0] = i;
794 }
795 return l;
796 }
797
798 static inline decl_enum_items *add_decl_enum_item(decl_enum_items *l, decl_enum_item *i) {
799 l->list = realloc(l->list, sizeof(*l->list) * (l->count + 1));
800 l->list[l->count] = i;
801 if (l->count) {
802 i->prev = l->list[l->count - 1];
803 }
804 ++l->count;
805 return l;
806 }
807
808 static inline void free_decl_enum_items(decl_enum_items *l) {
809 if (l->list) {
810 size_t j;
811
812 for (j = 0; j < l->count; ++j) {
813 free_decl_enum_item(l->list[j]);
814 }
815 free(l->list);
816 }
817 free(l);
818 }
819
820 typedef struct decl_enum {
821 PSI_Token *token;
822 char *name;
823 decl_enum_items *items;
824 } decl_enum;
825
826 static inline decl_enum *init_decl_enum(const char *name, decl_enum_items *l) {
827 decl_enum *e = calloc(1, sizeof(*e));
828
829 e->name = strdup(name);
830 e->items = l;
831 return e;
832 }
833
834 static inline void free_decl_enum(decl_enum *e) {
835 if (e->token) {
836 free(e->token);
837 }
838 if (e->items) {
839 free_decl_enum_items(e->items);
840 }
841 free(e->name);
842 free(e);
843 }
844
845 typedef struct decl_enums {
846 decl_enum **list;
847 size_t count;
848 } decl_enums;
849
850 static inline decl_enums* add_decl_enum(decl_enums *es, decl_enum *e) {
851 if (!es) {
852 es = calloc(1, sizeof(*es));
853 }
854 es->list = realloc(es->list, ++es->count * sizeof(*es->list));
855 es->list[es->count-1] = e;
856 return es;
857 }
858
859 static inline void free_decl_enums(decl_enums *es) {
860 if (es->list) {
861 size_t j;
862
863 for (j = 0; j < es->count; ++j) {
864 free_decl_enum(es->list[j]);
865 }
866 }
867 free(es->list);
868 free(es);
869 }
870
871 typedef struct let_calloc {
872 num_exp *nmemb;
873 num_exp *size;
874 } let_calloc;
875
876 static inline let_calloc *init_let_calloc(num_exp *nmemb, num_exp *size) {
877 let_calloc *alloc = calloc(1, sizeof(*alloc));
878 alloc->nmemb = nmemb;
879 alloc->size = size;
880 return alloc;
881 }
882
883 static inline void free_let_calloc(let_calloc *alloc) {
884 free_num_exp(alloc->nmemb);
885 free_num_exp(alloc->size);
886 free(alloc);
887 }
888
889 typedef struct let_func {
890 token_t type;
891 char *name;
892 impl_var *var;
893 impl_arg *arg;
894 set_values *callback;
895 } let_func;
896
897 static inline let_func *init_let_func(token_t type, const char *name, impl_var *var) {
898 let_func *func = calloc(1, sizeof(*func));
899 func->type = type;
900 func->name = strdup(name);
901 func->var = var;
902 return func;
903 }
904
905 static inline void free_let_func(let_func *func) {
906 free_impl_var(func->var);
907 free(func->name);
908 free(func);
909 }
910
911 #define PSI_LET_REFERENCE 0x1;
912 typedef struct let_val {
913 enum let_val_kind {
914 PSI_LET_NULL,
915 PSI_LET_NUMEXP,
916 PSI_LET_CALLOC,
917 PSI_LET_FUNC,
918 PSI_LET_TMP,
919 } kind;
920 union {
921 num_exp *num;
922 let_calloc *alloc;
923 let_func *func;
924 decl_var *var;
925 } data;
926 union {
927 struct {
928 unsigned is_reference:1;
929 } one;
930 unsigned all;
931 } flags;
932 } let_val;
933
934 static inline let_val *init_let_val(enum let_val_kind kind, void *data) {
935 let_val *let = calloc(1, sizeof(*let));
936 switch (let->kind = kind) {
937 case PSI_LET_NULL:
938 break;
939 case PSI_LET_NUMEXP:
940 let->data.num = data;
941 break;
942 case PSI_LET_CALLOC:
943 let->data.alloc = data;
944 break;
945 case PSI_LET_FUNC:
946 let->data.func = data;
947 break;
948 case PSI_LET_TMP:
949 let->data.var = data;
950 break;
951 EMPTY_SWITCH_DEFAULT_CASE();
952 }
953 return let;
954 }
955
956 static inline void free_let_val(let_val *let) {
957 switch (let->kind) {
958 case PSI_LET_NULL:
959 break;
960 case PSI_LET_NUMEXP:
961 free_num_exp(let->data.num);
962 break;
963 case PSI_LET_CALLOC:
964 free_let_calloc(let->data.alloc);
965 break;
966 case PSI_LET_FUNC:
967 free_let_func(let->data.func);
968 break;
969 case PSI_LET_TMP:
970 free_decl_var(let->data.var);
971 break;
972 EMPTY_SWITCH_DEFAULT_CASE();
973 }
974 free(let);
975 }
976
977 typedef struct let_stmt {
978 decl_var *var;
979 let_val *val;
980
981 void *ptr;
982 } let_stmt;
983
984 static inline let_stmt *init_let_stmt(decl_var *var, let_val *val) {
985 let_stmt *let = calloc(1, sizeof(*let));
986 let->var = var;
987 let->val = val;
988 return let;
989 }
990
991 static inline void free_let_stmt(let_stmt *stmt) {
992 if (stmt->val) {
993 if (stmt->val->kind == PSI_LET_TMP && stmt->var->arg) {
994 free_decl_arg(stmt->var->arg);
995 }
996 free_let_val(stmt->val);
997 }
998 free_decl_var(stmt->var);
999 free(stmt);
1000 }
1001
1002 struct set_value;
1003
1004 typedef struct set_func {
1005 PSI_Token *token;
1006 token_t type;
1007 char *name;
1008 void (*handler)(zval *, struct set_value *set, impl_val *ret_val);
1009 } set_func;
1010
1011 static inline set_func *init_set_func(token_t type, const char *name) {
1012 set_func *func = calloc(1, sizeof(*func));
1013 func->type = type;
1014 func->name = strdup(name);
1015 return func;
1016 }
1017
1018 static inline void free_set_func(set_func *func) {
1019 if (func->token) {
1020 free(func->token);
1021 }
1022 free(func->name);
1023 free(func);
1024 }
1025
1026 typedef struct set_value {
1027 set_func *func;
1028 decl_vars *vars;
1029 num_exp *num;
1030 struct {
1031 struct set_value *set;
1032 impl_val *val;
1033 } outer;
1034 struct set_value **inner;
1035 size_t count;
1036 } set_value;
1037
1038 static inline set_value *init_set_value(set_func *func, decl_vars *vars) {
1039 set_value *val = calloc(1, sizeof(*val));
1040 val->func = func;
1041 val->vars = vars;
1042 return val;
1043 }
1044 static inline set_value *add_inner_set_value(set_value *val, set_value *inner) {
1045 val->inner = realloc(val->inner, ++val->count * sizeof(*val->inner));
1046 val->inner[val->count-1] = inner;
1047 inner->outer.set = val;
1048 return val;
1049 }
1050
1051 static inline void free_set_value(set_value *val) {
1052 if (val->func) {
1053 free_set_func(val->func);
1054 }
1055 if (val->vars) {
1056 free_decl_vars(val->vars);
1057 }
1058 if (val->inner && (!val->outer.set || val->outer.set->inner != val->inner)) {
1059 size_t i;
1060 for (i = 0; i < val->count; ++i) {
1061 free_set_value(val->inner[i]);
1062 }
1063 free(val->inner);
1064 }
1065 if (val->num) {
1066 free_num_exp(val->num);
1067 }
1068 free(val);
1069 }
1070
1071 typedef struct set_values {
1072 set_value **vals;
1073 size_t count;
1074 } set_values;
1075
1076 static inline set_values *init_set_values(set_value *val) {
1077 set_values *vals = calloc(1, sizeof(*vals));
1078 if (val) {
1079 vals->count = 1;
1080 vals->vals = calloc(1, sizeof(val));
1081 vals->vals[0] = val;
1082 }
1083 return vals;
1084 }
1085
1086 static inline set_values *add_set_value(set_values *vals, set_value *val) {
1087 vals->vals = realloc(vals->vals, ++vals->count * sizeof(val));
1088 vals->vals[vals->count-1] = val;
1089 return vals;
1090 }
1091
1092 static inline void free_set_values(set_values *vals) {
1093 if (vals->vals) {
1094 free(vals->vals);
1095 }
1096 free(vals);
1097 }
1098
1099 typedef struct set_stmt {
1100 impl_var *var;
1101 set_value *val;
1102 impl_arg *arg;
1103 } set_stmt;
1104
1105 static inline set_stmt *init_set_stmt(impl_var *var, set_value *val) {
1106 set_stmt *set = calloc(1, sizeof(*set));
1107 set->var = var;
1108 set->val = val;
1109 return set;
1110 }
1111
1112 static inline void free_set_stmt(set_stmt *set) {
1113 free_impl_var(set->var);
1114 free_set_value(set->val);
1115 free(set);
1116 }
1117
1118 typedef struct return_stmt {
1119 PSI_Token *token;
1120 set_value *set;
1121 decl_arg *decl;
1122 } return_stmt;
1123
1124 static inline return_stmt *init_return_stmt(set_value *val) {
1125 return_stmt *ret = calloc(1, sizeof(*ret));
1126 ret->set = val;
1127 return ret;
1128 }
1129
1130 static inline void free_return_stmt(return_stmt *ret) {
1131 if (ret->token) {
1132 free(ret->token);
1133 }
1134 free_set_value(ret->set);
1135 free(ret);
1136 }
1137
1138 typedef struct free_call {
1139 PSI_Token *token;
1140 char *func;
1141 decl_vars *vars;
1142 decl *decl;
1143 } free_call;
1144
1145 static inline free_call *init_free_call(const char *func, decl_vars *vars) {
1146 free_call *f = calloc(1, sizeof(*f));
1147 f->func = strdup(func);
1148 f->vars = vars;
1149 return f;
1150 }
1151
1152 static inline void free_free_call(free_call *f) {
1153 if (f->token) {
1154 free(f->token);
1155 }
1156 free(f->func);
1157 free_decl_vars(f->vars);
1158 free(f);
1159 }
1160
1161 typedef struct free_calls {
1162 free_call **list;
1163 size_t count;
1164 } free_calls;
1165
1166 static inline free_calls *init_free_calls(free_call *f) {
1167 free_calls *fcs = calloc(1, sizeof(*fcs));
1168 if (f) {
1169 fcs->count = 1;
1170 fcs->list = calloc(1, sizeof(*fcs->list));
1171 fcs->list[0] = f;
1172 }
1173 return fcs;
1174 }
1175
1176 static inline void free_free_calls(free_calls *fcs) {
1177 size_t i;
1178
1179 for (i = 0; i < fcs->count; ++i) {
1180 free_free_call(fcs->list[i]);
1181 }
1182 free(fcs->list);
1183 free(fcs);
1184 }
1185
1186 static inline free_calls *add_free_call(free_calls *fcs, free_call *f) {
1187 fcs->list = realloc(fcs->list, ++fcs->count * sizeof(*fcs->list));
1188 fcs->list[fcs->count-1] = f;
1189 return fcs;
1190 }
1191
1192 typedef struct free_stmt {
1193 free_calls *calls;
1194 } free_stmt;
1195
1196 static inline free_stmt *init_free_stmt(free_calls *calls) {
1197 free_stmt *f = calloc(1, sizeof(*f));
1198 f->calls = calls;
1199 return f;
1200 }
1201
1202 static inline void free_free_stmt(free_stmt *f) {
1203 free_free_calls(f->calls);
1204 free(f);
1205 }
1206
1207 typedef struct impl_stmt {
1208 token_t type;
1209 union {
1210 let_stmt *let;
1211 set_stmt *set;
1212 return_stmt *ret;
1213 free_stmt *fre;
1214 void *ptr;
1215 } s;
1216 } impl_stmt;
1217
1218 static inline impl_stmt *init_impl_stmt(token_t type, void *ptr) {
1219 impl_stmt *stmt = calloc(1, sizeof(*stmt));
1220 stmt->type = type;
1221 stmt->s.ptr = ptr;
1222 return stmt;
1223 }
1224
1225 static inline void free_impl_stmt(impl_stmt *stmt) {
1226 switch (stmt->type) {
1227 case PSI_T_LET:
1228 free_let_stmt(stmt->s.let);
1229 break;
1230 case PSI_T_SET:
1231 free_set_stmt(stmt->s.set);
1232 break;
1233 case PSI_T_RETURN:
1234 free_return_stmt(stmt->s.ret);
1235 break;
1236 case PSI_T_FREE:
1237 free_free_stmt(stmt->s.fre);
1238 break;
1239 }
1240 free(stmt);
1241 }
1242
1243 typedef struct impl_stmts {
1244 struct {
1245 return_stmt **list;
1246 size_t count;
1247 } ret;
1248 struct {
1249 let_stmt **list;
1250 size_t count;
1251 } let;
1252 struct {
1253 set_stmt **list;
1254 size_t count;
1255 } set;
1256 struct {
1257 free_stmt **list;
1258 size_t count;
1259 } fre;
1260 } impl_stmts;
1261
1262 static inline void *add_impl_stmt_ex(void *list, size_t count, void *stmt) {
1263 list = realloc(list, count * sizeof(list));
1264 ((void **)list)[count-1] = stmt;
1265 return list;
1266 }
1267
1268 static inline impl_stmts *add_impl_stmt(impl_stmts *stmts, impl_stmt *stmt) {
1269 switch (stmt->type) {
1270 case PSI_T_RETURN:
1271 stmts->ret.list = add_impl_stmt_ex(stmts->ret.list, ++stmts->ret.count, stmt->s.ret);
1272 break;
1273 case PSI_T_LET:
1274 stmts->let.list = add_impl_stmt_ex(stmts->let.list, ++stmts->let.count, stmt->s.let);
1275 break;
1276 case PSI_T_SET:
1277 stmts->set.list = add_impl_stmt_ex(stmts->set.list, ++stmts->set.count, stmt->s.set);
1278 break;
1279 case PSI_T_FREE:
1280 stmts->fre.list = add_impl_stmt_ex(stmts->fre.list, ++stmts->fre.count, stmt->s.fre);
1281 break;
1282 }
1283 free(stmt);
1284 return stmts;
1285 }
1286
1287 static inline impl_stmts *init_impl_stmts(impl_stmt *stmt) {
1288 impl_stmts *stmts = calloc(1, sizeof(*stmts));
1289 return add_impl_stmt(stmts, stmt);
1290 }
1291
1292 static inline void free_impl_stmts(impl_stmts *stmts) {
1293 size_t i;
1294
1295 for (i = 0; i < stmts->let.count; ++i) {
1296 free_let_stmt(stmts->let.list[i]);
1297 }
1298 free(stmts->let.list);
1299 for (i = 0; i < stmts->ret.count; ++i) {
1300 free_return_stmt(stmts->ret.list[i]);
1301 }
1302 free(stmts->ret.list);
1303 for (i = 0; i < stmts->set.count; ++i) {
1304 free_set_stmt(stmts->set.list[i]);
1305 }
1306 free(stmts->set.list);
1307 for (i = 0; i < stmts->fre.count; ++i) {
1308 free_free_stmt(stmts->fre.list[i]);
1309 }
1310 free(stmts->fre.list);
1311 free(stmts);
1312 }
1313
1314 typedef struct impl {
1315 impl_func *func;
1316 impl_stmts *stmts;
1317 decl *decl;
1318 } impl;
1319
1320 static inline impl *init_impl(impl_func *func, impl_stmts *stmts) {
1321 impl *i = calloc(1, sizeof(*i));
1322 i->func = func;
1323 i->stmts = stmts;
1324 return i;
1325 }
1326
1327 static inline void free_impl(impl *impl) {
1328 free_impl_func(impl->func);
1329 free_impl_stmts(impl->stmts);
1330 free(impl);
1331 }
1332
1333 typedef struct impls {
1334 size_t count;
1335 impl **list;
1336 } impls;
1337
1338 static inline impls *add_impl(impls *impls, impl *impl) {
1339 if (!impls) {
1340 impls = calloc(1, sizeof(*impls));
1341 }
1342 impls->list = realloc(impls->list, ++impls->count * sizeof(*impls->list));
1343 impls->list[impls->count-1] = impl;
1344 return impls;
1345 }
1346
1347 static void free_impls(impls *impls) {
1348 size_t i;
1349
1350 for (i = 0; i < impls->count; ++i) {
1351 free_impl(impls->list[i]);
1352 }
1353 free(impls->list);
1354 free(impls);
1355 }
1356
1357 typedef struct decl_file {
1358 char *ln;
1359 char *fn;
1360 } decl_file;
1361
1362 static inline void free_decl_file(decl_file *file) {
1363 if (file->ln) {
1364 free(file->ln);
1365 }
1366 if (file->fn) {
1367 free(file->fn);
1368 }
1369 memset(file, 0, sizeof(*file));
1370 }
1371
1372 typedef struct decl_libs {
1373 void **dl;
1374 size_t count;
1375 } decl_libs;
1376
1377 static inline void free_decl_libs(decl_libs *libs) {
1378 if (libs->dl) {
1379 size_t i;
1380 for (i = 0; i < libs->count; ++i) {
1381 if (libs->dl[i]) {
1382 dlclose(libs->dl[i]);
1383 }
1384 }
1385 free(libs->dl);
1386 }
1387 memset(libs, 0, sizeof(*libs));
1388 }
1389
1390 static inline void add_decl_lib(decl_libs *libs, void *dlopened) {
1391 libs->dl = realloc(libs->dl, ++libs->count * sizeof(*libs->dl));
1392 libs->dl[libs->count-1] = dlopened;
1393 }
1394
1395 static inline impl_val *deref_impl_val(impl_val *ret_val, decl_var *var) {
1396 unsigned i;
1397
1398 ZEND_ASSERT(var->arg->var != var);
1399 #if 0
1400 fprintf(stderr, "deref: %s pl=%u:%u as=%u:%u %p\n",
1401 var->name, var->pointer_level, var->arg->var->pointer_level,
1402 var->array_size, var->arg->var->array_size, ret_val);
1403 #endif
1404 for (i = 0; i < var->pointer_level; ++i) {
1405 #if 0
1406 fprintf(stderr, "-- %p %p %p\n", ret_val, *(void**)ret_val, ret_val->ptr);
1407 #endif
1408 ret_val = *(void **) ret_val;
1409 }
1410 return ret_val;
1411 }
1412
1413 static inline impl_val *enref_impl_val(void *ptr, decl_var *var) {
1414 impl_val *val, *val_ptr;
1415 unsigned i;
1416
1417 ZEND_ASSERT(var->arg->var == var);
1418 #if 0
1419 fprintf(stderr, "enref: %s pl=%u:%u as=%u:%u\n",
1420 var->name, var->pointer_level, var->arg->var->pointer_level,
1421 var->array_size, var->arg->var->array_size);
1422 #endif
1423 if (!var->pointer_level ){//&& real_decl_type(var->arg->type)->type != PSI_T_STRUCT) {
1424 return ptr;
1425 }
1426
1427 val = val_ptr = calloc(var->pointer_level + 1, sizeof(void *));
1428 for (i = !var->arg->var->array_size; i < var->pointer_level; ++i) {
1429 #if 0
1430 fprintf(stderr, "++\n");
1431 #endif
1432 val_ptr->ptr = (void **) val_ptr + 1;
1433 val_ptr = val_ptr->ptr;
1434 }
1435 val_ptr->ptr = ptr;
1436 return val;
1437 }
1438
1439 static inline impl_val *struct_member_ref(decl_arg *set_arg, impl_val *struct_ptr, impl_val **to_free) {
1440 void *ptr = (char *) struct_ptr + set_arg->layout->pos;
1441 #if 0
1442 fprintf(stderr, "struct member %s: %p\n", set_arg->var->name, ptr);
1443 #endif
1444 return ptr;
1445 }
1446
1447
1448 #define PSI_ERROR 16
1449 #define PSI_WARNING 32
1450 typedef void (*psi_error_cb)(void *context, PSI_Token *token, int type, const char *msg, ...);
1451
1452 #define PSI_DATA(D) ((PSI_Data *) (D))
1453 #define PSI_DATA_MEMBERS \
1454 constants *consts; \
1455 decl_typedefs *defs; \
1456 decl_structs *structs; \
1457 decl_unions *unions; \
1458 decl_enums *enums; \
1459 decls *decls; \
1460 impls *impls; \
1461 union { \
1462 decl_file file; \
1463 decl_libs libs; \
1464 } psi; \
1465 psi_error_cb error; \
1466 unsigned errors; \
1467 unsigned flags
1468 typedef struct PSI_Data {
1469 PSI_DATA_MEMBERS;
1470 } PSI_Data;
1471
1472 static inline PSI_Data *PSI_DataExchange(PSI_Data *dest, PSI_Data *src) {
1473 if (!dest) {
1474 dest = malloc(sizeof(*dest));
1475 }
1476 memcpy(dest, src, sizeof(*dest));
1477 memset(src, 0, sizeof(*src));
1478 return dest;
1479 }
1480
1481 static inline void PSI_DataDtor(PSI_Data *data) {
1482 if (data->consts) {
1483 free_constants(data->consts);
1484 }
1485 if (data->defs) {
1486 free_decl_typedefs(data->defs);
1487 }
1488 if (data->structs) {
1489 free_decl_structs(data->structs);
1490 }
1491 if (data->unions) {
1492 free_decl_unions(data->unions);
1493 }
1494 if (data->enums) {
1495 free_decl_enums(data->enums);
1496 }
1497 if (data->decls) {
1498 free_decls(data->decls);
1499 }
1500 if (data->impls) {
1501 free_impls(data->impls);
1502 }
1503 free_decl_file(&data->psi.file);
1504 }
1505
1506 typedef struct PSI_Parser {
1507 PSI_DATA_MEMBERS;
1508 FILE *fp;
1509 token_t num;
1510 void *proc;
1511 unsigned line, col;
1512 char *cur, *tok, *lim, *eof, *ctx, *mrk, buf[BSIZE];
1513 } PSI_Parser;
1514
1515 static inline size_t PSI_TokenAllocSize(size_t token_len, size_t fname_len) {
1516 return sizeof(PSI_Token) + token_len + fname_len + 2;
1517 }
1518
1519 static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) {
1520 PSI_Token *T;
1521 size_t token_len, fname_len;
1522 token_t token_typ;
1523
1524 if (P->cur < P->tok) {
1525 return NULL;
1526 }
1527
1528 token_typ = P->num;
1529 token_len = P->cur - P->tok;
1530 fname_len = strlen(P->psi.file.fn);
1531
1532 T = calloc(1, PSI_TokenAllocSize(token_len, fname_len));
1533 T->type = token_typ;
1534 T->size = token_len;
1535 T->text = &T->buf[0];
1536 T->file = &T->buf[token_len + 1];
1537 T->line = P->line;
1538 T->col = P->col;
1539
1540 memcpy(T->text, P->tok, token_len);
1541 memcpy(T->file, P->psi.file.fn, fname_len);
1542
1543 return T;
1544 }
1545
1546 static inline PSI_Token *PSI_TokenCopy(PSI_Token *src) {
1547 size_t strct_len = PSI_TokenAllocSize(src->size, strlen(src->file));
1548 PSI_Token *ptr = malloc(strct_len);
1549
1550 memcpy(ptr, src, strct_len);
1551
1552 ptr->text = &ptr->buf[0];
1553 ptr->file = &ptr->buf[ptr->size + 1];
1554
1555 return ptr;
1556 }
1557
1558 static inline PSI_Token *PSI_TokenCat(unsigned argc, ...) {
1559 va_list argv;
1560 unsigned i;
1561 PSI_Token *T = NULL;
1562
1563 va_start(argv, argc);
1564 for (i = 0; i < argc; ++i) {
1565 PSI_Token *arg = va_arg(argv, PSI_Token *);
1566
1567 if (T) {
1568 size_t token_len = T->size, fname_len = strlen(T->file);
1569
1570 T = realloc(T, PSI_TokenAllocSize(T->size += arg->size + 1, fname_len));
1571 T->text = &T->buf[0];
1572 T->file = &T->buf[T->size + 1];
1573 T->buf[token_len] = ' ';
1574 memmove(&T->buf[T->size + 1], &T->buf[token_len + 1], fname_len + 1);
1575 memcpy(&T->buf[token_len + 1], arg->text, arg->size + 1);
1576 } else {
1577 T = PSI_TokenCopy(arg);
1578 T->type = PSI_T_NAME;
1579 }
1580 }
1581 va_end(argv);
1582
1583 return T;
1584 }
1585
1586 static inline PSI_Token *PSI_TokenAppend(PSI_Token *T, unsigned argc, ...) {
1587 va_list argv;
1588 unsigned i;
1589
1590 va_start(argv, argc);
1591 for (i = 0; i < argc; ++i) {
1592 char *str = va_arg(argv, char *);
1593 size_t str_len = strlen(str), token_len = T->size, fname_len = strlen(T->file);
1594
1595 T = realloc(T, PSI_TokenAllocSize(T->size += str_len + 1, fname_len));
1596 T->text = &T->buf[0];
1597 T->file = &T->buf[T->size + 1];
1598 T->buf[token_len] = ' ';
1599 memmove(&T->buf[T->size + 1], &T->buf[token_len + 1], fname_len + 1);
1600 memcpy(&T->buf[token_len + 1], str, str_len + 1);
1601 }
1602 va_end(argv);
1603
1604 return T;
1605 }
1606
1607 char *php_strtr(char *str, size_t len, char *str_from, char *str_to, size_t trlen);
1608 static inline PSI_Token *PSI_TokenTranslit(PSI_Token *T, char *from, char *to) {
1609 php_strtr(T->text, T->size, from, to, MIN(strlen(from), strlen(to)));
1610 return T;
1611 }
1612
1613 static inline uint64_t psi_hash(char *digest_buf, ...)
1614 {
1615 uint64_t hash = 5381;
1616 uint8_t c;
1617 const uint8_t *ptr;
1618 va_list argv;
1619
1620 va_start(argv, digest_buf);
1621 while ((ptr = va_arg(argv, const uint8_t *))) {
1622 while ((c = *ptr++)) {
1623 hash = ((hash << 5) + hash) + c;
1624 }
1625 }
1626 va_end(argv);
1627
1628 if (digest_buf) {
1629 sprintf(digest_buf, "%" PRIx64, hash);
1630 }
1631
1632 return hash;
1633 }
1634
1635 static inline uint64_t PSI_TokenHash(PSI_Token *t, char *digest_buf) {
1636 char loc_buf[48];
1637
1638 sprintf(loc_buf, "%u%u", t->line, t->col);
1639 return psi_hash(digest_buf, t->file, loc_buf, NULL);
1640 }
1641
1642 #define PSI_PARSER_DEBUG 0x1
1643 #define PSI_PARSER_SILENT 0x2
1644
1645 PSI_Parser *PSI_ParserInit(PSI_Parser *P, const char *filename, psi_error_cb error, unsigned flags);
1646 void PSI_ParserSyntaxError(PSI_Parser *P, const char *fn, size_t ln, const char *msg, ...);
1647 size_t PSI_ParserFill(PSI_Parser *P, size_t n);
1648 token_t PSI_ParserScan(PSI_Parser *P);
1649 void PSI_ParserParse(PSI_Parser *P, PSI_Token *src);
1650 void PSI_ParserDtor(PSI_Parser *P);
1651 void PSI_ParserFree(PSI_Parser **P);
1652
1653 #endif