From: Xinchen Hui Date: Sun, 15 Apr 2012 03:40:38 +0000 (+0800) Subject: Implement const array/string dereference X-Git-Tag: php-5.5.0alpha1~300 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=565892d4c09ff39e96d1de16a22be21242bb83e9;p=php Implement const array/string dereference RFC:https://wiki.php.net/rfc/constdereference --- diff --git a/NEWS b/NEWS index 6aa804cab7..ecfaa9385d 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ PHP NEWS . Drop Windows XP and 2003 support. (Pierre) . World domination . Improve set_exception_handler while doing reset.(Laruence) + . Support constant array/string dereferencing. (Laruence) - Core: . Implemented FR #60738 (Allow 'set_error_handler' to handle NULL). diff --git a/UPGRADING b/UPGRADING index 575ff1b750..d6d6e9bb73 100755 --- a/UPGRADING +++ b/UPGRADING @@ -26,6 +26,8 @@ PHP X.Y UPGRADE NOTES 2. New Features ======================================== +- Support constant array/string dereferencing. (Laruence) + (https://wiki.php.net/rfc/constdereference) ======================================== 2. Changes in SAPI modules diff --git a/Zend/tests/const_dereference_001.phpt b/Zend/tests/const_dereference_001.phpt new file mode 100644 index 0000000000..5fe6e4d433 --- /dev/null +++ b/Zend/tests/const_dereference_001.phpt @@ -0,0 +1,21 @@ +--TEST-- +Const array deference +--FILE-- + +--EXPECTF-- +int(4) + +Notice: Undefined index: foo in %sconst_dereference_001.php on line %d +NULL +int(6) +123 diff --git a/Zend/tests/const_dereference_002.phpt b/Zend/tests/const_dereference_002.phpt new file mode 100644 index 0000000000..ff89519755 --- /dev/null +++ b/Zend/tests/const_dereference_002.phpt @@ -0,0 +1,18 @@ +--TEST-- +Const string dereference +--FILE-- + +--EXPECTF-- +int(4) + +Notice: Undefined index: foo in %sconst_dereference_003.php on line %d +NULL +int(6) +123 diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index d0730b75d6..893e0133ef 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -789,8 +789,8 @@ expr_without_variable: | T_EXIT exit_expr { zend_do_exit(&$$, &$2 TSRMLS_CC); } | '@' { zend_do_begin_silence(&$1 TSRMLS_CC); } expr { zend_do_end_silence(&$1 TSRMLS_CC); $$ = $3; } | scalar { $$ = $1; } - | T_ARRAY '(' array_pair_list ')' { $$ = $3; } - | '[' array_pair_list ']' { $$ = $2; } + | combined_scalar_offset { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); } + | combined_scalar { $$ = $1; } | '`' backticks_expr '`' { zend_do_shell_exec(&$$, &$2 TSRMLS_CC); } | T_PRINT expr { zend_do_print(&$$, &$2 TSRMLS_CC); } | function is_reference '(' { zend_do_begin_lambda_function_declaration(&$$, &$1, $2.op_type, 0 TSRMLS_CC); } @@ -799,6 +799,15 @@ expr_without_variable: parameter_list ')' lexical_vars '{' inner_statement_list '}' { zend_do_end_function_declaration(&$2 TSRMLS_CC); $$ = $5; } ; +combined_scalar_offset: + combined_scalar '[' dim_offset ']' { zend_do_begin_variable_parse(TSRMLS_C); fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); } + | combined_scalar_offset '[' dim_offset ']' { fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); } + | T_CONSTANT_ENCAPSED_STRING '[' dim_offset ']' { zend_do_begin_variable_parse(TSRMLS_C); fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); } + +combined_scalar: + T_ARRAY '(' array_pair_list ')' { $$ = $3; } + | '[' array_pair_list ']' { $$ = $2; } + function: T_FUNCTION { $$.u.op.opline_num = CG(zend_lineno); } ; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 8cceb19d83..7b13b440fa 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1174,7 +1174,7 @@ ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_IS); } -ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, VAR|CV, CONST|TMP|VAR|CV) +ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) { USE_OPLINE zend_free_op free_op1, free_op2; @@ -1187,10 +1187,19 @@ ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, VAR|CV, CONST|TMP|VAR|CV) EX_T(opline->op1.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); } - container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); - FREE_OP2(); - FREE_OP1_VAR_PTR(); + + if (OP1_TYPE == IS_TMP_VAR || OP1_TYPE == IS_CONST) { + zval *container = GET_OP1_ZVAL_PTR(BP_VAR_R); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); + FREE_OP2(); + FREE_OP1(); + } else { + container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); + FREE_OP2(); + FREE_OP1_VAR_PTR(); + } + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 68ba74b440..2096c44e66 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3374,6 +3374,36 @@ static int ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HAN return zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } +static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval **container; + + SAVE_OPLINE(); + + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && + IS_CONST != IS_CV && + EX_T(opline->op1.var).var.ptr_ptr) { + PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); + } + + if (IS_CONST == IS_TMP_VAR || IS_CONST == IS_CONST) { + zval *container = opline->op1.zv; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); + + + } else { + container = NULL; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); + + + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -4200,6 +4230,36 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDL ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval **container; + + SAVE_OPLINE(); + + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && + IS_CONST != IS_CV && + EX_T(opline->op1.var).var.ptr_ptr) { + PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); + } + + if (IS_CONST == IS_TMP_VAR || IS_CONST == IS_CONST) { + zval *container = opline->op1.zv; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); + zval_dtor(free_op2.var); + + } else { + container = NULL; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); + zval_dtor(free_op2.var); + + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -4874,6 +4934,36 @@ static int ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL return zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } +static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op2; + zval **container; + + SAVE_OPLINE(); + + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && + IS_CONST != IS_CV && + EX_T(opline->op1.var).var.ptr_ptr) { + PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); + } + + if (IS_CONST == IS_TMP_VAR || IS_CONST == IS_CONST) { + zval *container = opline->op1.zv; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + + } else { + container = NULL; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -6104,6 +6194,36 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLE ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval **container; + + SAVE_OPLINE(); + + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && + IS_CONST != IS_CV && + EX_T(opline->op1.var).var.ptr_ptr) { + PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); + } + + if (IS_CONST == IS_TMP_VAR || IS_CONST == IS_CONST) { + zval *container = opline->op1.zv; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); + + + } else { + container = NULL; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); + + + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -7840,6 +7960,36 @@ static int ZEND_FASTCALL ZEND_FETCH_IS_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDL return zend_fetch_var_address_helper_SPEC_TMP_CONST(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } +static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval **container; + + SAVE_OPLINE(); + + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && + IS_TMP_VAR != IS_CV && + EX_T(opline->op1.var).var.ptr_ptr) { + PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); + } + + if (IS_TMP_VAR == IS_TMP_VAR || IS_TMP_VAR == IS_CONST) { + zval *container = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); + + zval_dtor(free_op1.var); + } else { + container = NULL; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); + + + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -8534,6 +8684,36 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval **container; + + SAVE_OPLINE(); + + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && + IS_TMP_VAR != IS_CV && + EX_T(opline->op1.var).var.ptr_ptr) { + PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); + } + + if (IS_TMP_VAR == IS_TMP_VAR || IS_TMP_VAR == IS_CONST) { + zval *container = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); + zval_dtor(free_op2.var); + zval_dtor(free_op1.var); + } else { + container = NULL; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); + zval_dtor(free_op2.var); + + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -9208,6 +9388,36 @@ static int ZEND_FASTCALL ZEND_FETCH_IS_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER return zend_fetch_var_address_helper_SPEC_TMP_VAR(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } +static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1, free_op2; + zval **container; + + SAVE_OPLINE(); + + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && + IS_TMP_VAR != IS_CV && + EX_T(opline->op1.var).var.ptr_ptr) { + PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); + } + + if (IS_TMP_VAR == IS_TMP_VAR || IS_TMP_VAR == IS_CONST) { + zval *container = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + zval_dtor(free_op1.var); + } else { + container = NULL; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -10304,6 +10514,36 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ ZEND_VM_NEXT_OPCODE(); } +static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_free_op free_op1; + zval **container; + + SAVE_OPLINE(); + + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && + IS_TMP_VAR != IS_CV && + EX_T(opline->op1.var).var.ptr_ptr) { + PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); + } + + if (IS_TMP_VAR == IS_TMP_VAR || IS_TMP_VAR == IS_CONST) { + zval *container = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); + + zval_dtor(free_op1.var); + } else { + container = NULL; + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); + + + } + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -12858,10 +13098,19 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA EX_T(opline->op1.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); } - container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (IS_VAR == IS_TMP_VAR || IS_VAR == IS_CONST) { + zval *container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); + + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + } else { + container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); + + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + } + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15025,10 +15274,19 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND EX_T(opline->op1.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); } - container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); - zval_dtor(free_op2.var); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + + if (IS_VAR == IS_TMP_VAR || IS_VAR == IS_CONST) { + zval *container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); + zval_dtor(free_op2.var); + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + } else { + container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); + zval_dtor(free_op2.var); + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + } + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17106,10 +17364,19 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND EX_T(opline->op1.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); } - container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + + if (IS_VAR == IS_TMP_VAR || IS_VAR == IS_CONST) { + zval *container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + } else { + container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + } + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20222,10 +20489,19 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL EX_T(opline->op1.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); } - container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + if (IS_VAR == IS_TMP_VAR || IS_VAR == IS_CONST) { + zval *container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); + + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + } else { + container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); + + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + } + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -28655,10 +28931,19 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN EX_T(opline->op1.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); } - container = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); + + if (IS_CV == IS_TMP_VAR || IS_CV == IS_CONST) { + zval *container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); + + + } else { + container = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC); + } + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -30601,9 +30886,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL EX_T(opline->op1.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); } - container = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); - zval_dtor(free_op2.var); + + if (IS_CV == IS_TMP_VAR || IS_CV == IS_CONST) { + zval *container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); + zval_dtor(free_op2.var); + + } else { + container = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC); + zval_dtor(free_op2.var); + + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -32553,9 +32847,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL EX_T(opline->op1.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); } - container = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + + if (IS_CV == IS_TMP_VAR || IS_CV == IS_CONST) { + zval *container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + + } else { + container = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC); + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -35400,9 +35703,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE EX_T(opline->op1.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); } - container = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); + if (IS_CV == IS_TMP_VAR || IS_CV == IS_CONST) { + zval *container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); + + + } else { + container = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC); + zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC); + + + } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -38520,16 +38832,16 @@ void zend_init_opcodes_handlers(void) ZEND_FETCH_R_SPEC_CV_VAR_HANDLER, ZEND_FETCH_R_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER, + ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER, + ZEND_FETCH_DIM_R_SPEC_CONST_VAR_HANDLER, ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER, + ZEND_FETCH_DIM_R_SPEC_TMP_CONST_HANDLER, + ZEND_FETCH_DIM_R_SPEC_TMP_TMP_HANDLER, + ZEND_FETCH_DIM_R_SPEC_TMP_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_FETCH_DIM_R_SPEC_TMP_CV_HANDLER, ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER, ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER, ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER,