@@ -1357,13 +1357,15 @@ pm_compile_call_and_or_write_node(rb_iseq_t *iseq, bool and_node, const pm_node_
1357
1357
if (lskip && !popped ) PUSH_LABEL (ret , lskip );
1358
1358
}
1359
1359
1360
+ static void pm_compile_shareable_constant_value (rb_iseq_t * iseq , const pm_node_t * node , const pm_node_flags_t shareability , VALUE path , LINK_ANCHOR * const ret , pm_scope_node_t * scope_node , bool top );
1361
+
1360
1362
/**
1361
1363
* This function compiles a hash onto the stack. It is used to compile hash
1362
1364
* literals and keyword arguments. It is assumed that if we get here that the
1363
1365
* contents of the hash are not popped.
1364
1366
*/
1365
1367
static void
1366
- pm_compile_hash_elements (rb_iseq_t * iseq , const pm_node_t * node , const pm_node_list_t * elements , bool argument , LINK_ANCHOR * const ret , pm_scope_node_t * scope_node )
1368
+ pm_compile_hash_elements (rb_iseq_t * iseq , const pm_node_t * node , const pm_node_list_t * elements , const pm_node_flags_t shareability , VALUE path , bool argument , LINK_ANCHOR * const ret , pm_scope_node_t * scope_node )
1367
1369
{
1368
1370
const pm_node_location_t location = PM_NODE_START_LOCATION (scope_node -> parser , node );
1369
1371
@@ -1406,11 +1408,11 @@ pm_compile_hash_elements(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l
1406
1408
for (size_t index = 0 ; index < elements -> size ; index ++ ) {
1407
1409
const pm_node_t * element = elements -> nodes [index ];
1408
1410
1409
-
1410
1411
switch (PM_NODE_TYPE (element )) {
1411
1412
case PM_ASSOC_NODE : {
1412
1413
// Pre-allocation check (this branch can be omitted).
1413
1414
if (
1415
+ (shareability == 0 ) &&
1414
1416
PM_NODE_FLAG_P (element , PM_NODE_FLAG_STATIC_LITERAL ) && (
1415
1417
(!static_literal && ((index + min_tmp_hash_length ) < elements -> size )) ||
1416
1418
(first_chunk && stack_length == 0 )
@@ -1468,7 +1470,15 @@ pm_compile_hash_elements(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l
1468
1470
1469
1471
// If this is a plain assoc node, then we can compile it directly
1470
1472
// and then add the total number of values on the stack.
1471
- pm_compile_node (iseq , element , anchor , false, scope_node );
1473
+ if (shareability == 0 ) {
1474
+ pm_compile_node (iseq , element , anchor , false, scope_node );
1475
+ }
1476
+ else {
1477
+ const pm_assoc_node_t * assoc = (const pm_assoc_node_t * ) element ;
1478
+ pm_compile_shareable_constant_value (iseq , assoc -> key , shareability , path , ret , scope_node , false);
1479
+ pm_compile_shareable_constant_value (iseq , assoc -> value , shareability , path , ret , scope_node , false);
1480
+ }
1481
+
1472
1482
if ((stack_length += 2 ) >= max_stack_length ) FLUSH_CHUNK ;
1473
1483
break ;
1474
1484
}
@@ -1511,7 +1521,12 @@ pm_compile_hash_elements(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l
1511
1521
// only done for method calls and not for literal hashes,
1512
1522
// because literal hashes should always result in a new
1513
1523
// hash.
1514
- PM_COMPILE_NOT_POPPED (element );
1524
+ if (shareability == 0 ) {
1525
+ PM_COMPILE_NOT_POPPED (element );
1526
+ }
1527
+ else {
1528
+ pm_compile_shareable_constant_value (iseq , element , shareability , path , ret , scope_node , false);
1529
+ }
1515
1530
}
1516
1531
else {
1517
1532
// There is more than one keyword argument, or this is not a
@@ -1527,7 +1542,13 @@ pm_compile_hash_elements(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l
1527
1542
PUSH_INSN (ret , location , swap );
1528
1543
}
1529
1544
1530
- PM_COMPILE_NOT_POPPED (element );
1545
+ if (shareability == 0 ) {
1546
+ PM_COMPILE_NOT_POPPED (element );
1547
+ }
1548
+ else {
1549
+ pm_compile_shareable_constant_value (iseq , element , shareability , path , ret , scope_node , false);
1550
+ }
1551
+
1531
1552
PUSH_SEND (ret , location , id_core_hash_merge_kwd , INT2FIX (2 ));
1532
1553
}
1533
1554
}
@@ -1590,17 +1611,17 @@ pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *b
1590
1611
// in this case, so mark the method as passing mutable
1591
1612
// keyword splat.
1592
1613
* flags |= VM_CALL_KW_SPLAT_MUT ;
1593
- pm_compile_hash_elements (iseq , argument , elements , true, ret , scope_node );
1614
+ pm_compile_hash_elements (iseq , argument , elements , 0 , Qundef , true, ret , scope_node );
1594
1615
}
1595
1616
else if (* dup_rest & DUP_SINGLE_KW_SPLAT ) {
1596
1617
* flags |= VM_CALL_KW_SPLAT_MUT ;
1597
1618
PUSH_INSN1 (ret , location , putspecialobject , INT2FIX (VM_SPECIAL_OBJECT_VMCORE ));
1598
1619
PUSH_INSN1 (ret , location , newhash , INT2FIX (0 ));
1599
- pm_compile_hash_elements (iseq , argument , elements , true, ret , scope_node );
1620
+ pm_compile_hash_elements (iseq , argument , elements , 0 , Qundef , true, ret , scope_node );
1600
1621
PUSH_SEND (ret , location , id_core_hash_merge_kwd , INT2FIX (2 ));
1601
1622
}
1602
1623
else {
1603
- pm_compile_hash_elements (iseq , argument , elements , true, ret , scope_node );
1624
+ pm_compile_hash_elements (iseq , argument , elements , 0 , Qundef , true, ret , scope_node );
1604
1625
}
1605
1626
}
1606
1627
else {
@@ -5289,19 +5310,7 @@ pm_compile_shareable_constant_value(rb_iseq_t *iseq, const pm_node_t *node, cons
5289
5310
PUSH_INSN1 (ret , location , putspecialobject , INT2FIX (VM_SPECIAL_OBJECT_VMCORE ));
5290
5311
}
5291
5312
5292
- for (size_t index = 0 ; index < cast -> elements .size ; index ++ ) {
5293
- const pm_node_t * element = cast -> elements .nodes [index ];
5294
-
5295
- if (!PM_NODE_TYPE_P (element , PM_ASSOC_NODE )) {
5296
- COMPILE_ERROR (iseq , location .line , "Ractor constant writes do not support **" );
5297
- }
5298
-
5299
- const pm_assoc_node_t * assoc = (const pm_assoc_node_t * ) element ;
5300
- pm_compile_shareable_constant_value (iseq , assoc -> key , shareability , path , ret , scope_node , false);
5301
- pm_compile_shareable_constant_value (iseq , assoc -> value , shareability , path , ret , scope_node , false);
5302
- }
5303
-
5304
- PUSH_INSN1 (ret , location , newhash , INT2FIX (cast -> elements .size * 2 ));
5313
+ pm_compile_hash_elements (iseq , (const pm_node_t * ) cast , & cast -> elements , shareability , path , false, ret , scope_node );
5305
5314
5306
5315
if (top ) {
5307
5316
ID method_id = (shareability & PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_COPY ) ? rb_intern ("make_shareable_copy" ) : rb_intern ("make_shareable" );
@@ -6752,7 +6761,7 @@ pm_compile_array_node(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_list
6752
6761
// ^^^^^
6753
6762
//
6754
6763
const pm_keyword_hash_node_t * keyword_hash = (const pm_keyword_hash_node_t * ) element ;
6755
- pm_compile_hash_elements (iseq , element , & keyword_hash -> elements , false, ret , scope_node );
6764
+ pm_compile_hash_elements (iseq , element , & keyword_hash -> elements , 0 , Qundef , false, ret , scope_node );
6756
6765
6757
6766
// This boolean controls the manner in which we push the
6758
6767
// hash onto the array. If it's all keyword splats, then we
@@ -8940,7 +8949,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
8940
8949
}
8941
8950
}
8942
8951
else {
8943
- pm_compile_hash_elements (iseq , node , elements , false, ret , scope_node );
8952
+ pm_compile_hash_elements (iseq , node , elements , 0 , Qundef , false, ret , scope_node );
8944
8953
}
8945
8954
}
8946
8955
0 commit comments