Skip to content

Commit 4a15c54

Browse files
committed
Support for FFI pointer math
1 parent 3011ba5 commit 4a15c54

File tree

3 files changed

+28
-3
lines changed

3 files changed

+28
-3
lines changed

ext/opcache/jit/zend_jit.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,17 @@ static bool zend_jit_ffi_compatible(zend_ffi_type *dst_type, uint32_t src_info,
122122
}
123123
return false;
124124
}
125+
126+
static bool zend_jit_ffi_compatible_addr_op(zend_ffi_type *dst_type, uint32_t src_info, zend_ffi_type *src_type, uint8_t opcode)
127+
{
128+
if (dst_type->kind == ZEND_FFI_TYPE_POINTER
129+
&& ZEND_FFI_TYPE(dst_type->pointer.type)->size != 0
130+
&& src_info == MAY_BE_LONG
131+
&& (opcode == ZEND_ADD || opcode == ZEND_SUB)) {
132+
return true;
133+
}
134+
return false;
135+
}
125136
#endif
126137

127138
#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP

ext/opcache/jit/zend_jit_ir.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14350,6 +14350,17 @@ static int zend_jit_ffi_assign_op_helper(zend_jit_ctx *jit,
1435014350
}
1435114351
break;
1435214352
#endif
14353+
case ZEND_FFI_TYPE_POINTER:
14354+
ZEND_ASSERT(opcode == ZEND_ADD || opcode == ZEND_SUB);
14355+
ZEND_ASSERT(ZEND_FFI_TYPE(el_type->pointer.type)->size != 0);
14356+
type = IR_ADDR;
14357+
if (op2_info == MAY_BE_LONG) {
14358+
op2 = ir_MUL_A(jit_Z_LVAL(jit, op2_addr), ir_CONST_LONG(ZEND_FFI_TYPE(el_type->pointer.type)->size));
14359+
} else {
14360+
ZEND_UNREACHABLE();
14361+
return 0;
14362+
}
14363+
break;
1435314364
default:
1435414365
ZEND_UNREACHABLE();
1435514366
return 0;

ext/opcache/jit/zend_jit_trace.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4721,7 +4721,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
47214721
if (op1_ffi_type
47224722
&& (op1_ffi_type->kind == ZEND_FFI_TYPE_ARRAY || op1_ffi_type->kind == ZEND_FFI_TYPE_POINTER)
47234723
&& op2_info == MAY_BE_LONG
4724-
&& zend_jit_ffi_compatible(op1_ffi_type->array.type, op1_data_info, op3_ffi_type)) {
4724+
&& (zend_jit_ffi_compatible(op1_ffi_type->array.type, op1_data_info, op3_ffi_type)
4725+
|| zend_jit_ffi_compatible_addr_op(op1_ffi_type->array.type, op1_data_info, op3_ffi_type, opline->extended_value))) {
47254726
if (!ffi_info) {
47264727
ffi_info = zend_arena_calloc(&CG(arena), ssa->vars_count, sizeof(zend_jit_ffi_info));
47274728
}
@@ -4926,7 +4927,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
49264927
if (field
49274928
&& !field->is_const
49284929
&& !field->bits
4929-
&& zend_jit_ffi_compatible(field->type, op1_data_info, op3_ffi_type)) {
4930+
&& (zend_jit_ffi_compatible(field->type, op1_data_info, op3_ffi_type)
4931+
|| zend_jit_ffi_compatible_addr_op(field->type, op1_data_info, op3_ffi_type, opline->extended_value))) {
49304932
if (!ffi_info) {
49314933
ffi_info = zend_arena_calloc(&CG(arena), ssa->vars_count, sizeof(zend_jit_ffi_info));
49324934
}
@@ -4943,7 +4945,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
49434945
Z_STR_P(RT_CONSTANT(opline, opline->op2)));
49444946
if (sym
49454947
&& sym->kind == ZEND_FFI_SYM_VAR
4946-
&& zend_jit_ffi_compatible(sym->type, op1_data_info, op3_ffi_type)) {
4948+
&& (zend_jit_ffi_compatible(sym->type, op1_data_info, op3_ffi_type)
4949+
|| zend_jit_ffi_compatible_addr_op(sym->type, op1_data_info, op3_ffi_type, opline->extended_value))) {
49474950
if (!ffi_info) {
49484951
ffi_info = zend_arena_calloc(&CG(arena), ssa->vars_count, sizeof(zend_jit_ffi_info));
49494952
}

0 commit comments

Comments
 (0)