From 0b71ad83b89f55f59cf763b038b8af0abfaeeb13 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Wed, 22 Oct 2014 13:00:12 +0100 Subject: [PATCH 1/3] hashKey impl --- Zend/tests/hashkey/001.phpt | 24 + Zend/tests/hashkey/002.phpt | 26 ++ Zend/tests/hashkey/003.phpt | 24 + Zend/tests/hashkey/004.phpt | 24 + Zend/tests/hashkey/005.phpt | 24 + Zend/tests/hashkey/006.phpt | 23 + Zend/tests/hashkey/007.phpt | 23 + Zend/tests/hashkey/008.phpt | 24 + Zend/tests/hashkey/009.phpt | 24 + Zend/tests/hashkey/010.phpt | 23 + Zend/zend.h | 3 +- Zend/zend_compile.c | 6 + Zend/zend_compile.h | 1 + Zend/zend_inheritance.c | 5 + Zend/zend_vm_def.h | 53 +++ Zend/zend_vm_execute.h | 848 ++++++++++++++++++++++++++++++++++++ 16 files changed, 1154 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/hashkey/001.phpt create mode 100644 Zend/tests/hashkey/002.phpt create mode 100644 Zend/tests/hashkey/003.phpt create mode 100644 Zend/tests/hashkey/004.phpt create mode 100644 Zend/tests/hashkey/005.phpt create mode 100644 Zend/tests/hashkey/006.phpt create mode 100644 Zend/tests/hashkey/007.phpt create mode 100644 Zend/tests/hashkey/008.phpt create mode 100644 Zend/tests/hashkey/009.phpt create mode 100644 Zend/tests/hashkey/010.phpt diff --git a/Zend/tests/hashkey/001.phpt b/Zend/tests/hashkey/001.phpt new file mode 100644 index 0000000000000..a3e7eb393858d --- /dev/null +++ b/Zend/tests/hashkey/001.phpt @@ -0,0 +1,24 @@ +--TEST-- +testing hashKey returns string +--FILE-- + true +]; + +var_dump($test); +?> +--EXPECT-- +array(1) { + ["Foo"]=> + bool(true) +} + + diff --git a/Zend/tests/hashkey/002.phpt b/Zend/tests/hashkey/002.phpt new file mode 100644 index 0000000000000..65f06054e0f31 --- /dev/null +++ b/Zend/tests/hashkey/002.phpt @@ -0,0 +1,26 @@ +--TEST-- +testing hashKey inheritance +--FILE-- + true +]; + +var_dump($test); +?> +--EXPECT-- +array(1) { + ["Bar"]=> + bool(true) +} + + diff --git a/Zend/tests/hashkey/003.phpt b/Zend/tests/hashkey/003.phpt new file mode 100644 index 0000000000000..614fee12c47d1 --- /dev/null +++ b/Zend/tests/hashkey/003.phpt @@ -0,0 +1,24 @@ +--TEST-- +testing hashKey returns true +--FILE-- + true +]; + +var_dump($test); +?> +--EXPECT-- +array(1) { + [1]=> + bool(true) +} + + diff --git a/Zend/tests/hashkey/004.phpt b/Zend/tests/hashkey/004.phpt new file mode 100644 index 0000000000000..8bbeafb73429d --- /dev/null +++ b/Zend/tests/hashkey/004.phpt @@ -0,0 +1,24 @@ +--TEST-- +testing hashKey returns false +--FILE-- + true +]; + +var_dump($test); +?> +--EXPECT-- +array(1) { + [0]=> + bool(true) +} + + diff --git a/Zend/tests/hashkey/005.phpt b/Zend/tests/hashkey/005.phpt new file mode 100644 index 0000000000000..b50ba8ce4e2cc --- /dev/null +++ b/Zend/tests/hashkey/005.phpt @@ -0,0 +1,24 @@ +--TEST-- +testing hashKey returns null +--FILE-- + true +]; + +var_dump($test); +?> +--EXPECT-- +array(1) { + [""]=> + bool(true) +} + + diff --git a/Zend/tests/hashkey/006.phpt b/Zend/tests/hashkey/006.phpt new file mode 100644 index 0000000000000..3e40eccce3c54 --- /dev/null +++ b/Zend/tests/hashkey/006.phpt @@ -0,0 +1,23 @@ +--TEST-- +testing hashKey returns object +--FILE-- + true +]; + +var_dump($test); +?> +--EXPECTF-- +Warning: Illegal offset type in %s on line %d +array(0) { +} + + diff --git a/Zend/tests/hashkey/007.phpt b/Zend/tests/hashkey/007.phpt new file mode 100644 index 0000000000000..38eeda5857cc5 --- /dev/null +++ b/Zend/tests/hashkey/007.phpt @@ -0,0 +1,23 @@ +--TEST-- +testing hashKey returns array +--FILE-- + true +]; + +var_dump($test); +?> +--EXPECTF-- +Warning: Illegal offset type in %s on line %d +array(0) { +} + + diff --git a/Zend/tests/hashkey/008.phpt b/Zend/tests/hashkey/008.phpt new file mode 100644 index 0000000000000..70e3d359440c5 --- /dev/null +++ b/Zend/tests/hashkey/008.phpt @@ -0,0 +1,24 @@ +--TEST-- +testing hashKey returns double +--FILE-- + true +]; + +var_dump($test); +?> +--EXPECT-- +array(1) { + [10]=> + bool(true) +} + + diff --git a/Zend/tests/hashkey/009.phpt b/Zend/tests/hashkey/009.phpt new file mode 100644 index 0000000000000..3fb9c5efcf702 --- /dev/null +++ b/Zend/tests/hashkey/009.phpt @@ -0,0 +1,24 @@ +--TEST-- +testing hashKey returns long +--FILE-- + true +]; + +var_dump($test); +?> +--EXPECT-- +array(1) { + [10]=> + bool(true) +} + + diff --git a/Zend/tests/hashkey/010.phpt b/Zend/tests/hashkey/010.phpt new file mode 100644 index 0000000000000..3bfa05e61420f --- /dev/null +++ b/Zend/tests/hashkey/010.phpt @@ -0,0 +1,23 @@ +--TEST-- +testing hashKey returns resource +--FILE-- + true +]; + +var_dump($test); +?> +--EXPECTF-- +Warning: Illegal offset type in %s on line 11 +array(0) { +} + + diff --git a/Zend/zend.h b/Zend/zend.h index b254b2974b1a2..bc422b447970e 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -136,9 +136,10 @@ struct _zend_class_entry { union _zend_function *__callstatic; union _zend_function *__tostring; union _zend_function *__debugInfo; + union _zend_function *__hashKey; union _zend_function *serialize_func; union _zend_function *unserialize_func; - + zend_class_iterator_funcs iterator_funcs; /* handlers */ diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index dae6c22026bcb..8e5536f1e68d6 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -4066,6 +4066,12 @@ void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_boo "public visibility and cannot be static"); } ce->__tostring = (zend_function *) op_array; + } else if (zend_string_equals_literal(lcname, ZEND_HASHKEY_FUNC_NAME)) { + if (!is_public || is_static) { + zend_error(E_WARNING, "The magic method __hashKey() must have " + "public visibility and cannot be static"); + } + ce->__hashKey = (zend_function *) op_array; } else if (zend_string_equals_literal(lcname, ZEND_INVOKE_FUNC_NAME)) { if (!is_public || is_static) { zend_error(E_WARNING, "The magic method __invoke() must have " diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 3b1e046cc0a03..43bf8a852a79a 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -883,6 +883,7 @@ END_EXTERN_C() #define ZEND_CALL_FUNC_NAME "__call" #define ZEND_CALLSTATIC_FUNC_NAME "__callstatic" #define ZEND_TOSTRING_FUNC_NAME "__tostring" +#define ZEND_HASHKEY_FUNC_NAME "__hashkey" #define ZEND_AUTOLOAD_FUNC_NAME "__autoload" #define ZEND_INVOKE_FUNC_NAME "__invoke" #define ZEND_DEBUGINFO_FUNC_NAME "__debuginfo" diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 8963d2b93b3b5..82dd75818f124 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -106,6 +106,9 @@ static void do_inherit_parent_constructor(zend_class_entry *ce TSRMLS_DC) /* {{{ if (!ce->__debugInfo) { ce->__debugInfo = ce->parent->__debugInfo; } + if (!ce->__hashKey) { + ce->__hashKey = ce->parent->__hashKey; + } if (ce->constructor) { if (ce->parent->constructor && ce->parent->constructor->common.fn_flags & ZEND_ACC_FINAL) { zend_error(E_ERROR, "Cannot override final %s::%s() with %s::%s()", @@ -1012,6 +1015,8 @@ static void zend_add_magic_methods(zend_class_entry* ce, zend_string* mname, zen ce->__callstatic = fe; } else if (!strncmp(mname->val, ZEND_TOSTRING_FUNC_NAME, mname->len)) { ce->__tostring = fe; + } else if (!strncmp(mname->val, ZEND_HASHKEY_FUNC_NAME, mname->len)) { + ce->__hashKey = fe; } else if (!strncmp(mname->val, ZEND_DEBUGINFO_FUNC_NAME, mname->len)) { ce->__debugInfo = fe; } else if (ce->name->len == mname->len) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index b9474793fbc0a..3bc608c5999c3 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4108,6 +4108,59 @@ ZEND_VM_C_LABEL(str_index): case IS_TRUE: hval = 1; ZEND_VM_C_GOTO(num_index); + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + ZEND_VM_C_GOTO(str_index); + case IS_LONG: + hval = Z_LVAL_P(key); + ZEND_VM_C_GOTO(num_index); + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + ZEND_VM_C_GOTO(num_index); + case IS_TRUE: + hval = 1; + ZEND_VM_C_GOTO(num_index); + case IS_FALSE: + hval = 0; + ZEND_VM_C_GOTO(num_index); + case IS_NULL: + str = STR_EMPTY_ALLOC(); + ZEND_VM_C_GOTO(str_index); + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + ZEND_VM_C_GOTO(add_again); + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); ZEND_VM_C_GOTO(add_again); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index d459461169937..0e4be47c4e736 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -4437,6 +4437,59 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O case IS_TRUE: hval = 1; goto num_index; + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + goto str_index; + case IS_LONG: + hval = Z_LVAL_P(key); + goto num_index; + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + goto num_index; + case IS_TRUE: + hval = 1; + goto num_index; + case IS_FALSE: + hval = 0; + goto num_index; + case IS_NULL: + str = STR_EMPTY_ALLOC(); + goto str_index; + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + goto add_again; + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -5962,6 +6015,59 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_ case IS_TRUE: hval = 1; goto num_index; + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + goto str_index; + case IS_LONG: + hval = Z_LVAL_P(key); + goto num_index; + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + goto num_index; + case IS_TRUE: + hval = 1; + goto num_index; + case IS_FALSE: + hval = 0; + goto num_index; + case IS_NULL: + str = STR_EMPTY_ALLOC(); + goto str_index; + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + goto add_again; + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -7126,6 +7232,59 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO case IS_TRUE: hval = 1; goto num_index; + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + goto str_index; + case IS_LONG: + hval = Z_LVAL_P(key); + goto num_index; + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + goto num_index; + case IS_TRUE: + hval = 1; + goto num_index; + case IS_FALSE: + hval = 0; + goto num_index; + case IS_NULL: + str = STR_EMPTY_ALLOC(); + goto str_index; + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + goto add_again; + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -8212,6 +8371,59 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_ case IS_TRUE: hval = 1; goto num_index; + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + goto str_index; + case IS_LONG: + hval = Z_LVAL_P(key); + goto num_index; + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + goto num_index; + case IS_TRUE: + hval = 1; + goto num_index; + case IS_FALSE: + hval = 0; + goto num_index; + case IS_NULL: + str = STR_EMPTY_ALLOC(); + goto str_index; + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + goto add_again; + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -9320,6 +9532,59 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC case IS_TRUE: hval = 1; goto num_index; + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + goto str_index; + case IS_LONG: + hval = Z_LVAL_P(key); + goto num_index; + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + goto num_index; + case IS_TRUE: + hval = 1; + goto num_index; + case IS_FALSE: + hval = 0; + goto num_index; + case IS_NULL: + str = STR_EMPTY_ALLOC(); + goto str_index; + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + goto add_again; + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -9929,6 +10194,59 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP case IS_TRUE: hval = 1; goto num_index; + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + goto str_index; + case IS_LONG: + hval = Z_LVAL_P(key); + goto num_index; + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + goto num_index; + case IS_TRUE: + hval = 1; + goto num_index; + case IS_FALSE: + hval = 0; + goto num_index; + case IS_NULL: + str = STR_EMPTY_ALLOC(); + goto str_index; + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + goto add_again; + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -10382,6 +10700,59 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE case IS_TRUE: hval = 1; goto num_index; + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + goto str_index; + case IS_LONG: + hval = Z_LVAL_P(key); + goto num_index; + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + goto num_index; + case IS_TRUE: + hval = 1; + goto num_index; + case IS_FALSE: + hval = 0; + goto num_index; + case IS_NULL: + str = STR_EMPTY_ALLOC(); + goto str_index; + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + goto add_again; + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -10806,6 +11177,59 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OP case IS_TRUE: hval = 1; goto num_index; + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + goto str_index; + case IS_LONG: + hval = Z_LVAL_P(key); + goto num_index; + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + goto num_index; + case IS_TRUE: + hval = 1; + goto num_index; + case IS_FALSE: + hval = 0; + goto num_index; + case IS_NULL: + str = STR_EMPTY_ALLOC(); + goto str_index; + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + goto add_again; + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -13370,6 +13794,59 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC case IS_TRUE: hval = 1; goto num_index; + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + goto str_index; + case IS_LONG: + hval = Z_LVAL_P(key); + goto num_index; + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + goto num_index; + case IS_TRUE: + hval = 1; + goto num_index; + case IS_FALSE: + hval = 0; + goto num_index; + case IS_NULL: + str = STR_EMPTY_ALLOC(); + goto str_index; + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + goto add_again; + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -14761,6 +15238,59 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP case IS_TRUE: hval = 1; goto num_index; + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + goto str_index; + case IS_LONG: + hval = Z_LVAL_P(key); + goto num_index; + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + goto num_index; + case IS_TRUE: + hval = 1; + goto num_index; + case IS_FALSE: + hval = 0; + goto num_index; + case IS_NULL: + str = STR_EMPTY_ALLOC(); + goto str_index; + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + goto add_again; + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -16205,6 +16735,59 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE case IS_TRUE: hval = 1; goto num_index; + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + goto str_index; + case IS_LONG: + hval = Z_LVAL_P(key); + goto num_index; + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + goto num_index; + case IS_TRUE: + hval = 1; + goto num_index; + case IS_FALSE: + hval = 0; + goto num_index; + case IS_NULL: + str = STR_EMPTY_ALLOC(); + goto str_index; + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + goto add_again; + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -17639,6 +18222,59 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OP case IS_TRUE: hval = 1; goto num_index; + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + goto str_index; + case IS_LONG: + hval = Z_LVAL_P(key); + goto num_index; + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + goto num_index; + case IS_TRUE: + hval = 1; + goto num_index; + case IS_FALSE: + hval = 0; + goto num_index; + case IS_NULL: + str = STR_EMPTY_ALLOC(); + goto str_index; + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + goto add_again; + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -25877,6 +26513,59 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO case IS_TRUE: hval = 1; goto num_index; + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + goto str_index; + case IS_LONG: + hval = Z_LVAL_P(key); + goto num_index; + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + goto num_index; + case IS_TRUE: + hval = 1; + goto num_index; + case IS_FALSE: + hval = 0; + goto num_index; + case IS_NULL: + str = STR_EMPTY_ALLOC(); + goto str_index; + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + goto add_again; + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -28041,6 +28730,59 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC case IS_TRUE: hval = 1; goto num_index; + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + goto str_index; + case IS_LONG: + hval = Z_LVAL_P(key); + goto num_index; + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + goto num_index; + case IS_TRUE: + hval = 1; + goto num_index; + case IS_FALSE: + hval = 0; + goto num_index; + case IS_NULL: + str = STR_EMPTY_ALLOC(); + goto str_index; + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + goto add_again; + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -29953,6 +30695,59 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_ case IS_TRUE: hval = 1; goto num_index; + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + goto str_index; + case IS_LONG: + hval = Z_LVAL_P(key); + goto num_index; + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + goto num_index; + case IS_TRUE: + hval = 1; + goto num_index; + case IS_FALSE: + hval = 0; + goto num_index; + case IS_NULL: + str = STR_EMPTY_ALLOC(); + goto str_index; + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + goto add_again; + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -31902,6 +32697,59 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPC case IS_TRUE: hval = 1; goto num_index; + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval result; + zval *key = &result; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = + &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = key; + fci.no_separation = 1; + + fcc.initialized = 1; + fcc.function_handler = + Z_OBJCE_P(offset)->__hashKey; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { + switch (Z_TYPE_P(key)) { + case IS_STRING: + str = Z_STR_P(key); + Z_DELREF_P(key); + goto str_index; + case IS_LONG: + hval = Z_LVAL_P(key); + goto num_index; + case IS_DOUBLE: + hval = zend_dval_to_lval(Z_DVAL_P(key)); + goto num_index; + case IS_TRUE: + hval = 1; + goto num_index; + case IS_FALSE: + hval = 0; + goto num_index; + case IS_NULL: + str = STR_EMPTY_ALLOC(); + goto str_index; + case IS_REFERENCE: + offset = Z_REFVAL_P(key); + goto add_again; + case IS_ARRAY: + zval_ptr_dtor(key); + /* intentionally fall through */ + } + } + } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; From d6d02f15261dfe51e5e4570e2ed44863f323d429 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Wed, 22 Oct 2014 18:44:37 +0100 Subject: [PATCH 2/3] rename toKey - rename to __hash to conform with Stas spec --- Zend/tests/hashkey/001.phpt | 4 +-- Zend/tests/hashkey/002.phpt | 4 +-- Zend/tests/hashkey/003.phpt | 4 +-- Zend/tests/hashkey/004.phpt | 4 +-- Zend/tests/hashkey/005.phpt | 4 +-- Zend/tests/hashkey/006.phpt | 4 +-- Zend/tests/hashkey/007.phpt | 4 +-- Zend/tests/hashkey/008.phpt | 4 +-- Zend/tests/hashkey/009.phpt | 4 +-- Zend/tests/hashkey/010.phpt | 4 +-- Zend/zend.h | 2 +- Zend/zend_compile.c | 7 ++-- Zend/zend_compile.h | 2 +- Zend/zend_inheritance.c | 10 +++--- Zend/zend_vm_def.h | 4 +-- Zend/zend_vm_execute.h | 64 ++++++++++++++++++------------------- 16 files changed, 65 insertions(+), 64 deletions(-) diff --git a/Zend/tests/hashkey/001.phpt b/Zend/tests/hashkey/001.phpt index a3e7eb393858d..86ea5f553a9cd 100644 --- a/Zend/tests/hashkey/001.phpt +++ b/Zend/tests/hashkey/001.phpt @@ -1,9 +1,9 @@ --TEST-- -testing hashKey returns string +testing hash returns string --FILE-- __call = NULL; ce->__callstatic = NULL; ce->__tostring = NULL; + ce->__hash = NULL; ce->create_object = NULL; ce->get_iterator = NULL; ce->iterator_funcs.funcs = NULL; @@ -4066,12 +4067,12 @@ void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_boo "public visibility and cannot be static"); } ce->__tostring = (zend_function *) op_array; - } else if (zend_string_equals_literal(lcname, ZEND_HASHKEY_FUNC_NAME)) { + } else if (zend_string_equals_literal(lcname, ZEND_HASH_FUNC_NAME)) { if (!is_public || is_static) { - zend_error(E_WARNING, "The magic method __hashKey() must have " + zend_error(E_WARNING, "The magic method __hash() must have " "public visibility and cannot be static"); } - ce->__hashKey = (zend_function *) op_array; + ce->__hash = (zend_function *) op_array; } else if (zend_string_equals_literal(lcname, ZEND_INVOKE_FUNC_NAME)) { if (!is_public || is_static) { zend_error(E_WARNING, "The magic method __invoke() must have " diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 43bf8a852a79a..96e6eb1ce2f74 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -883,7 +883,7 @@ END_EXTERN_C() #define ZEND_CALL_FUNC_NAME "__call" #define ZEND_CALLSTATIC_FUNC_NAME "__callstatic" #define ZEND_TOSTRING_FUNC_NAME "__tostring" -#define ZEND_HASHKEY_FUNC_NAME "__hashkey" +#define ZEND_HASH_FUNC_NAME "__hash" #define ZEND_AUTOLOAD_FUNC_NAME "__autoload" #define ZEND_INVOKE_FUNC_NAME "__invoke" #define ZEND_DEBUGINFO_FUNC_NAME "__debuginfo" diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 82dd75818f124..bfae43f161132 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -91,6 +91,9 @@ static void do_inherit_parent_constructor(zend_class_entry *ce TSRMLS_DC) /* {{{ if (!ce->__tostring) { ce->__tostring = ce->parent->__tostring; } + if (!ce->__hash) { + ce->__hash = ce->parent->__hash; + } if (!ce->clone) { ce->clone = ce->parent->clone; } @@ -106,9 +109,6 @@ static void do_inherit_parent_constructor(zend_class_entry *ce TSRMLS_DC) /* {{{ if (!ce->__debugInfo) { ce->__debugInfo = ce->parent->__debugInfo; } - if (!ce->__hashKey) { - ce->__hashKey = ce->parent->__hashKey; - } if (ce->constructor) { if (ce->parent->constructor && ce->parent->constructor->common.fn_flags & ZEND_ACC_FINAL) { zend_error(E_ERROR, "Cannot override final %s::%s() with %s::%s()", @@ -1015,8 +1015,8 @@ static void zend_add_magic_methods(zend_class_entry* ce, zend_string* mname, zen ce->__callstatic = fe; } else if (!strncmp(mname->val, ZEND_TOSTRING_FUNC_NAME, mname->len)) { ce->__tostring = fe; - } else if (!strncmp(mname->val, ZEND_HASHKEY_FUNC_NAME, mname->len)) { - ce->__hashKey = fe; + } else if (!strncmp(mname->val, ZEND_HASH_FUNC_NAME, mname->len)) { + ce->__hash = fe; } else if (!strncmp(mname->val, ZEND_DEBUGINFO_FUNC_NAME, mname->len)) { ce->__debugInfo = fe; } else if (ce->name->len == mname->len) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 3bc608c5999c3..3894ff92ac95b 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4108,7 +4108,7 @@ ZEND_VM_C_LABEL(str_index): case IS_TRUE: hval = 1; ZEND_VM_C_GOTO(num_index); - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -4126,7 +4126,7 @@ ZEND_VM_C_LABEL(str_index): fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 0e4be47c4e736..fe6437ffa6e37 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -4437,7 +4437,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -4455,7 +4455,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); @@ -6015,7 +6015,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_ case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -6033,7 +6033,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_ fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); @@ -7232,7 +7232,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -7250,7 +7250,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); @@ -8371,7 +8371,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_ case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -8389,7 +8389,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_ fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); @@ -9532,7 +9532,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -9550,7 +9550,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); @@ -10194,7 +10194,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -10212,7 +10212,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); @@ -10700,7 +10700,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -10718,7 +10718,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); @@ -11177,7 +11177,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OP case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -11195,7 +11195,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OP fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); @@ -13794,7 +13794,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -13812,7 +13812,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); @@ -15238,7 +15238,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -15256,7 +15256,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); @@ -16735,7 +16735,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -16753,7 +16753,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); @@ -18222,7 +18222,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OP case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -18240,7 +18240,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OP fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); @@ -26513,7 +26513,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -26531,7 +26531,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); @@ -28730,7 +28730,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -28748,7 +28748,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); @@ -30695,7 +30695,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_ case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -30713,7 +30713,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_ fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); @@ -32697,7 +32697,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPC case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hashKey) { + case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { zend_fcall_info fci; zend_fcall_info_cache fcc; zval result; @@ -32715,7 +32715,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPC fcc.initialized = 1; fcc.function_handler = - Z_OBJCE_P(offset)->__hashKey; + Z_OBJCE_P(offset)->__hash; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(offset); fcc.object = Z_OBJ_P(offset); From de2de6325ca70d294607e2b498ed1c8d28f4467b Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 26 Oct 2014 18:04:43 -0700 Subject: [PATCH 3/3] Cover more cases for object key --- Zend/tests/hashkey/011.phpt | 48 ++ Zend/zend.h | 2 +- Zend/zend_API.c | 13 + Zend/zend_API.h | 1 + Zend/zend_execute.c | 13 + Zend/zend_execute.h | 1 + Zend/zend_execute_API.c | 27 + Zend/zend_vm_def.h | 89 +-- Zend/zend_vm_execute.h | 1292 ++++++++++++----------------------- 9 files changed, 584 insertions(+), 902 deletions(-) create mode 100644 Zend/tests/hashkey/011.phpt diff --git a/Zend/tests/hashkey/011.phpt b/Zend/tests/hashkey/011.phpt new file mode 100644 index 0000000000000..f93176d355239 --- /dev/null +++ b/Zend/tests/hashkey/011.phpt @@ -0,0 +1,48 @@ +--TEST-- +testing hash returns string, different ops +--FILE-- + true, + "bar" => false, +]; + +var_dump($test); +var_dump($test[$foo]); +var_dump(isset($test[$foo])); +unset($test[$foo]); +var_dump($test); +var_dump(empty($test[$foo])); +$test[$foo] = 42; +$test[$foo]++; +var_dump($test); +?> +--EXPECT-- +array(2) { + ["Foo"]=> + bool(true) + ["bar"]=> + bool(false) +} +bool(true) +bool(true) +array(1) { + ["bar"]=> + bool(false) +} +bool(true) +array(2) { + ["bar"]=> + bool(false) + ["Foo"]=> + int(43) +} + + diff --git a/Zend/zend.h b/Zend/zend.h index 6a739de80eeb8..b61a2bdf02c22 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -135,7 +135,7 @@ struct _zend_class_entry { union _zend_function *__call; union _zend_function *__callstatic; union _zend_function *__tostring; - union _zend_function *__hash; + union _zend_function *__hash; union _zend_function *__debugInfo; union _zend_function *serialize_func; union _zend_function *unserialize_func; diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 74679c4f04aa1..ce0aaf05908e5 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1655,6 +1655,15 @@ ZEND_API zval *add_get_index_stringl(zval *arg, zend_ulong index, const char *st ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value TSRMLS_DC) /* {{{ */ { zval *result; + zval obj_key; + int free_key = 0; + + if (UNEXPECTED(Z_TYPE_P(key) == IS_OBJECT && Z_OBJCE_P(key)->__hash)) { + if (zend_object_offset(key, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + key = &obj_key; + } + } switch (Z_TYPE_P(key)) { case IS_STRING: @@ -1684,6 +1693,10 @@ ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value TSRMLS_DC) result = NULL; } + if(free_key) { + zval_dtor(&obj_key); + } + if (result) { if (Z_REFCOUNTED_P(result)) { Z_ADDREF_P(result); diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 1e031ca844fb3..80fe9eaaa79bd 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -193,6 +193,7 @@ typedef struct _zend_fcall_info_cache { class_container.__set = handle_propset; \ class_container.__unset = handle_propunset; \ class_container.__isset = handle_propisset; \ + class_container.__hash = NULL; \ class_container.__debugInfo = NULL; \ class_container.serialize_func = NULL; \ class_container.unserialize_func = NULL; \ diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 0a156f84a4189..aeaf1f46163fa 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1067,6 +1067,15 @@ static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht zval *retval; zend_string *offset_key; zend_ulong hval; + int free_key = 0; + zval obj_key; + + if (UNEXPECTED(Z_TYPE_P(dim) == IS_OBJECT && Z_OBJCE_P(dim)->__hash)) { + if (zend_object_offset(dim, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + dim = &obj_key; + } + } try_again: if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { @@ -1165,6 +1174,9 @@ static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht &EG(error_zval) : &EG(uninitialized_zval); } } + if(free_key) { + zval_dtor(&obj_key); + } return retval; } @@ -1890,6 +1902,7 @@ static zend_always_inline void zend_vm_stack_extend_call_frame(zend_execute_data } /* }}} */ + #define ZEND_VM_NEXT_OPCODE() \ CHECK_SYMBOL_TABLES() \ ZEND_VM_INC_OPCODE(); \ diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index a410f47edf38c..095784de9a216 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -233,6 +233,7 @@ ZEND_API zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, con void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC); ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *dim TSRMLS_DC); +ZEND_API int zend_object_offset(const zval *offset, zval *result TSRMLS_DC); ZEND_API zval* zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, uint32_t var); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 657a261d543ba..784b777565b0d 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1577,6 +1577,33 @@ ZEND_API int zend_set_local_var_str(const char *name, size_t len, zval *value, i } /* }}} */ +/* {{{ */ +ZEND_API int zend_object_offset(const zval *offset, zval *result TSRMLS_DC) +{ + zend_fcall_info fci; + zend_fcall_info_cache fcc; + + memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fcc, 0, sizeof(zend_fcall_info_cache)); + + fci.size = sizeof(zend_fcall_info); + fci.function_table = &Z_OBJCE_P(offset)->function_table; + fci.object = Z_OBJ_P(offset); + fci.retval = result; + fci.no_separation = 1; + ZVAL_STRING(&fci.function_name, ZEND_HASH_FUNC_NAME); + + fcc.initialized = 1; + fcc.function_handler = Z_OBJCE_P(offset)->__hash; + fcc.calling_scope = EG(scope); + fcc.called_scope = Z_OBJCE_P(offset); + fcc.object = Z_OBJ_P(offset); + + return zend_call_function(&fci, &fcc TSRMLS_CC); +} +/* }}} */ + + /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 3894ff92ac95b..eb381484f7ae4 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4078,8 +4078,17 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSE zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R); zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; ZEND_VM_C_LABEL(add_again): + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -4108,59 +4117,6 @@ ZEND_VM_C_LABEL(str_index): case IS_TRUE: hval = 1; ZEND_VM_C_GOTO(num_index); - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - ZEND_VM_C_GOTO(str_index); - case IS_LONG: - hval = Z_LVAL_P(key); - ZEND_VM_C_GOTO(num_index); - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - ZEND_VM_C_GOTO(num_index); - case IS_TRUE: - hval = 1; - ZEND_VM_C_GOTO(num_index); - case IS_FALSE: - hval = 0; - ZEND_VM_C_GOTO(num_index); - case IS_NULL: - str = STR_EMPTY_ALLOC(); - ZEND_VM_C_GOTO(str_index); - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - ZEND_VM_C_GOTO(add_again); - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); ZEND_VM_C_GOTO(add_again); @@ -4171,6 +4127,9 @@ ZEND_VM_C_LABEL(str_index): /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } FREE_OP2(); } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -4534,10 +4493,19 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMPVAR|CV) ZEND_VM_C_LABEL(unset_dim_again): if (OP1_TYPE != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; + zval obj_key; + int free_key = 0; ZEND_VM_C_LABEL(offset_again): + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } SEPARATE_ARRAY(container); ht = Z_ARRVAL_P(container); + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -4580,6 +4548,9 @@ ZEND_VM_C_LABEL(num_index_dim): zend_error(E_WARNING, "Illegal offset type in unset"); break; } + if(free_key) { + zval_dtor(offset); + } FREE_OP2(); } else if (OP1_TYPE == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { @@ -5173,8 +5144,17 @@ ZEND_VM_C_LABEL(isset_dim_obj_again): HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; + int free_key = 0; + zval obj_key; ZEND_VM_C_LABEL(isset_again): + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); if (OP2_TYPE != IS_CONST) { @@ -5214,6 +5194,9 @@ ZEND_VM_C_LABEL(num_index_prop): break; } } + if(free_key) { + zval_dtor(offset); + } if (opline->extended_value & ZEND_ISSET) { /* > IS_NULL means not IS_UNDEF and not IS_NULL */ diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index fe6437ffa6e37..67215d3ff9143 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -4407,8 +4407,17 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O zval *offset = EX_CONSTANT(opline->op2); zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; add_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -4437,59 +4446,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - goto str_index; - case IS_LONG: - hval = Z_LVAL_P(key); - goto num_index; - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - goto num_index; - case IS_TRUE: - hval = 1; - goto num_index; - case IS_FALSE: - hval = 0; - goto num_index; - case IS_NULL: - str = STR_EMPTY_ALLOC(); - goto str_index; - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - goto add_again; - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -4500,6 +4456,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -4703,8 +4662,17 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_HANDLER(ZE HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; + int free_key = 0; + zval obj_key; isset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); if (IS_CONST != IS_CONST) { @@ -4744,6 +4712,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_HANDLER(ZE break; } } + if(free_key) { + zval_dtor(offset); + } if (opline->extended_value & ZEND_ISSET) { /* > IS_NULL means not IS_UNDEF and not IS_NULL */ @@ -5985,8 +5956,17 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_ zval *offset = NULL; zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; add_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -6015,59 +5995,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_ case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - goto str_index; - case IS_LONG: - hval = Z_LVAL_P(key); - goto num_index; - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - goto num_index; - case IS_TRUE: - hval = 1; - goto num_index; - case IS_FALSE: - hval = 0; - goto num_index; - case IS_NULL: - str = STR_EMPTY_ALLOC(); - goto str_index; - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - goto add_again; - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -6078,6 +6005,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_ /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -7202,8 +7132,17 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; add_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -7232,59 +7171,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - goto str_index; - case IS_LONG: - hval = Z_LVAL_P(key); - goto num_index; - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - goto num_index; - case IS_TRUE: - hval = 1; - goto num_index; - case IS_FALSE: - hval = 0; - goto num_index; - case IS_NULL: - str = STR_EMPTY_ALLOC(); - goto str_index; - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - goto add_again; - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -7295,6 +7181,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -7352,8 +7241,17 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_HANDLER(ZEND_ HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; + int free_key = 0; + zval obj_key; isset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); if (IS_CV != IS_CONST) { @@ -7393,6 +7291,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_HANDLER(ZEND_ break; } } + if(free_key) { + zval_dtor(offset); + } if (opline->extended_value & ZEND_ISSET) { /* > IS_NULL means not IS_UNDEF and not IS_NULL */ @@ -8341,8 +8242,17 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_ zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; add_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -8371,59 +8281,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_ case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - goto str_index; - case IS_LONG: - hval = Z_LVAL_P(key); - goto num_index; - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - goto num_index; - case IS_TRUE: - hval = 1; - goto num_index; - case IS_FALSE: - hval = 0; - goto num_index; - case IS_NULL: - str = STR_EMPTY_ALLOC(); - goto str_index; - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - goto add_again; - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -8434,6 +8291,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_ /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } zval_ptr_dtor_nogc(free_op2); } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -8491,8 +8351,17 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER(Z HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; + int free_key = 0; + zval obj_key; isset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -8532,6 +8401,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER(Z break; } } + if(free_key) { + zval_dtor(offset); + } if (opline->extended_value & ZEND_ISSET) { /* > IS_NULL means not IS_UNDEF and not IS_NULL */ @@ -9502,8 +9374,17 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC zval *offset = EX_CONSTANT(opline->op2); zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; add_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -9532,59 +9413,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - goto str_index; - case IS_LONG: - hval = Z_LVAL_P(key); - goto num_index; - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - goto num_index; - case IS_TRUE: - hval = 1; - goto num_index; - case IS_FALSE: - hval = 0; - goto num_index; - case IS_NULL: - str = STR_EMPTY_ALLOC(); - goto str_index; - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - goto add_again; - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -9595,6 +9423,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -10164,8 +9995,17 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP zval *offset = NULL; zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; add_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -10194,59 +10034,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - goto str_index; - case IS_LONG: - hval = Z_LVAL_P(key); - goto num_index; - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - goto num_index; - case IS_TRUE: - hval = 1; - goto num_index; - case IS_FALSE: - hval = 0; - goto num_index; - case IS_NULL: - str = STR_EMPTY_ALLOC(); - goto str_index; - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - goto add_again; - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -10257,6 +10044,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -10670,8 +10460,17 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; add_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -10700,59 +10499,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - goto str_index; - case IS_LONG: - hval = Z_LVAL_P(key); - goto num_index; - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - goto num_index; - case IS_TRUE: - hval = 1; - goto num_index; - case IS_FALSE: - hval = 0; - goto num_index; - case IS_NULL: - str = STR_EMPTY_ALLOC(); - goto str_index; - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - goto add_again; - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -10763,6 +10509,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -11147,8 +10896,17 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OP zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; add_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -11177,59 +10935,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OP case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - goto str_index; - case IS_LONG: - hval = Z_LVAL_P(key); - goto num_index; - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - goto num_index; - case IS_TRUE: - hval = 1; - goto num_index; - case IS_FALSE: - hval = 0; - goto num_index; - case IS_NULL: - str = STR_EMPTY_ALLOC(); - goto str_index; - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - goto add_again; - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -11240,6 +10945,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OP /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } zval_ptr_dtor_nogc(free_op2); } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -13764,8 +13472,17 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC zval *offset = EX_CONSTANT(opline->op2); zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; add_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -13794,59 +13511,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - goto str_index; - case IS_LONG: - hval = Z_LVAL_P(key); - goto num_index; - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - goto num_index; - case IS_TRUE: - hval = 1; - goto num_index; - case IS_FALSE: - hval = 0; - goto num_index; - case IS_NULL: - str = STR_EMPTY_ALLOC(); - goto str_index; - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - goto add_again; - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -13857,6 +13521,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -13914,10 +13581,19 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND unset_dim_again: if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; + zval obj_key; + int free_key = 0; offset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } SEPARATE_ARRAY(container); ht = Z_ARRVAL_P(container); + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -13960,6 +13636,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND zend_error(E_WARNING, "Illegal offset type in unset"); break; } + if(free_key) { + zval_dtor(offset); + } } else if (IS_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { @@ -15208,8 +14887,17 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP zval *offset = NULL; zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; add_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -15238,59 +14926,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - goto str_index; - case IS_LONG: - hval = Z_LVAL_P(key); - goto num_index; - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - goto num_index; - case IS_TRUE: - hval = 1; - goto num_index; - case IS_FALSE: - hval = 0; - goto num_index; - case IS_NULL: - str = STR_EMPTY_ALLOC(); - goto str_index; - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - goto add_again; - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -15301,6 +14936,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -16705,8 +16343,17 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; add_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -16735,59 +16382,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - goto str_index; - case IS_LONG: - hval = Z_LVAL_P(key); - goto num_index; - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - goto num_index; - case IS_TRUE: - hval = 1; - goto num_index; - case IS_FALSE: - hval = 0; - goto num_index; - case IS_NULL: - str = STR_EMPTY_ALLOC(); - goto str_index; - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - goto add_again; - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -16798,6 +16392,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -16855,10 +16452,19 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER unset_dim_again: if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; + zval obj_key; + int free_key = 0; offset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } SEPARATE_ARRAY(container); ht = Z_ARRVAL_P(container); + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -16901,6 +16507,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER zend_error(E_WARNING, "Illegal offset type in unset"); break; } + if(free_key) { + zval_dtor(offset); + } } else if (IS_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { @@ -18192,8 +17801,17 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OP zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; add_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -18222,59 +17840,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OP case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - goto str_index; - case IS_LONG: - hval = Z_LVAL_P(key); - goto num_index; - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - goto num_index; - case IS_TRUE: - hval = 1; - goto num_index; - case IS_FALSE: - hval = 0; - goto num_index; - case IS_NULL: - str = STR_EMPTY_ALLOC(); - goto str_index; - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - goto add_again; - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -18285,6 +17850,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OP /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } zval_ptr_dtor_nogc(free_op2); } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -18342,10 +17910,19 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HAN unset_dim_again: if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; + zval obj_key; + int free_key = 0; offset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } SEPARATE_ARRAY(container); ht = Z_ARRVAL_P(container); + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -18388,6 +17965,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HAN zend_error(E_WARNING, "Illegal offset type in unset"); break; } + if(free_key) { + zval_dtor(offset); + } zval_ptr_dtor_nogc(free_op2); } else if (IS_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { @@ -19632,10 +19212,19 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H unset_dim_again: if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; + zval obj_key; + int free_key = 0; offset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } SEPARATE_ARRAY(container); ht = Z_ARRVAL_P(container); + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -19678,6 +19267,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H zend_error(E_WARNING, "Illegal offset type in unset"); break; } + if(free_key) { + zval_dtor(offset); + } } else if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { @@ -19757,8 +19349,17 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_CONST_HANDLER(Z HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; + int free_key = 0; + zval obj_key; isset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); if (IS_CONST != IS_CONST) { @@ -19798,6 +19399,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_CONST_HANDLER(Z break; } } + if(free_key) { + zval_dtor(offset); + } if (opline->extended_value & ZEND_ISSET) { /* > IS_NULL means not IS_UNDEF and not IS_NULL */ @@ -21715,10 +21319,19 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND unset_dim_again: if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; + zval obj_key; + int free_key = 0; offset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } SEPARATE_ARRAY(container); ht = Z_ARRVAL_P(container); + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -21761,6 +21374,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND zend_error(E_WARNING, "Illegal offset type in unset"); break; } + if(free_key) { + zval_dtor(offset); + } } else if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { @@ -21840,8 +21456,17 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; + int free_key = 0; + zval obj_key; isset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); if (IS_CV != IS_CONST) { @@ -21881,6 +21506,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND break; } } + if(free_key) { + zval_dtor(offset); + } if (opline->extended_value & ZEND_ISSET) { /* > IS_NULL means not IS_UNDEF and not IS_NULL */ @@ -23100,10 +22728,19 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_ unset_dim_again: if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; + zval obj_key; + int free_key = 0; offset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } SEPARATE_ARRAY(container); ht = Z_ARRVAL_P(container); + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -23146,6 +22783,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_ zend_error(E_WARNING, "Illegal offset type in unset"); break; } + if(free_key) { + zval_dtor(offset); + } zval_ptr_dtor_nogc(free_op2); } else if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { @@ -23226,8 +22866,17 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_TMPVAR_HANDLER( HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; + int free_key = 0; + zval obj_key; isset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -23267,6 +22916,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_TMPVAR_HANDLER( break; } } + if(free_key) { + zval_dtor(offset); + } if (opline->extended_value & ZEND_ISSET) { /* > IS_NULL means not IS_UNDEF and not IS_NULL */ @@ -26483,8 +26135,17 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO zval *offset = EX_CONSTANT(opline->op2); zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; add_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -26513,59 +26174,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - goto str_index; - case IS_LONG: - hval = Z_LVAL_P(key); - goto num_index; - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - goto num_index; - case IS_TRUE: - hval = 1; - goto num_index; - case IS_FALSE: - hval = 0; - goto num_index; - case IS_NULL: - str = STR_EMPTY_ALLOC(); - goto str_index; - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - goto add_again; - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -26576,6 +26184,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -26708,10 +26319,19 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL unset_dim_again: if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; + zval obj_key; + int free_key = 0; offset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } SEPARATE_ARRAY(container); ht = Z_ARRVAL_P(container); + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -26754,6 +26374,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL zend_error(E_WARNING, "Illegal offset type in unset"); break; } + if(free_key) { + zval_dtor(offset); + } } else if (IS_CV == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { @@ -26904,8 +26527,17 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER(ZEND_ HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; + int free_key = 0; + zval obj_key; isset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); if (IS_CONST != IS_CONST) { @@ -26945,6 +26577,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER(ZEND_ break; } } + if(free_key) { + zval_dtor(offset); + } if (opline->extended_value & ZEND_ISSET) { /* > IS_NULL means not IS_UNDEF and not IS_NULL */ @@ -28700,8 +28335,17 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC zval *offset = NULL; zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; add_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -28730,59 +28374,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - goto str_index; - case IS_LONG: - hval = Z_LVAL_P(key); - goto num_index; - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - goto num_index; - case IS_TRUE: - hval = 1; - goto num_index; - case IS_FALSE: - hval = 0; - goto num_index; - case IS_NULL: - str = STR_EMPTY_ALLOC(); - goto str_index; - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - goto add_again; - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -28793,6 +28384,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -30665,8 +30259,17 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_ zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; add_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -30695,59 +30298,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_ case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - goto str_index; - case IS_LONG: - hval = Z_LVAL_P(key); - goto num_index; - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - goto num_index; - case IS_TRUE: - hval = 1; - goto num_index; - case IS_FALSE: - hval = 0; - goto num_index; - case IS_NULL: - str = STR_EMPTY_ALLOC(); - goto str_index; - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - goto add_again; - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -30758,6 +30308,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_ /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -30815,10 +30368,19 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ unset_dim_again: if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; + zval obj_key; + int free_key = 0; offset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } SEPARATE_ARRAY(container); ht = Z_ARRVAL_P(container); + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -30861,6 +30423,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ zend_error(E_WARNING, "Illegal offset type in unset"); break; } + if(free_key) { + zval_dtor(offset); + } } else if (IS_CV == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { @@ -30940,8 +30505,17 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPC HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; + int free_key = 0; + zval obj_key; isset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); if (IS_CV != IS_CONST) { @@ -30981,6 +30555,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPC break; } } + if(free_key) { + zval_dtor(offset); + } if (opline->extended_value & ZEND_ISSET) { /* > IS_NULL means not IS_UNDEF and not IS_NULL */ @@ -32667,8 +32244,17 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPC zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); zend_string *str; zend_ulong hval; + zval obj_key; + int free_key = 0; add_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -32697,59 +32283,6 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPC case IS_TRUE: hval = 1; goto num_index; - case IS_OBJECT: if (Z_OBJCE_P(offset)->__hash) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval result; - zval *key = &result; - - memset(&fci, 0, sizeof(zend_fcall_info)); - memset(&fcc, 0, sizeof(zend_fcall_info_cache)); - - fci.size = sizeof(zend_fcall_info); - fci.function_table = - &Z_OBJCE_P(offset)->function_table; - fci.object = Z_OBJ_P(offset); - fci.retval = key; - fci.no_separation = 1; - - fcc.initialized = 1; - fcc.function_handler = - Z_OBJCE_P(offset)->__hash; - fcc.calling_scope = EG(scope); - fcc.called_scope = Z_OBJCE_P(offset); - fcc.object = Z_OBJ_P(offset); - - if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS) { - switch (Z_TYPE_P(key)) { - case IS_STRING: - str = Z_STR_P(key); - Z_DELREF_P(key); - goto str_index; - case IS_LONG: - hval = Z_LVAL_P(key); - goto num_index; - case IS_DOUBLE: - hval = zend_dval_to_lval(Z_DVAL_P(key)); - goto num_index; - case IS_TRUE: - hval = 1; - goto num_index; - case IS_FALSE: - hval = 0; - goto num_index; - case IS_NULL: - str = STR_EMPTY_ALLOC(); - goto str_index; - case IS_REFERENCE: - offset = Z_REFVAL_P(key); - goto add_again; - case IS_ARRAY: - zval_ptr_dtor(key); - /* intentionally fall through */ - } - } - } case IS_REFERENCE: offset = Z_REFVAL_P(offset); goto add_again; @@ -32760,6 +32293,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPC /* do nothing */ break; } + if(free_key) { + zval_dtor(offset); + } zval_ptr_dtor_nogc(free_op2); } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); @@ -32817,10 +32353,19 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HAND unset_dim_again: if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; + zval obj_key; + int free_key = 0; offset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } SEPARATE_ARRAY(container); ht = Z_ARRVAL_P(container); + switch (Z_TYPE_P(offset)) { case IS_DOUBLE: hval = zend_dval_to_lval(Z_DVAL_P(offset)); @@ -32863,6 +32408,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HAND zend_error(E_WARNING, "Illegal offset type in unset"); break; } + if(free_key) { + zval_dtor(offset); + } zval_ptr_dtor_nogc(free_op2); } else if (IS_CV == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { @@ -32943,8 +32491,17 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; + int free_key = 0; + zval obj_key; isset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -32984,6 +32541,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND break; } } + if(free_key) { + zval_dtor(offset); + } if (opline->extended_value & ZEND_ISSET) { /* > IS_NULL means not IS_UNDEF and not IS_NULL */ @@ -34462,8 +34022,17 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER(Z HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; + int free_key = 0; + zval obj_key; isset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); if (IS_CONST != IS_CONST) { @@ -34503,6 +34072,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER(Z break; } } + if(free_key) { + zval_dtor(offset); + } if (opline->extended_value & ZEND_ISSET) { /* > IS_NULL means not IS_UNDEF and not IS_NULL */ @@ -35778,8 +35350,17 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; + int free_key = 0; + zval obj_key; isset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); if (IS_CV != IS_CONST) { @@ -35819,6 +35400,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND break; } } + if(free_key) { + zval_dtor(offset); + } if (opline->extended_value & ZEND_ISSET) { /* > IS_NULL means not IS_UNDEF and not IS_NULL */ @@ -36421,8 +36005,17 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER( HashTable *ht = Z_ARRVAL_P(container); zval *value; zend_string *str; + int free_key = 0; + zval obj_key; isset_again: + if(UNEXPECTED(Z_TYPE_P(offset) == IS_OBJECT && Z_OBJCE_P(offset)->__hash)) { + if(zend_object_offset(offset, &obj_key TSRMLS_CC) == SUCCESS) { + free_key = 1; + offset = &obj_key; + } + } + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -36462,6 +36055,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER( break; } } + if(free_key) { + zval_dtor(offset); + } if (opline->extended_value & ZEND_ISSET) { /* > IS_NULL means not IS_UNDEF and not IS_NULL */