From: Dmitry Stogov Date: Wed, 8 Apr 2009 13:19:34 +0000 (+0000) Subject: Improved specialization (IS_CONST can't be IS_OBJECT) X-Git-Tag: php-5.3.0RC2~193 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ae2226133a289675d1d5dad0f16c8da0f2222245;p=php Improved specialization (IS_CONST can't be IS_OBJECT) --- diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 24c51f39f6..b4ee7be7cb 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -899,7 +899,8 @@ ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMP|VAR|CV, ANY) zval z_copy; zval *z = GET_OP1_ZVAL_PTR(BP_VAR_R); - if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && + if (OP1_TYPE != IS_CONST && + Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) { zend_print_variable(&z_copy); zval_dtor(&z_copy); @@ -1892,31 +1893,26 @@ ZEND_VM_HANDLER(56, ZEND_ADD_VAR, TMP|UNUSED, TMP|VAR|CV) ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMP|VAR|UNUSED|CV) { zend_op *opline = EX(opline); - zval *class_name; - zend_free_op free_op2; if (OP2_TYPE == IS_UNUSED) { EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); - } - - class_name = GET_OP2_ZVAL_PTR(BP_VAR_R); + } else { + zend_free_op free_op2; + zval *class_name = GET_OP2_ZVAL_PTR(BP_VAR_R); - switch (Z_TYPE_P(class_name)) { - case IS_OBJECT: + if (OP2_TYPE != IS_CONST && Z_TYPE_P(class_name) == IS_OBJECT) { EX_T(opline->result.u.var).class_entry = Z_OBJCE_P(class_name); - break; - case IS_STRING: + } else if (Z_TYPE_P(class_name) == IS_STRING) { EX_T(opline->result.u.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC); - break; - default: + } else { zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string"); - break; - } + } - FREE_OP2(); - ZEND_VM_NEXT_OPCODE(); + FREE_OP2(); + ZEND_VM_NEXT_OPCODE(); + } } ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) @@ -2090,7 +2086,8 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV) } else { function_name = GET_OP2_ZVAL_PTR(BP_VAR_R); - if (Z_TYPE_P(function_name) == IS_OBJECT && + if (OP2_TYPE != IS_CONST && + Z_TYPE_P(function_name) == IS_OBJECT && Z_OBJ_HANDLER_P(function_name, get_closure) && Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) { if (EX(object)) { @@ -2524,7 +2521,7 @@ ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY) value = GET_OP1_ZVAL_PTR(BP_VAR_R); - if (Z_TYPE_P(value) != IS_OBJECT) { + if (OP1_TYPE == IS_CONST || Z_TYPE_P(value) != IS_OBJECT) { zend_error_noreturn(E_ERROR, "Can only throw objects"); } zend_exception_save(TSRMLS_C); @@ -2936,7 +2933,9 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY) zend_function *clone; zend_object_clone_obj_t clone_call; - if (!obj || Z_TYPE_P(obj) != IS_OBJECT) { + if (OP1_TYPE == IS_CONST || + (OP1_TYPE == IS_VAR && !obj) || + Z_TYPE_P(obj) != IS_OBJECT) { zend_error_noreturn(E_ERROR, "__clone method called on non-object"); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index fe902cb244..bf3419ffc1 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -709,30 +709,25 @@ static int ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); - zval *class_name; - if (IS_CONST == IS_UNUSED) { EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); - } + } else { - class_name = &opline->op2.u.constant; + zval *class_name = &opline->op2.u.constant; - switch (Z_TYPE_P(class_name)) { - case IS_OBJECT: + if (IS_CONST != IS_CONST && Z_TYPE_P(class_name) == IS_OBJECT) { EX_T(opline->result.u.var).class_entry = Z_OBJCE_P(class_name); - break; - case IS_STRING: + } else if (Z_TYPE_P(class_name) == IS_STRING) { EX_T(opline->result.u.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC); - break; - default: + } else { zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string"); - break; - } + } - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE(); + } } static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -752,7 +747,8 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE } else { function_name = &opline->op2.u.constant; - if (Z_TYPE_P(function_name) == IS_OBJECT && + if (IS_CONST != IS_CONST && + Z_TYPE_P(function_name) == IS_OBJECT && Z_OBJ_HANDLER_P(function_name, get_closure) && Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) { if (EX(object)) { @@ -905,31 +901,26 @@ static int ZEND_FASTCALL ZEND_ADD_INTERFACE_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); - zval *class_name; - zend_free_op free_op2; if (IS_TMP_VAR == IS_UNUSED) { EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); - } - - class_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + } else { + zend_free_op free_op2; + zval *class_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); - switch (Z_TYPE_P(class_name)) { - case IS_OBJECT: + if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(class_name) == IS_OBJECT) { EX_T(opline->result.u.var).class_entry = Z_OBJCE_P(class_name); - break; - case IS_STRING: + } else if (Z_TYPE_P(class_name) == IS_STRING) { EX_T(opline->result.u.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC); - break; - default: + } else { zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string"); - break; - } + } - zval_dtor(free_op2.var); - ZEND_VM_NEXT_OPCODE(); + zval_dtor(free_op2.var); + ZEND_VM_NEXT_OPCODE(); + } } static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -949,7 +940,8 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H } else { function_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); - if (Z_TYPE_P(function_name) == IS_OBJECT && + if (IS_TMP_VAR != IS_CONST && + Z_TYPE_P(function_name) == IS_OBJECT && Z_OBJ_HANDLER_P(function_name, get_closure) && Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) { if (EX(object)) { @@ -1010,31 +1002,26 @@ static int ZEND_FASTCALL ZEND_CONT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); - zval *class_name; - zend_free_op free_op2; if (IS_VAR == IS_UNUSED) { EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); - } - - class_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + } else { + zend_free_op free_op2; + zval *class_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); - switch (Z_TYPE_P(class_name)) { - case IS_OBJECT: + if (IS_VAR != IS_CONST && Z_TYPE_P(class_name) == IS_OBJECT) { EX_T(opline->result.u.var).class_entry = Z_OBJCE_P(class_name); - break; - case IS_STRING: + } else if (Z_TYPE_P(class_name) == IS_STRING) { EX_T(opline->result.u.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC); - break; - default: + } else { zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string"); - break; - } + } - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; - ZEND_VM_NEXT_OPCODE(); + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + ZEND_VM_NEXT_OPCODE(); + } } static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -1054,7 +1041,8 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H } else { function_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); - if (Z_TYPE_P(function_name) == IS_OBJECT && + if (IS_VAR != IS_CONST && + Z_TYPE_P(function_name) == IS_OBJECT && Z_OBJ_HANDLER_P(function_name, get_closure) && Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) { if (EX(object)) { @@ -1115,59 +1103,49 @@ static int ZEND_FASTCALL ZEND_CONT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); - zval *class_name; - if (IS_UNUSED == IS_UNUSED) { EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); - } + } else { - class_name = NULL; + zval *class_name = NULL; - switch (Z_TYPE_P(class_name)) { - case IS_OBJECT: + if (IS_UNUSED != IS_CONST && Z_TYPE_P(class_name) == IS_OBJECT) { EX_T(opline->result.u.var).class_entry = Z_OBJCE_P(class_name); - break; - case IS_STRING: + } else if (Z_TYPE_P(class_name) == IS_STRING) { EX_T(opline->result.u.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC); - break; - default: + } else { zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string"); - break; - } + } - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE(); + } } static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); - zval *class_name; - if (IS_CV == IS_UNUSED) { EX_T(opline->result.u.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); - } + } else { - class_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval *class_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); - switch (Z_TYPE_P(class_name)) { - case IS_OBJECT: + if (IS_CV != IS_CONST && Z_TYPE_P(class_name) == IS_OBJECT) { EX_T(opline->result.u.var).class_entry = Z_OBJCE_P(class_name); - break; - case IS_STRING: + } else if (Z_TYPE_P(class_name) == IS_STRING) { EX_T(opline->result.u.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC); - break; - default: + } else { zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string"); - break; - } + } - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE(); + } } static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -1187,7 +1165,8 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA } else { function_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); - if (Z_TYPE_P(function_name) == IS_OBJECT && + if (IS_CV != IS_CONST && + Z_TYPE_P(function_name) == IS_OBJECT && Z_OBJ_HANDLER_P(function_name, get_closure) && Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) { if (EX(object)) { @@ -1312,7 +1291,8 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval z_copy; zval *z = &opline->op1.u.constant; - if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && + if (IS_CONST != IS_CONST && + Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) { zend_print_variable(&z_copy); zval_dtor(&z_copy); @@ -1704,7 +1684,7 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS value = &opline->op1.u.constant; - if (Z_TYPE_P(value) != IS_OBJECT) { + if (IS_CONST == IS_CONST || Z_TYPE_P(value) != IS_OBJECT) { zend_error_noreturn(E_ERROR, "Can only throw objects"); } zend_exception_save(TSRMLS_C); @@ -1767,7 +1747,9 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_function *clone; zend_object_clone_obj_t clone_call; - if (!obj || Z_TYPE_P(obj) != IS_OBJECT) { + if (IS_CONST == IS_CONST || + (IS_CONST == IS_VAR && !obj) || + Z_TYPE_P(obj) != IS_OBJECT) { zend_error_noreturn(E_ERROR, "__clone method called on non-object"); } @@ -4589,7 +4571,8 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval z_copy; zval *z = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && + if (IS_TMP_VAR != IS_CONST && + Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) { zend_print_variable(&z_copy); zval_dtor(&z_copy); @@ -4972,7 +4955,7 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) value = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - if (Z_TYPE_P(value) != IS_OBJECT) { + if (IS_TMP_VAR == IS_CONST || Z_TYPE_P(value) != IS_OBJECT) { zend_error_noreturn(E_ERROR, "Can only throw objects"); } zend_exception_save(TSRMLS_C); @@ -5036,7 +5019,9 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_function *clone; zend_object_clone_obj_t clone_call; - if (!obj || Z_TYPE_P(obj) != IS_OBJECT) { + if (IS_TMP_VAR == IS_CONST || + (IS_TMP_VAR == IS_VAR && !obj) || + Z_TYPE_P(obj) != IS_OBJECT) { zend_error_noreturn(E_ERROR, "__clone method called on non-object"); } @@ -7832,7 +7817,8 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval z_copy; zval *z = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && + if (IS_VAR != IS_CONST && + Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) { zend_print_variable(&z_copy); zval_dtor(&z_copy); @@ -8209,7 +8195,7 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) value = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - if (Z_TYPE_P(value) != IS_OBJECT) { + if (IS_VAR == IS_CONST || Z_TYPE_P(value) != IS_OBJECT) { zend_error_noreturn(E_ERROR, "Can only throw objects"); } zend_exception_save(TSRMLS_C); @@ -8388,7 +8374,9 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_function *clone; zend_object_clone_obj_t clone_call; - if (!obj || Z_TYPE_P(obj) != IS_OBJECT) { + if (IS_VAR == IS_CONST || + (IS_VAR == IS_VAR && !obj) || + Z_TYPE_P(obj) != IS_OBJECT) { zend_error_noreturn(E_ERROR, "__clone method called on non-object"); } @@ -16922,7 +16910,9 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_function *clone; zend_object_clone_obj_t clone_call; - if (!obj || Z_TYPE_P(obj) != IS_OBJECT) { + if (IS_UNUSED == IS_CONST || + (IS_UNUSED == IS_VAR && !obj) || + Z_TYPE_P(obj) != IS_OBJECT) { zend_error_noreturn(E_ERROR, "__clone method called on non-object"); } @@ -21736,7 +21726,8 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval z_copy; zval *z = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); - if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && + if (IS_CV != IS_CONST && + Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL && zend_std_cast_object_tostring(z, &z_copy, IS_STRING TSRMLS_CC) == SUCCESS) { zend_print_variable(&z_copy); zval_dtor(&z_copy); @@ -22112,7 +22103,7 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) value = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); - if (Z_TYPE_P(value) != IS_OBJECT) { + if (IS_CV == IS_CONST || Z_TYPE_P(value) != IS_OBJECT) { zend_error_noreturn(E_ERROR, "Can only throw objects"); } zend_exception_save(TSRMLS_C); @@ -22281,7 +22272,9 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_function *clone; zend_object_clone_obj_t clone_call; - if (!obj || Z_TYPE_P(obj) != IS_OBJECT) { + if (IS_CV == IS_CONST || + (IS_CV == IS_VAR && !obj) || + Z_TYPE_P(obj) != IS_OBJECT) { zend_error_noreturn(E_ERROR, "__clone method called on non-object"); }