summaryrefslogtreecommitdiff
path: root/vm_eval.c
AgeCommit message (Collapse)Author
2025-05-15Align styles [ci skip]Nobuyoshi Nakada
2025-05-11namespace on readSatoshi Tagomori
2025-04-24Do not allocate new objects at machine stack overflowNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/13167
2025-04-19Fix style [ci skip]Nobuyoshi Nakada
2025-02-18reject numbered parameters from Binding#local_variablesYusuke Endoh
Also, Binding#local_variable_get and #local_variable_set rejects an access to numbered parameters. [Bug #20965] [Bug #21049] Notes: Merged: https://github.com/ruby/ruby/pull/12746
2025-01-14[PRISM] Handle forwarding inside evalKevin Newton
Fixes [Bug #21031] Notes: Merged: https://github.com/ruby/ruby/pull/12575
2025-01-07Do not intern invalid symbols in eval parseKevin Newton
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 <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/12514
2024-12-23GC guard the iseq in eval for prismPeter Zhu
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 Notes: Merged: https://github.com/ruby/ruby/pull/12443
2024-12-20Fix GC compaction crash when using local variables in evalPeter Zhu
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 Notes: Merged: https://github.com/ruby/ruby/pull/12374
2024-12-20Don't recompute the strlen in pm_eval_make_iseqPeter Zhu
We've already computed the length of the string, so we can reuse it. Notes: Merged: https://github.com/ruby/ruby/pull/12374
2024-11-08Fix memory leak in prism when syntax error in iseq compilationPeter Zhu
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 Notes: Merged: https://github.com/ruby/ruby/pull/12036
2024-11-05Allow eval to see top scopeKevin Newton
Fixes [Bug #20856] Co-Authored-By: Aaron Patterson <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/11993
2024-10-11Remove 1 allocation in Enumerable#each_with_index (#11868)Alan Wu
* 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` Notes: Merged-By: maximecb <[email protected]>
2024-10-02Make default parser enum and define getter/setterNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/11761
2024-09-24Free scope node in prismPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/11670
2024-09-24Fix memory leak in constant ID list in prismPeter Zhu
Notes: Merged: https://github.com/ruby/ruby/pull/11670
2024-09-03[PRISM] Keep script lines option for eval iseqs as wellKevin Newton
Notes: Merged: https://github.com/ruby/ruby/pull/11534
2024-08-29[PRISM] Handle RubyVM.keep_script_linesKevin Newton
Notes: Merged: https://github.com/ruby/ruby/pull/11501
2024-08-07Delete unused rb_check_funcall_with_hook()Alan Wu
Notes: Merged: https://github.com/ruby/ruby/pull/11331
2024-07-10Add rb_block_call2, a flexible variant of rb_block_callYusuke Endoh
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-06-18Set a fast path for forwardable iseqsAaron Patterson
2024-05-20[PRISM] Respect eval coverage settingKevin Newton
2024-05-03Rename `vast` to `ast_value`yui-knk
There is an English word "vast". This commit changes the name to be more clear name to avoid confusion.
2024-04-26[Universal parser] Decouple IMEMO from rb_ast_tHASUMI Hitoshi
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 <[email protected]>
2024-04-24Pass a callinfo object to global call cache searchAaron Patterson
Global call cache can be used with only a CI
2024-04-24pass CI to gccct_method_search_slowpathAaron Patterson
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-24Reuse slow path method search for gccctAaron Patterson
This way all code paths use the same search code for finding call caches for a particular method.
2024-04-15[Universal parser] DeVALUE of p->debug_lines and ast->body.script_linesHASUMI Hitoshi
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-04[PRISM] Enable SCRIPT_COMPILED tracepoint eventKevin Newton
2024-03-27[PRISM] Pass --enable-frozen-string-literal through to evalsKevin Newton
2024-03-19[DOC] Unify Doxygen formats (#10285)Takashi Kokubun
2024-03-19Implement chilled stringsÉtienne Barrié
[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 <[email protected]>
2024-03-15Refactor frozen_string_literal check during compilationJean Boussier
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-13[PRISM] Do not send numbered parameters into evalKevin Newton
2024-03-06Refactor VM root modulesJean Boussier
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-02-21[PRISM] Eval frames should not have an absolute pathKevin Newton
2024-02-15Do not include a backtick in error messages and backtracesYusuke Endoh
[Feature #16495]
2024-02-14[PRISM] Correctly hook up line numbers for evalKevin Newton
2024-02-13[PRISM] Prism/eval should handle file names providedMatt Valentine-House
2024-02-13[PRISM] Build wrapper scopes for evalMatt Valentine-House
- 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 <[email protected]>
2024-02-13[PRISM] Use Prism for `eval` if enabledMatt Valentine-House
2024-02-09Remove unused bind argument from eval_make_iseqMatt Valentine-House
2024-01-12s/SafeStringValue/StringValue/Xavier Noria
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.
2023-12-07Support tracing of struct member accessor methodsJeremy Evans
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-11-07Suppress nonnull warning from gcc 13Nobuyoshi Nakada
2023-09-19Fix typo in "refinements"Peter Zhu
2023-08-25Move SCRIPT_LINES__ away from parse.yNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/8289
2023-07-31`calling->cd` instead of `calling->ci`Koichi Sasada
`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. Notes: Merged: https://github.com/ruby/ruby/pull/8129
2023-07-31mark `cc->cme_` if it is for `super`Koichi Sasada
`vm_search_super_method()` makes orphan CCs (they are not connected from ccs) and `cc->cme_` can be collected before without marking. Notes: Merged: https://github.com/ruby/ruby/pull/8145
2023-07-24Extract magic numbersNobuyoshi Nakada