summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/tests/closure_extra_args.phpt11
-rw-r--r--Zend/zend_vm_def.h6
-rw-r--r--Zend/zend_vm_execute.h12
3 files changed, 26 insertions, 3 deletions
diff --git a/Zend/tests/closure_extra_args.phpt b/Zend/tests/closure_extra_args.phpt
new file mode 100644
index 0000000000..05712e06c6
--- /dev/null
+++ b/Zend/tests/closure_extra_args.phpt
@@ -0,0 +1,11 @@
+--TEST--
+Immediately invoked closure with extra args
+--FILE--
+<?php
+
+(function() {})(new stdClass);
+
+?>
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index c10f9d6169..aa7a80c95c 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2909,13 +2909,17 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
zend_clean_and_cache_symbol_table(EX(symbol_table));
}
EG(current_execute_data) = EX(prev_execute_data);
+
+ /* Free extra args before releasing the closure,
+ * as that may free the op_array. */
+ zend_vm_stack_free_extra_args_ex(call_info, execute_data);
+
if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
OBJ_RELEASE(Z_OBJ(execute_data->This));
} else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
}
- zend_vm_stack_free_extra_args_ex(call_info, execute_data);
old_execute_data = execute_data;
execute_data = EX(prev_execute_data);
zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 6ac1d09e8f..6bc3bb2e94 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1173,13 +1173,17 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper
zend_clean_and_cache_symbol_table(EX(symbol_table));
}
EG(current_execute_data) = EX(prev_execute_data);
+
+ /* Free extra args before releasing the closure,
+ * as that may free the op_array. */
+ zend_vm_stack_free_extra_args_ex(call_info, execute_data);
+
if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
OBJ_RELEASE(Z_OBJ(execute_data->This));
} else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
}
- zend_vm_stack_free_extra_args_ex(call_info, execute_data);
old_execute_data = execute_data;
execute_data = EX(prev_execute_data);
zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);
@@ -53366,13 +53370,17 @@ zend_leave_helper_SPEC_LABEL:
zend_clean_and_cache_symbol_table(EX(symbol_table));
}
EG(current_execute_data) = EX(prev_execute_data);
+
+ /* Free extra args before releasing the closure,
+ * as that may free the op_array. */
+ zend_vm_stack_free_extra_args_ex(call_info, execute_data);
+
if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
OBJ_RELEASE(Z_OBJ(execute_data->This));
} else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) {
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func)));
}
- zend_vm_stack_free_extra_args_ex(call_info, execute_data);
old_execute_data = execute_data;
execute_data = EX(prev_execute_data);
zend_vm_stack_free_call_frame_ex(call_info, old_execute_data);