@@ -1357,13 +1357,15 @@ pm_compile_call_and_or_write_node(rb_iseq_t *iseq, bool and_node, const pm_node_
13571357 if (lskip && !popped ) PUSH_LABEL (ret , lskip );
13581358}
13591359
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+
13601362/**
13611363 * This function compiles a hash onto the stack. It is used to compile hash
13621364 * literals and keyword arguments. It is assumed that if we get here that the
13631365 * contents of the hash are not popped.
13641366 */
13651367static 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 )
13671369{
13681370 const pm_node_location_t location = PM_NODE_START_LOCATION (scope_node -> parser , node );
13691371
@@ -1406,11 +1408,11 @@ pm_compile_hash_elements(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l
14061408 for (size_t index = 0 ; index < elements -> size ; index ++ ) {
14071409 const pm_node_t * element = elements -> nodes [index ];
14081410
1409-
14101411 switch (PM_NODE_TYPE (element )) {
14111412 case PM_ASSOC_NODE : {
14121413 // Pre-allocation check (this branch can be omitted).
14131414 if (
1415+ (shareability == 0 ) &&
14141416 PM_NODE_FLAG_P (element , PM_NODE_FLAG_STATIC_LITERAL ) && (
14151417 (!static_literal && ((index + min_tmp_hash_length ) < elements -> size )) ||
14161418 (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
14681470
14691471 // If this is a plain assoc node, then we can compile it directly
14701472 // 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+
14721482 if ((stack_length += 2 ) >= max_stack_length ) FLUSH_CHUNK ;
14731483 break ;
14741484 }
@@ -1511,7 +1521,12 @@ pm_compile_hash_elements(rb_iseq_t *iseq, const pm_node_t *node, const pm_node_l
15111521 // only done for method calls and not for literal hashes,
15121522 // because literal hashes should always result in a new
15131523 // 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+ }
15151530 }
15161531 else {
15171532 // 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
15271542 PUSH_INSN (ret , location , swap );
15281543 }
15291544
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+
15311552 PUSH_SEND (ret , location , id_core_hash_merge_kwd , INT2FIX (2 ));
15321553 }
15331554 }
@@ -1590,17 +1611,17 @@ pm_setup_args_core(const pm_arguments_node_t *arguments_node, const pm_node_t *b
15901611 // in this case, so mark the method as passing mutable
15911612 // keyword splat.
15921613 * 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 );
15941615 }
15951616 else if (* dup_rest & DUP_SINGLE_KW_SPLAT ) {
15961617 * flags |= VM_CALL_KW_SPLAT_MUT ;
15971618 PUSH_INSN1 (ret , location , putspecialobject , INT2FIX (VM_SPECIAL_OBJECT_VMCORE ));
15981619 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 );
16001621 PUSH_SEND (ret , location , id_core_hash_merge_kwd , INT2FIX (2 ));
16011622 }
16021623 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 );
16041625 }
16051626 }
16061627 else {
@@ -5289,19 +5310,7 @@ pm_compile_shareable_constant_value(rb_iseq_t *iseq, const pm_node_t *node, cons
52895310 PUSH_INSN1 (ret , location , putspecialobject , INT2FIX (VM_SPECIAL_OBJECT_VMCORE ));
52905311 }
52915312
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 );
53055314
53065315 if (top ) {
53075316 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
67526761 // ^^^^^
67536762 //
67546763 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 );
67566765
67576766 // This boolean controls the manner in which we push the
67586767 // 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,
89408949 }
89418950 }
89428951 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 );
89448953 }
89458954 }
89468955
0 commit comments