Skip to content
Browse files

Changed the structure of op_array.opcodes. The constant values are mo…

…ved from opcode operands into a separate literal table
  • Loading branch information...
1 parent ea53dc5 commit 94dd83722b57c4613ccf8371a3c4f50ffc274584 Dmitry Stogov committed Apr 20, 2010
View
2 NEWS
@@ -17,6 +17,8 @@
- default_charset if not specified is now UTF-8 instead of ISO-8859-1. (Rasmus)
+- Changed the structure of op_array.opcodes. The constant values are moved from
+ opcode operands into a separate literal table. (Dmitry)
- Changed session.entropy_file to default to /dev/urandom or /dev/arandom if either
is present at compile time. (Rasmus)
View
18 Zend/zend.c
@@ -464,19 +464,19 @@ static void zend_init_exception_op(TSRMLS_D) /* {{{ */
{
memset(EG(exception_op), 0, sizeof(EG(exception_op)));
EG(exception_op)[0].opcode = ZEND_HANDLE_EXCEPTION;
- EG(exception_op)[0].op1.op_type = IS_UNUSED;
- EG(exception_op)[0].op2.op_type = IS_UNUSED;
- EG(exception_op)[0].result.op_type = IS_UNUSED;
+ EG(exception_op)[0].op1_type = IS_UNUSED;
+ EG(exception_op)[0].op2_type = IS_UNUSED;
+ EG(exception_op)[0].result_type = IS_UNUSED;
ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op));
EG(exception_op)[1].opcode = ZEND_HANDLE_EXCEPTION;
- EG(exception_op)[1].op1.op_type = IS_UNUSED;
- EG(exception_op)[1].op2.op_type = IS_UNUSED;
- EG(exception_op)[1].result.op_type = IS_UNUSED;
+ EG(exception_op)[1].op1_type = IS_UNUSED;
+ EG(exception_op)[1].op2_type = IS_UNUSED;
+ EG(exception_op)[1].result_type = IS_UNUSED;
ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+1);
EG(exception_op)[2].opcode = ZEND_HANDLE_EXCEPTION;
- EG(exception_op)[2].op1.op_type = IS_UNUSED;
- EG(exception_op)[2].op2.op_type = IS_UNUSED;
- EG(exception_op)[2].result.op_type = IS_UNUSED;
+ EG(exception_op)[2].op1_type = IS_UNUSED;
+ EG(exception_op)[2].op2_type = IS_UNUSED;
+ EG(exception_op)[2].result_type = IS_UNUSED;
ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+2);
}
/* }}} */
View
34 Zend/zend_API.c
@@ -971,7 +971,7 @@ static int zend_merge_property(zval **value TSRMLS_DC, int num_args, va_list arg
MAKE_STD_ZVAL(member);
ZVAL_STRINGL(member, hash_key->arKey, hash_key->nKeyLength-1, 1);
- obj_ht->write_property(obj, member, *value TSRMLS_CC);
+ obj_ht->write_property(obj, member, *value, 0 TSRMLS_CC);
zval_ptr_dtor(&member);
}
return ZEND_HASH_APPLY_KEEP;
@@ -1435,7 +1435,7 @@ ZEND_API int add_property_long_ex(zval *arg, const char *key, uint key_len, long
MAKE_STD_ZVAL(z_key);
ZVAL_STRINGL(z_key, key, key_len-1, 1);
- Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
+ Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp, 0 TSRMLS_CC);
zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
zval_ptr_dtor(&z_key);
return SUCCESS;
@@ -1453,7 +1453,7 @@ ZEND_API int add_property_bool_ex(zval *arg, const char *key, uint key_len, int
MAKE_STD_ZVAL(z_key);
ZVAL_STRINGL(z_key, key, key_len-1, 1);
- Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
+ Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp, 0 TSRMLS_CC);
zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
zval_ptr_dtor(&z_key);
return SUCCESS;
@@ -1471,7 +1471,7 @@ ZEND_API int add_property_null_ex(zval *arg, const char *key, uint key_len TSRML
MAKE_STD_ZVAL(z_key);
ZVAL_STRINGL(z_key, key, key_len-1, 1);
- Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
+ Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp, 0 TSRMLS_CC);
zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
zval_ptr_dtor(&z_key);
return SUCCESS;
@@ -1489,7 +1489,7 @@ ZEND_API int add_property_resource_ex(zval *arg, const char *key, uint key_len,
MAKE_STD_ZVAL(z_key);
ZVAL_STRINGL(z_key, key, key_len-1, 1);
- Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
+ Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp, 0 TSRMLS_CC);
zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
zval_ptr_dtor(&z_key);
return SUCCESS;
@@ -1507,7 +1507,7 @@ ZEND_API int add_property_double_ex(zval *arg, const char *key, uint key_len, do
MAKE_STD_ZVAL(z_key);
ZVAL_STRINGL(z_key, key, key_len-1, 1);
- Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
+ Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp, 0 TSRMLS_CC);
zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
zval_ptr_dtor(&z_key);
return SUCCESS;
@@ -1525,7 +1525,7 @@ ZEND_API int add_property_string_ex(zval *arg, const char *key, uint key_len, ch
MAKE_STD_ZVAL(z_key);
ZVAL_STRINGL(z_key, key, key_len-1, 1);
- Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
+ Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp, 0 TSRMLS_CC);
zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
zval_ptr_dtor(&z_key);
return SUCCESS;
@@ -1543,7 +1543,7 @@ ZEND_API int add_property_stringl_ex(zval *arg, const char *key, uint key_len, c
MAKE_STD_ZVAL(z_key);
ZVAL_STRINGL(z_key, key, key_len-1, 1);
- Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
+ Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp, 0 TSRMLS_CC);
zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
zval_ptr_dtor(&z_key);
return SUCCESS;
@@ -1557,7 +1557,7 @@ ZEND_API int add_property_zval_ex(zval *arg, const char *key, uint key_len, zval
MAKE_STD_ZVAL(z_key);
ZVAL_STRINGL(z_key, key, key_len-1, 1);
- Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, value TSRMLS_CC);
+ Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, value, 0 TSRMLS_CC);
zval_ptr_dtor(&z_key);
return SUCCESS;
}
@@ -1893,7 +1893,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
}
}
fname_len = strlen(ptr->fname);
- lowercase_name = zend_str_tolower_dup(ptr->fname, fname_len);
+ lowercase_name = zend_str_tolower_dup(ptr->fname, fname_len);
if (zend_hash_add(target_function_table, lowercase_name, fname_len+1, &function, sizeof(zend_function), (void**)&reg_function) == FAILURE) {
unload=1;
efree(lowercase_name);
@@ -2381,7 +2381,7 @@ static int zend_is_callable_check_class(const char *name, int name_len, zend_fca
*strict_class = 1;
ret = 1;
}
- } else if (zend_lookup_class_ex(name, name_len, 1, &pce TSRMLS_CC) == SUCCESS) {
+ } else if (zend_lookup_class_ex(name, name_len, NULL, 1, &pce TSRMLS_CC) == SUCCESS) {
zend_class_entry *scope = EG(active_op_array) ? EG(active_op_array)->scope : NULL;
fcc->calling_scope = *pce;
@@ -2546,7 +2546,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
call_via_handler = 1;
retval = 1;
} else if (Z_OBJ_HT_P(fcc->object_ptr)->get_method) {
- fcc->function_handler = Z_OBJ_HT_P(fcc->object_ptr)->get_method(&fcc->object_ptr, mname, mlen TSRMLS_CC);
+ fcc->function_handler = Z_OBJ_HT_P(fcc->object_ptr)->get_method(&fcc->object_ptr, mname, mlen, NULL TSRMLS_CC);
if (fcc->function_handler) {
if (strict_class &&
(!fcc->function_handler->common.scope ||
@@ -2567,7 +2567,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
if (fcc->calling_scope->get_static_method) {
fcc->function_handler = fcc->calling_scope->get_static_method(fcc->calling_scope, mname, mlen TSRMLS_CC);
} else {
- fcc->function_handler = zend_std_get_static_method(fcc->calling_scope, mname, mlen TSRMLS_CC);
+ fcc->function_handler = zend_std_get_static_method(fcc->calling_scope, mname, mlen, NULL TSRMLS_CC);
}
if (fcc->function_handler) {
retval = 1;
@@ -3343,7 +3343,7 @@ ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, char *
}
MAKE_STD_ZVAL(property);
ZVAL_STRINGL(property, name, name_length, 1);
- Z_OBJ_HT_P(object)->write_property(object, property, value TSRMLS_CC);
+ Z_OBJ_HT_P(object)->write_property(object, property, value, 0 TSRMLS_CC);
zval_ptr_dtor(&property);
EG(scope) = old_scope;
@@ -3428,7 +3428,7 @@ ZEND_API int zend_update_static_property(zend_class_entry *scope, char *name, in
zend_class_entry *old_scope = EG(scope);
EG(scope) = scope;
- property = zend_std_get_static_property(scope, name, name_length, 0 TSRMLS_CC);
+ property = zend_std_get_static_property(scope, name, name_length, 0, NULL TSRMLS_CC);
EG(scope) = old_scope;
if (!property) {
return FAILURE;
@@ -3546,7 +3546,7 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, char *n
MAKE_STD_ZVAL(property);
ZVAL_STRINGL(property, name, name_length, 1);
- value = Z_OBJ_HT_P(object)->read_property(object, property, silent?BP_VAR_IS:BP_VAR_R TSRMLS_CC);
+ value = Z_OBJ_HT_P(object)->read_property(object, property, silent?BP_VAR_IS:BP_VAR_R, 0 TSRMLS_CC);
zval_ptr_dtor(&property);
EG(scope) = old_scope;
@@ -3560,7 +3560,7 @@ ZEND_API zval *zend_read_static_property(zend_class_entry *scope, char *name, in
zend_class_entry *old_scope = EG(scope);
EG(scope) = scope;
- property = zend_std_get_static_property(scope, name, name_length, silent TSRMLS_CC);
+ property = zend_std_get_static_property(scope, name, name_length, silent, NULL TSRMLS_CC);
EG(scope) = old_scope;
return property?*property:NULL;
View
10 Zend/zend_builtin_functions.c
@@ -839,7 +839,7 @@ static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass)
RETURN_FALSE;
}
- if (zend_lookup_class_ex(class_name, class_name_len, 0, &ce TSRMLS_CC) == FAILURE) {
+ if (zend_lookup_class_ex(class_name, class_name_len, NULL, 0, &ce TSRMLS_CC) == FAILURE) {
retval = 0;
} else {
if (only_subclass) {
@@ -1102,7 +1102,7 @@ ZEND_FUNCTION(method_exists)
if (Z_TYPE_P(klass) == IS_OBJECT
&& Z_OBJ_HT_P(klass)->get_method != NULL
- && (func = Z_OBJ_HT_P(klass)->get_method(&klass, method_name, method_len TSRMLS_CC)) != NULL
+ && (func = Z_OBJ_HT_P(klass)->get_method(&klass, method_name, method_len, NULL TSRMLS_CC)) != NULL
) {
if (func->type == ZEND_INTERNAL_FUNCTION
&& ((zend_internal_function*)func)->handler == zend_std_call_user_call
@@ -1160,7 +1160,7 @@ ZEND_FUNCTION(property_exists)
if (Z_TYPE_P(object) == IS_OBJECT &&
Z_OBJ_HANDLER_P(object, has_property) &&
- Z_OBJ_HANDLER_P(object, has_property)(object, &property_z, 2 TSRMLS_CC)) {
+ Z_OBJ_HANDLER_P(object, has_property)(object, &property_z, 2, 0 TSRMLS_CC)) {
RETURN_TRUE;
}
RETURN_FALSE;
@@ -2021,7 +2021,7 @@ ZEND_FUNCTION(debug_print_backtrace)
function_name = "unknown";
build_filename_arg = 0;
} else
- switch (Z_LVAL(ptr->opline->op2.u.constant)) {
+ switch (ptr->opline->extended_value) {
case ZEND_EVAL:
function_name = "eval";
build_filename_arg = 0;
@@ -2204,7 +2204,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
function_name = "unknown";
build_filename_arg = 0;
} else
- switch (ptr->opline->op2.u.constant.value.lval) {
+ switch (ptr->opline->extended_value) {
case ZEND_EVAL:
function_name = "eval";
build_filename_arg = 0;
View
18 Zend/zend_closures.c
@@ -152,7 +152,7 @@ ZEND_API zval* zend_get_closure_this_ptr(zval *obj TSRMLS_DC) /* {{{ */
}
/* }}} */
-static zend_function *zend_closure_get_method(zval **object_ptr, char *method_name, int method_len TSRMLS_DC) /* {{{ */
+static zend_function *zend_closure_get_method(zval **object_ptr, char *method_name, int method_len, const zend_literal *key TSRMLS_DC) /* {{{ */
{
char *lc_name;
ALLOCA_FLAG(use_heap)
@@ -166,32 +166,32 @@ static zend_function *zend_closure_get_method(zval **object_ptr, char *method_na
return zend_get_closure_invoke_method(*object_ptr TSRMLS_CC);
}
free_alloca(lc_name, use_heap);
- return std_object_handlers.get_method(object_ptr, method_name, method_len TSRMLS_CC);
+ return std_object_handlers.get_method(object_ptr, method_name, method_len, key TSRMLS_CC);
}
/* }}} */
-static zval *zend_closure_read_property(zval *object, zval *member, int type TSRMLS_DC) /* {{{ */
+static zval *zend_closure_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
{
ZEND_CLOSURE_PROPERTY_ERROR();
Z_ADDREF(EG(uninitialized_zval));
return &EG(uninitialized_zval);
}
/* }}} */
-static void zend_closure_write_property(zval *object, zval *member, zval *value TSRMLS_DC) /* {{{ */
+static void zend_closure_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) /* {{{ */
{
ZEND_CLOSURE_PROPERTY_ERROR();
}
/* }}} */
-static zval **zend_closure_get_property_ptr_ptr(zval *object, zval *member TSRMLS_DC) /* {{{ */
+static zval **zend_closure_get_property_ptr_ptr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */
{
ZEND_CLOSURE_PROPERTY_ERROR();
return NULL;
}
/* }}} */
-static int zend_closure_has_property(zval *object, zval *member, int has_set_exists TSRMLS_DC) /* {{{ */
+static int zend_closure_has_property(zval *object, zval *member, int has_set_exists, const zend_literal *key TSRMLS_DC) /* {{{ */
{
if (has_set_exists != 2) {
ZEND_CLOSURE_PROPERTY_ERROR();
@@ -200,7 +200,7 @@ static int zend_closure_has_property(zval *object, zval *member, int has_set_exi
}
/* }}} */
-static void zend_closure_unset_property(zval *object, zval *member TSRMLS_DC) /* {{{ */
+static void zend_closure_unset_property(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */
{
ZEND_CLOSURE_PROPERTY_ERROR();
}
@@ -308,7 +308,7 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_
MAKE_STD_ZVAL(val);
array_init(val);
zend_hash_copy(Z_ARRVAL_P(val), static_variables, (copy_ctor_func_t)zval_add_ref, NULL, sizeof(zval*));
- zend_symtable_update(closure->debug_info, "static", sizeof("static"), (void *) &val, sizeof(zval *), NULL);
+ zend_hash_update(closure->debug_info, "static", sizeof("static"), (void *) &val, sizeof(zval *), NULL);
}
if (closure->this_ptr) {
@@ -340,7 +340,7 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_
efree(name);
arg_info++;
}
- zend_symtable_update(closure->debug_info, "parameter", sizeof("parameter"), (void *) &val, sizeof(zval *), NULL);
+ zend_hash_update(closure->debug_info, "parameter", sizeof("parameter"), (void *) &val, sizeof(zval *), NULL);
}
}
View
1,296 Zend/zend_compile.c
723 additions, 573 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
106 Zend/zend_compile.h
@@ -34,7 +34,7 @@
#define FREE_PNODE(znode) zval_dtor(&znode->u.constant);
-#define SET_UNUSED(op) (op).op_type = IS_UNUSED
+#define SET_UNUSED(op) op ## _type = IS_UNUSED
#define INC_BPC(op_array) if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) { ((op_array)->backpatch_count++); }
#define DEC_BPC(op_array) if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) { ((op_array)->backpatch_count--); }
@@ -52,20 +52,33 @@
typedef struct _zend_op_array zend_op_array;
typedef struct _zend_op zend_op;
-typedef struct _znode {
+typedef struct _zend_literal {
+ zval constant;
+ ulong hash_value;
+} zend_literal;
+
+#define Z_HASH_P(zv) \
+ (((zend_literal*)(zv))->hash_value)
+
+typedef union _znode_op {
+ zend_uint constant;
+ zend_uint var;
+ zend_uint num;
+ zend_ulong hash;
+ zend_uint opline_num; /* Needs to be signed */
+ zend_op *jmp_addr;
+ zval *zv;
+ zend_literal *literal;
+} znode_op;
+
+typedef struct _znode { /* used only during compilation */
int op_type;
union {
- zval constant;
-
- zend_uint var;
- zend_uint opline_num; /* Needs to be signed */
+ znode_op op;
+ zval constant; /* replaced by literal/zv */
zend_op_array *op_array;
- zend_op *jmp_addr;
- struct {
- zend_uint var; /* dummy */
- zend_uint type;
- } EA;
} u;
+ zend_uint EA; /* extended attributes */
} znode;
typedef struct _zend_execute_data zend_execute_data;
@@ -80,12 +93,15 @@ extern ZEND_API opcode_handler_t *zend_opcode_handlers;
struct _zend_op {
opcode_handler_t handler;
- znode result;
- znode op1;
- znode op2;
+ znode_op op1;
+ znode_op op2;
+ znode_op result;
ulong extended_value;
uint lineno;
zend_uchar opcode;
+ zend_uchar op1_type;
+ zend_uchar op2_type;
+ zend_uchar result_type;
};
@@ -236,6 +252,9 @@ struct _zend_op_array {
zend_uint doc_comment_len;
zend_uint early_binding; /* the linked list of delayed declarations */
+ zend_literal *literals;
+ int last_literal, size_literal;
+
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
};
@@ -335,8 +354,7 @@ struct _zend_execute_data {
#define IS_UNUSED (1<<3) /* Unused variable */
#define IS_CV (1<<4) /* Compiled variable */
-#define EXT_TYPE_UNUSED (1<<0)
-#define EXT_TYPE_FREE_ON_RETURN (2<<0)
+#define EXT_TYPE_UNUSED (1<<5)
#include "zend_globals.h"
@@ -373,7 +391,7 @@ int zend_get_zendleng(TSRMLS_D);
void zend_do_binary_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC);
void zend_do_unary_op(zend_uchar op, znode *result, const znode *op1 TSRMLS_DC);
void zend_do_binary_assign_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC);
-void zend_do_assign(znode *result, znode *variable, const znode *value TSRMLS_DC);
+void zend_do_assign(znode *result, znode *variable, znode *value TSRMLS_DC);
void zend_do_assign_ref(znode *result, const znode *lvar, const znode *rvar TSRMLS_DC);
void fetch_simple_variable(znode *result, znode *varname, int bp TSRMLS_DC);
void fetch_simple_variable_ex(znode *result, znode *varname, int bp, zend_uchar op TSRMLS_DC);
@@ -442,9 +460,9 @@ void zend_do_begin_catch(znode *try_token, znode *catch_class, const znode *catc
void zend_do_end_catch(const znode *try_token TSRMLS_DC);
void zend_do_throw(const znode *expr TSRMLS_DC);
-ZEND_API int do_bind_function(zend_op *opline, HashTable *function_table, zend_bool compile_time);
-ZEND_API zend_class_entry *do_bind_class(const zend_op *opline, HashTable *class_table, zend_bool compile_time TSRMLS_DC);
-ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op *opline, HashTable *class_table, zend_class_entry *parent_ce, zend_bool compile_time TSRMLS_DC);
+ZEND_API int do_bind_function(const zend_op_array *op_array, zend_op *opline, HashTable *function_table, zend_bool compile_time);
+ZEND_API zend_class_entry *do_bind_class(const zend_op_array *op_array, const zend_op *opline, HashTable *class_table, zend_bool compile_time TSRMLS_DC);
+ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array, const zend_op *opline, HashTable *class_table, zend_class_entry *parent_ce, zend_bool compile_time TSRMLS_DC);
ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_entry *iface TSRMLS_DC);
ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC);
void zend_do_implements_interface(znode *interface_znode TSRMLS_DC);
@@ -472,7 +490,6 @@ void zend_do_default_before_statement(const znode *case_list, znode *default_tok
void zend_do_begin_class_declaration(const znode *class_token, znode *class_name, const znode *parent_class_name TSRMLS_DC);
void zend_do_end_class_declaration(const znode *class_token, const znode *parent_token TSRMLS_DC);
void zend_do_declare_property(const znode *var_name, const znode *value, zend_uint access_type TSRMLS_DC);
-void zend_do_declare_implicit_property(TSRMLS_D);
void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_DC);
void zend_do_fetch_property(znode *result, znode *object, const znode *property TSRMLS_DC);
@@ -608,6 +625,8 @@ ZEND_API size_t zend_dirname(char *path, size_t len);
int zendlex(znode *zendlval TSRMLS_DC);
+int zend_add_literal(zend_op_array *op_array, const zval *zv);
+
/* BEGIN: OPCODES */
#include "zend_vm_opcodes.h"
@@ -616,18 +635,6 @@ int zendlex(znode *zendlval TSRMLS_DC);
/* END: OPCODES */
-
-
-
-/* global/local fetches */
-#define ZEND_FETCH_GLOBAL 0
-#define ZEND_FETCH_LOCAL 1
-#define ZEND_FETCH_STATIC 2
-#define ZEND_FETCH_STATIC_MEMBER 3
-#define ZEND_FETCH_GLOBAL_LOCK 4
-#define ZEND_FETCH_LEXICAL 5
-
-
/* class fetches */
#define ZEND_FETCH_CLASS_DEFAULT 0
#define ZEND_FETCH_CLASS_SELF 1
@@ -679,23 +686,36 @@ int zendlex(znode *zendlval TSRMLS_DC);
#define ZEND_REQUIRE (1<<3)
#define ZEND_REQUIRE_ONCE (1<<4)
-#define ZEND_ISSET (1<<0)
-#define ZEND_ISEMPTY (1<<1)
-#define ZEND_ISSET_ISEMPTY_MASK (ZEND_ISSET | ZEND_ISEMPTY)
-#define ZEND_QUICK_SET (1<<2)
-
#define ZEND_CT (1<<0)
#define ZEND_RT (1<<1)
-#define ZEND_FETCH_STANDARD 0
-#define ZEND_FETCH_ADD_LOCK (1<<0)
-#define ZEND_FETCH_MAKE_REF (1<<1)
+/* global/local fetches */
+#define ZEND_FETCH_GLOBAL 0x00000000
+#define ZEND_FETCH_LOCAL 0x10000000
+#define ZEND_FETCH_STATIC 0x20000000
+#define ZEND_FETCH_STATIC_MEMBER 0x30000000
+#define ZEND_FETCH_GLOBAL_LOCK 0x40000000
+#define ZEND_FETCH_LEXICAL 0x50000000
+
+#define ZEND_FETCH_TYPE_MASK 0x70000000
+
+#define ZEND_FETCH_STANDARD 0x00000000
+#define ZEND_FETCH_ADD_LOCK 0x08000000
+#define ZEND_FETCH_MAKE_REF 0x04000000
+
+#define ZEND_ISSET 0x02000000
+#define ZEND_ISEMPTY 0x01000000
+#define ZEND_ISSET_ISEMPTY_MASK (ZEND_ISSET | ZEND_ISEMPTY)
+#define ZEND_QUICK_SET 0x00800000
+
+#define ZEND_FETCH_ARG_MASK 0x000fffff
#define ZEND_FE_FETCH_BYREF 1
#define ZEND_FE_FETCH_WITH_KEY 2
-#define ZEND_FE_RESET_VARIABLE 1
-#define ZEND_FE_RESET_REFERENCE 2
+#define ZEND_FE_RESET_VARIABLE (1<<0)
+#define ZEND_FE_RESET_REFERENCE (1<<1)
+#define EXT_TYPE_FREE_ON_RETURN (1<<2)
#define ZEND_MEMBER_FUNC_CALL 1<<0
View
171 Zend/zend_execute.c
@@ -48,17 +48,17 @@
typedef int (*incdec_t)(zval *);
-#define get_zval_ptr(node, Ts, should_free, type) _get_zval_ptr(node, Ts, should_free, type TSRMLS_CC)
-#define get_zval_ptr_ptr(node, Ts, should_free, type) _get_zval_ptr_ptr(node, Ts, should_free, type TSRMLS_CC)
-#define get_obj_zval_ptr(node, Ts, should_free, type) _get_obj_zval_ptr(node, Ts, should_free, type TSRMLS_CC)
-#define get_obj_zval_ptr_ptr(node, Ts, should_free, type) _get_obj_zval_ptr_ptr(node, Ts, should_free, type TSRMLS_CC)
+#define get_zval_ptr(op_type, node, Ts, should_free, type) _get_zval_ptr(op_type, node, Ts, should_free, type TSRMLS_CC)
+#define get_zval_ptr_ptr(op_type, node, Ts, should_free, type) _get_zval_ptr_ptr(op_type, node, Ts, should_free, type TSRMLS_CC)
+#define get_obj_zval_ptr(op_type, node, Ts, should_free, type) _get_obj_zval_ptr(op_type, node, Ts, should_free, type TSRMLS_CC)
+#define get_obj_zval_ptr_ptr(op_type, node, Ts, should_free, type) _get_obj_zval_ptr_ptr(op_type, node, Ts, should_free, type TSRMLS_CC)
/* Prototypes */
static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
-#define RETURN_VALUE_USED(opline) (!((opline)->result.u.EA.type & EXT_TYPE_UNUSED))
+#define RETURN_VALUE_USED(opline) (!((opline)->result_type & EXT_TYPE_UNUSED))
#define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))
#define T(offset) (*(temp_variable *)((char *) Ts + offset))
@@ -96,8 +96,7 @@ static zend_always_inline void zend_pzval_unlock_free_func(zval *z TSRMLS_DC)
#define PZVAL_UNLOCK_EX(z, f, u) zend_pzval_unlock_func(z, f, u TSRMLS_CC)
#define PZVAL_UNLOCK_FREE(z) zend_pzval_unlock_free_func(z TSRMLS_CC)
#define PZVAL_LOCK(z) Z_ADDREF_P((z))
-#define RETURN_VALUE_UNUSED(pzn) (((pzn)->u.EA.type & EXT_TYPE_UNUSED))
-#define SELECTIVE_PZVAL_LOCK(pzv, pzn) if (!RETURN_VALUE_UNUSED(pzn)) { PZVAL_LOCK(pzv); }
+#define SELECTIVE_PZVAL_LOCK(pzv, opline) if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(pzv); }
#define AI_USE_PTR(ai) \
if ((ai).ptr_ptr) { \
@@ -172,14 +171,14 @@ ZEND_API zval** zend_get_compiled_variable_value(const zend_execute_data *execut
return execute_data_ptr->CVs[var];
}
-static zend_always_inline zval *_get_zval_ptr_tmp(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
+static zend_always_inline zval *_get_zval_ptr_tmp(zend_uint var, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
{
- return should_free->var = &T(node->u.var).tmp_var;
+ return should_free->var = &T(var).tmp_var;
}
-static zval *_get_zval_ptr_var_string_offset(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
+static zval *_get_zval_ptr_var_string_offset(zend_uint var, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
{
- temp_variable *T = &T(node->u.var);
+ temp_variable *T = &T(var);
zval *str = T->str_offset.str;
zval *ptr;
@@ -204,14 +203,14 @@ static zval *_get_zval_ptr_var_string_offset(const znode *node, const temp_varia
return ptr;
}
-static zend_always_inline zval *_get_zval_ptr_var(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
+static zend_always_inline zval *_get_zval_ptr_var(zend_uint var, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
{
- zval *ptr = T(node->u.var).var.ptr;
+ zval *ptr = T(var).var.ptr;
if (EXPECTED(ptr != NULL)) {
PZVAL_UNLOCK(ptr, should_free);
return ptr;
} else {
- return _get_zval_ptr_var_string_offset(node, Ts, should_free TSRMLS_CC);
+ return _get_zval_ptr_var_string_offset(var, Ts, should_free TSRMLS_CC);
}
}
@@ -246,74 +245,74 @@ static zval **_get_zval_cv_lookup(zval ***ptr, zend_uint var, int type TSRMLS_DC
return *ptr;
}
-static zend_always_inline zval *_get_zval_ptr_cv(const znode *node, const temp_variable *Ts, int type TSRMLS_DC)
+static zend_always_inline zval *_get_zval_ptr_cv(zend_uint var, int type TSRMLS_DC)
{
- zval ***ptr = &CV_OF(node->u.var);
+ zval ***ptr = &CV_OF(var);
if (UNEXPECTED(*ptr == NULL)) {
- return *_get_zval_cv_lookup(ptr, node->u.var, type TSRMLS_CC);
+ return *_get_zval_cv_lookup(ptr, var, type TSRMLS_CC);
}
return **ptr;
}
-static inline zval *_get_zval_ptr(znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
+static inline zval *_get_zval_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
{
/* should_free->is_var = 0; */
- switch (node->op_type) {
+ switch (op_type) {
case IS_CONST:
should_free->var = 0;
- return &node->u.constant;
+ return node->zv;
break;
case IS_TMP_VAR:
- should_free->var = TMP_FREE(&T(node->u.var).tmp_var);
- return &T(node->u.var).tmp_var;
+ should_free->var = TMP_FREE(&T(node->var).tmp_var);
+ return &T(node->var).tmp_var;
break;
case IS_VAR:
- return _get_zval_ptr_var(node, Ts, should_free TSRMLS_CC);
+ return _get_zval_ptr_var(node->var, Ts, should_free TSRMLS_CC);
break;
case IS_UNUSED:
should_free->var = 0;
return NULL;
break;
case IS_CV:
should_free->var = 0;
- return _get_zval_ptr_cv(node, Ts, type TSRMLS_CC);
+ return _get_zval_ptr_cv(node->var, type TSRMLS_CC);
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
return NULL;
}
-static zend_always_inline zval **_get_zval_ptr_ptr_var(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
+static zend_always_inline zval **_get_zval_ptr_ptr_var(zend_uint var, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
{
- zval** ptr_ptr = T(node->u.var).var.ptr_ptr;
+ zval** ptr_ptr = T(var).var.ptr_ptr;
if (EXPECTED(ptr_ptr != NULL)) {
PZVAL_UNLOCK(*ptr_ptr, should_free);
} else {
/* string offset */
- PZVAL_UNLOCK(T(node->u.var).str_offset.str, should_free);
+ PZVAL_UNLOCK(T(var).str_offset.str, should_free);
}
return ptr_ptr;
}
-static zend_always_inline zval **_get_zval_ptr_ptr_cv(const znode *node, const temp_variable *Ts, int type TSRMLS_DC)
+static zend_always_inline zval **_get_zval_ptr_ptr_cv(zend_uint var, int type TSRMLS_DC)
{
- zval ***ptr = &CV_OF(node->u.var);
+ zval ***ptr = &CV_OF(var);
if (UNEXPECTED(*ptr == NULL)) {
- return _get_zval_cv_lookup(ptr, node->u.var, type TSRMLS_CC);
+ return _get_zval_cv_lookup(ptr, var, type TSRMLS_CC);
}
return *ptr;
}
-static inline zval **_get_zval_ptr_ptr(const znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
+static inline zval **_get_zval_ptr_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
{
- if (node->op_type == IS_CV) {
+ if (op_type == IS_CV) {
should_free->var = 0;
- return _get_zval_ptr_ptr_cv(node, Ts, type TSRMLS_CC);
- } else if (node->op_type == IS_VAR) {
- return _get_zval_ptr_ptr_var(node, Ts, should_free TSRMLS_CC);
+ return _get_zval_ptr_ptr_cv(node->var, type TSRMLS_CC);
+ } else if (op_type == IS_VAR) {
+ return _get_zval_ptr_ptr_var(node->var, Ts, should_free TSRMLS_CC);
} else {
should_free->var = 0;
return NULL;
@@ -330,9 +329,9 @@ static zend_always_inline zval *_get_obj_zval_ptr_unused(TSRMLS_D)
}
}
-static inline zval **_get_obj_zval_ptr_ptr(const znode *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
+static inline zval **_get_obj_zval_ptr_ptr(int op_type, const znode_op *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
{
- if (op->op_type == IS_UNUSED) {
+ if (op_type == IS_UNUSED) {
if (EXPECTED(EG(This) != NULL)) {
/* this should actually never be modified, _ptr_ptr is modified only when
the object is empty */
@@ -342,7 +341,7 @@ static inline zval **_get_obj_zval_ptr_ptr(const znode *op, const temp_variable
zend_error_noreturn(E_ERROR, "Using $this when not in object context");
}
}
- return get_zval_ptr_ptr(op, Ts, should_free, type);
+ return get_zval_ptr_ptr(op_type, op, Ts, should_free, type);
}
static zend_always_inline zval **_get_obj_zval_ptr_ptr_unused(TSRMLS_D)
@@ -355,17 +354,17 @@ static zend_always_inline zval **_get_obj_zval_ptr_ptr_unused(TSRMLS_D)
}
}
-static inline zval *_get_obj_zval_ptr(znode *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
+static inline zval *_get_obj_zval_ptr(int op_type, znode_op *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
{
- if (op->op_type == IS_UNUSED) {
+ if (op_type == IS_UNUSED) {
if (EXPECTED(EG(This) != NULL)) {
should_free->var = 0;
return EG(This);
} else {
zend_error_noreturn(E_ERROR, "Using $this when not in object context");
}
}
- return get_zval_ptr(op, Ts, should_free, type);
+ return get_zval_ptr(op_type, op, Ts, should_free, type);
}
static inline void zend_switch_free(temp_variable *T, int extended_value TSRMLS_DC)
@@ -515,17 +514,15 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva
return 1;
}
-static inline void zend_assign_to_object(znode *result, zval **object_ptr, zval *property_name, znode *value_op, const temp_variable *Ts, int opcode TSRMLS_DC)
-
+static inline void zend_assign_to_object(zval **retval, zval **object_ptr, zval *property_name, int value_type, znode_op *value_op, const temp_variable *Ts, int opcode, const zend_literal *key TSRMLS_DC)
{
zval *object = *object_ptr;
zend_free_op free_value;
- zval *value = get_zval_ptr(value_op, Ts, &free_value, BP_VAR_R);
- zval **retval = &T(result->u.var).var.ptr;
+ zval *value = get_zval_ptr(value_type, value_op, Ts, &free_value, BP_VAR_R);
if (Z_TYPE_P(object) != IS_OBJECT) {
if (object == EG(error_zval_ptr)) {
- if (!RETURN_VALUE_UNUSED(result)) {
+ if (retval) {
*retval = EG(uninitialized_zval_ptr);
PZVAL_LOCK(*retval);
}
@@ -542,7 +539,7 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, zval
zend_error(E_STRICT, "Creating default object from empty value");
} else {
zend_error(E_WARNING, "Attempt to assign property of non-object");
- if (!RETURN_VALUE_UNUSED(result)) {
+ if (retval) {
*retval = EG(uninitialized_zval_ptr);
PZVAL_LOCK(*retval);
}
@@ -552,14 +549,14 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, zval
}
/* separate our value if necessary */
- if (value_op->op_type == IS_TMP_VAR) {
+ if (value_type == IS_TMP_VAR) {
zval *orig_value = value;
ALLOC_ZVAL(value);
*value = *orig_value;
Z_UNSET_ISREF_P(value);
Z_SET_REFCOUNT_P(value, 0);
- } else if (value_op->op_type == IS_CONST) {
+ } else if (value_type == IS_CONST) {
zval *orig_value = value;
ALLOC_ZVAL(value);
@@ -574,19 +571,19 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, zval
if (opcode == ZEND_ASSIGN_OBJ) {
if (!Z_OBJ_HT_P(object)->write_property) {
zend_error(E_WARNING, "Attempt to assign property of non-object");
- if (!RETURN_VALUE_UNUSED(result)) {
+ if (retval) {
*retval = EG(uninitialized_zval_ptr);
PZVAL_LOCK(*retval);
}
- if (value_op->op_type == IS_TMP_VAR) {
+ if (value_type == IS_TMP_VAR) {
FREE_ZVAL(value);
- } else if (value_op->op_type == IS_CONST) {
+ } else if (value_type == IS_CONST) {
zval_ptr_dtor(&value);
}
FREE_OP(free_value);
return;
}
- Z_OBJ_HT_P(object)->write_property(object, property_name, value TSRMLS_CC);
+ Z_OBJ_HT_P(object)->write_property(object, property_name, value, key TSRMLS_CC);
} else {
/* Note: property_name in this case is really the array index! */
if (!Z_OBJ_HT_P(object)->write_dimension) {
@@ -595,8 +592,8 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, zval
Z_OBJ_HT_P(object)->write_dimension(object, property_name, value TSRMLS_CC);
}
- if (!RETURN_VALUE_UNUSED(result) && !EG(exception)) {
- AI_SET_PTR(T(result->u.var).var, value);
+ if (retval && !EG(exception)) {
+ *retval = value;
PZVAL_LOCK(value);
}
zval_ptr_dtor(&value);
@@ -757,9 +754,9 @@ static void zend_extension_fcall_end_handler(const zend_extension *extension, ze
}
-static inline HashTable *zend_get_target_symbol_table(const zend_op *opline, const temp_variable *Ts, int type, const zval *variable TSRMLS_DC)
+static inline HashTable *zend_get_target_symbol_table(int fetch_type TSRMLS_DC)
{
- switch (opline->op2.u.EA.type) {
+ switch (fetch_type) {
case ZEND_FETCH_LOCAL:
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
@@ -782,26 +779,34 @@ static inline HashTable *zend_get_target_symbol_table(const zend_op *opline, con
return NULL;
}
-static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int type TSRMLS_DC)
+static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int dim_type, int type TSRMLS_DC)
{
zval **retval;
char *offset_key;
int offset_key_length;
long index;
+ ulong hval;
switch (dim->type) {
case IS_NULL:
offset_key = "";
offset_key_length = 0;
+ hval = zend_inline_hash_func("", 1);
goto fetch_string_dim;
case IS_STRING:
offset_key = dim->value.str.val;
offset_key_length = dim->value.str.len;
-
+
+ if (dim_type == IS_CONST) {
+ hval = Z_HASH_P(dim);
+ } else {
+ ZEND_HANDLE_NUMERIC_EX(offset_key, offset_key_length+1, index, goto num_index);
+ hval = zend_hash_func(offset_key, offset_key_length+1);
+ }
fetch_string_dim:
- if (zend_symtable_find(ht, offset_key, offset_key_length+1, (void **) &retval) == FAILURE) {
+ if (zend_hash_quick_find(ht, offset_key, offset_key_length+1, hval, (void **) &retval) == FAILURE) {
switch (type) {
case BP_VAR_R:
zend_error(E_NOTICE, "Undefined index: %s", offset_key);
@@ -817,7 +822,7 @@ static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, const zva
zval *new_zval = &EG(uninitialized_zval);
Z_ADDREF_P(new_zval);
- zend_symtable_update(ht, offset_key, offset_key_length+1, &new_zval, sizeof(zval *), (void **) &retval);
+ zend_hash_quick_update(ht, offset_key, offset_key_length+1, hval, &new_zval, sizeof(zval *), (void **) &retval);
}
break;
}
@@ -864,7 +869,7 @@ static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, const zva
return retval;
}
-static void zend_fetch_dimension_address(temp_variable *result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC)
+static void zend_fetch_dimension_address(temp_variable *result, zval **container_ptr, zval *dim, int dim_type, int type TSRMLS_DC)
{
zval *container = *container_ptr;
zval **retval;
@@ -887,7 +892,7 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container
Z_DELREF_P(new_zval);
}
} else {
- retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, type TSRMLS_CC);
+ retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC);
}
result->var.ptr_ptr = retval;
PZVAL_LOCK(*retval);
@@ -963,7 +968,7 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container
} else {
zval *overloaded_result;
- if (dim_is_tmp_var) {
+ if (dim_type == IS_TMP_VAR) {
zval *orig = dim;
MAKE_REAL_ZVAL_PTR(dim);
ZVAL_NULL(orig);
@@ -992,7 +997,7 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container
}
AI_SET_PTR(result->var, *retval);
PZVAL_LOCK(*retval);
- if (dim_is_tmp_var) {
+ if (dim_type == IS_TMP_VAR) {
zval_ptr_dtor(&dim);
}
}
@@ -1019,15 +1024,15 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container
}
}
-static void zend_fetch_dimension_address_read(temp_variable *result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC)
+static void zend_fetch_dimension_address_read(temp_variable *result, zval **container_ptr, zval *dim, int dim_type, int type TSRMLS_DC)
{
zval *container = *container_ptr;
zval **retval;
switch (Z_TYPE_P(container)) {
case IS_ARRAY:
- retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, type TSRMLS_CC);
+ retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC);
if (result) {
AI_SET_PTR(result->var, *retval);
PZVAL_LOCK(*retval);
@@ -1085,7 +1090,7 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval **cont
} else {
zval *overloaded_result;
- if (dim_is_tmp_var) {
+ if (dim_type == IS_TMP_VAR) {
zval *orig = dim;
MAKE_REAL_ZVAL_PTR(dim);
ZVAL_NULL(orig);
@@ -1105,7 +1110,7 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval **cont
AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));
PZVAL_LOCK(EG(uninitialized_zval_ptr));
}
- if (dim_is_tmp_var) {
+ if (dim_type == IS_TMP_VAR) {
zval_ptr_dtor(&dim);
}
}
@@ -1122,7 +1127,7 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval **cont
}
}
-static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, int type TSRMLS_DC)
+static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, const zend_literal *key, int type TSRMLS_DC)
{
zval *container = *container_ptr;;
@@ -1152,12 +1157,12 @@ static void zend_fetch_property_address(temp_variable *result, zval **container_
}
if (Z_OBJ_HT_P(container)->get_property_ptr_ptr) {
- zval **ptr_ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr TSRMLS_CC);
+ zval **ptr_ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, key TSRMLS_CC);
if (NULL == ptr_ptr) {
zval *ptr;
if (Z_OBJ_HT_P(container)->read_property &&
- (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type TSRMLS_CC)) != NULL) {
+ (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, key TSRMLS_CC)) != NULL) {
AI_SET_PTR(result->var, ptr);
PZVAL_LOCK(ptr);
} else {
@@ -1168,7 +1173,7 @@ static void zend_fetch_property_address(temp_variable *result, zval **container_
PZVAL_LOCK(*ptr_ptr);
}
} else if (Z_OBJ_HT_P(container)->read_property) {
- zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type TSRMLS_CC);
+ zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, key TSRMLS_CC);
AI_SET_PTR(result->var, ptr);
PZVAL_LOCK(ptr);
@@ -1179,7 +1184,7 @@ static void zend_fetch_property_address(temp_variable *result, zval **container_
}
}
-static inline zend_brk_cont_element* zend_brk_cont(const zval *nest_levels_zval, int array_offset, const zend_op_array *op_array, const temp_variable *Ts TSRMLS_DC)
+static inline zend_brk_cont_element* zend_brk_cont(zval *nest_levels_zval, int array_offset, const zend_op_array *op_array, const temp_variable *Ts TSRMLS_DC)
{
zval tmp;
int nest_levels, original_nest_levels;
@@ -1204,13 +1209,13 @@ static inline zend_brk_cont_element* zend_brk_cont(const zval *nest_levels_zval,
switch (brk_opline->opcode) {
case ZEND_SWITCH_FREE:
- if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) {
- zend_switch_free(&T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC);
+ if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
+ zend_switch_free(&T(brk_opline->op1.var), brk_opline->extended_value TSRMLS_CC);
}
break;
case ZEND_FREE:
- if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) {
- zendi_zval_dtor(T(brk_opline->op1.u.var).tmp_var);
+ if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
+ zendi_zval_dtor(T(brk_opline->op1.var).tmp_var);
}
break;
}
@@ -1256,7 +1261,7 @@ ZEND_API opcode_handler_t *zend_opcode_handlers;
ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC)
{
- zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.u.var)).var.ptr;
+ zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.var)).var.ptr;
((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr, execute_data_ptr->function_state.function->common.return_reference?return_value_ptr:NULL, execute_data_ptr->object, return_value_used TSRMLS_CC);
}
@@ -1296,12 +1301,12 @@ ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode)
return zend_user_opcode_handlers[opcode];
}
-ZEND_API zval *zend_get_zval_ptr(znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) {
- return get_zval_ptr(node, Ts, should_free, type);
+ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) {
+ return get_zval_ptr(op_type, node, Ts, should_free, type);
}
-ZEND_API zval **zend_get_zval_ptr_ptr(const znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) {
- return get_zval_ptr_ptr(node, Ts, should_free, type);
+ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) {
+ return get_zval_ptr_ptr(op_type, node, Ts, should_free, type);
}
/*
View
7 Zend/zend_execute.h
@@ -71,7 +71,7 @@ static inline void safe_free_zval_ptr_rel(zval *p ZEND_FILE_LINE_DC ZEND_FILE_LI
}
}
ZEND_API int zend_lookup_class(const char *name, int name_length, zend_class_entry ***ce TSRMLS_DC);
-ZEND_API int zend_lookup_class_ex(const char *name, int name_length, int use_autoload, zend_class_entry ***ce TSRMLS_DC);
+ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_literal *key, int use_autoload, zend_class_entry ***ce TSRMLS_DC);
ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC);
ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *string_name TSRMLS_DC);
ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC);
@@ -364,6 +364,7 @@ ZEND_API void zend_set_timeout(long seconds, int reset_signals);
ZEND_API void zend_unset_timeout(TSRMLS_D);
ZEND_API void zend_timeout(int dummy);
ZEND_API zend_class_entry *zend_fetch_class(const char *class_name, uint class_name_len, int fetch_type TSRMLS_DC);
+ZEND_API zend_class_entry *zend_fetch_class_by_name(const char *class_name, uint class_name_len, const zend_literal *key, int fetch_type TSRMLS_DC);
void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC);
#ifdef ZEND_WIN32
@@ -402,8 +403,8 @@ typedef struct _zend_free_op {
/* int is_var; */
} zend_free_op;
-ZEND_API zval *zend_get_zval_ptr(znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC);
-ZEND_API zval **zend_get_zval_ptr_ptr(const znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC);
+ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC);
+ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC);
ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS);
View
98 Zend/zend_execute_API.c
@@ -1023,7 +1023,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
}
/* }}} */
-ZEND_API int zend_lookup_class_ex(const char *name, int name_length, int use_autoload, zend_class_entry ***ce TSRMLS_DC) /* {{{ */
+ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_literal *key, int use_autoload, zend_class_entry ***ce TSRMLS_DC) /* {{{ */
{
zval **args[1];
zval autoload_function;
@@ -1038,31 +1038,41 @@ ZEND_API int zend_lookup_class_ex(const char *name, int name_length, int use_aut
ulong hash;
ALLOCA_FLAG(use_heap)
- if (name == NULL || !name_length) {
- return FAILURE;
- }
+ if (key) {
+ lc_name = Z_STRVAL(key->constant);
+ lc_length = Z_STRLEN(key->constant) + 1;
+ hash = key->hash_value;
+ } else {
+ if (name == NULL || !name_length) {
+ return FAILURE;
+ }
- lc_free = lc_name = do_alloca(name_length + 1, use_heap);
- zend_str_tolower_copy(lc_name, name, name_length);
- lc_length = name_length + 1;
+ lc_free = lc_name = do_alloca(name_length + 1, use_heap);
+ zend_str_tolower_copy(lc_name, name, name_length);
+ lc_length = name_length + 1;
- if (lc_name[0] == '\\') {
- lc_name += 1;
- lc_length -= 1;
- }
+ if (lc_name[0] == '\\') {
+ lc_name += 1;
+ lc_length -= 1;
+ }
- hash = zend_inline_hash_func(lc_name, lc_length);
+ hash = zend_inline_hash_func(lc_name, lc_length);
+ }
if (zend_hash_quick_find(EG(class_table), lc_name, lc_length, hash, (void **) ce) == SUCCESS) {
- free_alloca(lc_free, use_heap);
+ if (!key) {
+ free_alloca(lc_free, use_heap);
+ }
return SUCCESS;
}
/* The compiler is not-reentrant. Make sure we __autoload() only during run-time
* (doesn't impact fuctionality of __autoload()
*/
if (!use_autoload || zend_is_compiling(TSRMLS_C)) {
- free_alloca(lc_free, use_heap);
+ if (!key) {
+ free_alloca(lc_free, use_heap);
+ }
return FAILURE;
}
@@ -1072,7 +1082,9 @@ ZEND_API int zend_lookup_class_ex(const char *name, int name_length, int use_aut
}
if (zend_hash_quick_add(EG(in_autoload), lc_name, lc_length, hash, (void**)&dummy, sizeof(char), NULL) == FAILURE) {
- free_alloca(lc_free, use_heap);
+ if (!key) {
+ free_alloca(lc_free, use_heap);
+ }
return FAILURE;
}
@@ -1118,20 +1130,19 @@ ZEND_API int zend_lookup_class_ex(const char *name, int name_length, int use_aut
zval_ptr_dtor(&retval_ptr);
}
- if (retval == FAILURE) {
+ if (retval == SUCCESS) {
+ retval = zend_hash_quick_find(EG(class_table), lc_name, lc_length, hash, (void **) ce);
+ }
+ if (!key) {
free_alloca(lc_free, use_heap);
- return FAILURE;
}
-
- retval = zend_hash_quick_find(EG(class_table), lc_name, lc_length, hash, (void **) ce);
- free_alloca(lc_free, use_heap);
return retval;
}
/* }}} */
ZEND_API int zend_lookup_class(const char *name, int name_length, zend_class_entry ***ce TSRMLS_DC) /* {{{ */
{
- return zend_lookup_class_ex(name, name_length, 1, ce TSRMLS_CC);
+ return zend_lookup_class_ex(name, name_length, NULL, 1, ce TSRMLS_CC);
}
/* }}} */
@@ -1249,8 +1260,8 @@ void execute_new_code(TSRMLS_D) /* {{{ */
ret_opline = get_next_op(CG(active_op_array) TSRMLS_CC);
ret_opline->opcode = ZEND_RETURN;
- ret_opline->op1.op_type = IS_CONST;
- INIT_ZVAL(ret_opline->op1.u.constant);
+ ret_opline->op1_type = IS_CONST;
+ ret_opline->op1.constant = zend_add_literal(CG(active_op_array), &EG(uninitialized_zval));
SET_UNUSED(ret_opline->op2);
if (!CG(active_op_array)->start_op) {
@@ -1261,29 +1272,27 @@ void execute_new_code(TSRMLS_D) /* {{{ */
end=CG(active_op_array)->opcodes+CG(active_op_array)->last;
while (opline<end) {
- if (opline->op1.op_type == IS_CONST) {
- Z_SET_ISREF(opline->op1.u.constant);
- Z_SET_REFCOUNT(opline->op1.u.constant, 2); /* Make sure is_ref won't be reset */
+ if (opline->op1_type == IS_CONST) {
+ opline->op1.zv = &CG(active_op_array)->literals[opline->op1.constant].constant;
}
- if (opline->op2.op_type == IS_CONST) {
- Z_SET_ISREF(opline->op2.u.constant);
- Z_SET_REFCOUNT(opline->op2.u.constant, 2);
+ if (opline->op2_type == IS_CONST) {
+ opline->op2.zv = &CG(active_op_array)->literals[opline->op2.constant].constant;
}
switch (opline->opcode) {
case ZEND_GOTO:
- if (Z_TYPE(opline->op2.u.constant) != IS_LONG) {
+ if (Z_TYPE_P(opline->op2.zv) != IS_LONG) {
zend_resolve_goto_label(CG(active_op_array), opline, 1 TSRMLS_CC);
}
/* break omitted intentionally */
case ZEND_JMP:
- opline->op1.u.jmp_addr = &CG(active_op_array)->opcodes[opline->op1.u.opline_num];
+ opline->op1.jmp_addr = &CG(active_op_array)->opcodes[opline->op1.opline_num];
break;
case ZEND_JMPZ:
case ZEND_JMPNZ:
case ZEND_JMPZ_EX:
case ZEND_JMPNZ_EX:
case ZEND_JMP_SET:
- opline->op2.u.jmp_addr = &CG(active_op_array)->opcodes[opline->op2.u.opline_num];
+ opline->op2.jmp_addr = &CG(active_op_array)->opcodes[opline->op2.opline_num];
break;
}
ZEND_VM_SET_OPCODE_HANDLER(opline);
@@ -1547,7 +1556,7 @@ zend_class_entry *zend_fetch_class(const char *class_name, uint class_name_len,
break;
}
- if (zend_lookup_class_ex(class_name, class_name_len, use_autoload, &pce TSRMLS_CC) == FAILURE) {
+ if (zend_lookup_class_ex(class_name, class_name_len, NULL, use_autoload, &pce TSRMLS_CC) == FAILURE) {
if (use_autoload) {
if (!silent && !EG(exception)) {
if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) {
@@ -1563,6 +1572,27 @@ zend_class_entry *zend_fetch_class(const char *class_name, uint class_name_len,
}
/* }}} */
+zend_class_entry *zend_fetch_class_by_name(const char *class_name, uint class_name_len, const zend_literal *key, int fetch_type TSRMLS_DC) /* {{{ */
+{
+ zend_class_entry **pce;
+ int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) == 0;
+
+ if (zend_lookup_class_ex(class_name, class_name_len, key, use_autoload, &pce TSRMLS_CC) == FAILURE) {
+ if (use_autoload) {
+ if ((fetch_type & ZEND_FETCH_CLASS_SILENT) == 0 && !EG(exception)) {
+ if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_INTERFACE) {
+ zend_error(E_ERROR, "Interface '%s' not found", class_name);
+ } else {
+ zend_error(E_ERROR, "Class '%s' not found", class_name);
+ }
+ }
+ }
+ return NULL;
+ }
+ return *pce;
+}
+/* }}} */
+
#define MAX_ABSTRACT_INFO_CNT 3
#define MAX_ABSTRACT_INFO_FMT "%s%s%s%s"
#define DISPLAY_ABSTRACT_FN(idx) \
@@ -1684,7 +1714,7 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */
EG(active_symbol_table) = *(EG(symtable_cache_ptr)--);
} else {
ALLOC_HASHTABLE(EG(active_symbol_table));
- zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0);
+ zend_hash_init(EG(active_symbol_table), ex->op_array->last_var, NULL, ZVAL_PTR_DTOR, 0);
/*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/
}
ex->symbol_table = EG(active_symbol_table);
View
11 Zend/zend_hash.h
@@ -304,15 +304,14 @@ END_EXTERN_C()
#define ZEND_INIT_SYMTABLE_EX(ht, n, persistent) \
zend_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent)
-#define ZEND_HANDLE_NUMERIC(key, length, func) do { \
+#define ZEND_HANDLE_NUMERIC_EX(key, length, idx, func) do { \
register const char *tmp = key; \
\
if (*tmp == '-') { \
tmp++; \
} \
if (*tmp >= '0' && *tmp <= '9') { /* possibly a numeric index */ \
const char *end = key + length - 1; \
- long idx; \
\
if ((*end != '\0') /* not a null terminated string */ \
|| (*tmp == '0' && length > 2) /* numbers with leading zeros */ \
@@ -335,11 +334,17 @@ END_EXTERN_C()
} else if (idx < 0) { /* overflow */ \
break; \
} \
- return func; \
+ func; \
} \
} \
} while (0)
+#define ZEND_HANDLE_NUMERIC(key, length, func) do { \
+ long idx; \
+ \
+ ZEND_HANDLE_NUMERIC_EX(key, length, idx, return func); \
+} while (0)
+
static inline int zend_symtable_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest) \
{
ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_update(ht, idx, pData, nDataSize, pDest));
View
84 Zend/zend_language_parser.y
@@ -219,12 +219,12 @@ unticked_statement:
'{' inner_statement_list '}'
| T_IF '(' expr ')' { zend_do_if_cond(&$3, &$4 TSRMLS_CC); } statement { zend_do_if_after_statement(&$4, 1 TSRMLS_CC); } elseif_list else_single { zend_do_if_end(TSRMLS_C); }
| T_IF '(' expr ')' ':' { zend_do_if_cond(&$3, &$4 TSRMLS_CC); } inner_statement_list { zend_do_if_after_statement(&$4, 1 TSRMLS_CC); } new_elseif_list new_else_single T_ENDIF ';' { zend_do_if_end(TSRMLS_C); }
- | T_WHILE '(' { $1.u.opline_num = get_next_op_number(CG(active_op_array)); } expr ')' { zend_do_while_cond(&$4, &$5 TSRMLS_CC); } while_statement { zend_do_while_end(&$1, &$5 TSRMLS_CC); }
- | T_DO { $1.u.opline_num = get_next_op_number(CG(active_op_array)); zend_do_do_while_begin(TSRMLS_C); } statement T_WHILE '(' { $5.u.opline_num = get_next_op_number(CG(active_op_array)); } expr ')' ';' { zend_do_do_while_end(&$1, &$5, &$7 TSRMLS_CC); }
+ | T_WHILE '(' { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); } expr ')' { zend_do_while_cond(&$4, &$5 TSRMLS_CC); } while_statement { zend_do_while_end(&$1, &$5 TSRMLS_CC); }
+ | T_DO { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); zend_do_do_while_begin(TSRMLS_C); } statement T_WHILE '(' { $5.u.op.opline_num = get_next_op_number(CG(active_op_array)); } expr ')' ';' { zend_do_do_while_end(&$1, &$5, &$7 TSRMLS_CC); }
| T_FOR
'('
for_expr
- ';' { zend_do_free(&$3 TSRMLS_CC); $4.u.opline_num = get_next_op_number(CG(active_op_array)); }
+ ';' { zend_do_free(&$3 TSRMLS_CC); $4.u.op.opline_num = get_next_op_number(CG(active_op_array)); }
for_expr
';' { zend_do_extended_info(TSRMLS_C); zend_do_for_cond(&$6, &$7 TSRMLS_CC); }
for_expr
@@ -252,7 +252,7 @@ unticked_statement:
{ zend_do_foreach_begin(&$1, &$2, &$3, &$4, 0 TSRMLS_CC); }
variable foreach_optional_arg ')' { zend_check_writable_variable(&$6); zend_do_foreach_cont(&$1, &$2, &$4, &$6, &$7 TSRMLS_CC); }
foreach_statement { zend_do_foreach_end(&$1, &$4 TSRMLS_CC); }
- | T_DECLARE { $1.u.opline_num = get_next_op_number(CG(active_op_array)); zend_do_declare_begin(TSRMLS_C); } '(' declare_list ')' declare_statement { zend_do_declare_end(&$1 TSRMLS_CC); }
+ | T_DECLARE { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); zend_do_declare_begin(TSRMLS_C); } '(' declare_list ')' declare_statement { zend_do_declare_end(&$1 TSRMLS_CC); }
| ';' /* empty statement */
| T_TRY { zend_do_try(&$1 TSRMLS_CC); } '{' inner_statement_list '}'
T_CATCH '(' { zend_initialize_try_catch_element(&$1 TSRMLS_CC); }
@@ -267,7 +267,7 @@ unticked_statement:
additional_catches:
non_empty_additional_catches { $$ = $1; }
- | /* empty */ { $$.u.opline_num = -1; }
+ | /* empty */ { $$.u.op.opline_num = -1; }
;
non_empty_additional_catches:
@@ -277,7 +277,7 @@ non_empty_additional_catches:
additional_catch:
- T_CATCH '(' fully_qualified_class_name { $$.u.opline_num = get_next_op_number(CG(active_op_array)); } T_VARIABLE ')' { zend_do_begin_catch(&$1, &$3, &$5, NULL TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
+ T_CATCH '(' fully_qualified_class_name { $$.u.op.opline_num = get_next_op_number(CG(active_op_array)); } T_VARIABLE ')' { zend_do_begin_catch(&$1, &$3, &$5, NULL TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
;
@@ -327,9 +327,9 @@ unticked_class_declaration_statement:
class_entry_type:
- T_CLASS { $$.u.opline_num = CG(zend_lineno); $$.u.EA.type = 0; }
- | T_ABSTRACT T_CLASS { $$.u.opline_num = CG(zend_lineno); $$.u.EA.type = ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; }
- | T_FINAL T_CLASS { $$.u.opline_num = CG(zend_lineno); $$.u.EA.type = ZEND_ACC_FINAL_CLASS; }
+ T_CLASS { $$.u.op.opline_num = CG(zend_lineno); $$.EA = 0; }
+ | T_ABSTRACT T_CLASS { $$.u.op.opline_num = CG(zend_lineno); $$.EA = ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; }
+ | T_FINAL T_CLASS { $$.u.op.opline_num = CG(zend_lineno); $$.EA = ZEND_ACC_FINAL_CLASS; }
;
extends_from:
@@ -338,7 +338,7 @@ extends_from:
;
interface_entry:
- T_INTERFACE { $$.u.opline_num = CG(zend_lineno); $$.u.EA.type = ZEND_ACC_INTERFACE; }
+ T_INTERFACE { $$.u.op.opline_num = CG(zend_lineno); $$.EA = ZEND_ACC_INTERFACE; }
;
interface_extends_list:
@@ -364,7 +364,7 @@ foreach_optional_arg:
foreach_variable:
variable { zend_check_writable_variable(&$1); $$ = $1; }
- | '&' variable { zend_check_writable_variable(&$2); $$ = $2; $$.u.EA.type |= ZEND_PARSED_REFERENCE_VARIABLE; }
+ | '&' variable { zend_check_writable_variable(&$2); $$ = $2; $$.EA |= ZEND_PARSED_REFERENCE_VARIABLE; }
;
for_statement:
@@ -450,14 +450,14 @@ 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; Z_LVAL($$.u.constant)=1; Z_TYPE($$.u.constant)=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; Z_LVAL($$.u.constant)=1; Z_TYPE($$.u.constant)=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; Z_LVAL($$.u.constant)=1; Z_TYPE($$.u.constant)=IS_LONG; INIT_PZVAL(&$$.u.constant); zend_do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$5, &$1, &$3, 1 TSRMLS_CC); }
- | optional_class_type T_VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$2, 0 TSRMLS_CC); $$.op_type = IS_CONST; Z_LVAL($$.u.constant)=1; Z_TYPE($$.u.constant)=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; Z_LVAL($$.u.constant)++; 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; Z_LVAL($$.u.constant)++; 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; Z_LVAL($$.u.constant)++; zend_do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$7, &$3, &$5, 1 TSRMLS_CC); }
- | non_empty_parameter_list ',' optional_class_type T_VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$4, 0 TSRMLS_CC); $$=$1; Z_LVAL($$.u.constant)++; zend_do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$6, &$3, &$4, 0 TSRMLS_CC); }
+ optional_class_type T_VARIABLE { znode tmp; fetch_simple_variable(&tmp, &$2, 0 TSRMLS_CC); $$.op_type = IS_UNUSED; $$.u.op.num=1; Z_TYPE($$.u.constant)=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_UNUSED; $$.u.op.num=1; Z_TYPE($$.u.constant)=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_UNUSED; $$.u.op.num=1; Z_TYPE($$.u.constant)=IS_LONG; INIT_PZVAL(&$$.u.constant); zend_do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$5, &$1, &$3, 1 TSRMLS_CC); }
+ | optional_class_type T_VARIABLE '=' static_scalar { znode tmp; fetch_simple_variable(&tmp, &$2, 0 TSRMLS_CC); $$.op_type = IS_UNUSED; $$.u.op.num=1; Z_TYPE($$.u.constant)=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.op.num++; 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.op.num++; 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.op.num++; zend_do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$7, &$3, &$5, 1 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.op.num++; zend_do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$6, &$3, &$4, 0 TSRMLS_CC); }
;
@@ -580,7 +580,7 @@ expr_without_variable:
T_LIST '(' { zend_do_list_init(TSRMLS_C); } assignment_list ')' '=' expr { zend_do_list_end(&$$, &$7 TSRMLS_CC); }
| variable '=' expr { zend_check_writable_variable(&$1); zend_do_assign(&$$, &$1, &$3 TSRMLS_CC); }
| variable '=' '&' variable { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$4, BP_VAR_W, 1 TSRMLS_CC); zend_do_end_variable_parse(&$1, BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); }
- | variable '=' '&' T_NEW class_name_reference { zend_error(E_DEPRECATED, "Assigning the return value of new by reference is deprecated"); zend_check_writable_variable(&$1); zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(&$1, BP_VAR_W, 0 TSRMLS_CC); $3.u.EA.type = ZEND_PARSED_NEW; zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); }
+ | variable '=' '&' T_NEW class_name_reference { zend_error(E_DEPRECATED, "Assigning the return value of new by reference is deprecated"); zend_check_writable_variable(&$1); zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(&$1, BP_VAR_W, 0 TSRMLS_CC); $3.EA = ZEND_PARSED_NEW; zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); }
| T_NEW class_name_reference { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$1, &$2 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$$, &$1, &$4 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
| T_CLONE expr { zend_do_clone(&$$, &$2 TSRMLS_CC); }
| variable T_PLUS_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 TSRMLS_CC); }
@@ -654,7 +654,7 @@ expr_without_variable:
;
function:
- T_FUNCTION { $$.u.opline_num = CG(zend_lineno); }
+ T_FUNCTION { $$.u.op.opline_num = CG(zend_lineno); }
;
lexical_vars:
@@ -670,18 +670,18 @@ lexical_var_list:
;
function_call:
- namespace_name '(' { $2.u.opline_num = zend_do_begin_function_call(&$1, 1 TSRMLS_CC); }
+ namespace_name '(' { $2.u.op.opline_num = zend_do_begin_function_call(&$1, 1 TSRMLS_CC); }
function_call_parameter_list
- ')' { zend_do_end_function_call(&$1, &$$, &$4, 0, $2.u.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
- | T_NAMESPACE T_NS_SEPARATOR namespace_name '(' { $1.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$1.u.constant); zend_do_build_namespace_name(&$1, &$1, &$3 TSRMLS_CC); $4.u.opline_num = zend_do_begin_function_call(&$1, 0 TSRMLS_CC); }
+ ')' { zend_do_end_function_call(&$1, &$$, &$4, 0, $2.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
+ | T_NAMESPACE T_NS_SEPARATOR namespace_name '(' { $1.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$1.u.constant); zend_do_build_namespace_name(&$1, &$1, &$3 TSRMLS_CC); $4.u.op.opline_num = zend_do_begin_function_call(&$1, 0 TSRMLS_CC); }
function_call_parameter_list
- ')' { zend_do_end_function_call(&$1, &$$, &$6, 0, $4.u.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
- | T_NS_SEPARATOR namespace_name '(' { $3.u.opline_num = zend_do_begin_function_call(&$2, 0 TSRMLS_CC); }
+ ')' { zend_do_end_function_call(&$1, &$$, &$6, 0, $4.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
+ | T_NS_SEPARATOR namespace_name '(' { $3.u.op.opline_num = zend_do_begin_function_call(&$2, 0 TSRMLS_CC); }
function_call_parameter_list
- ')' { zend_do_end_function_call(&$2, &$$, &$5, 0, $3.u.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
- | class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING '(' { $4.u.opline_num = zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
+ ')' { zend_do_end_function_call(&$2, &$$, &$5, 0, $3.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
+ | class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING '(' { $4.u.op.opline_num = zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
function_call_parameter_list
- ')' { zend_do_end_function_call($4.u.opline_num?NULL:&$3, &$$, &$6, $4.u.opline_num, $4.u.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+ ')' { zend_do_end_function_call($4.u.op.opline_num?NULL:&$3, &$$, &$6, $4.u.op.opline_num, $4.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
| class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects '(' { zend_do_end_variable_parse(&$3, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
function_call_parameter_list
')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
@@ -719,8 +719,8 @@ class_name_reference:
dynamic_class_name_reference:
base_variable T_OBJECT_OPERATOR { zend_do_push_object(&$1 TSRMLS_CC); }
- object_property { zend_do_push_object(&$4 TSRMLS_CC); zend_do_declare_implicit_property(TSRMLS_C); } dynamic_class_name_variable_properties
- { zend_do_pop_object(&$$ TSRMLS_CC); $$.u.EA.type = ZEND_PARSED_MEMBER; }
+ object_property { zend_do_push_object(&$4 TSRMLS_CC); } dynamic_class_name_variable_properties
+ { zend_do_pop_object(&$$ TSRMLS_CC); $$.EA = ZEND_PARSED_MEMBER; }
| base_variable { $$ = $1; }
;
@@ -732,7 +732,7 @@ dynamic_class_name_variable_properties:
dynamic_class_name_variable_property:
- T_OBJECT_OPERATOR object_property { zend_do_push_object(&$2 TSRMLS_CC); zend_do_declare_implicit_property(TSRMLS_C); }
+ T_OBJECT_OPERATOR object_property { zend_do_push_object(&$2 TSRMLS_CC); }
;
exit_expr:
@@ -838,26 +838,26 @@ rw_variable:
variable:
base_variable_with_function_calls T_OBJECT_OPERATOR { zend_do_push_object(&$1 TSRMLS_CC); }
object_property { zend_do_push_object(&$4 TSRMLS_CC); } method_or_not variable_properties
- { zend_do_pop_object(&$$ TSRMLS_CC); $$.u.EA.type = $1.u.EA.type | ($7.u.EA.type ? $7.u.EA.type : $6.u.EA.type); }
+ { zend_do_pop_object(&$$ TSRMLS_CC); $$.EA = $1.EA | ($7.EA ? $7.EA : $6.EA); }
| base_variable_with_function_calls { $$ = $1; }
;
variable_properties:
- variable_properties variable_property { $$.u.EA.type = $2.u.EA.type; }
- | /* empty */ { $$.u.EA.type = 0; }
+ variable_properties variable_property { $$.EA = $2.EA; }
+ | /* empty */ { $$.EA = 0; }
;
variable_property:
- T_OBJECT_OPERATOR object_property { zend_do_push_object(&$2 TSRMLS_CC); } method_or_not { $$.u.EA.type = $4.u.EA.type; }
+ T_OBJECT_OPERATOR object_property { zend_do_push_object(&$2 TSRMLS_CC); } method_or_not { $$.EA = $4.EA; }
;
method_or_not:
'(' { zend_do_pop_object(&$1 TSRMLS_CC); zend_do_begin_method_call(&$1 TSRMLS_CC); }
function_call_parameter_list ')'
{ zend_do_end_function_call(&$1, &$$, &$3, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);
- zend_do_push_object(&$$ TSRMLS_CC); $$.u.EA.type = ZEND_PARSED_METHOD_CALL; }
- | /* empty */ { zend_do_declare_implicit_property(TSRMLS_C); $$.u.EA.type = ZEND_PARSED_MEMBER; }
+ zend_do_push_object(&$$ TSRMLS_CC); $$.EA = ZEND_PARSED_METHOD_CALL; }
+ | /* empty */ { $$.EA = ZEND_PARSED_MEMBER; }
;
variable_without_objects:
@@ -877,14 +877,14 @@ variable_class_name:
base_variable_with_function_calls:
base_variable { $$ = $1; }
- | function_call { zend_do_begin_variable_parse(TSRMLS_C); $$ = $1; $$.u.EA.type = ZEND_PARSED_FUNCTION_CALL; }
+ | function_call { zend_do_begin_variable_parse(TSRMLS_C); $$ = $1; $$.EA = ZEND_PARSED_FUNCTION_CALL; }
;
base_variable:
- reference_variable { $$ = $1; $$.u.EA.type = ZEND_PARSED_VARIABLE; }
- | simple_indirect_reference reference_variable { zend_do_indirect_references(&$$, &$1, &$2 TSRMLS_CC); $$.u.EA.type = ZEND_PARSED_VARIABLE; }
- | static_member { $$ = $1; $$.u.EA.type = ZEND_PARSED_STATIC_MEMBER; }
+ reference_variable { $$ = $1; $$.EA = ZEND_PARSED_VARIABLE; }
+ | simple_indirect_reference reference_variable { zend_do_indirect_references(&$$, &$1, &$2 TSRMLS_CC); $$.EA = ZEND_PARSED_VARIABLE; }
+ | static_member { $$ = $1; $$.EA = ZEND_PARSED_STATIC_MEMBER; }
;
reference_variable:
View
151 Zend/zend_object_handlers.c
@@ -191,12 +191,11 @@ static inline zend_bool is_derived_class(zend_class_entry *child_class, zend_cla
}
/* }}} */
-ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce, zval *member, int silent TSRMLS_DC) /* {{{ */
+static struct _zend_property_info *zend_get_property_info_quick(zend_class_entry *ce, zval *member, int silent, ulong h TSRMLS_DC) /* {{{ */
{
zend_property_info *property_info = NULL;
zend_property_info *scope_property_info;
zend_bool denied_access = 0;
- ulong h;
if (Z_STRVAL_P(member)[0] == '\0') {
if (!silent) {
@@ -208,7 +207,6 @@ ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce
}
return NULL;
}
- h = zend_get_hash_value(Z_STRVAL_P(member), Z_STRLEN_P(member) + 1);
if (zend_hash_quick_find(&ce->properties_info, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, h, (void **) &property_info)==SUCCESS) {
if(property_info->flags & ZEND_ACC_SHADOW) {
/* if it's a shadow - go to access it's private */
@@ -261,6 +259,14 @@ ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce
}
/* }}} */
+ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce, zval *member, int silent TSRMLS_DC) /* {{{ */
+{
+ zend_ulong h = zend_get_hash_value(Z_STRVAL_P(member), Z_STRLEN_P(member) + 1);
+
+ return zend_get_property_info_quick(ce, member, silent, h TSRMLS_CC);
+}
+/* }}} */
+
ZEND_API int zend_check_property_access(zend_object *zobj, char *prop_info_name, int prop_info_name_len TSRMLS_DC) /* {{{ */
{
zend_property_info *property_info;
@@ -311,7 +317,7 @@ static int zend_get_property_guard(zend_object *zobj, zend_property_info *proper
}
/* }}} */
-zval *zend_std_read_property(zval *object, zval *member, int type TSRMLS_DC) /* {{{ */
+zval *zend_std_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
{
zend_object *zobj;
zval *tmp_member = NULL;
@@ -330,14 +336,19 @@ zval *zend_std_read_property(zval *object, zval *member, int type TSRMLS_DC) /*
zval_copy_ctor(tmp_member);
convert_to_string(tmp_member);
member = tmp_member;
+ key = NULL;
}
#if DEBUG_OBJECT_HANDLERS
fprintf(stderr, "Read object #%d property: %s\n", Z_OBJ_HANDLE_P(object), Z_STRVAL_P(member));
#endif
/* make zend_get_property_info silent if we have getter - we may want to use it */
- property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__get != NULL) TSRMLS_CC);
+ if (key) {
+ property_info = zend_get_property_info_quick(zobj->ce, member, (zobj->ce->__get != NULL), key->hash_value TSRMLS_CC);
+ } else {
+ property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__get != NULL) TSRMLS_CC);
+ }
if (!property_info || zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval) == FAILURE) {
zend_guard *guard;
@@ -388,7 +399,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type TSRMLS_DC) /*
}
/* }}} */
-static void zend_std_write_property(zval *object, zval *member, zval *value TSRMLS_DC) /* {{{ */
+static void zend_std_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) /* {{{ */
{
zend_object *zobj;
zval *tmp_member = NULL;
@@ -404,9 +415,14 @@ static void zend_std_write_property(zval *object, zval *member, zval *value TSRM
zval_copy_ctor(tmp_member);
convert_to_string(tmp_member);
member = tmp_member;
+ key = NULL;
}
- property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__set != NULL) TSRMLS_CC);
+ if (key) {
+ property_info = zend_get_property_info_quick(zobj->ce, member, (zobj->ce->__set != NULL), key->hash_value TSRMLS_CC);
+ } else {
+ property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__set != NULL) TSRMLS_CC);
+ }
if (property_info && zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &variable_ptr) == SUCCESS) {
/* if we already have this value there, we don't actually need to do anything */
@@ -552,7 +568,7 @@ static int zend_std_has_dimension(zval *object, zval *offset, int check_empty TS
}
/* }}} */
-static zval **zend_std_get_property_ptr_ptr(zval *object, zval *member TSRMLS_DC) /* {{{ */
+static zval **zend_std_get_property_ptr_ptr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */
{
zend_object *zobj;
zval tmp_member;
@@ -566,13 +582,18 @@ static zval **zend_std_get_property_ptr_ptr(zval *object, zval *member TSRMLS_DC
zval_copy_ctor(&tmp_member);
convert_to_string(&tmp_member);
member = &tmp_member;
+ key = NULL;
}
#if DEBUG_OBJECT_HANDLERS
fprintf(stderr, "Ptr object #%d property: %s\n", Z_OBJ_HANDLE_P(object), Z_STRVAL_P(member));
#endif
- property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__get != NULL) TSRMLS_CC);
+ if (key) {
+ property_info = zend_get_property_info_quick(zobj->ce, member, (zobj->ce->__get != NULL), key->hash_value TSRMLS_CC);
+ } else {
+ property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__get != NULL) TSRMLS_CC);
+ }
if (!property_info || zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval) == FAILURE) {
zval *new_zval;
@@ -599,7 +620,7 @@ static zval **zend_std_get_property_ptr_ptr(zval *object, zval *member TSRMLS_DC
}
/* }}} */
-static void zend_std_unset_property(zval *object, zval *member TSRMLS_DC) /* {{{ */
+static void zend_std_unset_property(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */
{
zend_object *zobj;
zval *tmp_member = NULL;
@@ -614,9 +635,14 @@ static void zend_std_unset_property(zval *object, zval *member TSRMLS_DC) /* {{{
zval_copy_ctor(tmp_member);
convert_to_string(tmp_member);
member = tmp_member;
+ key = NULL;
}
- property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__unset != NULL) TSRMLS_CC);
+ if (key) {
+ property_info = zend_get_property_info_quick(zobj->ce, member, (zobj->ce->__unset != NULL), key->hash_value TSRMLS_CC);
+ } else {
+ property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__unset != NULL) TSRMLS_CC);
+ }
if (!property_info || zend_hash_quick_del(zobj->properties, property_info->name, property_info->name_length+1, property_info->h) == FAILURE) {
zend_guard *guard;
@@ -702,7 +728,7 @@ ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
* Returns the function address that should be called, or NULL
* if no such function exists.
*/
-static inline zend_function *zend_check_private_int(zend_function *fbc, zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC) /* {{{ */
+static inline zend_function *zend_check_private_int(zend_function *fbc, zend_class_entry *ce, char *function_name_strval, int function_name_strlen, ulong hash_value TSRMLS_DC) /* {{{ */
{
if (!ce) {
return 0;
@@ -724,7 +750,7 @@ static inline zend_function *zend_check_private_int(zend_function *fbc, zend_cla
ce = ce->parent;
while (ce) {
if (ce == EG(scope)) {
- if (zend_hash_find(&ce->function_table, function_name_strval, function_name_strlen+1, (void **) &fbc)==SUCCESS
+ if (zend_hash_quick_find(&ce->function_table, function_name_strval, function_name_strlen+1, hash_value, (void **) &fbc)==SUCCESS
&& fbc->op_array.fn_flags & ZEND_ACC_PRIVATE
&& fbc->common.scope == EG(scope)) {
return fbc;
@@ -739,7 +765,7 @@ static inline zend_function *zend_check_private_int(zend_function *fbc, zend_cla
ZEND_API int zend_check_private(zend_function *fbc, zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC) /* {{{ */
{
- return zend_check_private_int(fbc, ce, function_name_strval, function_name_strlen TSRMLS_CC) != NULL;
+ return zend_check_private_int(fbc, ce, function_name_strval, function_name_strlen, zend_hash_func(function_name_strval, function_name_strlen+1) TSRMLS_CC) != NULL;
}
/* }}} */
@@ -796,21 +822,29 @@ static inline union _zend_function *zend_get_user_call_function(zend_class_entry
}
/* }}} */
-static union _zend_function *zend_std_get_method(zval **object_ptr, char *method_name, int method_len TSRMLS_DC) /* {{{ */
+static union _zend_function *zend_std_get_method(zval **object_ptr, char *method_name, int method_len, const zend_literal *key TSRMLS_DC) /* {{{ */
{
- zend_object *zobj;
zend_function *fbc;
- char *lc_method_name;
zval *object = *object_ptr;
+ zend_object *zobj = Z_OBJ_P(object);
+ ulong hash_value;
+ char *lc_method_name;
ALLOCA_FLAG(use_heap)
- lc_method_name = do_alloca(method_len+1, use_heap);
- /* Create a zend_copy_str_tolower(dest, src, src_length); */
- zend_str_tolower_copy(lc_method_name, method_name, method_len);
+ if (key) {
+ lc_method_name = Z_STRVAL(key->constant);
+ hash_value = key->hash_value;
+ } else {
+ lc_method_name = do_alloca(method_len+1, use_heap);
+ /* Create a zend_copy_str_tolower(dest, src, src_length); */
+ zend_str_tolower_copy(lc_method_name, method_name, method_len);
+ hash_value = zend_hash_func(lc_method_name, method_len+1);
+ }
- zobj = Z_OBJ_P(object);
- if (zend_hash_find(&zobj->ce->function_table, lc_method_name, method_len+1, (void **)&fbc) == FAILURE) {
- free_alloca(lc_method_name, use_heap);
+ if (zend_hash_quick_find(&zobj->ce->function_table, lc_method_name, method_len+1, hash_value, (void **)&fbc) == FAILURE) {
+ if (!key) {
+ free_alloca(lc_method_name, use_heap);
+ }
if (zobj->ce->__call) {
return zend_get_user_call_function(zobj->ce, method_name, method_len);
} else {
@@ -825,7 +859,7 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *method
/* Ensure that if we're calling a private function, we're allowed to do so.
* If we're not and __call() handler exists, invoke it, otherwise error out.
*/
- updated_fbc = zend_check_private_int(fbc, Z_OBJ_HANDLER_P(object, get_class_entry)(object TSRMLS_CC), lc_method_name, method_len TSRMLS_CC);
+ updated_fbc = zend_check_private_int(fbc, Z_OBJ_HANDLER_P(object, get_class_entry)(object TSRMLS_CC), lc_method_name, method_len, hash_value TSRMLS_CC);
if (updated_fbc) {
fbc = updated_fbc;
} else {
@@ -844,7 +878,7 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *method
fbc->op_array.fn_flags & ZEND_ACC_CHANGED) {
zend_function *priv_fbc;
- if (zend_hash_find(&EG(scope)->function_table, lc_method_name, method_len+1, (void **) &priv_fbc)==SUCCESS
+ if (zend_hash_quick_find(&EG(scope)->function_table, lc_method_name, method_len+1, hash_value, (void **) &priv_fbc)==SUCCESS
&& priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE
&& priv_fbc->common.scope == EG(scope)) {
fbc = priv_fbc;
@@ -864,7 +898,9 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *method
}
}
- free_alloca(lc_method_name, use_heap);
+ if (!key) {
+ free_alloca(lc_method_name, use_heap);
+ }
return fbc;
}
/* }}} */
@@ -933,13 +969,23 @@ static inline union _zend_function *zend_get_user_callstatic_function(zend_class
/* This is not (yet?) in the API, but it belongs in the built-in objects callbacks */
-ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC) /* {{{ */
+ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, char *function_name_strval, int function_name_strlen, const zend_literal *key TSRMLS_DC) /* {{{ */
{
zend_function *fbc = NULL;
char *lc_class_name, *lc_function_name = NULL;
-
- lc_function_name = zend_str_tolower_dup(function_name_strval, function_name_strlen);
+ ulong hash_value;
+ ALLOCA_FLAG(use_heap)
+ if (key) {
+ lc_function_name = Z_STRVAL(key->constant);
+ hash_value = key->hash_value;
+ } else {
+ lc_function_name = do_alloca(function_name_strlen+1, use_heap);
+ /* Create a zend_copy_str_tolower(dest, src, src_length); */
+ zend_str_tolower_copy(lc_function_name, function_name_strval, function_name_strlen);
+ hash_value = zend_hash_func(lc_function_name, function_name_strlen+1);
+ }
+
if (function_name_strlen == ce->name_length && ce->constructor) {
lc_class_name = zend_str_tolower_dup(ce->name, ce->name_length);
/* Only change the method to the constructor if the constructor isn't called __construct
@@ -950,8 +996,10 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, char *f
}
efree(lc_class_name);
}
- if (!fbc && zend_hash_find(&ce->function_table, lc_function_name, function_name_strlen+1, (void **) &fbc)==FAILURE) {
- efree(lc_function_name);
+ if (!fbc && zend_hash_quick_find(&ce->function_table, lc_function_name, function_name_strlen+1, hash_value, (void **) &fbc)==FAILURE) {
+ if (!key) {
+ free_alloca(lc_function_name, use_heap);
+ }
if (ce->__callstatic) {
return zend_get_user_callstatic_function(ce, function_name_strval, function_name_strlen);
@@ -964,7 +1012,6 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, char *f
return NULL;
}
}
- efree(lc_function_name);
#if MBO_0
/* right now this function is used for non static method lookup too */
@@ -980,42 +1027,55 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, char *f
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
- updated_fbc = zend_check_private_int(fbc, EG(scope), function_name_strval, function_name_strlen TSRMLS_CC);
+ updated_fbc = zend_check_private_int(fbc, EG(scope), lc_function_name, function_name_strlen, hash_value TSRMLS_CC);
if (updated_fbc) {
fbc = updated_fbc;
} else {
if (ce->__callstatic) {
- return zend_get_user_callstatic_function(ce, function_name_strval, function_name_strlen);
+ fbc = zend_get_user_callstatic_function(ce, function_name_strval, function_name_strlen);
+ } else {
+ zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : "");
}
- zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : "");
}
} else if ((fbc->common.fn_flags & ZEND_ACC_PROTECTED)) {
/* Ensure that if we're calling a protected function, we're allowed to do so.
*/
if (!zend_check_protected(zend_get_function_root_class(fbc), EG(scope))) {
if (ce->__callstatic) {
- return zend_get_user_callstatic_function(ce, function_name_strval, function_name_strlen);
+ fbc = zend_get_user_callstatic_function(ce, function_name_strval, function_name_strlen);
+ } else {
+ zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : "");
}
- zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : "");
}
}
+ if (!key) {
+ free_alloca(lc_function_name, use_heap);
+ }
+
return fbc;
}
/* }}} */
-ZEND_API zval **zend_std_get_static_property(zend_class_entry *ce, char *property_name, int property_name_len, zend_bool silent TSRMLS_DC) /* {{{ */
+ZEND_API zval **zend_std_get_static_property(zend_class_entry *ce, char *property_name, int property_name_len, zend_bool silent, const zend_literal *key TSRMLS_DC) /* {{{ */
{
zval **retval = NULL;
zend_class_entry *tmp_ce = ce;
zend_property_info *property_info;
zend_property_info std_property_info;
+ ulong hash_value;
+
+ if (key) {
+ hash_value = key->hash_value;
+ } else {
+ hash_value = zend_hash_func(property_name, property_name_len+1);
+ }
- if (zend_hash_find(&ce->properties_info, property_name, property_name_len+1, (void **) &property_info)==FAILURE) {
+ if (zend_hash_quick_find(&ce->properties_info, property_name, property_name_len+1, hash_value, (void **) &property_info)==FAILURE) {
std_property_info.flags = ZEND_ACC_PUBLIC;
std_property_info.name = property_name;
std_property_info.name_length = property_name_len;
- std_property_info.h = zend_get_hash_value(std_property_info.name, std_property_info.name_length+1);
+ std_property_info.h = hash_value;
std_property_info.ce = ce;
property_info = &std_property_info;
}
@@ -1047,7 +1107,7 @@ ZEND_API zval **zend_std_get_static_property(zend_class_entry *ce, char *propert
}
/* }}} */
-ZEND_API zend_bool zend_std_unset_static_property(zend_class_entry *ce, char *property_name, int property_name_len TSRMLS_DC) /* {{{ */
+ZEND_API zend_bool zend_std_unset_static_property(zend_class_entry *ce, char *property_name, int property_name_len, const zend_literal *key TSRMLS_DC) /* {{{ */
{
zend_error(E_ERROR, "Attempt to unset static property %s::$%s", ce->name, property_name);
return 0;