|
27 | 27 | #include <ZendAccelerator.h> |
28 | 28 | #include "Optimizer/zend_func_info.h" |
29 | 29 | #include "Optimizer/zend_call_graph.h" |
| 30 | +#include "zend_partial.h" |
30 | 31 | #include "zend_jit.h" |
31 | 32 |
|
32 | 33 | #include "zend_jit_internal.h" |
@@ -59,6 +60,8 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_nested_func_helper(ZEND_OPC |
59 | 60 | OBJ_RELEASE(Z_OBJ(execute_data->This)); |
60 | 61 | } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { |
61 | 62 | OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); |
| 63 | + } else if (UNEXPECTED(call_info & ZEND_CALL_FAKE_CLOSURE)) { |
| 64 | + OBJ_RELEASE(ZEND_PARTIAL_OBJECT(EX(func))); |
62 | 65 | } |
63 | 66 | if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { |
64 | 67 | zend_free_extra_named_params(EX(extra_named_params)); |
@@ -100,6 +103,8 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_top_func_helper(ZEND_OPCODE |
100 | 103 | } |
101 | 104 | if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { |
102 | 105 | OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); |
| 106 | + } else if (UNEXPECTED(call_info & ZEND_CALL_FAKE_CLOSURE)) { |
| 107 | + OBJ_RELEASE(ZEND_PARTIAL_OBJECT(EX(func))); |
103 | 108 | } |
104 | 109 | execute_data = EG(current_execute_data); |
105 | 110 | #ifdef HAVE_GCC_GLOBAL_REGS |
@@ -692,7 +697,9 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, |
692 | 697 | (zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(op_array); |
693 | 698 | offset = jit_extension->offset; |
694 | 699 | if (!op_array->function_name |
695 | | - || (op_array->fn_flags & ZEND_ACC_CLOSURE)) { |
| 700 | + || (op_array->fn_flags & (ZEND_ACC_CLOSURE|ZEND_ACC_FAKE_CLOSURE))) { |
| 701 | + /* op_array is a copy that may be freed during tracing. Also, it |
| 702 | + * may be bound to a custom scope. Fetch the original op_array. */ |
696 | 703 | op_array = jit_extension->op_array; |
697 | 704 | } |
698 | 705 |
|
@@ -977,7 +984,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, |
977 | 984 | TRACE_RECORD(ZEND_JIT_TRACE_DO_ICALL, 0, func); |
978 | 985 | } |
979 | 986 | } else if (opline->opcode == ZEND_INCLUDE_OR_EVAL |
980 | | - || opline->opcode == ZEND_CALLABLE_CONVERT) { |
| 987 | + || opline->opcode == ZEND_CALLABLE_CONVERT |
| 988 | + || opline->opcode == ZEND_CALLABLE_CONVERT_PARTIAL) { |
981 | 989 | /* TODO: Support tracing JIT for ZEND_CALLABLE_CONVERT. */ |
982 | 990 | stop = ZEND_JIT_TRACE_STOP_INTERPRETER; |
983 | 991 | break; |
@@ -1016,7 +1024,9 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, |
1016 | 1024 | } |
1017 | 1025 | offset = jit_extension->offset; |
1018 | 1026 | if (!op_array->function_name |
1019 | | - || (op_array->fn_flags & ZEND_ACC_CLOSURE)) { |
| 1027 | + || (op_array->fn_flags & (ZEND_ACC_CLOSURE|ZEND_ACC_FAKE_CLOSURE))) { |
| 1028 | + /* op_array is a copy that may be freed during tracing. Also, it |
| 1029 | + * may be bound to a custom scope. Fetch the original op_array. */ |
1020 | 1030 | op_array = jit_extension->op_array; |
1021 | 1031 | } |
1022 | 1032 |
|
|
0 commit comments