Skip to content

Commit a77dbb7

Browse files
committed
Support for FFI pointer assignment
1 parent cc9d068 commit a77dbb7

File tree

3 files changed

+57
-3
lines changed

3 files changed

+57
-3
lines changed

ext/opcache/jit/zend_jit.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,26 @@ static bool zend_jit_ffi_compatible(zend_ffi_type *dst_type, uint32_t src_info,
123123
return false;
124124
}
125125

126+
static bool zend_jit_ffi_compatible_addr(zend_ffi_type *dst_type, uint32_t src_info, zend_ffi_type *src_type)
127+
{
128+
if (dst_type->kind == ZEND_FFI_TYPE_POINTER) {
129+
if (src_info == MAY_BE_NULL) {
130+
return true;
131+
} else if (src_type
132+
&& src_type->kind == ZEND_FFI_TYPE_POINTER
133+
&& (dst_type == src_type
134+
|| ZEND_FFI_TYPE(dst_type->pointer.type) == ZEND_FFI_TYPE(src_type->pointer.type)
135+
|| ZEND_FFI_TYPE(dst_type->pointer.type)->kind == ZEND_FFI_TYPE_VOID
136+
|| ZEND_FFI_TYPE(src_type->pointer.type)->kind == ZEND_FFI_TYPE_VOID
137+
// TODO: calls between shared extensions doesn't work on Windows
138+
// || zend_ffi_is_compatible_type(dst_type, src_type)
139+
)) {
140+
return true;
141+
}
142+
}
143+
return false;
144+
}
145+
126146
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)
127147
{
128148
if (dst_type->kind == ZEND_FFI_TYPE_POINTER

ext/opcache/jit/zend_jit_ir.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14009,6 +14009,25 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
1400914009
}
1401014010
break;
1401114011
#endif
14012+
case ZEND_FFI_TYPE_POINTER:
14013+
if (val_info == MAY_BE_NULL) {
14014+
ref = IR_NULL;
14015+
} else if (val_ffi_type
14016+
&& val_ffi_type->kind == ZEND_FFI_TYPE_POINTER
14017+
&& (val_ffi_type == ffi_type
14018+
|| ZEND_FFI_TYPE(val_ffi_type->pointer.type) == ZEND_FFI_TYPE(ffi_type->pointer.type)
14019+
|| ZEND_FFI_TYPE(val_ffi_type->pointer.type)->kind == ZEND_FFI_TYPE_VOID
14020+
|| ZEND_FFI_TYPE(ffi_type->pointer.type)->kind == ZEND_FFI_TYPE_VOID)) {
14021+
ref = ir_LOAD_A(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr)));
14022+
} else {
14023+
ZEND_UNREACHABLE();
14024+
}
14025+
ir_STORE(ptr, ref);
14026+
if (res_addr) {
14027+
ir_CALL_3(IR_VOID, ir_CONST_FC_FUNC(zend_jit_zval_ffi_ptr),
14028+
jit_ZVAL_ADDR(jit, res_addr), ir_CONST_ADDR(ffi_type), ref);
14029+
}
14030+
break;
1401214031
default:
1401314032
ZEND_UNREACHABLE();
1401414033
}
@@ -14067,6 +14086,8 @@ static int zend_jit_ffi_assign_dim(zend_jit_ctx *jit,
1406714086
return 0;
1406814087
}
1406914088

14089+
jit_FREE_OP(jit, (opline+1)->op1_type, (opline+1)->op1, val_info, opline);
14090+
1407014091
return 1;
1407114092
}
1407214093
#endif
@@ -14504,6 +14525,8 @@ static int zend_jit_ffi_assign_dim_op(zend_jit_ctx *jit,
1450414525
return 0;
1450514526
}
1450614527

14528+
jit_FREE_OP(jit, (opline+1)->op1_type, (opline+1)->op1, op1_data_info, opline);
14529+
1450714530
return 1;
1450814531
}
1450914532
#endif
@@ -15578,6 +15601,8 @@ static int zend_jit_ffi_assign_obj(zend_jit_ctx *jit,
1557815601
return 0;
1557915602
}
1558015603

