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