summaryrefslogtreecommitdiff
path: root/parse.y
AgeCommit message (Collapse)Author
2019-10-10Fixed numbered parameter checkNobuyoshi Nakada
* parse.y (struct local_vars): moved numbered parameter NODEs for nesting check to separate per local variable scopes, as numbered parameters should belong to local variable scopes. [Bug #16248]
2019-10-10lhs of pattern matching expression of should have a valueNobuyoshi Nakada
2019-10-09Prefer st_is_member over st_lookup with 0Ben Woosley
The st_is_member DEFINE has simpler semantics, for more readable code. Notes: Merged: https://github.com/ruby/ruby/pull/1622
2019-10-08Packed delayed token elementsNobuyoshi Nakada
2019-10-05Fix potential memory leaks by `rb_imemo_tmpbuf_auto_free_pointer`Nobuyoshi Nakada
This function has been used wrongly always at first, "allocate a buffer then wrap it with tmpbuf". This order can cause a memory leak, as tmpbuf creation also can raise a NoMemoryError exception. The right order is "create a tmpbuf then allocate&wrap a buffer". So the argument of this function is rather harmful than just useless. TODO: * Rename this function to more proper name, as it is not used "temporary" (function local) purpose. * Allocate and wrap at once safely, like `ALLOCV`.
2019-10-04parse.y: use "struct rb_iseq_struct" instead of rb_iseq_tYusuke Endoh
typedef was not declared in parse.y. Sorry.
2019-10-04Make parser_params have parent_iseq instead of base_blockYusuke Endoh
The parser needs to determine whether a local varaiable is defined or not in outer scope. For the sake, "base_block" field has kept the outer block. However, the whole block was actually unneeded; the parser used only base_block->iseq. So, this change lets parser_params have the iseq directly, instead of the whole block. Notes: Merged: https://github.com/ruby/ruby/pull/2519
2019-10-04Refactor parser_params by removing "in_main" flagYusuke Endoh
The relation between parser_param#base_block and #in_main were very subtle. A main script (that is passed via a command line) was parsed under base_block = TOPLEVEL_BINDING and in_main = 1. A script loaded by Kernel#require was parsed under base_block = NULL and in_main = 0. If base_block is non-NULL and in_main == 0, it is parsed by Kernel#eval or family. However, we know that TOPLEVEL_BINDING has no local variables when a main script is parsed. So, we don't have to parse a main script under base_block = TOPLEVEL_BINDING. Instead, this change parses a main script under base_block = 0. If base_block is non-NULL, it is parsed by Kernel#eval or family. By this simplication, "in_main" is no longer needed. Notes: Merged: https://github.com/ruby/ruby/pull/2519
2019-09-26[EXPERIMENTAL] Expression with modifier `in`Nobuyoshi Nakada
[Feature #15865] Notes: Merged: https://github.com/ruby/ruby/pull/2485
2019-09-25Removed idNUMPARAM_0Nobuyoshi Nakada
2019-09-25Changed numbered parameters semanticsNobuyoshi Nakada
* `_1` (and no other numbered parameters) to work as `|x|`. * giving up `_0`. [ruby-core:95074] [Bug #16178]
2019-09-25Simplified duplicate codeNobuyoshi Nakada
2019-09-24Make numbered parameters exclusive in a scopeNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/2431
2019-09-24Changed numbered parameter prefixNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/2431
2019-09-24Added implicit block parameterNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/2431
2019-09-20Allows calling a private method only with bare `self`Nobuyoshi Nakada
2019-09-19Fixed reserved numbered parameter warningNobuyoshi Nakada
2019-09-15Comment lines can be placed between fluent dot nowNobuyoshi Nakada
2019-09-11Make NODE_ARYPTN layout consistent between Ripper and ASTAaron Patterson
We are seeing SEGVs in CI: http://ci.rvm.jp/results/trunk-gc-asserts@ruby-sky1/2253563 This is happening because Ripper constructs AST nodes differently than parse.y normally does. Specifically in this case Ripper is assigning 3 `VALUE` objects: https://github.com/ruby/ruby/blob/1febb6f4a14f7222c6d30250bfdc252d34238187/parse.y#L757-L761 Where parse.y will normally assign other things: https://github.com/ruby/ruby/blob/1febb6f4a14f7222c6d30250bfdc252d34238187/parse.y#L11258-L11260 The important one is the last one, the `struct rb_ary_pattern_info`. The mark function assumed that `NODE_ARYPTN` have a pointer to `struct rb_ary_pattern_info`, and used it: https://github.com/ruby/ruby/blob/1febb6f4a14f7222c6d30250bfdc252d34238187/node.c#L1269-L1274 In the case of Ripper, `NODE_ARYPTN` doesn't point to an `rb_ary_pattern_info`, so the mark function would SEGV. This commit changes Ripper so that its `NODE_ARYPTN` nodes also point at an `rb_ary_pattern_info`, and the mark function can continue with the same assumption.
2019-09-11Make sure WB executes after object is reachableAaron Patterson
2019-09-11Made a short-circuit expression w/o result into an `if`-statementNobuyoshi Nakada
2019-09-11&$$->nd_lit is uninitialized at this point卜部昌平
See also https://travis-ci.org/ruby/ruby/jobs/583031687#L1874 Notes: Merged: https://github.com/ruby/ruby/pull/2444
2019-09-10Macros can't be expressions, so make a functionAaron Patterson
Macros can't be expressions, that is a GNU extension (I didn't know that). This commit converts the macro to a function so that everything will compile correctly on non-GNU compatible compilers.
2019-09-10WB needs to be executed after object is reachableAaron Patterson
2019-09-09Only use `add_mark_object` in RipperAaron Patterson
This patch changes parse.y to only use `add_mark_object` in Ripper. Previously we were seeing a bug in write barrier verification. I had changed `add_mark_object` to execute the write barrier, but the problem is that we had code like this: ``` NEW_STR(add_mark_object(p, obj), loc) ``` In this case, `add_mark_object` would execute the write barrier between the ast and `obj`, but the problem is that `obj` isn't actually reachable from the AST at the time the write barrier executed. `NEW_STR` can possibly call `malloc` which can kick a GC, and since `obj` isn't actually reachable from the AST at the time of WB execution, verification would fail. Basically the steps were like this: 1. RB_OBJ_WRITTEN via `add_mark_object` 2. Allocate node 3. *Possibly* execute GC via malloc 4. Write obj in to allocated node This patch changes the steps to: 1. Allocate node 2. *Possibly* execute GC via malloc 3. Write obj in to allocated node 4. RB_OBJ_WRITTEN
2019-09-09Revert "Reverting node marking until I can fix GC problem."Aaron Patterson
This reverts commit 092f31e7e23c0ee04df987f0c0f979d036971804.
2019-09-08parse.y: Use the correct alias for brace flag of hash literalYusuke Endoh
nd_alen and nd_brace is the same field, but nd_brace is more suitable for this case.
2019-09-07Rename some function/definition names that handles NODE_LISTYusuke Endoh
from array to list. Follow up to ac50ac03aeb210763730cdc45f230e236519223d
2019-09-07Rename NODE_ARRAY to NODE_LIST to reflect its actual use casesYusuke Endoh
and NODE_ZARRAY to NODE_ZLIST. NODE_ARRAY is used not only by an Array literal, but also the contents of Hash literals, method call arguments, dynamic string literals, etc. In addition, the structure of NODE_ARRAY is a linked list, not an array. This is very confusing, so I believe `NODE_LIST` is a better name.
2019-09-06Warn local variables which conflict with new numbered parametersNobuyoshi Nakada
2019-09-05Reverting node marking until I can fix GC problem.Aaron Patterson
Looks like we're getting WB misses during stressful GC on startup. I am investigating.
2019-09-05Stash tmpbuffer inside internal structsAaron Patterson
I guess those AST node were actually used for something, so we'd better not touch them. Instead this commit just puts the tmpbuffer inside a different internal struct so that we can mark them.
2019-09-05Don't change DSTR nodes to ARRAY nodesAaron Patterson
DSTR nodes are allocated in to the "markable" bucket where ARRAY nodes are not. Switching buckets can cause errors during GC.
2019-09-05Create two buckets for allocating NODE structsAaron Patterson
This commit adds two buckets for allocating NODE structs, then allocates "markable" NODE objects from one bucket. The reason to do this is so when the AST mark function scans nodes for VALUE objects to mark, we only scan NODE objects that we know to reference VALUE objects. If we *did not* divide the objects, then the mark function spends too much time scanning objects that don't contain any references.
2019-09-05Stash the imemo buf at the end of the ID listAaron Patterson
Now we can reach the ID table buffer from the id table itself, so when SCOPE nodes are marked we can keep the buffers alive. This eliminates the need for the "mark array" during normal parse / compile (IOW *not* Ripper).
2019-09-05Mark some tmpbufs via node objectsAaron Patterson
This way we don't need to add the tmpbufs to a Ruby array for marking
2019-09-05Directly mark node objects instead of using a mark arrayAaron Patterson
This patch changes the AST mark function so that it will walk through nodes in the NODE buffer marking Ruby objects rather than using a mark array to guarantee liveness. The reason I want to do this is so that when compaction happens on major GCs, node objects will have their references pinned (or possibly we can update them correctly).
2019-09-05Fix code locations of array node inside hash node when multiple kw splatsJeremy Evans
This is broken at least since 2.5 (I didn't check earlier versions). It resulted in failure in test_ast.rb when the tests were added before the parser change. Basically, in remove_duplicate_keys, if the node is modified, set the location information to the previous location information. The removal of keys should not affect the location in the code. Notes: Merged: https://github.com/ruby/ruby/pull/2428
2019-09-05Make m(**{}) mean call without keywordsJeremy Evans
Previously, **{} was removed by the parser: ``` $ ruby --dump=parse -e '{**{}}' @ NODE_SCOPE (line: 1, location: (1,0)-(1,6)) +- nd_tbl: (empty) +- nd_args: | (null node) +- nd_body: @ NODE_HASH (line: 1, location: (1,0)-(1,6))* +- nd_brace: 1 (hash literal) +- nd_head: (null node) ``` Since it was removed by the parser, the compiler did not know about it, and `m(**{})` was therefore treated as `m()`. This modifies the parser to not remove the `**{}`. A simple approach for this is fairly simple by just removing a few lines from the parser, but that would cause two hash allocations every time it was used. The approach taken here modifies both the parser and the compiler, and results in `**{}` not allocating any hashes in the usual case. The basic idea is we use a literal node in the parser containing a frozen empty hash literal. In the compiler, we recognize when that is used, and if it is the only keyword present, we just push it onto the VM stack (no creation of a new hash or merging of keywords). If it is the first keyword present, we push a new empty hash onto the VM stack, so that later keywords can merge into it. If it is not the first keyword present, we can ignore it, since the there is no reason to merge an empty hash into the existing hash. Example instructions for `m(**{})` Before (note ARGS_SIMPLE): ``` == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,7)> (catch: FALSE) 0000 putself ( 1)[Li] 0001 opt_send_without_block <callinfo!mid:m, argc:0, FCALL|ARGS_SIMPLE>, <callcache> 0004 leave ``` After (note putobject and KW_SPLAT): ``` == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,7)> (catch: FALSE) 0000 putself ( 1)[Li] 0001 putobject {} 0003 opt_send_without_block <callinfo!mid:m, argc:1, FCALL|KW_SPLAT>, <callcache> 0006 leave ``` Example instructions for `m(**h, **{})` Before and After (no change): ``` == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE) 0000 putself ( 1)[Li] 0001 putspecialobject 1 0003 newhash 0 0005 putself 0006 opt_send_without_block <callinfo!mid:h, argc:0, FCALL|VCALL|ARGS_SIMPLE>, <callcache> 0009 opt_send_without_block <callinfo!mid:core#hash_merge_kwd, argc:2, ARGS_SIMPLE>, <callcache> 0012 opt_send_without_block <callinfo!mid:m, argc:1, FCALL|KW_SPLAT>, <callcache> 0015 leave ``` Example instructions for `m(**{}, **h)` Before: ``` == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE) 0000 putself ( 1)[Li] 0001 putspecialobject 1 0003 newhash 0 0005 putself 0006 opt_send_without_block <callinfo!mid:h, argc:0, FCALL|VCALL|ARGS_SIMPLE>, <callcache> 0009 opt_send_without_block <callinfo!mid:core#hash_merge_kwd, argc:2, ARGS_SIMPLE>, <callcache> 0012 opt_send_without_block <callinfo!mid:m, argc:1, FCALL|KW_SPLAT>, <callcache> 0015 leave ``` After (basically the same except for the addition of swap): ``` == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE) 0000 putself ( 1)[Li] 0001 newhash 0 0003 putspecialobject 1 0005 swap 0006 putself 0007 opt_send_without_block <callinfo!mid:h, argc:0, FCALL|VCALL|ARGS_SIMPLE>, <callcache> 0010 opt_send_without_block <callinfo!mid:core#hash_merge_kwd, argc:2, ARGS_SIMPLE>, <callcache> 0013 opt_send_without_block <callinfo!mid:m, argc:1, FCALL|KW_SPLAT>, <callcache> 0016 leave ``` Notes: Merged: https://github.com/ruby/ruby/pull/2428
2019-09-01Make pattern matching support **nil syntaxKazuki Tsujimoto
2019-09-01Made :nil static IDNobuyoshi Nakada
2019-08-30Add back missing warning for duplicate keys in splatted hashesJeremy Evans
This reverts the changes to parse.y in a5b37262524ac39d2af13eea174486370a581c23 as they are not actually needed and cause the warning for duplicate hash keys to not be emitted. Notes: Merged: https://github.com/ruby/ruby/pull/2395
2019-08-30Make ripper support **nil syntaxJeremy Evans
The on_params hook will use :nil as the keyword rest argument. There is a new on_nokw_param hook as well. This fixes a type issue in the previous code, where an ID was passed where a VALUE was the declared type. The symbol :nil is passed instead of the id. Notes: Merged: https://github.com/ruby/ruby/pull/2395
2019-08-30Support **nil syntax for specifying a method does not accept keyword argumentsJeremy Evans
This syntax means the method should be treated as a method that uses keyword arguments, but no specific keyword arguments are supported, and therefore calling the method with keyword arguments will raise an ArgumentError. It is still allowed to double splat an empty hash when calling the method, as that does not pass any keyword arguments. Notes: Merged: https://github.com/ruby/ruby/pull/2395
2019-08-30Separate keyword arguments from positional argumentsYusuke Endoh
And, allow non-symbol keys as a keyword arugment Notes: Merged: https://github.com/ruby/ruby/pull/2395
2019-08-29Refined warnings against literal in flip-flopNobuyoshi Nakada
2019-08-29Revert "Add pipeline operator [Feature #15799]"Nobuyoshi Nakada
This reverts commits: * d365fd5a024254d7c105a62a015a7ea29ccf3e5d * d780c3662484d6072b3a6945b840049de72c2096 * aa7211836b769231a2a8ef6b6ec2fd0ec882ef29 * 043f010c28e82ea38978bf8ed885416f133b5b75 * bb4dd7c6af05c7821d572e2592ea3d0cc748d81f * 043f010c28e82ea38978bf8ed885416f133b5b75 * f169043d81524b5b529f2c1e9c35437ba5bc3a7a http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/94645
2019-08-27Directly mark compile options from the AST objectAaron Patterson
`rb_ast_t` holds a reference to this object, so it should mark the object. Currently it is relying on the `mark_ary` on `node_buffer` to ensure that the object stays alive. But since the array internals can move, this could cause a segv if compaction impacts the array.
2019-08-24Fix typosKazuhiro NISHIYAMA
2019-08-24Named numbered parameter indexesNobuyoshi Nakada