OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
-#include "php_psi_stdinc.h"
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#else
+# include "php_config.h"
+#endif
+
#include "context.h"
#include "data.h"
#include "call.h"
+#include "php_psi.h"
+
#include "php.h"
#include "zend_exceptions.h"
struct psi_call_frame *frame, struct psi_decl_var *dvar) {
struct psi_call_frame_symbol *frame_sym;
- frame_sym = zend_hash_str_find_ptr(&frame->symbols, dvar->fqn, strlen(dvar->fqn));
+ frame_sym = zend_hash_find_ptr(&frame->symbols, dvar->fqn);
if (!frame_sym) {
- frame_sym = zend_hash_str_add_ptr(&frame->symbols, dvar->fqn, strlen(dvar->fqn),
+ frame_sym = zend_hash_add_ptr(&frame->symbols, dvar->fqn,
psi_call_frame_symbol_init(dvar));
}
return frame_sym;
/* varargs are just appended with numeric indices */
return zend_hash_next_index_insert_ptr(&frame->arguments, frame_arg);
} else {
- return zend_hash_str_add_ptr(&frame->arguments,
- frame_arg->spec->var->name, strlen(frame_arg->spec->var->name),
- frame_arg);
+ return zend_hash_add_ptr(&frame->arguments,
+ frame_arg->spec->var->name, frame_arg);
}
}
zval *psi_call_frame_sub_argument(struct psi_call_frame *frame,
- struct psi_impl_var *inner_var, zval *outer_zval, const char *name) {
+ struct psi_impl_var *inner_var, zval *outer_zval, zend_string *name) {
struct psi_call_frame_argument *iarg;
zval *inner_zval = zend_symtable_str_find(Z_ARRVAL_P(outer_zval),
- &inner_var->name[1], strlen(&inner_var->name[1]));
+ &inner_var->name->val[1], inner_var->name->len - 1);
if (!inner_zval) {
zval empty_zval;
+ SEPARATE_ZVAL(outer_zval);
ZVAL_NULL(&empty_zval);
inner_zval = zend_symtable_str_update(Z_ARRVAL_P(outer_zval),
- &inner_var->name[1], strlen(&inner_var->name[1]),
+ &inner_var->name->val[1], inner_var->name->len - 1,
&empty_zval);
}
if (!iarg) {
struct psi_call_frame_argument *frame_arg;
impl_val empty_val = {0};
+ zend_string *type_str = psi_string_init_interned(ZEND_STRL("mixed"), 1);
struct psi_impl_arg *carg_spec = psi_impl_arg_init(
- psi_impl_type_init(PSI_T_MIXED, "mixed"),
+ psi_impl_type_init(PSI_T_MIXED, type_str),
psi_impl_var_copy(inner_var), NULL);
psi_call_frame_push_auto_ex(frame, carg_spec, (void(*)(void*)) psi_impl_arg_free);
frame_arg = psi_call_frame_argument_init(carg_spec, &empty_val, inner_zval, 0);
- zend_hash_str_add_ptr(&frame->arguments, name, strlen(name), frame_arg);
+ zend_hash_add_ptr(&frame->arguments, name, frame_arg);
+ zend_string_release(type_str);
}
return inner_zval;
}
struct psi_call_frame_argument *psi_call_frame_get_argument(
- struct psi_call_frame *frame, const char *name) {
- return zend_hash_str_find_ptr(&frame->arguments, name, strlen(name));
+ struct psi_call_frame *frame, zend_string *name) {
+ return zend_hash_find_ptr(&frame->arguments, name);
}
size_t psi_call_frame_num_var_args(struct psi_call_frame *frame) {
- return zend_hash_next_free_element(&frame->arguments);
+ zend_long nfe = zend_hash_next_free_element(&frame->arguments);
+ return nfe > 0 ? nfe : 0;
}
size_t psi_call_frame_num_fixed_args(struct psi_call_frame *frame) {
return frame->pointers;
}
-ZEND_RESULT_CODE psi_call_frame_parse_args(struct psi_call_frame *frame,
+void *psi_call_frame_get_rpointer(struct psi_call_frame *frame) {
+ return frame->rpointer;
+}
+
+struct psi_decl *psi_call_frame_get_decl(struct psi_call_frame *frame) {
+ return frame->decl;
+}
+
+struct psi_impl *psi_call_frame_get_impl(struct psi_call_frame *frame) {
+ return frame->impl;
+}
+
+struct psi_context *psi_call_frame_get_context(struct psi_call_frame *frame) {
+ return frame->context;
+}
+
+#if PHP_VERSION_ID < 70300
+# define PARAM_PROLOGUE(separate) Z_PARAM_PROLOGUE(separate)
+#else
+# define PARAM_PROLOGUE(separate) Z_PARAM_PROLOGUE(1, separate)
+#endif
+bool psi_call_frame_parse_args(struct psi_call_frame *frame,
zend_execute_data *execute_data) {
size_t i, argc = psi_plist_count(frame->impl->func->args);
zend_error_handling zeh;
rv = zend_parse_parameters_none();
zend_restore_error_handling(&zeh);
- return rv;
+ return rv == SUCCESS;
}
ZEND_PARSE_PARAMETERS_START(
Z_PARAM_ARRAY_EX(tmp, _optional || iarg->var->reference,
iarg->var->reference);
} else if (PSI_T_OBJECT == iarg->type->type) {
- Z_PARAM_PROLOGUE(0);
+ PARAM_PROLOGUE(iarg->var->reference);
} else if (PSI_T_MIXED == iarg->type->type) {
- Z_PARAM_PROLOGUE(0);
+ PARAM_PROLOGUE(iarg->var->reference);
} else if (PSI_T_CALLABLE == iarg->type->type) {
zend_fcall_info fci;
zend_fcall_info_cache fcc;
ival.zend.cb->fcc = fcc;
}
} else {
- error_code = ZPP_ERROR_FAILURE;
+ _error_code = ZPP_ERROR_FAILURE;
break;
}
}
ZEND_PARSE_PARAMETERS_END_EX(
zend_restore_error_handling(&zeh);
- return FAILURE;
+ return false;
);
/* set up defaults */
}
zend_restore_error_handling(&zeh);
- return SUCCESS;
+ return true;
}
void psi_call_frame_enter(struct psi_call_frame *frame) {
frame->rpointer = rv_sym->ptr = rv_sym->ival_ptr;
}
-ZEND_RESULT_CODE psi_call_frame_do_let(struct psi_call_frame *frame) {
+bool psi_call_frame_do_let(struct psi_call_frame *frame) {
size_t i;
struct psi_let_stmt *let;
struct psi_decl_arg *arg;
void *temp = NULL;
frame_arg = psi_call_frame_get_var_argument(frame, i);
+ if (!frame_arg) {
+ return false;
+ }
switch (frame_arg->va_type) {
case PSI_T_BOOL: let_fn = psi_let_boolval; break;
case PSI_T_INT: let_fn = psi_let_intval; break;
case PSI_T_STRING: let_fn = psi_let_strval; break;
default:
assert(0);
+ return false;
}
frame_arg->ival_ptr = let_fn(&frame_arg->temp_val, NULL, frame_arg->va_type,
}
}
- return SUCCESS;
+ return true;
}
-void psi_call_frame_do_call(struct psi_call_frame *frame) {
- size_t va_count = psi_call_frame_num_var_args(frame);
-
- if (va_count) {
- void **va_types = ecalloc(va_count, sizeof(void *));
- size_t i;
-
- for (i = 0; i < va_count; ++i) {
- struct psi_call_frame_argument *frame_arg;
+bool psi_call_frame_do_assert(struct psi_call_frame *frame, enum psi_assert_kind kind) {
+ size_t i = 0;
+ struct psi_assert_stmt *ass;
- frame_arg = psi_call_frame_get_var_argument(frame, i);
- va_types[i] = frame->context->ops->query(frame->context,
- PSI_CONTEXT_QUERY_TYPE, &frame_arg->va_type);
+ while (psi_plist_get(frame->impl->stmts.ass, i++, &ass)) {
+ if (ass->kind == kind) {
+ if (!psi_assert_stmt_exec(ass, frame)) {
+ psi_assert_stmt_throw(ass);
+ return false;
+ }
}
+ }
- frame->context->ops->call_va(frame->context,
- frame,
- frame->decl,
- frame->rpointer,
- frame->pointers,
- va_count,
- va_types);
+ return true;
+}
- efree(va_types);
- } else {
- frame->context->ops->call(frame->context,
- frame,
- frame->decl,
- frame->rpointer,
- frame->pointers);
- }
+void psi_call_frame_do_call(struct psi_call_frame *frame) {
+ frame->context->ops->call(frame);
}
void psi_call_frame_do_callback(struct psi_call_frame *frame, struct psi_call_frame_callback *cbdata)
}
frame_arg = psi_call_frame_get_argument(frame, cb->func->var->fqn);
+ if (!frame_arg) {
+ return;
+ }
/* callback into userland */
ZVAL_UNDEF(&return_value);
rc = zend_fcall_info_call(&frame_arg->ival_ptr->zend.cb->fci,
&frame_arg->ival_ptr->zend.cb->fcc, &return_value, NULL);
assert(rc == SUCCESS);
+ (void) rc;
/* marshal return value of the userland call */
frame_arg->zval_ptr = &return_value;
efree(auto_list);
}
-#include "php_psi.h"
-
void psi_call_frame_free(struct psi_call_frame *frame) {
zend_hash_destroy(&frame->arguments);
zend_hash_destroy(&frame->symbols);
memcpy(temp, &frame->temp, sizeof(*temp));
ZVAL_OBJ(&zlocal, psi_object_init_ex(NULL, temp, psi_call_frame_local_auto_dtor));
- zend_set_local_var_str(frame->impl->func->name,
- strlen(frame->impl->func->name), &zlocal, /* force */ 1);
+ zend_set_local_var(frame->impl->func->name, &zlocal, /* force */ 1);
} else {
zend_llist_destroy(&frame->temp);
}