634 Commits

Author SHA1 Message Date
Nobuyoshi Nakada
2e3f81838c
Align styles [ci skip] 2025-05-15 17:48:40 +09:00
Satoshi Tagomori
382645d440 namespace on read 2025-05-11 23:32:50 +09:00
Nobuyoshi Nakada
5dc155351a
Do not allocate new objects at machine stack overflow 2025-04-24 17:28:18 +09:00
Nobuyoshi Nakada
c218862d3c
Fix style [ci skip] 2025-04-19 22:02:10 +09:00
Yusuke Endoh
993fd96ce6 reject numbered parameters from Binding#local_variables
Also, Binding#local_variable_get and #local_variable_set rejects an
access to numbered parameters.

[Bug #20965] [Bug #21049]
2025-02-18 16:23:24 +09:00
Kevin Newton
cb419e3912 [PRISM] Handle forwarding inside eval
Fixes [Bug #21031]
2025-01-14 18:41:50 -05:00
Kevin Newton
1a06bee027 Do not intern invalid symbols in eval parse
When the inner code cannot represent the name of the locals in the
outer code, do not bother putting them into the constant pool as
they will not be referenced.

Fixes [Bug #20992]

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
2025-01-07 22:30:16 -05:00
Peter Zhu
5b22f14e53 GC guard the iseq in eval for prism
We need to GC guard the iseq because the code above it malloc memory which
could trigger a GC. Since we only use ISEQ_BODY, the compiler may optimize
out the iseq local variable so we need to GC guard it.

Fixes: http://ci.rvm.jp/results/trunk_asan@ruby-sp1/5484752
2024-12-23 16:44:30 -05:00
Peter Zhu
e23a60b929 Fix GC compaction crash when using local variables in eval
If we have local variables outside of the eval, the local variables names
are IDs. We convert these IDs to char * using rb_id2name. However, these
char * are actually Ruby strings, which may be embedded. This means that
it is not safe to rb_id2name and call any potential GC entrypoints because
if a GC compaction runs, the embedded string may move and the pointer will
change.

For example, if you compile with `-DRGENGC_CHECK_MODE=1`, then the following
script will crash:

    GC.auto_compact = :empty
    GC.stress = true

    o = Object.new

    eval("def o.m(k: 0) k end")

The crash message is:

    test.rb:6: [BUG] Local with constant_id 1 does not exist
    ruby 3.4.0dev (2024-12-17T18:34:57Z prism-local-compac.. 434346726c) +PRISM [arm64-darwin24]

    -- C level backtrace information -------------------------------------------
    miniruby(rb_print_backtrace+0x24) [0x10312fec4] vm_dump.c:823
    miniruby(rb_print_backtrace) (null):0
    miniruby(rb_vm_bugreport+0x2d4) [0x1031301b8] vm_dump.c:1155
    miniruby(rb_bug_without_die_internal+0xa8) [0x102dd6a94] error.c:1097
    miniruby(rb_bug+0x28) [0x102dd6b00] error.c:1115
    miniruby(pm_lookup_local_index+0xec) [0x102d61e4c] prism_compile.c:1237
    miniruby(pm_compile_node+0x45d0) [0x102d252f4] prism_compile.c:9334
    miniruby(pm_compile_node+0x1864) [0x102d22588] prism_compile.c:8650
    miniruby(pm_compile_node+0x65ec) [0x102d27310] prism_compile.c:9897
    miniruby(pm_compile_scope_node+0x3008) [0x102d77bcc] prism_compile.c:6584
    miniruby(pm_compile_node+0x5ec4) [0x102d26be8] prism_compile.c:9768
    miniruby(pm_iseq_compile_node+0xac) [0x102d20bf0] prism_compile.c:10069
    miniruby(pm_iseq_new_with_opt_try+0x2c) [0x102e7d088] iseq.c:1029
    miniruby(rb_protect+0x108) [0x102dea9bc] eval.c:1033
    miniruby(pm_iseq_new_with_opt+0x264) [0x102e7c444] iseq.c:1082
    miniruby(pm_iseq_new_eval+0xec) [0x102e7c8e0] iseq.c:961
    miniruby(pm_eval_make_iseq+0x594) [0x1031209cc] vm_eval.c:1770
    miniruby(eval_make_iseq+0x54) [0x103120068] vm_eval.c:1799
2024-12-20 08:24:54 -05:00
Peter Zhu
85f3ed8cdb Don't recompute the strlen in pm_eval_make_iseq
We've already computed the length of the string, so we can reuse it.
2024-12-20 08:24:54 -05:00
Peter Zhu
51ffef2819 Fix memory leak in prism when syntax error in iseq compilation
If there's a syntax error during iseq compilation then prism would leak
memory because it would not free the pm_parse_result_t.

This commit changes pm_iseq_new_with_opt to have a rb_protect to catch
when an error is raised, and return NULL and set error_state to a value
that can be raised by calling rb_jump_tag after memory has been freed.

For example:

    10.times do
      10_000.times do
        eval("/[/=~s")
      rescue SyntaxError
      end

      puts `ps -o rss= -p #{$$}`
    end

Before:

    39280
    68736
    99232
    128864
    158896
    188208
    217344
    246304
    275376
    304592

After:

    12192
    13200
    14256
    14848
    16000
    16000
    16000
    16064
    17232
    17952
2024-11-08 15:43:41 -05:00
Kevin Newton
4203c70dfa Allow eval to see top scope
Fixes [Bug #20856]

Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org>
2024-11-05 17:08:35 -05:00
Alan Wu
11e7ab79de
Remove 1 allocation in Enumerable#each_with_index (#11868)
* Remove 1 allocation in Enumerable#each_with_index

Previously, each call to Enumerable#each_with_index allocates 2
objects, one for the counting index, the other an imemo_ifunc passed
to `self.each` as a block.

Use `struct vm_ifunc::data` to hold the counting index directly to
remove 1 allocation.

* [DOC] Brief summary for usages of `struct vm_ifunc`
2024-10-11 10:22:44 -04:00
Nobuyoshi Nakada
3e1021b144 Make default parser enum and define getter/setter 2024-10-02 20:43:40 +09:00
Peter Zhu
4f0fe97995 Free scope node in prism 2024-09-24 10:23:45 -04:00
Peter Zhu
4113dcc4ae Fix memory leak in constant ID list in prism 2024-09-24 10:23:45 -04:00
Kevin Newton
f7b097dea0 [PRISM] Keep script lines option for eval iseqs as well 2024-09-03 12:12:08 -04:00
Kevin Newton
371432b2d7 [PRISM] Handle RubyVM.keep_script_lines 2024-08-29 20:27:01 -04:00
Alan Wu
68a419d749 Delete unused rb_check_funcall_with_hook() 2024-08-07 19:17:31 -04:00
Yusuke Endoh
114e32b357 Add rb_block_call2, a flexible variant of rb_block_call
This function accepts flags:

RB_NO_KEYWORDS, RB_PASS_KEYWORDS, RB_PASS_CALLED_KEYWORDS:
Works as the same as rb_block_call_kw.

RB_BLOCK_NO_USE_PACKED_ARGS:
The given block ("bl_proc") does not use "yielded_arg" of rb_block_call_func_t.
Instead, the block accesses the yielded arguments via "argc" and "argv".
This flag allows the called method to yield arguments without allocating an Array.
2024-07-10 13:00:47 +09:00
Aaron Patterson
a25dd5b12c Set a fast path for forwardable iseqs 2024-06-18 09:28:25 -07:00
Kevin Newton
a708b6aa65 [PRISM] Respect eval coverage setting 2024-05-20 12:28:47 -04:00
yui-knk
899d9f79dd Rename vast to ast_value
There is an English word "vast".
This commit changes the name to be more clear name to avoid confusion.
2024-05-03 12:40:35 +09:00
HASUMI Hitoshi
2244c58b00 [Universal parser] Decouple IMEMO from rb_ast_t
This patch removes the `VALUE flags` member from the `rb_ast_t` structure making `rb_ast_t` no longer an IMEMO object.

## Background

We are trying to make the Ruby parser generated from parse.y a universal parser that can be used by other implementations such as mruby.
To achieve this, it is necessary to exclude VALUE and IMEMO from parse.y, AST, and NODE.

## Summary (file by file)

- `rubyparser.h`
  - Remove the `VALUE flags` member from `rb_ast_t`
- `ruby_parser.c` and `internal/ruby_parser.h`
  - Use TypedData_Make_Struct VALUE which wraps `rb_ast_t` `in ast_alloc()` so that GC can manage it
    - You can retrieve `rb_ast_t` from the VALUE by `rb_ruby_ast_data_get()`
  - Change the return type of `rb_parser_compile_XXXX()` functions from `rb_ast_t *` to `VALUE`
  - rb_ruby_ast_new() which internally `calls ast_alloc()` is to create VALUE vast outside ruby_parser.c
- `iseq.c` and `vm_core.h`
  - Amend the first parameter of `rb_iseq_new_XXXX()` functions from `rb_ast_body_t *` to `VALUE`
  - This keeps the VALUE of AST on the machine stack to prevent being removed by GC
- `ast.c`
  - Almost all change is replacement `rb_ast_t *ast` with `VALUE vast` (sorry for the big diff)
  - Fix `node_memsize()`
    - Now it includes `rb_ast_local_table_link`, `tokens` and script_lines
- `compile.c`, `load.c`, `node.c`, `parse.y`, `proc.c`, `ruby.c`, `template/prelude.c.tmpl`, `vm.c` and `vm_eval.c`
  - Follow-up due to the above changes
- `imemo.{c|h}`
  - If an object with `imemo_ast` appears, considers it a bug

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
2024-04-26 11:21:08 +09:00
Aaron Patterson
73a7e51535 Pass a callinfo object to global call cache search
Global call cache can be used with only a CI
2024-04-24 11:21:18 -07:00
Aaron Patterson
2cc59c1b31 pass CI to gccct_method_search_slowpath
Also the slow path only needs to look up the method once: via
vm_search_method_slowpath0.  gccct just returns whatever cc normal
method lookup does.
2024-04-24 11:21:18 -07:00
Aaron Patterson
853c0b1a77 Reuse slow path method search for gccct
This way all code paths use the same search code for finding call caches
for a particular method.
2024-04-24 09:30:59 -07:00
HASUMI Hitoshi
9b1e97b211 [Universal parser] DeVALUE of p->debug_lines and ast->body.script_lines
This patch is part of universal parser work.

## Summary
- Decouple VALUE from members below:
  - `(struct parser_params *)->debug_lines`
  - `(rb_ast_t *)->body.script_lines`
- Instead, they are now `rb_parser_ary_t *`
  - They can also be a `(VALUE)FIXNUM` as before to hold line count
- `ISEQ_BODY(iseq)->variable.script_lines` remains VALUE
  - In order to do this,
  - Add `VALUE script_lines` param to `rb_iseq_new_with_opt()`
  - Introduce `rb_parser_build_script_lines_from()` to convert `rb_parser_ary_t *` into `VALUE`

## Other details
- Extend `rb_parser_ary_t *`. It previously could only store `rb_parser_ast_token *`, now can store script_lines, too
- Change tactics of building the top-level `SCRIPT_LINES__` in `yycompile0()`
  - Before: While parsing, each line of the script is added to `SCRIPT_LINES__[path]`
  - After: After `yyparse(p)`, `SCRIPT_LINES__[path]` will be built from `p->debug_lines`
- Remove the second parameter of `rb_parser_set_script_lines()` to make it simple
- Introduce `script_lines_free()` to be called from `rb_ast_free()` because the GC no longer takes care of the script_lines
- Introduce `rb_parser_string_deep_copy()` in parse.y to maintain script_lines when `rb_ruby_parser_free()` called
  - With regard to this, please see *Future tasks* below

## Future tasks
- Decouple IMEMO from `rb_ast_t *`
  - This lifts the five-members-restriction of Ruby object,
  - So we will be able to move the ownership of the `lex.string_buffer` from parser to AST
  - Then we remove `rb_parser_string_deep_copy()` to make the whole thing simple
2024-04-15 20:51:54 +09:00
Kevin Newton
48c2ffe980 [PRISM] Enable SCRIPT_COMPILED tracepoint event 2024-04-04 15:27:51 -04:00
Kevin Newton
42d1cd8f7f [PRISM] Pass --enable-frozen-string-literal through to evals 2024-03-27 08:34:42 -04:00
Takashi Kokubun
cbcb2d46fc
[DOC] Unify Doxygen formats (#10285) 2024-03-19 10:59:25 -07:00
Étienne Barrié
12be40ae6b Implement chilled strings
[Feature #20205]

As a path toward enabling frozen string literals by default in the future,
this commit introduce "chilled strings". From a user perspective chilled
strings pretend to be frozen, but on the first attempt to mutate them,
they lose their frozen status and emit a warning rather than to raise a
`FrozenError`.

Implementation wise, `rb_compile_option_struct.frozen_string_literal` is
no longer a boolean but a tri-state of `enabled/disabled/unset`.

When code is compiled with frozen string literals neither explictly enabled
or disabled, string literals are compiled with a new `putchilledstring`
instruction. This instruction is identical to `putstring` except it marks
the String with the `STR_CHILLED (FL_USER3)` and `FL_FREEZE` flags.

Chilled strings have the `FL_FREEZE` flag as to minimize the need to check
for chilled strings across the codebase, and to improve compatibility with
C extensions.

Notes:
  - `String#freeze`: clears the chilled flag.
  - `String#-@`: acts as if the string was mutable.
  - `String#+@`: acts as if the string was mutable.
  - `String#clone`: copies the chilled flag.

Co-authored-by: Jean Boussier <byroot@ruby-lang.org>
2024-03-19 09:26:49 +01:00
Jean Boussier
91bf7eb274 Refactor frozen_string_literal check during compilation
In preparation for https://bugs.ruby-lang.org/issues/20205.

The `frozen_string_literal` compilation option will no longer
be a boolean but a tri-state: `on/off/default`.
2024-03-15 15:52:33 +01:00
Kevin Newton
00c32f606a [PRISM] Do not send numbered parameters into eval 2024-03-13 19:01:43 -04:00
Jean Boussier
d4f3dcf4df Refactor VM root modules
This `st_table` is used to both mark and pin classes
defined from the C API. But `vm->mark_object_ary` already
does both much more efficiently.

Currently a Ruby process starts with 252 rooted classes,
which uses `7224B` in an `st_table` or `2016B` in an `RArray`.

So a baseline of 5kB saved, but since `mark_object_ary` is
preallocated with `1024` slots but only use `405` of them,
it's a net `7kB` save.

`vm->mark_object_ary` is also being refactored.

Prior to this changes, `mark_object_ary` was a regular `RArray`, but
since this allows for references to be moved, it was marked a second
time from `rb_vm_mark()` to pin these objects.

This has the detrimental effect of marking these references on every
minors even though it's a mostly append only list.

But using a custom TypedData we can save from having to mark
all the references on minor GC runs.

Addtionally, immediate values are now ignored and not appended
to `vm->mark_object_ary` as it's just wasted space.
2024-03-06 15:33:43 -05:00
Kevin Newton
80ffa3006c [PRISM] Eval frames should not have an absolute path 2024-02-21 17:25:55 -05:00
Yusuke Endoh
25d74b9527 Do not include a backtick in error messages and backtraces
[Feature #16495]
2024-02-15 18:42:31 +09:00
Kevin Newton
9933377c34 [PRISM] Correctly hook up line numbers for eval 2024-02-14 15:29:26 -05:00
Matt Valentine-House
adb2fbf69a [PRISM] Prism/eval should handle file names provided 2024-02-13 21:19:12 -05:00
Matt Valentine-House
c2af974e67 [PRISM] Build wrapper scopes for eval
- Don't use `build_options_scopes` We can inline the code here instead
  and avoid allocating all the extra arrays.

- Create `pm_scope_node_t` objects with the correct local table, for the
  scope node returned from the parser.

Co-Authored-By: Kevin Newton <kddnewton@gmail.com>
2024-02-13 21:19:12 -05:00
Matt Valentine-House
fd3f776a05 [PRISM] Use Prism for eval if enabled 2024-02-13 21:19:12 -05:00
Matt Valentine-House
08b77dd682 Remove unused bind argument from eval_make_iseq 2024-02-09 12:28:26 +00:00
Xavier Noria
aad246feba s/SafeStringValue/StringValue/
The macro SafeStringValue() became just StringValue() in c5c05460ac2,
and it is deprecated nowadays.

This patch replaces remaining macro usage. Some occurrences are left in
ext/stringio and ext/win32ole, they should be fixed upstream.

The macro itself is not deleted, because it may be used in extensions.
2024-01-12 12:24:48 -08:00
Jeremy Evans
3081c83169 Support tracing of struct member accessor methods
This follows the same approach used for attr_reader/attr_writer in
2d98593bf54a37397c6e4886ccc7e3654c2eaf85, skipping the checking for
tracing after the first call using the call cache, and clearing the
call cache when tracing is turned on/off.

Fixes [Bug #18886]
2023-12-07 10:29:33 -08:00
Nobuyoshi Nakada
1cfc853be6
Suppress nonnull warning from gcc 13 2023-11-07 23:19:51 +09:00
Peter Zhu
38e98cbb6a Fix typo in "refinements" 2023-09-19 19:34:50 -04:00
Nobuyoshi Nakada
6aa16f9ec1 Move SCRIPT_LINES__ away from parse.y 2023-08-25 18:23:05 +09:00
Koichi Sasada
280419d0e0 calling->cd instead of calling->ci
`struct rb_calling_info::cd` is introduced and `rb_calling_info::ci`
is replaced with it to manipulate the inline cache of iseq while
method invocation process. So that `ci` can be acessed with
`calling->cd->ci`. It adds one indirection but it can be justified
by the following points:

1) `vm_search_method_fastpath()` doesn't need `ci` and also
`vm_call_iseq_setup_normal()` doesn't need `ci`. It means
reducing `cd->ci` access in `vm_sendish()` can make it faster.

2) most of method types need to access `ci` once in theory
so that 1 additional indirection doesn't matter.
2023-07-31 17:13:43 +09:00
Koichi Sasada
36023d5cb7 mark cc->cme_ if it is for super
`vm_search_super_method()` makes orphan CCs (they are not connected
from ccs) and `cc->cme_` can be collected before without marking.
2023-07-31 14:04:31 +09:00
Nobuyoshi Nakada
1780ad3748
Extract magic numbers 2023-07-24 23:41:01 +09:00