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