summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend.h17
-rw-r--r--Zend/zend_API.c11
-rw-r--r--Zend/zend_API.h40
-rw-r--r--Zend/zend_builtin_functions.c31
-rw-r--r--Zend/zend_compile.c104
-rw-r--r--Zend/zend_compile.h55
-rw-r--r--Zend/zend_execute.c108
-rw-r--r--Zend/zend_execute_API.c16
-rw-r--r--Zend/zend_language_parser.y22
-rw-r--r--Zend/zend_modules.h10
-rw-r--r--Zend/zend_object_handlers.c3
-rw-r--r--Zend/zend_opcode.c14
-rw-r--r--Zend/zend_reflection_api.c2
-rw-r--r--ext/reflection/php_reflection.c2
14 files changed, 241 insertions, 194 deletions
diff --git a/Zend/zend.h b/Zend/zend.h
index 0fd5576610..2b61e3692e 100644
--- a/Zend/zend.h
+++ b/Zend/zend.h
@@ -262,15 +262,6 @@ struct _zval_struct {
zend_uchar is_ref;
};
-struct _zend_op_array;
-
-typedef struct _zend_function_entry {
- char *fname;
- void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
- unsigned char *func_arg_types;
-} zend_function_entry;
-
-
typedef struct _zend_property_reference {
int type; /* read, write or r/w */
zval *object;
@@ -306,7 +297,7 @@ struct _zend_class_entry {
HashTable properties_info;
HashTable *static_members;
HashTable constants_table;
- zend_function_entry *builtin_functions;
+ struct _zend_function_entry *builtin_functions;
union _zend_function *constructor;
union _zend_function *destructor;
@@ -397,12 +388,6 @@ typedef int (*zend_write_func_t)(const char *str, uint str_length);
#define OE_IS_METHOD (1<<2)
-/* Argument passing types */
-#define BYREF_NONE 0
-#define BYREF_FORCE 1
-#define BYREF_ALLOW 2
-#define BYREF_FORCE_REST 3
-
int zend_startup(zend_utility_functions *utility_functions, char **extensions, int start_builtin_functions);
void zend_shutdown(TSRMLS_D);
void zend_register_standard_ini_entries(TSRMLS_D);
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index c22cef4708..88faa34bd5 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -1158,11 +1158,20 @@ int zend_register_functions(zend_class_entry *scope, zend_function_entry *functi
while (ptr->fname) {
internal_function->handler = ptr->handler;
- internal_function->arg_types = ptr->func_arg_types;
internal_function->function_name = ptr->fname;
internal_function->scope = scope;
internal_function->fn_flags = ZEND_ACC_PUBLIC;
internal_function->prototype = NULL;
+ if (ptr->arg_info) {
+ internal_function->arg_info = ptr->arg_info+1;
+ internal_function->num_args = ptr->num_args;
+ internal_function->pass_rest_by_reference = ptr->arg_info[0].pass_by_reference;
+ } else {
+ internal_function->arg_info = NULL;
+ internal_function->num_args = 0;
+ internal_function->pass_rest_by_reference = 0;
+ }
+ internal_function->fn_flags = ptr->flags;
if (!internal_function->handler) {
zend_error(error_type, "Null function defined as active function");
zend_unregister_functions(functions, count, target_function_table TSRMLS_CC);
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index b3606305c5..5a3abe20c4 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -32,16 +32,32 @@
BEGIN_EXTERN_C()
-#define ZEND_FN(name) zif_##name
-#define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS)
-#define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
-#define ZEND_METHOD(class, name) ZEND_NAMED_FUNCTION(ZEND_FN(class##_##name))
-#define ZEND_NAMED_FE(zend_name, name, arg_types) { #zend_name, name, arg_types },
-#define ZEND_FE(name, arg_types) ZEND_NAMED_FE(name, ZEND_FN(name), arg_types)
-#define ZEND_FALIAS(name, alias, arg_types) ZEND_NAMED_FE(name, ZEND_FN(alias), arg_types)
-#define ZEND_STATIC_FE(name, impl_name, arg_types) { name, impl_name, arg_types },
-#define ZEND_ME(class, name, arg_types) ZEND_NAMED_FE(name, ZEND_FN(class##_##name), arg_types)
+typedef struct _zend_function_entry {
+ char *fname;
+ void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
+ struct _zend_arg_info *arg_info;
+ zend_uint num_args;
+ zend_uint flags;
+} zend_function_entry;
+
+#define ZEND_FN(name) zif_##name
+#define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS)
+#define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
+#define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_FN(classname##_##name))
+
+#define ZEND_NAMED_FE(zend_name, name, arg_info) { #zend_name, name, arg_info, sizeof(arg_info)/sizeof(struct _zend_arg_info)-1, 0 },
+#define ZEND_FE(name, arg_info) ZEND_NAMED_FE(name, ZEND_FN(name), arg_info)
+#define ZEND_FALIAS(name, alias, arg_info) ZEND_NAMED_FE(name, ZEND_FN(alias), arg_info)
+#define ZEND_ME(classname, name, arg_info, flags) { #name, ZEND_FN(classname##_##name), arg_info, sizeof(arg_info)/sizeof(struct _zend_arg_info)-1, flags },
+
+#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, pass_by_ref },
+#define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, pass_by_ref },
+#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, allow_null, pass_by_ref },
+#define ZEND_BEGIN_ARG_INFO(name, pass_rest_by_reference) \
+ zend_arg_info name[] = { \
+ ZEND_ARG_PASS_INFO(pass_rest_by_reference)
+#define ZEND_END_ARG_INFO() };
/* Name macros */
#define ZEND_MODULE_STARTUP_N(module) zm_startup_##module
@@ -249,9 +265,9 @@ ZEND_API int add_property_zval_ex(zval *arg, char *key, uint key_len, zval *valu
#define add_property_stringl(__arg, __key, __str, __length, __duplicate) add_property_stringl_ex(__arg, __key, strlen(__key)+1, __str, __length, __duplicate TSRMLS_CC)
#define add_property_zval(__arg, __key, __value) add_property_zval_ex(__arg, __key, strlen(__key)+1, __value TSRMLS_CC)
-ZEND_API int call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, int param_count, zval *params[] TSRMLS_DC);
-ZEND_API int call_user_function_ex(HashTable *function_table, zval **object_pp, zval *function_name, zval **retval_ptr_ptr, int param_count, zval **params[], int no_separation, HashTable *symbol_table TSRMLS_DC);
-ZEND_API int fast_call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval **retval_ptr_ptr, int param_count, zval **params[], int no_separation, HashTable *symbol_table, zend_function **function_pointer TSRMLS_DC);
+ZEND_API int call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, zend_uint param_count, zval *params[] TSRMLS_DC);
+ZEND_API int call_user_function_ex(HashTable *function_table, zval **object_pp, zval *function_name, zval **retval_ptr_ptr, zend_uint param_count, zval **params[], int no_separation, HashTable *symbol_table TSRMLS_DC);
+ZEND_API int fast_call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval **retval_ptr_ptr, zend_uint param_count, zval **params[], int no_separation, HashTable *symbol_table, zend_function **function_pointer TSRMLS_DC);
ZEND_API int zend_set_hash_symbol(zval *symbol, char *name, int name_length,
zend_bool is_ref, int num_symbol_tables, ...);
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 6fc3017c3a..1032d79204 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -80,9 +80,33 @@ static ZEND_FUNCTION(zend_thread_id);
#endif
#endif
-ZEND_API unsigned char first_arg_force_ref[] = { 1, BYREF_FORCE };
-ZEND_API unsigned char second_arg_force_ref[] = { 2, BYREF_NONE, BYREF_FORCE };
-ZEND_API unsigned char third_arg_force_ref[] = { 3, BYREF_NONE, BYREF_NONE, BYREF_FORCE };
+ZEND_API
+ ZEND_BEGIN_ARG_INFO(first_arg_force_ref, 0)
+ ZEND_ARG_PASS_INFO(1)
+ ZEND_END_ARG_INFO();
+
+
+ZEND_API
+ ZEND_BEGIN_ARG_INFO(second_arg_force_ref, 0)
+ ZEND_ARG_PASS_INFO(0)
+ ZEND_ARG_PASS_INFO(1)
+ ZEND_END_ARG_INFO();
+
+ZEND_API
+ ZEND_BEGIN_ARG_INFO(third_arg_force_ref, 0)
+ ZEND_ARG_PASS_INFO(0)
+ ZEND_ARG_PASS_INFO(0)
+ ZEND_ARG_PASS_INFO(1)
+ ZEND_END_ARG_INFO();
+
+
+ZEND_API
+ ZEND_BEGIN_ARG_INFO(fourth_arg_force_ref, 0)
+ ZEND_ARG_PASS_INFO(0)
+ ZEND_ARG_PASS_INFO(0)
+ ZEND_ARG_PASS_INFO(0)
+ ZEND_ARG_PASS_INFO(1)
+ ZEND_END_ARG_INFO();
static zend_function_entry builtin_functions[] = {
ZEND_FE(zend_version, NULL)
@@ -1712,6 +1736,7 @@ ZEND_FUNCTION(get_extension_funcs)
}
/* }}} */
+
/*
* Local variables:
* tab-width: 4
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index a4e212a973..4ff5de2ef9 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -930,7 +930,6 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
init_op_array(&op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
op_array.function_name = name;
- op_array.arg_types = NULL;
op_array.return_reference = return_reference;
op_array.fn_flags = fn_flags;
@@ -1048,10 +1047,12 @@ void zend_do_end_function_declaration(znode *function_token TSRMLS_DC)
}
-void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initialization, znode *class_type, zend_uchar pass_type TSRMLS_DC)
+void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initialization, znode *class_type, znode *varname, zend_uchar pass_by_reference TSRMLS_DC)
{
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+ zend_arg_info *cur_arg_info;
+ CG(active_op_array)->num_args++;
opline->opcode = op;
opline->result = *var;
opline->op1 = *offset;
@@ -1060,33 +1061,20 @@ void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initia
} else {
SET_UNUSED(opline->op2);
}
- if (!CG(active_op_array)->arg_types) {
- if (pass_type==BYREF_FORCE) {
- int i;
-
- CG(active_op_array)->arg_types = (unsigned char *) emalloc(sizeof(unsigned char)*(offset->u.constant.value.lval+1));
- for (i=1; i<offset->u.constant.value.lval; i++) {
- CG(active_op_array)->arg_types[i] = BYREF_NONE;
- }
- CG(active_op_array)->arg_types[0]=(unsigned char) offset->u.constant.value.lval;
- CG(active_op_array)->arg_types[offset->u.constant.value.lval] = pass_type;
- }
- } else {
- CG(active_op_array)->arg_types = (unsigned char *) erealloc(CG(active_op_array)->arg_types, sizeof(unsigned char)*(offset->u.constant.value.lval+1));
- CG(active_op_array)->arg_types[0]=(unsigned char) offset->u.constant.value.lval;
- CG(active_op_array)->arg_types[offset->u.constant.value.lval] = pass_type;
- }
+ CG(active_op_array)->arg_info = erealloc(CG(active_op_array)->arg_info, sizeof(zend_arg_info)*(CG(active_op_array)->num_args));
+ cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1];
+ cur_arg_info->name = estrndup(varname->u.constant.value.str.val, varname->u.constant.value.str.len);
+ cur_arg_info->name_len = varname->u.constant.value.str.len;
+ cur_arg_info->allow_null = 1;
+ cur_arg_info->pass_by_reference = pass_by_reference;
if (class_type->op_type != IS_UNUSED) {
- znode passed_var = opline->result;
-
- opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-
- opline->opcode = ZEND_VERIFY_INSTANCEOF;
- opline->op1 = *class_type;
- opline->op2 = passed_var;
- opline->extended_value = offset->u.constant.value.lval;
+ cur_arg_info->class_name = class_type->u.constant.value.str.val;
+ cur_arg_info->class_name_len = class_type->u.constant.value.str.len;
+ zend_str_tolower(cur_arg_info->class_name, cur_arg_info->class_name_len);
} else {
+ cur_arg_info->class_name = NULL;
+ cur_arg_info->class_name_len = 0;
opline->result.u.EA.type |= EXT_TYPE_UNUSED;
}
}
@@ -1296,12 +1284,10 @@ void zend_do_end_function_call(znode *function_name, znode *result, znode *argum
void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC)
{
zend_op *opline;
- unsigned char *arg_types;
int original_op=op;
zend_function **function_ptr_ptr, *function_ptr;
int send_by_reference;
-
-
+
zend_stack_top(&CG(function_call_stack), (void **) &function_ptr_ptr);
function_ptr = *function_ptr_ptr;
@@ -1318,14 +1304,11 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC)
}
if (function_ptr) {
- arg_types = function_ptr->common.arg_types;
+ send_by_reference = ARG_SHOULD_BE_SENT_BY_REF(function_ptr, (zend_uint) offset) ? ZEND_ARG_SEND_BY_REF : 0;
} else {
- arg_types = NULL;
+ send_by_reference = 0;
}
- send_by_reference = ARG_SHOULD_BE_SENT_BY_REF(offset, 1, arg_types)?ZEND_ARG_SEND_BY_REF:0;
-
-
if (op == ZEND_SEND_VAR && zend_is_function_or_method_call(param)) {
/* Method call */
op = ZEND_SEND_VAR_NO_REF;
@@ -1333,7 +1316,7 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC)
op = ZEND_SEND_VAR_NO_REF;
}
- if (op!=ZEND_SEND_VAR_NO_REF && send_by_reference == ZEND_ARG_SEND_BY_REF) {
+ if (op!=ZEND_SEND_VAR_NO_REF && send_by_reference==ZEND_ARG_SEND_BY_REF) {
/* change to passing by reference */
switch (param->op_type) {
case IS_VAR:
@@ -1611,63 +1594,26 @@ static void do_inherit_method(zend_function *function)
static zend_bool zend_do_perform_implementation_check(zend_function *fe)
{
- zend_op *op, *proto_op;
+ zend_uint i;
if (!fe->common.prototype) {
return 1;
}
- if ((fe->common.arg_types && !fe->common.prototype->common.arg_types)
- || (!fe->common.arg_types && fe->common.prototype->common.arg_types)) {
+ if (fe->common.num_args != fe->common.prototype->common.num_args
+ || fe->common.pass_rest_by_reference != fe->common.prototype->common.pass_rest_by_reference) {
return 0;
}
- if (fe->common.arg_types) {
- if (fe->common.arg_types[0] != fe->common.prototype->common.arg_types[0]) {
+ for (i=0; i< fe->common.num_args; i++) {
+ if (strcmp(fe->common.arg_info[i].class_name, fe->common.prototype->common.arg_info[i].class_name)!=0) {
return 0;
}
- if (memcmp(fe->common.arg_types+1, fe->common.prototype->common.arg_types+1, fe->common.arg_types[0]*sizeof(zend_uchar)) != 0) {
+ if (fe->common.arg_info[i].pass_by_reference != fe->common.prototype->common.arg_info[i].pass_by_reference) {
return 0;
}
}
-
- if (fe->common.prototype->type == ZEND_INTERNAL_FUNCTION) {
- return 1; /* nothing further we can do here */
- }
-
- op = fe->op_array.opcodes;
- proto_op = fe->common.prototype->op_array.opcodes;
-
- /* Make sure that the implementation has all of the arguments of the interface */
- while (proto_op->opcode != ZEND_RAISE_ABSTRACT_ERROR) {
- if (proto_op->opcode != op->opcode) {
- return 0;
- }
- switch (proto_op->opcode) {
- case ZEND_FETCH_CLASS:
- if (zend_binary_zval_strcasecmp(&op->op2.u.constant, &proto_op->op2.u.constant)!=0) {
- return 0;
- }
- break;
- }
- proto_op++;
- op++;
- }
-
- /* Make sure that the implementation doesn't receive more arguments than the interface */
- while (1) {
- switch (op->opcode) {
- case ZEND_FETCH_CLASS:
- case ZEND_FETCH_W:
- op++;
- break;
- case ZEND_RECV:
- case ZEND_RECV_INIT:
- return 0;
- default:
- return 1;
- }
- }
+ return 1;
}
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 59e05ea273..8e93dbb90e 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -121,14 +121,25 @@ typedef struct _zend_property_info {
} zend_property_info;
+typedef struct _zend_arg_info {
+ char *name;
+ zend_uint name_len;
+ char *class_name;
+ zend_uint class_name_len;
+ zend_bool allow_null;
+ zend_bool pass_by_reference;
+} zend_arg_info;
+
struct _zend_op_array {
/* Common elements */
zend_uchar type;
- zend_uchar *arg_types;
char *function_name;
zend_class_entry *scope;
zend_uint fn_flags;
union _zend_function *prototype;
+ zend_uint num_args;
+ zend_arg_info *arg_info;
+ zend_bool pass_rest_by_reference;
/* END of common elements */
zend_uint *refcount;
@@ -165,11 +176,13 @@ struct _zend_op_array {
typedef struct _zend_internal_function {
/* Common elements */
zend_uchar type;
- zend_uchar *arg_types;
char *function_name;
zend_class_entry *scope;
zend_uint fn_flags;
union _zend_function *prototype;
+ zend_uint num_args;
+ zend_arg_info *arg_info;
+ zend_bool pass_rest_by_reference;
/* END of common elements */
void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
@@ -182,11 +195,13 @@ typedef union _zend_function {
struct {
zend_uchar type; /* never used */
- zend_uchar *arg_types;
char *function_name;
zend_class_entry *scope;
zend_uint fn_flags;
union _zend_function *prototype;
+ zend_uint num_args;
+ zend_arg_info *arg_info;
+ zend_bool pass_rest_by_reference;
} common;
zend_op_array op_array;
@@ -320,7 +335,7 @@ void zend_do_add_variable(znode *result, znode *op1, znode *op2 TSRMLS_DC);
int zend_do_verify_access_types(znode *current_access_type, znode *new_modifier);
void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC);
void zend_do_end_function_declaration(znode *function_token TSRMLS_DC);
-void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initialization, znode *class_type, zend_uchar pass_type TSRMLS_DC);
+void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initialization, znode *class_type, znode *varname, zend_bool pass_by_reference TSRMLS_DC);
int zend_do_begin_function_call(znode *function_name TSRMLS_DC);
void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC);
void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC);
@@ -653,7 +668,6 @@ int zendlex(znode *zendlval TSRMLS_DC);
#define ZEND_ADD_INTERFACE 144
-#define ZEND_VERIFY_INSTANCEOF 145
#define ZEND_VERIFY_ABSTRACT_CLASS 146
#define ZEND_ASSIGN_DIM 147
@@ -751,23 +765,24 @@ int zendlex(znode *zendlval TSRMLS_DC);
}
/* Lost In Stupid Parentheses */
-#define ARG_SHOULD_BE_SENT_BY_REF(offset, conduct_check, arg_types) \
- ( \
- conduct_check \
- && arg_types \
- && \
- ( \
- ( \
- offset<=arg_types[0] \
- && arg_types[offset]==BYREF_FORCE \
- ) \
- || ( \
- offset>=arg_types[0] \
- && arg_types[arg_types[0]]==BYREF_FORCE_REST \
- ) \
- ) \
+#define ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \
+ ( \
+ zf \
+ && ((zend_function *) zf)->common.arg_info \
+ && \
+ ( \
+ ( \
+ arg_num<=((zend_function *) zf)->common.num_args \
+ && ((zend_function *) zf)->common.arg_info[arg_num-1].pass_by_reference \
+ ) \
+ || ( \
+ arg_num>((zend_function *) zf)->common.num_args \
+ && ((zend_function *) zf)->common.pass_rest_by_reference \
+ ) \
+ ) \
)
+
#define ZEND_RETURN_VAL 0
#define ZEND_RETURN_REF 1
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 5cba52658f..4afc36f267 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -281,6 +281,49 @@ static inline zval *get_obj_zval_ptr(znode *op, temp_variable *Ts, zval **freeop
return get_zval_ptr(op, Ts, freeop, type);
}
+
+static inline void zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg TSRMLS_DC)
+{
+ zend_arg_info *cur_arg_info;
+
+ if (!zf->common.arg_info
+ || arg_num>zf->common.num_args) {
+ return;
+ }
+
+ cur_arg_info = &zf->common.arg_info[arg_num-1];
+
+ if (cur_arg_info->class_name) {
+ if (!arg) {
+ zend_error(E_ERROR, "Argument %d must be an object of class %s", arg_num, cur_arg_info->class_name);
+ }
+ switch (Z_TYPE_P(arg)) {
+ case IS_NULL:
+ if (!cur_arg_info->allow_null) {
+ zend_error(E_ERROR, "Argument %d must not be null", arg_num);
+ }
+ break;
+ case IS_OBJECT: {
+ zend_class_entry *ce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
+ if (!instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
+ char *error_msg;
+
+ if (ce->ce_flags & ZEND_ACC_INTERFACE) {
+ error_msg = "implement interface";
+ } else {
+ error_msg = "be an instance of";
+ }
+ zend_error(E_ERROR, "Argument %d must %s %s", arg_num, error_msg, ce->name);
+ }
+ }
+ break;
+ default:
+ zend_error(E_ERROR, "Argument %d must be an object of class %s", arg_num, cur_arg_info->class_name);
+ break;
+ }
+ }
+}
+
static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode *op2, znode *value_op, temp_variable *Ts, int opcode TSRMLS_DC)
{
zval *object;
@@ -1784,7 +1827,7 @@ int zend_fetch_rw_handler(ZEND_OPCODE_HANDLER_ARGS)
int zend_fetch_func_arg_handler(ZEND_OPCODE_HANDLER_ARGS)
{
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(opline)->extended_value, EX(fbc), EX(fbc)->common.arg_types)) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), EX(opline)->extended_value)) {
/* Behave like FETCH_W */
zend_fetch_var_address(EX(opline), EX(Ts), BP_VAR_W TSRMLS_CC);
} else {
@@ -1851,7 +1894,7 @@ int zend_fetch_dim_is_handler(ZEND_OPCODE_HANDLER_ARGS)
int zend_fetch_dim_func_arg_handler(ZEND_OPCODE_HANDLER_ARGS)
{
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(opline)->extended_value, EX(fbc), EX(fbc)->common.arg_types)) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), EX(opline)->extended_value)) {
/* Behave like FETCH_DIM_W */
zend_fetch_dimension_address(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX(Ts), BP_VAR_W TSRMLS_CC);
} else {
@@ -1912,7 +1955,7 @@ int zend_fetch_obj_is_handler(ZEND_OPCODE_HANDLER_ARGS)
int zend_fetch_obj_func_arg_handler(ZEND_OPCODE_HANDLER_ARGS)
{
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(opline)->extended_value, EX(fbc), EX(fbc)->common.arg_types)) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), EX(opline)->extended_value)) {
/* Behave like FETCH_OBJ_W */
zend_fetch_property_address(&EX(opline)->result, &EX(opline)->op1, &EX(opline)->op2, EX(Ts), BP_VAR_W TSRMLS_CC);
} else {
@@ -2453,6 +2496,19 @@ int zend_do_fcall_common_helper(ZEND_OPCODE_HANDLER_ARGS)
ALLOC_ZVAL(EX_T(EX(opline)->result.u.var).var.ptr);
INIT_ZVAL(*(EX_T(EX(opline)->result.u.var).var.ptr));
+ if (EX(function_state).function->common.arg_info) {
+ zend_uint i=0;
+ zval **p;
+ ulong arg_count;
+
+ p = (zval **) EG(argument_stack).top_element-2;
+ arg_count = (ulong) *p;
+
+ while (arg_count>0) {
+ zend_verify_arg_type(EX(function_state).function, ++i, *(p-arg_count) TSRMLS_CC);
+ arg_count--;
+ }
+ }
if (!zend_execute_internal) {
/* saves one function call if zend_execute_internal is not used */
((zend_internal_function *) EX(function_state).function)->handler(EX(opline)->extended_value, EX_T(EX(opline)->result.u.var).var.ptr, EX(object), return_value_used TSRMLS_CC);
@@ -2702,7 +2758,7 @@ exception_should_be_taken:
int zend_send_val_handler(ZEND_OPCODE_HANDLER_ARGS)
{
if (EX(opline)->extended_value==ZEND_DO_FCALL_BY_NAME
- && ARG_SHOULD_BE_SENT_BY_REF(EX(opline)->op2.u.opline_num, EX(fbc), EX(fbc)->common.arg_types)) {
+ && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), EX(opline)->op2.u.opline_num)) {
zend_error(E_ERROR, "Cannot pass parameter %d by reference", EX(opline)->op2.u.opline_num);
}
{
@@ -2755,7 +2811,7 @@ int zend_send_var_no_ref_handler(ZEND_OPCODE_HANDLER_ARGS)
if (!(EX(opline)->extended_value & ZEND_ARG_SEND_BY_REF)) {
return zend_send_by_var_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
- } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(opline)->op2.u.opline_num, EX(fbc), EX(fbc)->common.arg_types)) {
+ } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), EX(opline)->op2.u.opline_num)) {
return zend_send_by_var_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
{
@@ -2796,7 +2852,7 @@ int zend_send_ref_handler(ZEND_OPCODE_HANDLER_ARGS)
int zend_send_var_handler(ZEND_OPCODE_HANDLER_ARGS)
{
if ((EX(opline)->extended_value == ZEND_DO_FCALL_BY_NAME)
- && ARG_SHOULD_BE_SENT_BY_REF(EX(opline)->op2.u.opline_num, EX(fbc), EX(fbc)->common.arg_types)) {
+ && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), EX(opline)->op2.u.opline_num)) {
return zend_send_ref_handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
return zend_send_by_var_helper(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -2806,16 +2862,21 @@ int zend_send_var_handler(ZEND_OPCODE_HANDLER_ARGS)
int zend_recv_handler(ZEND_OPCODE_HANDLER_ARGS)
{
zval **param;
+ zend_uint arg_num = EX(opline)->op1.u.constant.value.lval;
- if (zend_ptr_stack_get_arg(EX(opline)->op1.u.constant.value.lval, (void **) &param TSRMLS_CC)==FAILURE) {
+ if (zend_ptr_stack_get_arg(arg_num, (void **) &param TSRMLS_CC)==FAILURE) {
+ zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL TSRMLS_CC);
zend_error(E_WARNING, "Missing argument %d for %s()\n", EX(opline)->op1.u.constant.value.lval, get_active_function_name(TSRMLS_C));
if (EX(opline)->result.op_type == IS_VAR) {
PZVAL_UNLOCK(*EX_T(EX(opline)->result.u.var).var.ptr_ptr);
}
- } else if (PZVAL_IS_REF(*param)) {
- zend_assign_to_variable_reference(&EX(opline)->result, get_zval_ptr_ptr(&EX(opline)->result, EX(Ts), BP_VAR_W), param, NULL TSRMLS_CC);
} else {
- zend_assign_to_variable(&EX(opline)->result, &EX(opline)->result, NULL, *param, IS_VAR, EX(Ts) TSRMLS_CC);
+ zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param TSRMLS_CC);
+ if (PZVAL_IS_REF(*param)) {
+ zend_assign_to_variable_reference(&EX(opline)->result, get_zval_ptr_ptr(&EX(opline)->result, EX(Ts), BP_VAR_W), param, NULL TSRMLS_CC);
+ } else {
+ zend_assign_to_variable(&EX(opline)->result, &EX(opline)->result, NULL, *param, IS_VAR, EX(Ts) TSRMLS_CC);
+ }
}
NEXT_OPCODE();
@@ -2825,8 +2886,9 @@ int zend_recv_handler(ZEND_OPCODE_HANDLER_ARGS)
int zend_recv_init_handler(ZEND_OPCODE_HANDLER_ARGS)
{
zval **param, *assignment_value;
+ zend_uint arg_num = EX(opline)->op1.u.constant.value.lval;
- if (zend_ptr_stack_get_arg(EX(opline)->op1.u.constant.value.lval, (void **) &param TSRMLS_CC)==FAILURE) {
+ if (zend_ptr_stack_get_arg(arg_num, (void **) &param TSRMLS_CC)==FAILURE) {
if (EX(opline)->op2.u.constant.type == IS_CONSTANT || EX(opline)->op2.u.constant.type==IS_CONSTANT_ARRAY) {
zval *default_value;
@@ -2845,9 +2907,11 @@ int zend_recv_init_handler(ZEND_OPCODE_HANDLER_ARGS)
param = NULL;
assignment_value = &EX(opline)->op2.u.constant;
}
+ zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value TSRMLS_CC);
zend_assign_to_variable(&EX(opline)->result, &EX(opline)->result, NULL, assignment_value, IS_VAR, EX(Ts) TSRMLS_CC);
} else {
assignment_value = *param;
+ zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value TSRMLS_CC);
if (PZVAL_IS_REF(assignment_value)) {
zend_assign_to_variable_reference(&EX(opline)->result, get_zval_ptr_ptr(&EX(opline)->result, EX(Ts), BP_VAR_W), param, NULL TSRMLS_CC);
} else {
@@ -3847,27 +3911,6 @@ int zend_add_interface_handler(ZEND_OPCODE_HANDLER_ARGS)
}
-int zend_verify_instanceof_handler(ZEND_OPCODE_HANDLER_ARGS)
-{
- zval *arg = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
- zend_class_entry *ce = EX_T(EX(opline)->op1.u.var).EA.class_entry;
-
- if ((Z_TYPE_P(arg) != IS_OBJECT)
- || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
- char *error_msg;
-
- if (ce->ce_flags & ZEND_ACC_INTERFACE) {
- error_msg = "implement interface";
- } else {
- error_msg = "be an instance of";
- }
- zend_error(E_ERROR, "Argument %d must %s %s", EX(opline)->extended_value, error_msg, ce->name);
- }
-
- NEXT_OPCODE();
-}
-
-
#define MAX_ABSTRACT_INFO_CNT 3
#define MAX_ABSTRACT_INFO_FMT "%s%s%s%s"
@@ -4075,7 +4118,6 @@ void zend_init_opcodes_handlers()
zend_opcode_handlers[ZEND_RAISE_ABSTRACT_ERROR] = zend_raise_abstract_error_handler;
zend_opcode_handlers[ZEND_ADD_INTERFACE] = zend_add_interface_handler;
- zend_opcode_handlers[ZEND_VERIFY_INSTANCEOF] = zend_verify_instanceof_handler;
zend_opcode_handlers[ZEND_VERIFY_ABSTRACT_CLASS] = zend_verify_abstract_class_handler;
zend_opcode_handlers[ZEND_ASSIGN_DIM] = zend_assign_dim_handler;
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index d57ac934db..4fd8f06c64 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -459,10 +459,10 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC)
}
-int call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, int param_count, zval *params[] TSRMLS_DC)
+int call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, zend_uint param_count, zval *params[] TSRMLS_DC)
{
zval ***params_array = (zval ***) emalloc(sizeof(zval **)*param_count);
- int i;
+ zend_uint i;
int ex_retval;
zval *local_retval_ptr;
@@ -479,16 +479,18 @@ int call_user_function(HashTable *function_table, zval **object_pp, zval *functi
return ex_retval;
}
-int call_user_function_ex(HashTable *function_table, zval **object_pp, zval *function_name, zval **retval_ptr_ptr, int param_count, zval **params[], int no_separation, HashTable *symbol_table TSRMLS_DC)
+
+int call_user_function_ex(HashTable *function_table, zval **object_pp, zval *function_name, zval **retval_ptr_ptr, zend_uint param_count, zval **params[], int no_separation, HashTable *symbol_table TSRMLS_DC)
{
zend_function *function_pointer = NULL;
return fast_call_user_function(function_table, object_pp, function_name, retval_ptr_ptr, param_count, params, no_separation, symbol_table, &function_pointer TSRMLS_CC);
}
-int fast_call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval **retval_ptr_ptr, int param_count, zval **params[], int no_separation, HashTable *symbol_table, zend_function **function_pointer TSRMLS_DC)
+
+int fast_call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval **retval_ptr_ptr, zend_uint param_count, zval **params[], int no_separation, HashTable *symbol_table, zend_function **function_pointer TSRMLS_DC)
{
- int i;
+ zend_uint i;
zval **original_return_value;
HashTable *calling_symbol_table;
zend_function_state *original_function_state_ptr;
@@ -611,9 +613,7 @@ int fast_call_user_function(HashTable *function_table, zval **object_pp, zval *f
for (i=0; i<param_count; i++) {
zval *param;
- if (EX(function_state).function->common.arg_types
- && i<EX(function_state).function->common.arg_types[0]
- && EX(function_state).function->common.arg_types[i+1]==BYREF_FORCE
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i+1)
&& !PZVAL_IS_REF(*params[i])) {
if ((*params[i])->refcount>1) {
zval *new_zval;
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index 3e72f0370b..37b2412c8c 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -390,22 +390,22 @@ parameter_list:
non_empty_parameter_list:
- optional_class_type T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$2, 0 TSRMLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); zend_do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, &$1, BYREF_NONE TSRMLS_CC); }
- | optional_class_type '&' T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$3, 0 TSRMLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); zend_do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, &$1, BYREF_FORCE TSRMLS_CC); }
- | optional_class_type '&' T_VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$3, 0 TSRMLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); zend_do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$5, &$1, BYREF_FORCE TSRMLS_CC); }
- | T_CONST optional_class_type T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$3, 0 TSRMLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); zend_do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, &$2, BYREF_NONE TSRMLS_CC); }
- | optional_class_type T_VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$2, 0 TSRMLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); zend_do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$4, &$1, BYREF_NONE TSRMLS_CC); }
- | non_empty_parameter_list ',' optional_class_type T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$4, 0 TSRMLS_CC); $$=$1; $$.u.constant.value.lval++; zend_do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, &$3, BYREF_NONE TSRMLS_CC); }
- | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$5, 0 TSRMLS_CC); $$=$1; $$.u.constant.value.lval++; zend_do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, &$3, BYREF_FORCE TSRMLS_CC); }
- | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$5, 0 TSRMLS_CC); $$=$1; $$.u.constant.value.lval++; zend_do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$7, &$3, BYREF_FORCE TSRMLS_CC); }
- | non_empty_parameter_list ',' T_CONST optional_class_type T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$5, 0 TSRMLS_CC); $$=$1; $$.u.constant.value.lval++; zend_do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, &$4, BYREF_NONE TSRMLS_CC); }
- | non_empty_parameter_list ',' optional_class_type T_VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$4, 0 TSRMLS_CC); $$=$1; $$.u.constant.value.lval++; zend_do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$6, &$3, BYREF_NONE TSRMLS_CC); }
+ optional_class_type T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$2, 0 TSRMLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); zend_do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, &$1, &$2, 0 TSRMLS_CC); }
+ | optional_class_type '&' T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$3, 0 TSRMLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); zend_do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, &$1, &$3, 1 TSRMLS_CC); }
+ | optional_class_type '&' T_VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$3, 0 TSRMLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); zend_do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$5, &$1, &$3, 1 TSRMLS_CC); }
+ | T_CONST optional_class_type T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$3, 0 TSRMLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); zend_do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, &$2, &$3, 0 TSRMLS_CC); }
+ | optional_class_type T_VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$2, 0 TSRMLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); zend_do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$4, &$1, &$2, 0 TSRMLS_CC); }
+ | non_empty_parameter_list ',' optional_class_type T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$4, 0 TSRMLS_CC); $$=$1; $$.u.constant.value.lval++; zend_do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, &$3, &$4, 0 TSRMLS_CC); }
+ | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$5, 0 TSRMLS_CC); $$=$1; $$.u.constant.value.lval++; zend_do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, &$3, &$5, 1 TSRMLS_CC); }
+ | non_empty_parameter_list ',' optional_class_type '&' T_VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$5, 0 TSRMLS_CC); $$=$1; $$.u.constant.value.lval++; zend_do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$7, &$3, &$5, 1 TSRMLS_CC); }
+ | non_empty_parameter_list ',' T_CONST optional_class_type T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$5, 0 TSRMLS_CC); $$=$1; $$.u.constant.value.lval++; zend_do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, &$4, &$5, 0 TSRMLS_CC); }
+ | non_empty_parameter_list ',' optional_class_type T_VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$4, 0 TSRMLS_CC); $$=$1; $$.u.constant.value.lval++; zend_do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$6, &$3, &$4, 0 TSRMLS_CC); }
;
optional_class_type:
/* empty */ { $$.op_type = IS_UNUSED; }
- | fully_qualified_class_name { $$ = $1; }
+ | T_STRING { $$ = $1; }
;
diff --git a/Zend/zend_modules.h b/Zend/zend_modules.h
index 572f52c315..1d56f1e89a 100644
--- a/Zend/zend_modules.h
+++ b/Zend/zend_modules.h
@@ -31,9 +31,11 @@
#define ZEND_MODULE_INFO_FUNC_ARGS zend_module_entry *zend_module TSRMLS_DC
#define ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU zend_module TSRMLS_CC
-ZEND_API extern unsigned char first_arg_force_ref[];
-ZEND_API extern unsigned char second_arg_force_ref[];
-ZEND_API extern unsigned char third_arg_force_ref[];
+ZEND_API extern struct _zend_arg_info first_arg_force_ref[2];
+ZEND_API extern struct _zend_arg_info second_arg_force_ref[3];
+ZEND_API extern struct _zend_arg_info third_arg_force_ref[4];
+ZEND_API extern struct _zend_arg_info fourth_arg_force_ref[5];
+ZEND_API extern struct _zend_arg_info all_args_by_ref[1];
#define ZEND_MODULE_API_NO 20020429
#ifdef ZTS
@@ -65,7 +67,7 @@ struct _zend_module_entry {
unsigned char zts;
struct _zend_ini_entry *ini_entry;
char *name;
- zend_function_entry *functions;
+ struct _zend_function_entry *functions;
int (*module_startup_func)(INIT_FUNC_ARGS);
int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);
int (*request_startup_func)(INIT_FUNC_ARGS);
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index a5d913d409..4d1589ace9 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -617,7 +617,8 @@ static union _zend_function *zend_std_get_method(zval *object, char *method_name
zend_internal_function *call_user_call = emalloc(sizeof(zend_internal_function));
call_user_call->type = ZEND_INTERNAL_FUNCTION;
call_user_call->handler = zend_std_call_user_call;
- call_user_call->arg_types = NULL;
+ call_user_call->arg_info = NULL;
+ call_user_call->num_args = 0;
call_user_call->scope = zobj->ce;
call_user_call->fn_flags = 0;
call_user_call->function_name = estrndup(method_name, method_len);
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index ea3732f56e..6afead0c7f 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -77,7 +77,8 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz
op_array->doc_comment = NULL;
op_array->doc_comment_len = 0;
- op_array->arg_types = NULL;
+ op_array->arg_info = NULL;
+ op_array->num_args = 0;
op_array->scope = NULL;
@@ -190,6 +191,7 @@ ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC)
{
zend_op *opline = op_array->opcodes;
zend_op *end = op_array->opcodes+op_array->last;
+ zend_uint i;
if (op_array->static_variables) {
zend_hash_destroy(op_array->static_variables);
@@ -224,15 +226,19 @@ ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC)
if (op_array->doc_comment) {
efree(op_array->doc_comment);
}
- if (op_array->arg_types) {
- efree(op_array->arg_types);
- }
if (op_array->brk_cont_array) {
efree(op_array->brk_cont_array);
}
if (op_array->done_pass_two) {
zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_dtor_handler, op_array TSRMLS_CC);
}
+ if (op_array->arg_info) {
+ for (i=0; i<op_array->num_args; i++) {
+ efree(op_array->arg_info[i].name);
+ efree(op_array->arg_info[i].class_name);
+ }
+ efree(op_array->arg_info);
+ }
}
diff --git a/Zend/zend_reflection_api.c b/Zend/zend_reflection_api.c
index af5286c891..efbadb544f 100644
--- a/Zend/zend_reflection_api.c
+++ b/Zend/zend_reflection_api.c
@@ -1621,7 +1621,7 @@ ZEND_FUNCTION(reflection_class_getinterfaces)
array_init(return_value);
if (ce->num_interfaces) {
- int i;
+ zend_uint i;
for (i=0; i < ce->num_interfaces; i++) {
zval *interface;
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index af5286c891..efbadb544f 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -1621,7 +1621,7 @@ ZEND_FUNCTION(reflection_class_getinterfaces)
array_init(return_value);
if (ce->num_interfaces) {
- int i;
+ zend_uint i;
for (i=0; i < ce->num_interfaces; i++) {
zval *interface;