@@ -2315,13 +2315,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_
23152315
23162316static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
23172317{
2318+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: start: %s\n", ZSTR_VAL(EX(call)->func->common.function_name));
23182319 USE_OPLINE
23192320 zval *args;
23202321
23212322 SAVE_OPLINE();
2323+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: before get args\n");
23222324 args = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R);
2325+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: after get args\n");
23232326
23242327 if (UNEXPECTED(Z_TYPE_P(args) != IS_ARRAY)) {
2328+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: args not an array\n");
23252329 if ((opline->op1_type & (IS_VAR|IS_CV)) && Z_ISREF_P(args)) {
23262330 args = Z_REFVAL_P(args);
23272331 if (EXPECTED(Z_TYPE_P(args) == IS_ARRAY)) {
@@ -2333,21 +2337,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_O
23332337 FREE_OP(opline->op1_type, opline->op1.var);
23342338 HANDLE_EXCEPTION();
23352339 } else {
2340+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: args looks like an array\n");
23362341 uint32_t arg_num;
23372342 HashTable *ht;
23382343 zval *arg, *param;
23392344
23402345send_array:
23412346 ht = Z_ARRVAL_P(args);
23422347 if (opline->op2_type != IS_UNUSED) {
2348+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: not handling named params\n");
23432349 /* We don't need to handle named params in this case,
23442350 * because array_slice() is called with $preserve_keys == false. */
23452351 zval *op2 = get_zval_ptr(opline->op2_type, opline->op2, BP_VAR_R);
23462352 uint32_t skip = opline->extended_value;
23472353 uint32_t count = zend_hash_num_elements(ht);
23482354 zend_long len = zval_get_long(op2);
23492355
2356+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: %d skip, %d count, %ld len\n", skip, count, len);
2357+
23502358 if (len < 0) {
2359+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: len < 0\n");
23512360 len += (zend_long)(count - skip);
23522361 }
23532362 if (skip < count && len > 0) {
@@ -2393,14 +2402,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_O
23932402 }
23942403 FREE_OP(opline->op2_type, opline->op2.var);
23952404 } else {
2405+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: need to potentially handle named params\n");
23962406 zend_string *name;
23972407 zend_bool have_named_params;
23982408 zend_vm_stack_extend_call_frame(&EX(call), 0, zend_hash_num_elements(ht));
2409+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: after extend call stack frame\n");
2410+
23992411 arg_num = 1;
24002412 param = ZEND_CALL_ARG(EX(call), 1);
24012413 have_named_params = 0;
24022414 ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) {
2415+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: foreach_str_key_val\n");
24032416 if (name) {
2417+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: named arg: %s\n", ZSTR_VAL(name));
24042418 void *cache_slot[2] = {NULL, NULL};
24052419 have_named_params = 1;
24062420 param = zend_handle_named_arg(&EX(call), name, &arg_num, cache_slot);
@@ -2409,6 +2423,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_O
24092423 HANDLE_EXCEPTION();
24102424 }
24112425 } else if (have_named_params) {
2426+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: incorrect presence of positional arg\n");
24122427 zend_throw_error(NULL,
24132428 "Cannot use positional argument after named argument");
24142429 FREE_OP(opline->op1_type, opline->op1.var);
@@ -2419,6 +2434,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_O
24192434 if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
24202435 if (UNEXPECTED(!Z_ISREF_P(arg))) {
24212436 if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
2437+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: warn about pass by value when ref wanted\n");
24222438 /* By-value send is not allowed -- emit a warning,
24232439 * but still perform the call. */
24242440 zend_param_must_be_ref(EX(call)->func, arg_num);
@@ -2429,25 +2445,63 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_ARRAY_SPEC_HANDLER(ZEND_O
24292445 if (Z_ISREF_P(arg) &&
24302446 !(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
24312447 /* don't separate references for __call */
2448+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: don't separate refs\n");
24322449 arg = Z_REFVAL_P(arg);
24332450 }
24342451 }
24352452
24362453 if (EXPECTED(!must_wrap)) {
2437- ZVAL_COPY(param, arg);
2454+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: ZVAL_COPY: attempt\n");
2455+ //ZVAL_COPY(param, arg);
2456+ do {
2457+ zval *_z1 = (param);
2458+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: ZVAL_COPY: assign param: %p\n", _z1);
2459+ const zval *_z2 = (arg);
2460+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: ZVAL_COPY: assign arg: %p\n", _z2);
2461+ zend_refcounted *_gc = Z_COUNTED_P(_z2);
2462+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: ZVAL_COPY: assign refcounted: %p\n", _gc);
2463+ uint32_t _t = Z_TYPE_INFO_P(_z2);
2464+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: assign type info: %d\n", _t);
2465+ //ZVAL_COPY_VALUE_EX(_z1, _z2, _gc, _t);
2466+ //ZVAL_COPY_VALUE_EX(z = _z1, v = _z2, gc = _gc, t = _t);
2467+ do {
2468+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: attempting to assign v->value.ww.w2 from v: %p\n", _z2);
2469+ uint32_t _w2 = _z2->value.ww.w2;
2470+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: assigned v->value.ww.w2\n");
2471+ Z_COUNTED_P(_z1) = _gc;
2472+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: assigned to counted z\n");
2473+ _z1->value.ww.w2 = _w2;
2474+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: assigned to z->value.ww.w2\n");
2475+ Z_TYPE_INFO_P(_z1) = _t;
2476+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: assigned type info: %d\n", _t);
2477+ } while (0);
2478+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: check whether refcounted\n");
2479+ if (Z_TYPE_INFO_REFCOUNTED(_t)) { \
2480+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: refcounted: adding ref\n");
2481+ GC_ADDREF(_gc); \
2482+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: refcounted: added\n");
2483+ }
2484+ } while (0);
2485+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: ZVAL_COPY: done\n");
24382486 } else {
2487+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: Z_TRY_ADDREF_P: attempt\n");
24392488 Z_TRY_ADDREF_P(arg);
2489+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: Z_TRY_ADDREF_P: done and then ZVAL_NEW_REF\n");
24402490 ZVAL_NEW_REF(param, arg);
2491+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: ZVAL_NEW_REF: done\n");
24412492 }
24422493 if (!name) {
2494+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: increment arg pointers/indices\n");
24432495 ZEND_CALL_NUM_ARGS(EX(call))++;
24442496 arg_num++;
24452497 param++;
24462498 }
2499+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: end of one foreach iteration\n");
24472500 } ZEND_HASH_FOREACH_END();
24482501 }
24492502 }
24502503 FREE_OP(opline->op1_type, opline->op1.var);
2504+ fprintf(stderr, "ZEND_SEND_ARRAY_SPEC_HANDLER: returning: %s\n", ZSTR_VAL(EX(call)->func->common.function_name));
24512505 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
24522506}
24532507
0 commit comments