summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/opcache/jit/zend_jit_x86.dasc5
-rw-r--r--ext/opcache/tests/jit/send_ref_001.phpt26
2 files changed, 30 insertions, 1 deletions
diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc
index c689359272..a6f9edecc3 100644
--- a/ext/opcache/jit/zend_jit_x86.dasc
+++ b/ext/opcache/jit/zend_jit_x86.dasc
@@ -10136,13 +10136,16 @@ static int zend_jit_send_ref(dasm_State **Dst, const zend_op *opline, const zend
|2:
| // ZVAL_NEW_REF(arg, varptr);
if (opline->op1_type == IS_VAR) {
+ if (Z_REG(op1_addr) != ZREG_R0 || Z_OFFSET(op1_addr) != 0) {
+ | LOAD_ZVAL_ADDR r0, op1_addr
+ }
| mov aword T1, r0 // save
}
| EMALLOC sizeof(zend_reference), op_array, opline
| mov dword [r0], 2
| mov dword [r0 + offsetof(zend_reference, gc.u.type_info)], GC_REFERENCE
| mov aword [r0 + offsetof(zend_reference, sources.ptr)], 0
- ref_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 8);
+ ref_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, offsetof(zend_reference, val));
if (opline->op1_type == IS_VAR) {
zend_jit_addr val_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R1, 0);
diff --git a/ext/opcache/tests/jit/send_ref_001.phpt b/ext/opcache/tests/jit/send_ref_001.phpt
new file mode 100644
index 0000000000..55a2359038
--- /dev/null
+++ b/ext/opcache/tests/jit/send_ref_001.phpt
@@ -0,0 +1,26 @@
+--TEST--
+JIT SEND_REF: 001
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.file_update_protection=0
+opcache.jit_buffer_size=1M
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+function foo(&$obj) {
+}
+class A {
+ function foo() {
+ for ($i = 0; $i < 10; $i++) {
+ foo($this);
+ }
+ echo "ok\n";
+ }
+}
+$a = new A;
+$a->foo();
+?>
+--EXPECT--
+ok