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