@@ -3212,7 +3212,6 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
3212
3212
3213
3213
if (op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - MAY_BE_LONG)) {
3214
3214
| // if (EXPECTED(Z_TYPE_P(dim) == IS_LONG))
3215
- | brk #0 // TODO
3216
3215
| IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >3, TMP1w, TMP2
3217
3216
}
3218
3217
if (op1_info & MAY_BE_PACKED_GUARD) {
@@ -3240,7 +3239,6 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
3240
3239
} else {
3241
3240
if (!op2_loaded) {
3242
3241
| // hval = Z_LVAL_P(dim);
3243
- | brk #0 // TODO
3244
3242
| GET_ZVAL_LVAL ZREG_FCARG2x, op2_addr, TMP1
3245
3243
op2_loaded = 1;
3246
3244
}
@@ -3303,7 +3301,34 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
3303
3301
case BP_VAR_R:
3304
3302
case BP_VAR_IS:
3305
3303
case BP_VAR_UNSET:
3304
+ if (packed_loaded) {
3305
+ | brk #0 // TODO
3306
+ }
3307
+ if (!(op1_info & MAY_BE_ARRAY_KEY_LONG) || (packed_loaded && (op1_info & MAY_BE_ARRAY_HASH))) {
3308
+ | brk #0 // TODO
3309
+ }
3310
+ if (op1_info & MAY_BE_ARRAY_HASH) {
3311
+ |4:
3312
+ if (!op2_loaded) {
3313
+ | brk #0 // TODO
3314
+ }
3315
+ | EXT_CALL _zend_hash_index_find, REG0
3316
+ | mov REG0, RETVALx
3317
+ | tst REG0, REG0
3318
+ if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) {
3319
+ | brk #0 // TODO
3320
+ } else if (type == BP_VAR_IS && not_found_exit_addr) {
3321
+ | brk #0 // TODO
3322
+ } else if (type == BP_VAR_IS && found_exit_addr) {
3323
+ | brk #0 // TODO
3324
+ } else {
3325
+ | beq >2 // NOT_FOUND
3326
+ }
3327
+ }
3328
+ |.cold_code
3329
+ |2:
3306
3330
| brk #0 // TODO
3331
+ |.code
3307
3332
break;
3308
3333
case BP_VAR_RW:
3309
3334
| brk #0 // TODO
@@ -3336,7 +3361,6 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
3336
3361
}
3337
3362
3338
3363
if (type != BP_JIT_IS && (op2_info & MAY_BE_STRING)) {
3339
- | brk #0 // TODO
3340
3364
| b >8
3341
3365
}
3342
3366
}
@@ -3345,7 +3369,6 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
3345
3369
|3:
3346
3370
if (op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - (MAY_BE_LONG|MAY_BE_STRING))) {
3347
3371
| // if (EXPECTED(Z_TYPE_P(dim) == IS_STRING))
3348
- | brk #0 // TODO
3349
3372
| IF_NOT_ZVAL_TYPE op2_addr, IS_STRING, >3, TMP1w, TMP2
3350
3373
}
3351
3374
| // offset_key = Z_STR_P(dim);
@@ -3358,7 +3381,36 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
3358
3381
case BP_VAR_R:
3359
3382
case BP_VAR_IS:
3360
3383
case BP_VAR_UNSET:
3361
- | brk #0 // TODO
3384
+ if (opline->op2_type != IS_CONST) {
3385
+ | ldrb TMP1w, [FCARG2x, #offsetof(zend_string, val)]
3386
+ | cmp TMP1w, #((uint8_t) ('9'))
3387
+ | ble >1
3388
+ |.cold_code
3389
+ |1:
3390
+ | EXT_CALL zend_jit_symtable_find, REG0
3391
+ | b >1
3392
+ |.code
3393
+ | EXT_CALL zend_hash_find, REG0
3394
+ |1:
3395
+ } else {
3396
+ | brk #0 // TODO
3397
+ | EXT_CALL _zend_hash_find_known_hash, REG0
3398
+ }
3399
+ | mov REG0, RETVALx
3400
+ | tst REG0, REG0
3401
+ if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) {
3402
+ | brk #0 // TODO
3403
+ } else if (type == BP_VAR_IS && not_found_exit_addr) {
3404
+ | brk #0 // TODO
3405
+ } else if (type == BP_VAR_IS && found_exit_addr) {
3406
+ | brk #0 // TODO
3407
+ } else {
3408
+ | beq >2 // NOT_FOUND
3409
+ |.cold_code
3410
+ |2:
3411
+ | brk #0 // TODO
3412
+ |.code
3413
+ }
3362
3414
break;
3363
3415
case BP_VAR_RW:
3364
3416
| brk #0 // TODO
@@ -3386,7 +3438,34 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
3386
3438
|.cold_code
3387
3439
|3:
3388
3440
}
3389
- | brk #0 // TODO
3441
+ | SET_EX_OPLINE opline, REG0
3442
+ | LOAD_ZVAL_ADDR FCARG2x, op2_addr
3443
+ switch (type) {
3444
+ case BP_VAR_R:
3445
+ | LOAD_ZVAL_ADDR CARG3, res_addr
3446
+ | EXT_CALL zend_jit_fetch_dim_r_helper, REG0
3447
+ | mov REG0, RETVALx
3448
+ | b >9
3449
+ break;
3450
+ case BP_JIT_IS:
3451
+ | brk #0 // TODO
3452
+ break;
3453
+ case BP_VAR_IS:
3454
+ case BP_VAR_UNSET:
3455
+ | brk #0 // TODO
3456
+ break;
3457
+ case BP_VAR_RW:
3458
+ | brk #0 // TODO
3459
+ break;
3460
+ case BP_VAR_W:
3461
+ | brk #0 // TODO
3462
+ break;
3463
+ default:
3464
+ ZEND_UNREACHABLE();
3465
+ }
3466
+ if (op2_info & (MAY_BE_LONG|MAY_BE_STRING)) {
3467
+ |.code
3468
+ }
3390
3469
}
3391
3470
3392
3471
return 1;
@@ -5381,10 +5460,9 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
5381
5460
| // zend_vm_stack_free_call_frame(call);
5382
5461
| ldrb TMP1w, [RX, #(offsetof(zend_execute_data, This.u1.type_info) + 2)]
5383
5462
| tst TMP1w, #((ZEND_CALL_ALLOCATED >> 16) & 0xff)
5384
- | bne >1 // TODO: test. In current case, don't jump to cold-code.
5463
+ | bne >1
5385
5464
|.cold_code
5386
5465
|1:
5387
- | brk #0 // TODO
5388
5466
| mov FCARG1x, RX
5389
5467
| EXT_CALL zend_jit_free_call_frame, REG0
5390
5468
| b >1
@@ -6102,7 +6180,149 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst,
6102
6180
orig_op1_addr = OP1_ADDR();
6103
6181
op2_addr = OP2_ADDR();
6104
6182
6105
- | brk #0 // TODO
6183
+ if (opline->opcode != ZEND_FETCH_DIM_IS
6184
+ && JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
6185
+ int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
6186
+ exit_addr = zend_jit_trace_get_exit_addr(exit_point);
6187
+ if (!exit_addr) {
6188
+ return 0;
6189
+ }
6190
+ }
6191
+
6192
+ if ((res_info & MAY_BE_GUARD)
6193
+ && JIT_G(current_frame)
6194
+ && (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) {
6195
+ uint32_t flags = 0;
6196
+ uint32_t old_op1_info = 0;
6197
+ uint32_t old_info;
6198
+ zend_jit_trace_stack *stack = JIT_G(current_frame)->stack;
6199
+ int32_t exit_point;
6200
+
6201
+ if (opline->opcode != ZEND_FETCH_LIST_R
6202
+ && (opline->op1_type & (IS_VAR|IS_TMP_VAR))
6203
+ && !op1_avoid_refcounting) {
6204
+ flags |= ZEND_JIT_EXIT_FREE_OP1;
6205
+ }
6206
+ if ((opline->op2_type & (IS_VAR|IS_TMP_VAR))
6207
+ && (op2_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
6208
+ flags |= ZEND_JIT_EXIT_FREE_OP2;
6209
+ }
6210
+ if ((opline->result_type & (IS_VAR|IS_TMP_VAR))
6211
+ && !(flags & ZEND_JIT_EXIT_FREE_OP1)
6212
+ && (res_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))
6213
+ && (ssa_op+1)->op1_use == ssa_op->result_def
6214
+ && !(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF) - (MAY_BE_STRING|MAY_BE_LONG)))
6215
+ && zend_jit_may_avoid_refcounting(opline+1)) {
6216
+ result_avoid_refcounting = 1;
6217
+ ssa->var_info[ssa_op->result_def].avoid_refcounting = 1;
6218
+ }
6219
+
6220
+ if (op1_avoid_refcounting) {
6221
+ old_op1_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->op1.var));
6222
+ SET_STACK_REG(stack, EX_VAR_TO_NUM(opline->op1.var), ZREG_NONE);
6223
+ }
6224
+
6225
+ if (!(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF) - (MAY_BE_STRING|MAY_BE_LONG)))) {
6226
+ old_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var));
6227
+ SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->result.var), IS_UNKNOWN, 1);
6228
+ SET_STACK_REG(stack, EX_VAR_TO_NUM(opline->result.var), ZREG_ZVAL_COPY_GPR0);
6229
+ exit_point = zend_jit_trace_get_exit_point(opline+1, flags);
6230
+ SET_STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var), old_info);
6231
+ res_exit_addr = zend_jit_trace_get_exit_addr(exit_point);
6232
+ if (!res_exit_addr) {
6233
+ return 0;
6234
+ }
6235
+ res_info &= ~MAY_BE_GUARD;
6236
+ ssa->var_info[ssa_op->result_def].type &= ~MAY_BE_GUARD;
6237
+ }
6238
+
6239
+ if (opline->opcode == ZEND_FETCH_DIM_IS
6240
+ && !(res_info & MAY_BE_NULL)) {
6241
+ old_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var));
6242
+ SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->result.var), IS_NULL, 0);
6243
+ SET_STACK_REG(stack, EX_VAR_TO_NUM(opline->result.var), ZREG_NULL);
6244
+ exit_point = zend_jit_trace_get_exit_point(opline+1, flags);
6245
+ SET_STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var), old_info);
6246
+ not_found_exit_addr = zend_jit_trace_get_exit_addr(exit_point);
6247
+ if (!not_found_exit_addr) {
6248
+ return 0;
6249
+ }
6250
+ }
6251
+
6252
+ if (op1_avoid_refcounting) {
6253
+ SET_STACK_INFO(stack, EX_VAR_TO_NUM(opline->op1.var), old_op1_info);
6254
+ }
6255
+ }
6256
+
6257
+ if (op1_info & MAY_BE_REF) {
6258
+ | brk #0 // TODO
6259
+ op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1x, 0);
6260
+ }
6261
+
6262
+ if (op1_info & MAY_BE_ARRAY) {
6263
+ if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - MAY_BE_ARRAY)) {
6264
+ | brk #0 // TODO
6265
+ }
6266
+ | GET_ZVAL_LVAL ZREG_FCARG1x, op1_addr, TMP1
6267
+ if (!zend_jit_fetch_dimension_address_inner(Dst, opline, (opline->opcode != ZEND_FETCH_DIM_IS) ? BP_VAR_R : BP_VAR_IS, op1_info, op2_info, res_exit_addr, not_found_exit_addr, exit_addr)) {
6268
+ return 0;
6269
+ }
6270
+ }
6271
+
6272
+ if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_ARRAY)) {
6273
+ if (op1_info & MAY_BE_ARRAY) {
6274
+ |.cold_code
6275
+ |7:
6276
+ }
6277
+
6278
+ | brk #0 // TODO
6279
+
6280
+ if (op1_info & MAY_BE_ARRAY) {
6281
+ |.code
6282
+ }
6283
+ }
6284
+
6285
+ if (op1_info & MAY_BE_ARRAY) {
6286
+ zend_jit_addr val_addr = ZEND_ADDR_MEM_ZVAL(ZREG_REG0, 0);
6287
+
6288
+ |8:
6289
+ if (res_exit_addr) {
6290
+ zend_uchar type = concrete_type(res_info);
6291
+
6292
+ | brk #0 // TODO
6293
+ } else if (op1_info & MAY_BE_ARRAY_OF_REF) {
6294
+ | brk #0 // TODO
6295
+ if (!zend_jit_zval_copy_deref(Dst, res_addr, val_addr, ZREG_REG2)) {
6296
+ return 0;
6297
+ }
6298
+ } else {
6299
+ | // ZVAL_COPY
6300
+ | ZVAL_COPY_VALUE res_addr, -1, val_addr, res_info, ZREG_REG1, ZREG_REG2, ZREG_TMP1, ZREG_TMP2, ZREG_FPR0
6301
+ | lsr REG1w, REG1w, #8
6302
+ | and REG1w, REG1w, #0xff
6303
+ | TRY_ADDREF res_info, REG1w, REG2, TMP1
6304
+ }
6305
+ }
6306
+ |9: // END
6307
+
6308
+ #ifdef ZEND_JIT_USE_RC_INFERENCE
6309
+ if ((opline->op2_type & (IS_TMP_VAR|IS_VAR)) && (op1_info & MAY_BE_OBJECT)) {
6310
+ /* Magic offsetGet() may increase refcount of the key */
6311
+ op2_info |= MAY_BE_RCN;
6312
+ }
6313
+ #endif
6314
+
6315
+ | FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline
6316
+ if (opline->opcode != ZEND_FETCH_LIST_R && !op1_avoid_refcounting) {
6317
+ | FREE_OP opline->op1_type, opline->op1, op1_info, 0, opline
6318
+ }
6319
+
6320
+ if (may_throw) {
6321
+ if (!zend_jit_check_exception(Dst)) {
6322
+ return 0;
6323
+ }
6324
+ }
6325
+
6106
6326
return 1;
6107
6327
}
6108
6328
0 commit comments