X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=src%2Ftypes%2Flet_func.c;h=ea2f371907ef46c973fdafdad429c2417516e1d0;hb=09529efcde471127419e141807b83b37077003a0;hp=27c37027ad5c7f2cd6f98693bde452e5782e1831;hpb=9bcb1df0786a8193d65949c857baaba2f4296e84;p=m6w6%2Fext-psi diff --git a/src/types/let_func.c b/src/types/let_func.c index 27c3702..ea2f371 100644 --- a/src/types/let_func.c +++ b/src/types/let_func.c @@ -32,12 +32,12 @@ #include -struct psi_let_func *psi_let_func_init(token_t type, const char *name, +struct psi_let_func *psi_let_func_init(token_t type, zend_string *name, struct psi_impl_var *var) { struct psi_let_func *func = calloc(1, sizeof(*func)); func->type = type; - func->name = strdup(name); + func->name = zend_string_copy(name); func->var = var; return func; } @@ -48,11 +48,9 @@ void psi_let_func_free(struct psi_let_func **func_ptr) struct psi_let_func *func = *func_ptr; *func_ptr = NULL; - if (func->token) { - free(func->token); - } + psi_token_free(&func->token); psi_impl_var_free(&func->var); - free(func->name); + zend_string_release(func->name); if (func->inner) { psi_plist_free(func->inner); } @@ -62,7 +60,8 @@ void psi_let_func_free(struct psi_let_func **func_ptr) void psi_let_func_dump(int fd, struct psi_let_func *func, unsigned level) { - dprintf(fd, "%s(%s\t/* fqn=%s */", func->name, func->var->name, func->var->fqn); + dprintf(fd, "%s(%s\t/* fqn=%s */", func->name->val, func->var->name->val, + func->var->fqn->val); if (func->inner) { size_t i = 0, count = psi_plist_count(func->inner); @@ -82,7 +81,7 @@ void psi_let_func_dump(int fd, struct psi_let_func *func, unsigned level) } static inline int validate_let_func_type(struct psi_data *data, - struct psi_let_func *func, struct psi_impl *impl) + struct psi_let_func *func, struct psi_validate_scope *scope) { switch (func->type) { case PSI_T_BOOLVAL: @@ -108,15 +107,16 @@ static inline int validate_let_func_type(struct psi_data *data, default: data->error(data, func->var->token, PSI_WARNING, "Unknown `let` cast function '%s' of implementation '%s'", - func->name, impl->func->name); + func->name->val, scope->impl->func->name->val); return false; } } static inline bool validate_let_func_inner(struct psi_data *data, - struct psi_let_exp *exp, struct psi_let_func *func, - struct psi_impl *impl) + struct psi_let_func *func, struct psi_validate_scope *scope) { + struct psi_let_exp *exp = scope->current_let; + if (func->inner) { struct psi_decl_var *let_var = psi_let_exp_get_decl_var(exp); struct psi_decl_type *var_typ; @@ -132,20 +132,26 @@ static inline bool validate_let_func_inner(struct psi_data *data, struct psi_let_exp *inner; while (psi_plist_get(func->inner, i++, &inner)) { - const char *name = psi_let_exp_get_decl_var_name(inner); + zend_string *name = psi_let_exp_get_decl_var_name(inner); struct psi_decl_arg *sub_arg; inner->outer = exp; if (name) { sub_arg = psi_decl_arg_get_by_name(sub_args, name); + zend_string_release(name); } if (!name || !sub_arg) { /* remove expr for portability with different struct members */ psi_plist_del(func->inner, --i, NULL); psi_let_exp_free(&inner); - } else if (!psi_let_exp_validate(data, inner, impl)) { - return false; + } else { + scope->current_let = inner; + if (!psi_let_exp_validate(data, inner, scope)) { + scope->current_let = exp; + return false; + } + scope->current_let = exp; } } } else if (func->type == PSI_T_ARRVAL @@ -163,21 +169,24 @@ static inline bool validate_let_func_inner(struct psi_data *data, sub_var = psi_let_exp_get_impl_var(exp); sub_ref = psi_let_exp_get_impl_var(inner); - if (strcmp(sub_var->name, sub_ref->name)) { + if (!zend_string_equals(sub_var->name, sub_ref->name)) { data->error(data, sub_var->token, E_WARNING, "Inner `set` statement casts on pointers must" " reference the same variable"); return false; } - if (!psi_let_exp_validate(data, inner, impl)) { + scope->current_let = inner; + if (!psi_let_exp_validate(data, inner, scope)) { + scope->current_let = exp; return false; } + scope->current_let = exp; } else { data->error(data, let_var->token, PSI_WARNING, "Inner let statement's values must refer to a structure or" " array type, got '%s%s' for '%s'", var_typ->name, psi_t_indirection(let_var->arg->var->pointer_level), - let_var->name); + let_var->name->val); return false; } @@ -191,22 +200,22 @@ static inline bool validate_let_func_inner(struct psi_data *data, return true; } -bool psi_let_func_validate(struct psi_data *data, struct psi_let_exp *val, - struct psi_let_func *func, struct psi_impl *impl) +bool psi_let_func_validate(struct psi_data *data, struct psi_let_func *func, + struct psi_validate_scope *scope) { - if (impl->func->args) { + if (scope->impl->func->args) { /* FIXME, func->var does not need to be referring to a func arg */ - psi_impl_get_arg(impl, func->var); + psi_impl_get_arg(scope->impl, func->var); } - if (!psi_impl_var_validate(data, func->var, impl, val, NULL)) { + if (!psi_impl_var_validate(data, func->var, scope)) { return false; } - if (!validate_let_func_type(data, func, impl)) { + if (!validate_let_func_type(data, func, scope)) { return false; } - if (!validate_let_func_inner(data, val, func, impl)) { + if (!validate_let_func_inner(data, func, scope)) { return false; } return 1; @@ -226,7 +235,7 @@ void exec_let_func_arrval_inner(struct psi_let_func *func, * we only want to set supplied data on unions */ if (!zend_symtable_str_exists(Z_ARRVAL_P(frame_arg->zval_ptr), - &inner_var->name[1], strlen(&inner_var->name[1]))) { + &inner_var->name->val[1], inner_var->name->len - 1)) { return; } } @@ -235,8 +244,8 @@ void exec_let_func_arrval_inner(struct psi_let_func *func, /* example from dm_store/dbm_fetch with arrval($string) conversion: let key = arrval($key, - dptr = strval($0), - dsize = strlen($0) + dptr = strval($0), + dsize = strlen($0) ); # --- darg = key @@ -255,12 +264,12 @@ static void *exec_let_func_arrval(struct psi_let_exp *val, struct psi_call_frame *frame); void exec_let_func_arrval_seq(struct psi_let_func *func, - struct psi_decl_arg *darg, struct psi_decl_type *darg_type, + struct psi_decl_arg *darg, struct psi_call_frame_argument *frame_arg, struct psi_let_exp *inner_let_exp, void *container, struct psi_call_frame *frame) { - zval *zval_ptr; + zval *zval_ptr = NULL; psi_marshal_let let_fn; size_t i = 0, size; struct psi_decl_var *dvar; @@ -287,7 +296,7 @@ void exec_let_func_arrval_seq(struct psi_let_func *func, impl_val val = {0}, *ptr, *sub; if (let_fn) { - ptr = let_fn(&val, darg_type, 0, NULL, zval_ptr, &temp); + ptr = let_fn(&val, darg, 0, NULL, zval_ptr, &temp); if (temp) { psi_call_frame_push_auto(frame, temp); } @@ -315,10 +324,9 @@ static void *exec_let_func_arrval(struct psi_let_exp *val, { void *container = NULL; struct psi_call_frame_argument *frame_arg; - struct psi_decl_type *darg_type; struct psi_plist *darg_members; - darg_members = psi_decl_type_get_args(darg->type, &darg_type); + darg_members = psi_decl_type_get_args(darg->type, NULL); frame_arg = psi_call_frame_get_argument(frame, func->var->fqn); if (frame_arg->zval_ptr && Z_TYPE_P(frame_arg->zval_ptr) != IS_ARRAY) { @@ -342,11 +350,12 @@ static void *exec_let_func_arrval(struct psi_let_exp *val, if (frame_arg->zval_ptr) { while (psi_plist_get(func->inner, i++, &inner)) { - darg_member = psi_decl_arg_get_by_name(darg_members, - psi_let_exp_get_decl_var_name(inner)); + zend_string *var_name = psi_let_exp_get_decl_var_name(inner); + darg_member = psi_decl_arg_get_by_name(darg_members, var_name); exec_let_func_arrval_inner(func, darg, darg_member, frame_arg, inner, container, frame); + zend_string_release(var_name); } } } else if (func->inner) { @@ -368,8 +377,7 @@ static void *exec_let_func_arrval(struct psi_let_exp *val, container = ecalloc(arcount + 1, psi_decl_var_get_size(inner->var)); inner->var->pointer_level -= inner->is_reference; - exec_let_func_arrval_seq(func, darg, darg_type, frame_arg, inner, - container, frame); + exec_let_func_arrval_seq(func, darg, frame_arg, inner, container, frame); } else { assert(0); } @@ -393,8 +401,7 @@ void *psi_let_func_exec(struct psi_let_exp *val, struct psi_let_func *func, assert(iarg); - frame_sym->ival_ptr = let_fn(&frame_sym->temp_val, - psi_decl_type_get_real(darg->type), + frame_sym->ival_ptr = let_fn(&frame_sym->temp_val, darg, iarg->spec ? iarg->spec->type->type : 0, iarg->ival_ptr, iarg->zval_ptr, &temp); if (temp) {