| Age | Commit message (Collapse) | Author |
|
|
|
|
|
|
|
of `VALUE`
This change reduces parser's dependency on ruby object.
|
|
|
|
|
|
rb_ast_dispose does not free the rb_ast_t causing it to be leaked. This
commit changes it to use rb_ast_free instead.
For example:
require "ripper"
10.times do
100_000.times do
Ripper.sexp("")
end
puts `ps -o rss= -p #{$$}`
end
Before:
27648
32512
37376
42240
47232
52224
57344
62208
67072
71936
After:
22784
22784
22784
22784
22912
22912
22912
22912
22912
22912
|
|
|
|
|
|
|
|
This reduces dependency on VALUE.
|
|
|
|
|
|
This patch adds `int line_count` field to `rb_ast_body_t` structure.
Instead, we no longer cast `script_lines` to Fixnum.
## Background
Ref https://github.com/ruby/ruby/pull/10618
In the PR above, we have decoupled IMEMO from `rb_ast_t`.
This means we could lift the five-words-restriction of the structure
that forced us to unionize `rb_ast_t *` and `FIXNUM` in one field.
## Relating refactor
- Remove the second parameter of `rb_ruby_ast_new()` function
## Attention
I will remove a code that assigns -1 to line_count, in `rb_binding_add_dynavars()`
of vm.c, because I don't think it is necessary.
But I will make another PR for this so that we can atomically revert
in case I was wrong (See the comment on the code)
|
|
Parser should not depend on functions defiend on "ruby_parser.c".
|
|
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>
|
|
This function returned VALUE before. False made sense back then.
Now that it returns a pointer. NULL should be used instead.
|
|
Reduce the parser's dependence on `VALUE` and `rb_enc_from_encoding`.
|
|
Refactor parser compile functions to reduce the dependence
on ruby functions.
This commit includes these changes
1. Refactor `gets`, `input` and `gets_` of `parser_params`
Parser needs two different data structure to get next line, function (`gets`) and input data (`input`).
However `gets_` is used for both function (`call`) and input data (`ptr`).
`call` is used for managing general callback function when `rb_ruby_parser_compile_generic` is used.
`ptr` is used for managing the current pointer on String when `parser_compile_string` is used.
This commit changes parser to used only `gets` and `input` then removes `gets_`.
2. Move parser_compile functions and `gets` functions from parse.y to ruby_parser.c
This change reduces the dependence on ruby functions from parser.
3. Change ruby_parser and ripper to take care of `VALUE input` GC mark
Move the responsibility of calling `rb_gc_mark` for `VALUE input` from parser to ruby_parser and ripper.
`input` is arbitrary data pointer from the viewpoint of parser.
4. Introduce rb_parser_compile_array function
Caller of `rb_parser_compile_generic` needs to take care about GC because ruby_parser doesn’t know
about the detail of `lex_gets` and `input`.
Introduce `rb_parser_compile_array` to reduce the complexity of ast.c.
|
|
In the past, `Qnone` and `Qnull` had different values
in ripper context like below.
However 89cfc152071 removes the usage in ripper context,
then expand the macro.
```
#ifndef RIPPER
# define Qnone 0
# define Qnull 0
#else
# define Qnone Qnil
# define Qnull Qundef
#endif
```
|
|
|
|
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
|
|
Need to use `rb_warn` macro instead of calling `rb_compile_warn`
directly to emit `warn` event on ripper.
|
|
|
|
|
|
The `rb_fstring(rb_enc_str_new())` pattern is inneficient because:
- It passes a mutable string to `rb_fstring` so if it has to be interned
it will first be duped.
- It an equivalent interned string already exists, we allocated the string
for nothing.
With `rb_enc_interned_str` we either directly get the pre-existing string
with 0 allocations, or efficiently directly intern the one we create
without first duping it.
|
|
|
|
|
|
89cfc152071 made this event dispatch to pass `Qundef`
to user defined callback method by mistake.
This commit fix it to be `nil`.
|
|
|
|
Need to separate `check_literal_when` function for parser and
ripper otherwise warning event is not dispatched because
parser `rb_warning1` is used in ripper.
|
|
|
|
The first argument of `WARN_SPACE_CHAR` is always `c2` in caller
side, so `c` equals to `c2`.
|
|
|
|
|
|
|
|
|
|
No parser semantic value types are `VALUE` then no need to
use imemo for managing semantic value stack anymore.
|
|
clause duplication
This commit simplifies warnings for hash keys duplication and when clause duplication,
based on the discussion of https://bugs.ruby-lang.org/issues/20331.
Warnings are reported only when strings are same to ohters.
|
|
In the past, it was imemo. However a075c55 changed it.
Therefore no need to use `VALUE` for the first field.
|
|
|
|
|
|
The size of `struct parser_params` is 8 bytes difference in `ripper_s_allocate` and `rb_ruby_parser_allocate` when the universal parser is
enabled.
This causes a situation where `*r->p` is not fully initialized in `ripper_s_allocate` as shown below.
```console
(gdb) p *r->p
$2 = {heap = 0x0, lval = 0x0, yylloc = 0x0, lex = {strterm = 0x0, gets = 0x0, input = 0, string_buffer = {head = 0x0, last = 0x0}, lastlin
e = 0x0,
nextline = 0x0, pbeg = 0x0, pcur = 0x0, pend = 0x0, ptok = 0x0, gets_ = {ptr = 0, call = 0x0}, state = EXPR_NONE, paren_nest = 0, lpar
_seen = 0,
debug = 0, has_shebang = 0, token_seen = 0, token_info_enabled = 0, error_p = 0, cr_seen = 0, value = 0, result = 0, parsing_thread = 0, s_value = 0,
s_lvalue = 0, s_value_stack = 2097}
````
This seems to cause `double free or corruption (!prev)` and SEGV.
So, fixing this by introduce `rb_ripper_parser_params_allocate` and `rb_ruby_parser_config` functions for Ripper, and `struct parser_params` same size is returned.
|
|
[Bug #20339]
[Bug #20341]
`const_decl_path` changes the value of `NODE **dest`, LHS of an assignment,
with `NODE_LIT` created by `const_decl_path`. `shareable_literal_constant` calls
`const_decl_path` via `ensure_shareable_node` multiple times if RHS of an assignment
is array or hash. This means `NODE **dest` argument of `const_decl_path` can be `NODE_LIT`
from the second time then causes `[BUG] unexpected node: NODE_LIT` in
`rb_node_const_decl_val`.
This commit change to not update `NODE **dest` in `const_decl_path` to
fix the issue.
|
|
|
|
|
|
parse.y:2624:1: warning: unused function 'rb_parser_ary_new'
|
|
- Introduce `rb_parser_ary_t` structure to partly eliminate RArray from parse.y
- In this patch, `parser_params->tokens` and `parser_params->ast->node_buffer->tokens` are now `rb_parser_ary_t *`
- Instead, `ast_node_all_tokens()` internally creates a Ruby Array object from the `rb_parser_ary_t`
- Also, delete `rb_ast_tokens()` and `rb_ast_set_tokens()` in node.c
- Implement `rb_parser_str_escape()`
- This is a port of the `rb_str_escape()` function in string.c
- `rb_parser_str_escape()` does not depend on `VALUE` (RString)
- Instead, it uses `rb_parser_stirng_t *`
- This function works when --dump=y option passed
- Because WIP of the universal parser, similar functions like `rb_parser_tokens_free()` exist in both node.c and parse.y. Refactoring them may be needed in some way in the future
- Although we considered redesigning the structure: `ast->node_buffer->tokens` into `ast->tokens`, we leave it as it is because `rb_ast_t` is an imemo. (We will address it in the future)
|
|
|
|
|