9 #include <Zend/zend_types.h>
10 #include <Zend/zend_API.h> /* fcall */
12 #include "parser_proc.h"
16 #define PSI_T_POINTER PSI_T_ASTERISK
17 #define PSI_T_LONG_DOUBLE (PSI_T_DOUBLE << 16)
21 size_t psi_t_alignment(token_t
);
22 size_t psi_t_size(token_t
);
24 typedef struct PSI_Token
{
26 unsigned size
, line
, col
;
31 static inline PSI_Token
*PSI_TokenCopy(PSI_Token
*src
);
33 typedef struct zend_fcall
{
35 zend_fcall_info_cache fcc
;
38 typedef union impl_val
{
53 #ifdef HAVE_LONG_DOUBLE
65 typedef struct decl_type
{
71 struct decl_struct
*strct
;
72 struct decl_union
*unn
;
73 struct decl_enum
*enm
;
78 static inline decl_type
*init_decl_type(token_t type
, const char *name
) {
79 decl_type
*t
= calloc(1, sizeof(*t
));
81 t
->name
= strdup(name
);
85 static inline int weak_decl_type(decl_type
*type
) {
98 static inline void free_decl(struct decl
*decl
);
99 static inline void free_decl_type(decl_type
*type
) {
103 if (type
->type
== PSI_T_FUNCTION
) {
104 free_decl(type
->real
.func
);
110 typedef struct decl_var
{
113 unsigned pointer_level
;
115 struct decl_arg
*arg
;
118 static inline decl_var
*init_decl_var(const char *name
, unsigned pl
, unsigned as
) {
119 decl_var
*v
= calloc(1, sizeof(*v
));
120 v
->name
= (char *) strdup((const char *) name
);
121 v
->pointer_level
= pl
;
126 static inline decl_var
*copy_decl_var(decl_var
*src
) {
127 decl_var
*dest
= calloc(1, sizeof(*dest
));
129 memcpy(dest
, src
, sizeof(*dest
));
130 dest
->name
= strdup(dest
->name
);
132 dest
->token
= PSI_TokenCopy(dest
->token
);
137 static inline void free_decl_var(decl_var
*var
) {
145 typedef struct decl_struct_layout
{
148 } decl_struct_layout
;
150 static inline decl_struct_layout
*init_decl_struct_layout(size_t pos
, size_t len
) {
151 decl_struct_layout
*l
= calloc(1, sizeof(*l
));
152 ZEND_ASSERT(pos
+len
);
158 static inline void free_decl_struct_layout(decl_struct_layout
*l
) {
162 typedef struct decl_arg
{
166 decl_struct_layout
*layout
;
173 static inline decl_arg
*init_decl_arg(decl_type
*type
, decl_var
*var
) {
174 decl_arg
*arg
= calloc(1, sizeof(*arg
));
175 arg
->token
= var
->token
;
179 arg
->ptr
= &arg
->val
;
184 static inline void free_decl_arg(decl_arg
*arg
) {
185 if (arg
->token
&& arg
->token
!= arg
->var
->token
) {
188 free_decl_type(arg
->type
);
189 free_decl_var(arg
->var
);
191 free_decl_struct_layout(arg
->layout
);
196 static inline decl_type
*real_decl_type(decl_type
*type
) {
197 while (weak_decl_type(type
)) {
198 type
= type
->real
.def
->type
;
203 typedef struct decl_typedefs
{
208 static inline decl_typedefs
*add_decl_typedef(decl_typedefs
*defs
, decl_arg
*def
) {
210 defs
= calloc(1, sizeof(*defs
));
212 defs
->list
= realloc(defs
->list
, ++defs
->count
* sizeof(*defs
->list
));
213 defs
->list
[defs
->count
-1] = def
;
217 static void free_decl_typedefs(decl_typedefs
*defs
) {
220 for (i
= 0; i
< defs
->count
; ++i
) {
221 free_decl_arg(defs
->list
[i
]);
227 typedef struct decl_vars
{
232 static inline decl_vars
*init_decl_vars(decl_var
*var
) {
233 decl_vars
*vars
= calloc(1, sizeof(*vars
));
236 vars
->vars
= calloc(1, sizeof(*vars
->vars
));
242 static inline decl_vars
*add_decl_var(decl_vars
*vars
, decl_var
*var
) {
243 vars
->vars
= realloc(vars
->vars
, ++vars
->count
* sizeof(*vars
->vars
));
244 vars
->vars
[vars
->count
-1] = var
;
248 static inline void free_decl_vars(decl_vars
*vars
) {
251 for (i
= 0; i
< vars
->count
; ++i
) {
252 free_decl_var(vars
->vars
[i
]);
258 typedef struct decl_args
{
264 static inline decl_args
*init_decl_args(decl_arg
*arg
) {
265 decl_args
*args
= calloc(1, sizeof(*args
));
268 args
->args
= calloc(1, sizeof(*args
->args
));
274 static inline decl_args
*add_decl_arg(decl_args
*args
, decl_arg
*arg
) {
275 args
->args
= realloc(args
->args
, ++args
->count
* sizeof(*args
->args
));
276 args
->args
[args
->count
-1] = arg
;
280 static inline void free_decl_args(decl_args
*args
) {
283 for (i
= 0; i
< args
->count
; ++i
) {
284 free_decl_arg(args
->args
[i
]);
290 typedef struct decl_abi
{
295 static inline decl_abi
*init_decl_abi(const char *convention
) {
296 decl_abi
*abi
= calloc(1, sizeof(*abi
));
297 abi
->convention
= strdup(convention
);
301 static inline void free_decl_abi(decl_abi
*abi
) {
305 free(abi
->convention
);
309 typedef struct decl_callinfo
{
317 typedef struct decl
{
325 static inline decl
* init_decl(decl_abi
*abi
, decl_arg
*func
, decl_args
*args
) {
326 decl
*d
= calloc(1, sizeof(*d
));
333 static inline void free_decl(decl
*d
) {
334 free_decl_abi(d
->abi
);
335 free_decl_arg(d
->func
);
337 free_decl_args(d
->args
);
342 typedef struct decls
{
347 static inline decls
*add_decl(decls
*decls
, decl
*decl
) {
349 decls
= calloc(1, sizeof(*decls
));
351 decls
->list
= realloc(decls
->list
, ++decls
->count
* sizeof(*decls
->list
));
352 decls
->list
[decls
->count
-1] = decl
;
356 static inline void free_decls(decls
*decls
) {
359 for (i
= 0; i
< decls
->count
; ++i
) {
360 free_decl(decls
->list
[i
]);
367 typedef struct decl_struct
{
375 void (*dtor
)(void *type
);
379 static inline decl_struct
*init_decl_struct(const char *name
, decl_args
*args
) {
380 decl_struct
*s
= calloc(1, sizeof(*s
));
381 s
->name
= strdup(name
);
386 static inline void free_decl_struct(decl_struct
*s
) {
391 free_decl_args(s
->args
);
393 if (s
->engine
.type
&& s
->engine
.dtor
) {
394 s
->engine
.dtor(s
->engine
.type
);
400 typedef struct decl_structs
{
405 static inline decl_structs
*add_decl_struct(decl_structs
*ss
, decl_struct
*s
) {
407 ss
= calloc(1, sizeof(*ss
));
409 ss
->list
= realloc(ss
->list
, ++ss
->count
* sizeof(*ss
->list
));
410 ss
->list
[ss
->count
-1] = s
;
414 static inline void free_decl_structs(decl_structs
*ss
) {
417 for (i
= 0; i
< ss
->count
; ++i
) {
418 free_decl_struct(ss
->list
[i
]);
424 typedef struct decl_union
{
432 static inline decl_union
*init_decl_union(const char *name
, decl_args
*args
) {
433 decl_union
*u
= calloc(1, sizeof(*u
));
434 u
->name
= strdup(name
);
439 static inline void free_decl_union(decl_union
*u
) {
444 free_decl_args(u
->args
);
450 typedef struct decl_unions
{
455 static inline decl_unions
*add_decl_union(decl_unions
*uu
, decl_union
*u
) {
457 uu
= calloc(1, sizeof(*uu
));
459 uu
->list
= realloc(uu
->list
, ++uu
->count
* sizeof(*uu
->list
));
460 uu
->list
[uu
->count
-1] = u
;
464 static inline void free_decl_unions(decl_unions
*uu
) {
467 for (i
= 0; i
< uu
->count
; ++i
) {
468 free_decl_union(uu
->list
[i
]);
474 typedef struct impl_type
{
479 static inline impl_type
*init_impl_type(token_t type
, const char *name
) {
480 impl_type
*t
= calloc(1, sizeof(*t
));
483 t
->name
= strdup(name
);
487 static inline void free_impl_type(impl_type
*type
) {
492 typedef struct impl_var
{
495 struct impl_arg
*arg
;
496 unsigned reference
:1;
499 static inline impl_var
*init_impl_var(const char *name
, int is_reference
) {
500 impl_var
*var
= calloc(1, sizeof(*var
));
501 var
->name
= strdup(name
);
502 var
->reference
= is_reference
;
506 static inline impl_var
*copy_impl_var(impl_var
*var
) {
507 impl_var
*cpy
= malloc(sizeof(*cpy
));
509 memcpy(cpy
, var
, sizeof(*cpy
));
510 cpy
->name
= strdup(cpy
->name
);
512 cpy
->token
= PSI_TokenCopy(cpy
->token
);
517 static inline void free_impl_var(impl_var
*var
) {
525 typedef struct impl_def_val
{
530 static inline impl_def_val
*init_impl_def_val(token_t t
, const char *text
) {
531 impl_def_val
*def
= calloc(1, sizeof(*def
));
533 def
->text
= strdup(text
);
537 static inline void free_impl_def_val(impl_def_val
*def
) {
542 typedef struct const_type
{
547 static inline const_type
*init_const_type(token_t type
, const char *name
) {
548 const_type
*ct
= calloc(1, sizeof(*ct
));
550 ct
->name
= strdup(name
);
554 static inline void free_const_type(const_type
*type
) {
559 typedef struct constant
{
565 static inline constant
*init_constant(const_type
*type
, const char *name
, impl_def_val
*val
) {
566 constant
*c
= calloc(1, sizeof(*c
));
568 c
->name
= strdup(name
);
573 static inline void free_constant(constant
*constant
) {
574 free_const_type(constant
->type
);
575 free(constant
->name
);
576 free_impl_def_val(constant
->val
);
580 typedef struct constants
{
585 static inline constants
*add_constant(constants
*constants
, constant
*constant
) {
587 constants
= calloc(1, sizeof(*constants
));
589 constants
->list
= realloc(constants
->list
, ++constants
->count
* sizeof(*constants
->list
));
590 constants
->list
[constants
->count
-1] = constant
;
594 static inline void free_constants(constants
*c
) {
597 for (i
= 0; i
< c
->count
; ++i
) {
598 free_constant(c
->list
[i
]);
604 typedef struct impl_arg
{
612 static inline impl_arg
*init_impl_arg(impl_type
*type
, impl_var
*var
, impl_def_val
*def
) {
613 impl_arg
*arg
= calloc(1, sizeof(*arg
));
621 static inline void free_impl_arg(impl_arg
*arg
) {
622 free_impl_type(arg
->type
);
623 free_impl_var(arg
->var
);
625 free_impl_def_val(arg
->def
);
630 typedef struct impl_vararg
{
632 struct impl_args
*args
;
638 typedef struct impl_args
{
644 static inline impl_args
*init_impl_args(impl_arg
*arg
) {
645 impl_args
*args
= calloc(1, sizeof(*args
));
648 args
->args
= calloc(1, sizeof(*args
->args
));
654 static inline impl_args
*add_impl_arg(impl_args
*args
, impl_arg
*arg
) {
655 args
->args
= realloc(args
->args
, ++args
->count
* sizeof(*args
->args
));
656 args
->args
[args
->count
-1] = arg
;
660 static inline void free_impl_args(impl_args
*args
) {
663 for (i
= 0; i
< args
->count
; ++i
) {
664 free_impl_arg(args
->args
[i
]);
666 if (args
->vararg
.name
) {
667 free_impl_arg(args
->vararg
.name
);
673 typedef struct impl_func
{
677 impl_type
*return_type
;
678 unsigned return_reference
:1;
681 static inline impl_func
*init_impl_func(char *name
, impl_args
*args
, impl_type
*type
, int ret_reference
) {
682 impl_func
*func
= calloc(1, sizeof(*func
));
683 func
->name
= strdup(name
);
684 func
->args
= args
? args
: init_impl_args(NULL
);
685 func
->return_type
= type
;
686 func
->return_reference
= ret_reference
;
690 static inline void free_impl_func(impl_func
*f
) {
694 free_impl_type(f
->return_type
);
695 free_impl_args(f
->args
);
700 typedef struct num_exp
{
707 struct decl_enum_item
*enm
;
710 int (*calculator
)(int t1
, impl_val
*v1
, int t2
, impl_val
*v2
, impl_val
*res
);
711 struct num_exp
*operand
;
714 static inline num_exp
*init_num_exp(token_t t
, void *num
) {
715 num_exp
*exp
= calloc(1, sizeof(*exp
));
716 switch (exp
->t
= t
) {
719 exp
->u
.numb
= strdup(num
);
724 EMPTY_SWITCH_DEFAULT_CASE();
729 static inline num_exp
*copy_num_exp(num_exp
*exp
) {
731 num_exp
*num
= calloc(1, sizeof(*num
));
733 memcpy(num
, exp
, sizeof(*num
));
736 num
->token
= PSI_TokenCopy(num
->token
);
739 num
->operand
= copy_num_exp(num
->operand
);
744 num
->u
.numb
= strdup(num
->u
.numb
);
747 dvar
= init_decl_var(num
->u
.dvar
->name
, num
->u
.dvar
->pointer_level
, num
->u
.dvar
->array_size
);
748 dvar
->arg
= num
->u
.dvar
->arg
;
749 if (num
->u
.dvar
->token
) {
750 dvar
->token
= PSI_TokenCopy(num
->u
.dvar
->token
);
758 static inline void free_num_exp(num_exp
*exp
) {
769 free_decl_var(exp
->u
.dvar
);
773 EMPTY_SWITCH_DEFAULT_CASE();
776 free_num_exp(exp
->operand
);
781 typedef struct decl_enum_item
{
786 struct decl_enum_item
*prev
;
789 static inline decl_enum_item
*init_decl_enum_item(const char *name
, num_exp
*num
) {
790 decl_enum_item
*i
= calloc(1, sizeof(*i
));
792 i
->name
= strdup(name
);
797 static inline void free_decl_enum_item(decl_enum_item
*i
) {
801 if (i
->num
&& i
->num
!= &i
->inc
) {
802 free_num_exp(i
->num
);
808 typedef struct decl_enum_items
{
809 decl_enum_item
**list
;
813 static inline decl_enum_items
*init_decl_enum_items(decl_enum_item
*i
) {
814 decl_enum_items
*l
= calloc(1, sizeof(*l
));
818 l
->list
= calloc(1, sizeof(*l
->list
));
824 static inline decl_enum_items
*add_decl_enum_item(decl_enum_items
*l
, decl_enum_item
*i
) {
825 l
->list
= realloc(l
->list
, sizeof(*l
->list
) * (l
->count
+ 1));
826 l
->list
[l
->count
] = i
;
828 i
->prev
= l
->list
[l
->count
- 1];
834 static inline void free_decl_enum_items(decl_enum_items
*l
) {
838 for (j
= 0; j
< l
->count
; ++j
) {
839 free_decl_enum_item(l
->list
[j
]);
846 typedef struct decl_enum
{
849 decl_enum_items
*items
;
852 static inline decl_enum
*init_decl_enum(const char *name
, decl_enum_items
*l
) {
853 decl_enum
*e
= calloc(1, sizeof(*e
));
855 e
->name
= strdup(name
);
860 static inline void free_decl_enum(decl_enum
*e
) {
865 free_decl_enum_items(e
->items
);
871 typedef struct decl_enums
{
876 static inline decl_enums
* add_decl_enum(decl_enums
*es
, decl_enum
*e
) {
878 es
= calloc(1, sizeof(*es
));
880 es
->list
= realloc(es
->list
, ++es
->count
* sizeof(*es
->list
));
881 es
->list
[es
->count
-1] = e
;
885 static inline void free_decl_enums(decl_enums
*es
) {
889 for (j
= 0; j
< es
->count
; ++j
) {
890 free_decl_enum(es
->list
[j
]);
897 typedef struct let_calloc
{
902 static inline let_calloc
*init_let_calloc(num_exp
*nmemb
, num_exp
*size
) {
903 let_calloc
*alloc
= calloc(1, sizeof(*alloc
));
904 alloc
->nmemb
= nmemb
;
909 static inline void free_let_calloc(let_calloc
*alloc
) {
910 free_num_exp(alloc
->nmemb
);
911 free_num_exp(alloc
->size
);
915 typedef struct let_callback
{
916 struct let_func
*func
;
917 struct set_values
*args
;
921 static inline void free_let_func(struct let_func
*func
);
922 static inline void free_set_values(struct set_values
*vals
);
923 static inline let_callback
*init_let_callback(struct let_func
*func
, struct set_values
*args
) {
924 let_callback
*cb
= calloc(1, sizeof(*cb
));
931 static inline void free_let_callback(let_callback
*cb
) {
932 free_let_func(cb
->func
);
933 free_set_values(cb
->args
);
937 typedef impl_val
*(*let_func_handler
)(impl_val
*tmp
, decl_type
*type
, impl_arg
*iarg
, void **to_free
);
939 typedef struct let_func
{
943 let_func_handler handler
;
946 static inline let_func
*init_let_func(token_t type
, const char *name
, impl_var
*var
) {
947 let_func
*func
= calloc(1, sizeof(*func
));
949 func
->name
= strdup(name
);
954 static inline void free_let_func(let_func
*func
) {
955 free_impl_var(func
->var
);
968 #define PSI_LET_REFERENCE 0x1;
969 typedef struct let_val
{
970 enum let_val_kind kind
;
974 let_callback
*callback
;
980 unsigned is_reference
:1;
986 static inline let_val
*init_let_val(enum let_val_kind kind
, void *data
) {
987 let_val
*let
= calloc(1, sizeof(*let
));
988 switch (let
->kind
= kind
) {
992 let
->data
.num
= data
;
995 let
->data
.alloc
= data
;
997 case PSI_LET_CALLBACK
:
998 let
->data
.callback
= data
;
1001 let
->data
.func
= data
;
1004 let
->data
.var
= data
;
1006 EMPTY_SWITCH_DEFAULT_CASE();
1011 static inline void free_let_val(let_val
*let
) {
1012 switch (let
->kind
) {
1015 case PSI_LET_NUMEXP
:
1016 free_num_exp(let
->data
.num
);
1018 case PSI_LET_CALLOC
:
1019 free_let_calloc(let
->data
.alloc
);
1021 case PSI_LET_CALLBACK
:
1022 free_let_callback(let
->data
.callback
);
1025 free_let_func(let
->data
.func
);
1028 free_decl_var(let
->data
.var
);
1030 EMPTY_SWITCH_DEFAULT_CASE();
1035 typedef struct let_stmt
{
1040 static inline let_stmt
*init_let_stmt(decl_var
*var
, let_val
*val
) {
1041 let_stmt
*let
= calloc(1, sizeof(*let
));
1047 static inline void free_let_stmt(let_stmt
*stmt
) {
1049 if (stmt
->val
->kind
== PSI_LET_TMP
&& stmt
->var
->arg
) {
1050 free_decl_arg(stmt
->var
->arg
);
1052 free_let_val(stmt
->val
);
1054 free_decl_var(stmt
->var
);
1060 typedef struct set_func
{
1064 void (*handler
)(zval
*, struct set_value
*set
, impl_val
*ret_val
);
1067 static inline set_func
*init_set_func(token_t type
, const char *name
) {
1068 set_func
*func
= calloc(1, sizeof(*func
));
1070 func
->name
= strdup(name
);
1074 static inline void free_set_func(set_func
*func
) {
1082 typedef struct set_value
{
1087 struct set_value
*set
;
1090 struct set_values
*inner
;
1093 typedef struct set_values
{
1099 static inline set_value
*init_set_value(set_func
*func
, decl_vars
*vars
) {
1100 set_value
*val
= calloc(1, sizeof(*val
));
1106 static inline set_values
*add_set_value(set_values
*vals
, set_value
*val
);
1107 static inline set_value
*add_inner_set_value(set_value
*val
, set_value
*inner
) {
1108 val
->inner
= add_set_value(val
->inner
, inner
);
1109 inner
->outer
.set
= val
;
1113 static inline void free_set_value(set_value
*val
) {
1115 free_set_func(val
->func
);
1118 free_decl_vars(val
->vars
);
1120 if (val
->inner
&& (!val
->outer
.set
|| val
->outer
.set
->inner
!= val
->inner
)) {
1121 free_set_values(val
->inner
);
1124 free_num_exp(val
->num
);
1129 static inline set_values
*init_set_values(set_value
*val
) {
1130 set_values
*vals
= calloc(1, sizeof(*vals
));
1133 vals
->vals
= calloc(1, sizeof(val
));
1134 vals
->vals
[0] = val
;
1139 static inline set_values
*add_set_value(set_values
*vals
, set_value
*val
) {
1141 vals
= calloc(1, sizeof(*vals
));
1143 vals
->vals
= realloc(vals
->vals
, ++vals
->count
* sizeof(val
));
1144 vals
->vals
[vals
->count
-1] = val
;
1148 static inline void free_set_values(set_values
*vals
) {
1152 for (i
= 0; i
< vals
->count
; ++i
) {
1153 free_set_value(vals
->vals
[i
]);
1160 typedef struct set_stmt
{
1166 static inline set_stmt
*init_set_stmt(impl_var
*var
, set_value
*val
) {
1167 set_stmt
*set
= calloc(1, sizeof(*set
));
1173 static inline void free_set_stmt(set_stmt
*set
) {
1174 free_impl_var(set
->var
);
1175 free_set_value(set
->val
);
1179 typedef struct return_stmt
{
1185 static inline return_stmt
*init_return_stmt(set_value
*val
) {
1186 return_stmt
*ret
= calloc(1, sizeof(*ret
));
1191 static inline void free_return_stmt(return_stmt
*ret
) {
1195 free_set_value(ret
->set
);
1199 typedef struct free_call
{
1206 static inline free_call
*init_free_call(const char *func
, decl_vars
*vars
) {
1207 free_call
*f
= calloc(1, sizeof(*f
));
1208 f
->func
= strdup(func
);
1213 static inline void free_free_call(free_call
*f
) {
1218 free_decl_vars(f
->vars
);
1222 typedef struct free_calls
{
1227 static inline free_calls
*init_free_calls(free_call
*f
) {
1228 free_calls
*fcs
= calloc(1, sizeof(*fcs
));
1231 fcs
->list
= calloc(1, sizeof(*fcs
->list
));
1237 static inline void free_free_calls(free_calls
*fcs
) {
1240 for (i
= 0; i
< fcs
->count
; ++i
) {
1241 free_free_call(fcs
->list
[i
]);
1247 static inline free_calls
*add_free_call(free_calls
*fcs
, free_call
*f
) {
1248 fcs
->list
= realloc(fcs
->list
, ++fcs
->count
* sizeof(*fcs
->list
));
1249 fcs
->list
[fcs
->count
-1] = f
;
1253 typedef struct free_stmt
{
1257 static inline free_stmt
*init_free_stmt(free_calls
*calls
) {
1258 free_stmt
*f
= calloc(1, sizeof(*f
));
1263 static inline void free_free_stmt(free_stmt
*f
) {
1264 free_free_calls(f
->calls
);
1268 typedef struct impl_stmt
{
1279 static inline impl_stmt
*init_impl_stmt(token_t type
, void *ptr
) {
1280 impl_stmt
*stmt
= calloc(1, sizeof(*stmt
));
1286 static inline void free_impl_stmt(impl_stmt
*stmt
) {
1287 switch (stmt
->type
) {
1289 free_let_stmt(stmt
->s
.let
);
1292 free_set_stmt(stmt
->s
.set
);
1295 free_return_stmt(stmt
->s
.ret
);
1298 free_free_stmt(stmt
->s
.fre
);
1304 typedef struct impl_stmts
{
1323 static inline void *add_impl_stmt_ex(void *list
, size_t count
, void *stmt
) {
1324 list
= realloc(list
, count
* sizeof(list
));
1325 ((void **)list
)[count
-1] = stmt
;
1329 static inline impl_stmts
*add_impl_stmt(impl_stmts
*stmts
, impl_stmt
*stmt
) {
1330 switch (stmt
->type
) {
1332 stmts
->ret
.list
= add_impl_stmt_ex(stmts
->ret
.list
, ++stmts
->ret
.count
, stmt
->s
.ret
);
1335 stmts
->let
.list
= add_impl_stmt_ex(stmts
->let
.list
, ++stmts
->let
.count
, stmt
->s
.let
);
1338 stmts
->set
.list
= add_impl_stmt_ex(stmts
->set
.list
, ++stmts
->set
.count
, stmt
->s
.set
);
1341 stmts
->fre
.list
= add_impl_stmt_ex(stmts
->fre
.list
, ++stmts
->fre
.count
, stmt
->s
.fre
);
1348 static inline impl_stmts
*init_impl_stmts(impl_stmt
*stmt
) {
1349 impl_stmts
*stmts
= calloc(1, sizeof(*stmts
));
1350 return add_impl_stmt(stmts
, stmt
);
1353 static inline void free_impl_stmts(impl_stmts
*stmts
) {
1356 for (i
= 0; i
< stmts
->let
.count
; ++i
) {
1357 free_let_stmt(stmts
->let
.list
[i
]);
1359 free(stmts
->let
.list
);
1360 for (i
= 0; i
< stmts
->ret
.count
; ++i
) {
1361 free_return_stmt(stmts
->ret
.list
[i
]);
1363 free(stmts
->ret
.list
);
1364 for (i
= 0; i
< stmts
->set
.count
; ++i
) {
1365 free_set_stmt(stmts
->set
.list
[i
]);
1367 free(stmts
->set
.list
);
1368 for (i
= 0; i
< stmts
->fre
.count
; ++i
) {
1369 free_free_stmt(stmts
->fre
.list
[i
]);
1371 free(stmts
->fre
.list
);
1375 typedef struct impl
{
1381 static inline impl
*init_impl(impl_func
*func
, impl_stmts
*stmts
) {
1382 impl
*i
= calloc(1, sizeof(*i
));
1388 static inline void free_impl(impl
*impl
) {
1389 free_impl_func(impl
->func
);
1390 free_impl_stmts(impl
->stmts
);
1394 typedef struct impls
{
1399 static inline impls
*add_impl(impls
*impls
, impl
*impl
) {
1401 impls
= calloc(1, sizeof(*impls
));
1403 impls
->list
= realloc(impls
->list
, ++impls
->count
* sizeof(*impls
->list
));
1404 impls
->list
[impls
->count
-1] = impl
;
1408 static void free_impls(impls
*impls
) {
1411 for (i
= 0; i
< impls
->count
; ++i
) {
1412 free_impl(impls
->list
[i
]);
1418 typedef struct decl_file
{
1423 static inline void free_decl_file(decl_file
*file
) {
1430 memset(file
, 0, sizeof(*file
));
1433 typedef struct decl_libs
{
1438 static inline void free_decl_libs(decl_libs
*libs
) {
1441 for (i
= 0; i
< libs
->count
; ++i
) {
1443 dlclose(libs
->dl
[i
]);
1448 memset(libs
, 0, sizeof(*libs
));
1451 static inline void add_decl_lib(decl_libs
*libs
, void *dlopened
) {
1452 libs
->dl
= realloc(libs
->dl
, ++libs
->count
* sizeof(*libs
->dl
));
1453 libs
->dl
[libs
->count
-1] = dlopened
;
1456 static inline impl_val
*deref_impl_val(impl_val
*ret_val
, decl_var
*var
) {
1459 ZEND_ASSERT(var
->arg
->var
!= var
);
1461 fprintf(stderr
, "deref: %s pl=%u:%u as=%u:%u %p\n",
1462 var
->name
, var
->pointer_level
, var
->arg
->var
->pointer_level
,
1463 var
->array_size
, var
->arg
->var
->array_size
, ret_val
);
1465 for (i
= 0; i
< var
->pointer_level
; ++i
) {
1467 fprintf(stderr
, "-- %p %p %p\n", ret_val
, *(void**)ret_val
, ret_val
->ptr
);
1469 ret_val
= *(void **) ret_val
;
1474 static inline impl_val
*enref_impl_val(void *ptr
, decl_var
*var
) {
1475 impl_val
*val
, *val_ptr
;
1478 ZEND_ASSERT(var
->arg
->var
== var
);
1480 fprintf(stderr
, "enref: %s pl=%u:%u as=%u:%u\n",
1481 var
->name
, var
->pointer_level
, var
->arg
->var
->pointer_level
,
1482 var
->array_size
, var
->arg
->var
->array_size
);
1484 if (!var
->pointer_level
){//&& real_decl_type(var->arg->type)->type != PSI_T_STRUCT) {
1488 val
= val_ptr
= calloc(var
->pointer_level
+ 1, sizeof(void *));
1489 for (i
= !var
->arg
->var
->array_size
; i
< var
->pointer_level
; ++i
) {
1491 fprintf(stderr
, "++\n");
1493 val_ptr
->ptr
= (void **) val_ptr
+ 1;
1494 val_ptr
= val_ptr
->ptr
;
1500 static inline impl_val
*struct_member_ref(decl_arg
*set_arg
, impl_val
*struct_ptr
, impl_val
**to_free
) {
1501 void *ptr
= (char *) struct_ptr
+ set_arg
->layout
->pos
;
1503 fprintf(stderr
, "struct member %s: %p\n", set_arg
->var
->name
, ptr
);
1509 #define PSI_ERROR 16
1510 #define PSI_WARNING 32
1511 typedef void (*psi_error_cb
)(void *context
, PSI_Token
*token
, int type
, const char *msg
, ...);
1513 #define PSI_DATA(D) ((PSI_Data *) (D))
1514 #define PSI_DATA_MEMBERS \
1515 constants *consts; \
1516 decl_typedefs *defs; \
1517 decl_structs *structs; \
1518 decl_unions *unions; \
1519 decl_enums *enums; \
1526 psi_error_cb error; \
1529 typedef struct PSI_Data
{
1533 static inline PSI_Data
*PSI_DataExchange(PSI_Data
*dest
, PSI_Data
*src
) {
1535 dest
= malloc(sizeof(*dest
));
1537 memcpy(dest
, src
, sizeof(*dest
));
1538 memset(src
, 0, sizeof(*src
));
1542 static inline void PSI_DataDtor(PSI_Data
*data
) {
1544 free_constants(data
->consts
);
1547 free_decl_typedefs(data
->defs
);
1549 if (data
->structs
) {
1550 free_decl_structs(data
->structs
);
1553 free_decl_unions(data
->unions
);
1556 free_decl_enums(data
->enums
);
1559 free_decls(data
->decls
);
1562 free_impls(data
->impls
);
1564 free_decl_file(&data
->psi
.file
);
1567 typedef struct PSI_Parser
{
1573 char *cur
, *tok
, *lim
, *eof
, *ctx
, *mrk
, buf
[BSIZE
];
1576 static inline size_t PSI_TokenAllocSize(size_t token_len
, size_t fname_len
) {
1577 return sizeof(PSI_Token
) + token_len
+ fname_len
+ 2;
1580 static inline PSI_Token
*PSI_TokenAlloc(PSI_Parser
*P
) {
1582 size_t token_len
, fname_len
;
1585 if (P
->cur
< P
->tok
) {
1590 token_len
= P
->cur
- P
->tok
;
1591 fname_len
= strlen(P
->psi
.file
.fn
);
1593 T
= calloc(1, PSI_TokenAllocSize(token_len
, fname_len
));
1594 T
->type
= token_typ
;
1595 T
->size
= token_len
;
1596 T
->text
= &T
->buf
[0];
1597 T
->file
= &T
->buf
[token_len
+ 1];
1601 memcpy(T
->text
, P
->tok
, token_len
);
1602 memcpy(T
->file
, P
->psi
.file
.fn
, fname_len
);
1607 static inline PSI_Token
*PSI_TokenCopy(PSI_Token
*src
) {
1608 size_t strct_len
= PSI_TokenAllocSize(src
->size
, strlen(src
->file
));
1609 PSI_Token
*ptr
= malloc(strct_len
);
1611 memcpy(ptr
, src
, strct_len
);
1613 ptr
->text
= &ptr
->buf
[0];
1614 ptr
->file
= &ptr
->buf
[ptr
->size
+ 1];
1619 static inline PSI_Token
*PSI_TokenCat(unsigned argc
, ...) {
1622 PSI_Token
*T
= NULL
;
1624 va_start(argv
, argc
);
1625 for (i
= 0; i
< argc
; ++i
) {
1626 PSI_Token
*arg
= va_arg(argv
, PSI_Token
*);
1629 size_t token_len
= T
->size
, fname_len
= strlen(T
->file
);
1631 T
= realloc(T
, PSI_TokenAllocSize(T
->size
+= arg
->size
+ 1, fname_len
));
1632 T
->text
= &T
->buf
[0];
1633 T
->file
= &T
->buf
[T
->size
+ 1];
1634 T
->buf
[token_len
] = ' ';
1635 memmove(&T
->buf
[T
->size
+ 1], &T
->buf
[token_len
+ 1], fname_len
+ 1);
1636 memcpy(&T
->buf
[token_len
+ 1], arg
->text
, arg
->size
+ 1);
1638 T
= PSI_TokenCopy(arg
);
1639 T
->type
= PSI_T_NAME
;
1647 static inline PSI_Token
*PSI_TokenAppend(PSI_Token
*T
, unsigned argc
, ...) {
1651 va_start(argv
, argc
);
1652 for (i
= 0; i
< argc
; ++i
) {
1653 char *str
= va_arg(argv
, char *);
1654 size_t str_len
= strlen(str
), token_len
= T
->size
, fname_len
= strlen(T
->file
);
1656 T
= realloc(T
, PSI_TokenAllocSize(T
->size
+= str_len
+ 1, fname_len
));
1657 T
->text
= &T
->buf
[0];
1658 T
->file
= &T
->buf
[T
->size
+ 1];
1659 T
->buf
[token_len
] = ' ';
1660 memmove(&T
->buf
[T
->size
+ 1], &T
->buf
[token_len
+ 1], fname_len
+ 1);
1661 memcpy(&T
->buf
[token_len
+ 1], str
, str_len
+ 1);
1668 char *php_strtr(char *str
, size_t len
, char *str_from
, char *str_to
, size_t trlen
);
1669 static inline PSI_Token
*PSI_TokenTranslit(PSI_Token
*T
, char *from
, char *to
) {
1670 php_strtr(T
->text
, T
->size
, from
, to
, MIN(strlen(from
), strlen(to
)));
1674 static inline uint64_t psi_hash(char *digest_buf
, ...)
1676 uint64_t hash
= 5381;
1681 va_start(argv
, digest_buf
);
1682 while ((ptr
= va_arg(argv
, const uint8_t *))) {
1683 while ((c
= *ptr
++)) {
1684 hash
= ((hash
<< 5) + hash
) + c
;
1690 sprintf(digest_buf
, "%" PRIx64
, hash
);
1696 static inline uint64_t PSI_TokenHash(PSI_Token
*t
, char *digest_buf
) {
1699 sprintf(loc_buf
, "%u%u", t
->line
, t
->col
);
1700 return psi_hash(digest_buf
, t
->file
, loc_buf
, NULL
);
1703 #define PSI_PARSER_DEBUG 0x1
1704 #define PSI_PARSER_SILENT 0x2
1706 PSI_Parser
*PSI_ParserInit(PSI_Parser
*P
, const char *filename
, psi_error_cb error
, unsigned flags
);
1707 void PSI_ParserSyntaxError(PSI_Parser
*P
, const char *fn
, size_t ln
, const char *msg
, ...);
1708 size_t PSI_ParserFill(PSI_Parser
*P
, size_t n
);
1709 token_t
PSI_ParserScan(PSI_Parser
*P
);
1710 void PSI_ParserParse(PSI_Parser
*P
, PSI_Token
*src
);
1711 void PSI_ParserDtor(PSI_Parser
*P
);
1712 void PSI_ParserFree(PSI_Parser
**P
);