]> granicus.if.org Git - php/commitdiff
Don't check type of simple parameter default values
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 8 Oct 2019 15:29:41 +0000 (17:29 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 8 Oct 2019 15:29:41 +0000 (17:29 +0200)
After fixing the int->double coercion case, this is already verified
at compile-time, so there is no need to redo this type check on
every call.

Only perform the type check every time for the case of AST default
values.

Zend/zend_compile.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 255b89d95f065896c9dd916f1f55148643c3a868..ce37710dd09e90a7e9cfee863ed1cda940af7ceb 100644 (file)
@@ -5392,10 +5392,6 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
                        op_array->required_num_args = i + 1;
                }
 
-               opline = zend_emit_op(NULL, opcode, NULL, &default_node);
-               SET_NODE(opline->result, &var_node);
-               opline->op1.num = i + 1;
-
                arg_info = &arg_infos[i];
                arg_info->name = zend_string_copy(name);
                arg_info->pass_by_reference = is_ref;
@@ -5443,6 +5439,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
                                                                zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
                                                                        "with a float type can only be float, integer, or NULL");
                                                        }
+                                                       convert_to_double(&default_node.u.constant);
                                                        break;
 
                                                case IS_ITERABLE:
@@ -5467,7 +5464,13 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
                                        }
                                }
                        }
+               }
 
+               opline = zend_emit_op(NULL, opcode, NULL, &default_node);
+               SET_NODE(opline->result, &var_node);
+               opline->op1.num = i + 1;
+
+               if (type_ast) {
                        /* Allocate cache slot to speed-up run-time class resolution */
                        if (opline->opcode == ZEND_RECV_INIT) {
                                if (ZEND_TYPE_IS_CLASS(arg_info->type)) {
index 649b07d36ebc27ed9fb389c327f0790d8335e55c..0c1ab106b3e7b4bce5873c683be11d10f7625b79 100644 (file)
@@ -5248,17 +5248,19 @@ ZEND_VM_HOT_HANDLER(64, ZEND_RECV_INIT, NUM, CONST, CACHE_SLOT)
                                        ZVAL_COPY_VALUE(cache_val, param);
                                }
                        }
+                       ZEND_VM_C_GOTO(recv_init_check_type);
                } else {
                        ZVAL_COPY(param, default_value);
                }
-       }
-
-       if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
-               zval *default_value = RT_CONSTANT(opline, opline->op2);
+       } else {
+ZEND_VM_C_LABEL(recv_init_check_type):
+               if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
+                       zval *default_value = RT_CONSTANT(opline, opline->op2);
 
-               SAVE_OPLINE();
-               if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(opline->extended_value)))) {
-                       HANDLE_EXCEPTION();
+                       SAVE_OPLINE();
+                       if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(opline->extended_value)))) {
+                               HANDLE_EXCEPTION();
+                       }
                }
        }
 
index b4a59dff0e7278b5951242f68be5ae9767e6980e..f1b46fbd97d007e39ff73a193e335b9d923feeb3 100644 (file)
@@ -3051,17 +3051,19 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CON
                                        ZVAL_COPY_VALUE(cache_val, param);
                                }
                        }
+                       goto recv_init_check_type;
                } else {
                        ZVAL_COPY(param, default_value);
                }
-       }
-
-       if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
-               zval *default_value = RT_CONSTANT(opline, opline->op2);
+       } else {
+recv_init_check_type:
+               if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
+                       zval *default_value = RT_CONSTANT(opline, opline->op2);
 
-               SAVE_OPLINE();
-               if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(opline->extended_value)))) {
-                       HANDLE_EXCEPTION();
+                       SAVE_OPLINE();
+                       if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param, default_value, CACHE_ADDR(opline->extended_value)))) {
+                               HANDLE_EXCEPTION();
+                       }
                }
        }