Project

General

Profile

Actions

Bug #20916

open

Prism compiler should support ** in Ractor constant

Added by mame (Yusuke Endoh) 7 days ago. Updated 2 days ago.

Status:
Assigned
Assignee:
Target version:
-
ruby -v:
ruby 3.4.0dev (2024-11-28T02:34:20Z avoid-uninitialize.. 79ae6e72c8) +PRISM [x86_64-linux]
[ruby-core:120033]

Description

The Prism compiler raises an exception against the following code.

$ ./miniruby -e '# shareable_constant_value: experimental_everything
C = { **{ } }'
-e:2: Ractor constant writes do not support **
-e: node type  not implemented (NotImplementedError)

But the traditional compiler support it, and @ko1 (Koichi Sasada) said it should be supported.

Also, I feel that this error message node type not implemented is a sign of a worse problem. Actually, valgrind reports Conditional jump or move depends on uninitialised value(s)against the Prism compiler. An assertion failure is also reported.

$ valgrind ./miniruby -e '# shareable_constant_value: experimental_everything
C = { **{ } }'
==49978== Memcheck, a memory error detector
==49978== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==49978== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==49978== Command: ./miniruby -e #\ shareable_constant_value:\ experimental_everything_C\ =\ {\ **{\ }\ }
==49978==
==49978== Warning: set address range perms: large range [0x64e0000, 0x1e4e0000) (defined)
-e:2: Ractor constant writes do not support **
==49978== Conditional jump or move depends on uninitialised value(s)
==49978==    at 0x4BB42A: pm_newline_list_line (pm_newline_list.c:63)
==49978==    by 0x1E718A: pm_compile_shareable_constant_value (prism_compile.c:5280)
==49978==    by 0x1E7243: pm_compile_shareable_constant_value (prism_compile.c:5318)
==49978==    by 0x1E8DC1: pm_compile_constant_write_node.isra.0 (prism_compile.c:5372)
==49978==    by 0x1DCB2F: pm_compile_node (prism_compile.c:9823)
==49978==    by 0x1DC9C8: pm_compile_node (prism_compile.c:9934)
==49978==    by 0x1F3AC9: pm_compile_scope_node.isra.0 (prism_compile.c:6603)
==49978==    by 0x1DA66A: pm_compile_node (prism_compile.c:9805)
==49978==    by 0x1F61A7: pm_iseq_compile_node (prism_compile.c:10109)
==49978==    by 0x2A5303: pm_iseq_new_with_opt_try (iseq.c:1027)
==49978==    by 0x23DFF2: rb_protect (eval.c:1033)
==49978==    by 0x2AB198: pm_iseq_new_with_opt (iseq.c:1080)
==49978==
miniruby: prism/util/pm_newline_list.c:63: pm_newline_list_line: Assertion `cursor >= list->start' failed.
==49978==
==49978== Process terminating with default action of signal 6 (SIGABRT)
==49978==    at 0x4AFAB1C: __pthread_kill_implementation (pthread_kill.c:44)
==49978==    by 0x4AFAB1C: __pthread_kill_internal (pthread_kill.c:78)
==49978==    by 0x4AFAB1C: pthread_kill@@GLIBC_2.34 (pthread_kill.c:89)
==49978==    by 0x4AA126D: raise (raise.c:26)
==49978==    by 0x4A848FE: abort (abort.c:79)
==49978==    by 0x4A8481A: __assert_fail_base.cold (assert.c:94)
==49978==    by 0x4A97506: __assert_fail (assert.c:103)
==49978==    by 0x4BB49B: pm_newline_list_line (pm_newline_list.c:63)
==49978==    by 0x1E718A: pm_compile_shareable_constant_value (prism_compile.c:5280)
==49978==    by 0x1E7243: pm_compile_shareable_constant_value (prism_compile.c:5318)
==49978==    by 0x1E8DC1: pm_compile_constant_write_node.isra.0 (prism_compile.c:5372)
==49978==    by 0x1DCB2F: pm_compile_node (prism_compile.c:9823)
==49978==    by 0x1DC9C8: pm_compile_node (prism_compile.c:9934)
==49978==    by 0x1F3AC9: pm_compile_scope_node.isra.0 (prism_compile.c:6603)
==49978==
==49978== HEAP SUMMARY:
==49978==     in use at exit: 2,645,494 bytes in 10,084 blocks
==49978==   total heap usage: 36,662 allocs, 26,578 frees, 6,066,537 bytes allocated
==49978==
==49978== LEAK SUMMARY:
==49978==    definitely lost: 0 bytes in 0 blocks
==49978==    indirectly lost: 0 bytes in 0 blocks
==49978==      possibly lost: 1,050,576 bytes in 4 blocks
==49978==    still reachable: 1,594,918 bytes in 10,080 blocks
==49978==         suppressed: 0 bytes in 0 blocks
==49978== Rerun with --leak-check=full to see details of leaked memory
==49978==
==49978== Use --track-origins=yes to see where uninitialised values come from
==49978== For lists of detected and suppressed errors, rerun with: -s
==49978== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Aborted (core dumped)

Related issues 1 (1 open0 closed)

Related to Ruby master - Bug #20927: `{ **{ } }` behaves differently when `shareable_constant_value: experimental_everything`OpenActions

Updated by kddnewton (Kevin Newton) 2 days ago

I'm fine supporting this, but I'm not sure what the behavior should be since the current compiler just segfaults. What is the behavior if the value being splatted isn't an empty hash?

Updated by tenderlovemaking (Aaron Patterson) 2 days ago

I created a bug for the parse.y version here: https://bugs.ruby-lang.org/issues/20926

The example @mame (Yusuke Endoh) provides works on Ruby 3.3. I think it's supposed to emit instructions like this:

$ ruby -v --dump=insns test.rb
ruby 3.3.4 (2024-07-16 revision 425e468d25) [arm64-darwin23]
== disasm: #<ISeq:<main>@test.rb:1 (1,0)-(3,13)>
0000 putobject                              {nil=>{}}                 (   3)[Li]
0002 dup
0003 putspecialobject                       3
0005 setconstant                            :C
0007 leave

Note that if you remove the comment the iseqs look like this:

$ ruby -v --dump=insns test.rb
ruby 3.3.4 (2024-07-16 revision 425e468d25) [arm64-darwin23]
== disasm: #<ISeq:<main>@test.rb:1 (1,0)-(2,13)>
0000 newhash                                0                         (   2)[Li]
0002 dup
0003 putspecialobject                       3
0005 setconstant                            :C
0007 leave

I think the main difference is the putobject instruction.

Updated by tenderlovemaking (Aaron Patterson) 2 days ago

After reading the instruction sequences, I realized that Ruby 3.3 has an odd behavior with shareable_constant_value: experimental_everything. I filed an issue about it here: https://bugs.ruby-lang.org/issues/20927

I personally think the fix for this ticket is that C should be an empty hash (whether the comment is there or not).

Actions #4

Updated by tenderlovemaking (Aaron Patterson) 2 days ago

  • Related to Bug #20927: `{ **{ } }` behaves differently when `shareable_constant_value: experimental_everything` added
Actions #5

Updated by hsbt (Hiroshi SHIBATA) 2 days ago

  • Status changed from Open to Assigned
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0