15604+
jit_FREE_OP(jit, (opline+1)->op1_type, (opline+1)->op1, val_info, opline);
15605+
1558115606
if (!op1_indirect) {
1558215607
jit_FREE_OP(jit, opline->op1_type, opline->op1, op1_info, opline);
1558315608
}
@@ -15624,6 +15649,8 @@ static int zend_jit_ffi_assign_sym(zend_jit_ctx *jit,
1562415649
return 0;
1562515650
}
1562615651

15652+
jit_FREE_OP(jit, (opline+1)->op1_type, (opline+1)->op1, val_info, opline);
15653+
1562715654
if (!op1_indirect) {
1562815655
jit_FREE_OP(jit, opline->op1_type, opline->op1, op1_info, opline);
1562915656
}
@@ -16015,6 +16042,8 @@ static int zend_jit_ffi_assign_obj_op(zend_jit_ctx *jit,
1601516042
return 0;
1601616043
}
1601716044

16045+
jit_FREE_OP(jit, (opline+1)->op1_type, (opline+1)->op1, val_info, opline);
16046+
1601816047
if (!op1_indirect) {
1601916048
jit_FREE_OP(jit, opline->op1_type, opline->op1, op1_info, opline);
1602016049
}
@@ -16048,6 +16077,8 @@ static int zend_jit_ffi_assign_sym_op(zend_jit_ctx *jit,
1604816077
return 0;
1604916078
}
1605016079

16080+
jit_FREE_OP(jit, (opline+1)->op1_type, (opline+1)->op1, val_info, opline);
16081+
1605116082
if (!op1_indirect) {
1605216083
jit_FREE_OP(jit, opline->op1_type, opline->op1, op1_info, opline);
1605316084
}

ext/opcache/jit/zend_jit_trace.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5051,7 +5051,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
50515051
if (field
50525052
&& !field->is_const
50535053
&& !field->bits
5054-
&& zend_jit_ffi_compatible(field->type, op1_data_info, op3_ffi_type)) {
5054+
&& (zend_jit_ffi_compatible(field->type, op1_data_info, op3_ffi_type)
5055+
|| zend_jit_ffi_compatible_addr(field->type, op1_data_info, op3_ffi_type))) {
50555056
if (!ffi_info) {
50565057
ffi_info = zend_arena_calloc(&CG(arena), ssa->vars_count, sizeof(zend_jit_ffi_info));
50575058
}
@@ -5074,7 +5075,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
50745075
Z_STR_P(RT_CONSTANT(opline, opline->op2)));
50755076
if (sym
50765077
&& sym->kind == ZEND_FFI_SYM_VAR
5077-
&& zend_jit_ffi_compatible(sym->type, op1_data_info, op3_ffi_type)) {
5078+
&& (zend_jit_ffi_compatible(sym->type, op1_data_info, op3_ffi_type)
5079+
|| zend_jit_ffi_compatible_addr(sym->type, op1_data_info, op3_ffi_type))) {
50785080
if (!ffi_info) {
50795081
ffi_info = zend_arena_calloc(&CG(arena), ssa->vars_count, sizeof(zend_jit_ffi_info));
50805082
}
@@ -5150,7 +5152,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
51505152
if (op1_ffi_type
51515153
&& (op1_ffi_type->kind == ZEND_FFI_TYPE_ARRAY || op1_ffi_type->kind == ZEND_FFI_TYPE_POINTER)
51525154
&& op2_info == MAY_BE_LONG
5153-
&& zend_jit_ffi_compatible(op1_ffi_type->array.type, op1_data_info, op3_ffi_type)) {
5155+
&& (zend_jit_ffi_compatible(op1_ffi_type->array.type, op1_data_info, op3_ffi_type)
5156+
|| zend_jit_ffi_compatible_addr(op1_ffi_type->array.type, op1_data_info, op3_ffi_type))) {
51545157
if (!ffi_info) {
51555158
ffi_info = zend_arena_calloc(&CG(arena), ssa->vars_count, sizeof(zend_jit_ffi_info));
51565159
}

0 commit comments

Comments
 (0)