@@ -5380,12 +5380,17 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const
5380
5380
5381
5381
CHECK (COMPILE_POPPED (pre , "masgn lhs (NODE_ATTRASGN)" , node ));
5382
5382
5383
+ bool safenav_call = false;
5383
5384
LINK_ELEMENT * insn_element = LAST_ELEMENT (pre );
5384
5385
iobj = (INSN * )get_prev_insn ((INSN * )insn_element ); /* send insn */
5385
5386
ASSUME (iobj );
5386
- ELEM_REMOVE (LAST_ELEMENT (pre ));
5387
- ELEM_REMOVE ((LINK_ELEMENT * )iobj );
5388
- pre -> last = iobj -> link .prev ;
5387
+ ELEM_REMOVE (insn_element );
5388
+ if (!IS_INSN_ID (iobj , send )) {
5389
+ safenav_call = true;
5390
+ iobj = (INSN * )get_prev_insn (iobj );
5391
+ ELEM_INSERT_NEXT (& iobj -> link , insn_element );
5392
+ }
5393
+ (pre -> last = iobj -> link .prev )-> next = 0 ;
5389
5394
5390
5395
const struct rb_callinfo * ci = (struct rb_callinfo * )OPERAND_AT (iobj , 0 );
5391
5396
int argc = vm_ci_argc (ci ) + 1 ;
@@ -5404,7 +5409,9 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const
5404
5409
return COMPILE_NG ;
5405
5410
}
5406
5411
5407
- ADD_ELEM (lhs , (LINK_ELEMENT * )iobj );
5412
+ iobj -> link .prev = lhs -> last ;
5413
+ lhs -> last -> next = & iobj -> link ;
5414
+ for (lhs -> last = & iobj -> link ; lhs -> last -> next ; lhs -> last = lhs -> last -> next );
5408
5415
if (vm_ci_flag (ci ) & VM_CALL_ARGS_SPLAT ) {
5409
5416
int argc = vm_ci_argc (ci );
5410
5417
bool dupsplat = false;
@@ -5437,9 +5444,11 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const
5437
5444
}
5438
5445
INSERT_BEFORE_INSN1 (iobj , line_no , node_id , pushtoarray , INT2FIX (1 ));
5439
5446
}
5440
- ADD_INSN (lhs , line_node , pop );
5441
- if (argc != 1 ) {
5447
+ if (!safenav_call ) {
5442
5448
ADD_INSN (lhs , line_node , pop );
5449
+ if (argc != 1 ) {
5450
+ ADD_INSN (lhs , line_node , pop );
5451
+ }
5443
5452
}
5444
5453
for (int i = 0 ; i < argc ; i ++ ) {
5445
5454
ADD_INSN (post , line_node , pop );
0 commit comments