aboutsummaryrefslogtreecommitdiffstats
path: root/parse.y
Commit message (Collapse)AuthorAgeFilesLines
* Fixed numbered parameter checkNobuyoshi Nakada2019-10-101-23/+26
| | | | | | * 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]
* lhs of pattern matching expression of should have a valueNobuyoshi Nakada2019-10-101-0/+1
|
* Prefer st_is_member over st_lookup with 0Ben Woosley2019-10-091-2/+2
| | | | The st_is_member DEFINE has simpler semantics, for more readable code.
* Packed delayed token elementsNobuyoshi Nakada2019-10-081-18/+20
|
* Fix potential memory leaks by `rb_imemo_tmpbuf_auto_free_pointer`Nobuyoshi Nakada2019-10-051-21/+22
| | | | | | | | | | | | | | 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`.
* parse.y: use "struct rb_iseq_struct" instead of rb_iseq_tYusuke Endoh2019-10-041-2/+2
| | | | typedef was not declared in parse.y. Sorry.
* Make parser_params have parent_iseq instead of base_blockYusuke Endoh2019-10-041-6/+6
| | | | | | | | | | | | 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.
* Refactor parser_params by removing "in_main" flagYusuke Endoh2019-10-041-4/+2
| | | | | | | | | | | | | | | | | | | 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.
* [EXPERIMENTAL] Expression with modifier `in`Nobuyoshi Nakada2019-09-261-2/+18
| | | | [Feature #15865]
* Removed idNUMPARAM_0Nobuyoshi Nakada2019-09-251-3/+10
|
* Changed numbered parameters semanticsNobuyoshi Nakada2019-09-251-38/+12
| | | | | | | * `_1` (and no other numbered parameters) to work as `|x|`. * giving up `_0`. [ruby-core:95074] [Bug #16178]
* Simplified duplicate codeNobuyoshi Nakada2019-09-251-11/+11
|
* Make numbered parameters exclusive in a scopeNobuyoshi Nakada2019-09-241-12/+104
|
* Changed numbered parameter prefixNobuyoshi Nakada2019-09-241-52/+29
|
* Added implicit block parameterNobuyoshi Nakada2019-09-241-8/+30
|
* Allows calling a private method only with bare `self`Nobuyoshi Nakada2019-09-201-0/+2
|
* Fixed reserved numbered parameter warningNobuyoshi Nakada2019-09-191-3/+7
|
* Comment lines can be placed between fluent dot nowNobuyoshi Nakada2019-09-151-0/+4
|
* Make NODE_ARYPTN layout consistent between Ripper and ASTAaron Patterson2019-09-111-5/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Make sure WB executes after object is reachableAaron Patterson2019-09-111-1/+1
|
* Made a short-circuit expression w/o result into an `if`-statementNobuyoshi Nakada2019-09-111-1/+1
|
* &$$->nd_lit is uninitialized at this point卜部昌平2019-09-111-2/+2
| | | | See also https://travis-ci.org/ruby/ruby/jobs/583031687#L1874
* Macros can't be expressions, so make a functionAaron Patterson2019-09-101-0/+16
| | | | | | 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.
* WB needs to be executed after object is reachableAaron Patterson2019-09-101-4/+4
|
* Only use `add_mark_object` in RipperAaron Patterson2019-09-091-23/+38
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* Revert "Reverting node marking until I can fix GC problem."Aaron Patterson2019-09-091-18/+22
| | | | This reverts commit 092f31e7e23c0ee04df987f0c0f979d036971804.
* parse.y: Use the correct alias for brace flag of hash literalYusuke Endoh2019-09-081-1/+1
| | | | | nd_alen and nd_brace is the same field, but nd_brace is more suitable for this case.
* Rename some function/definition names that handles NODE_LISTYusuke Endoh2019-09-071-7/+7
| | | | | from array to list. Follow up to ac50ac03aeb210763730cdc45f230e236519223d
* Rename NODE_ARRAY to NODE_LIST to reflect its actual use casesYusuke Endoh2019-09-071-18/+18
| | | | | | | | | | 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.
* Warn local variables which conflict with new numbered parametersNobuyoshi Nakada2019-09-061-0/+4
|
* Reverting node marking until I can fix GC problem.Aaron Patterson2019-09-051-22/+18
| | | | | Looks like we're getting WB misses during stressful GC on startup. I am investigating.
* Stash tmpbuffer inside internal structsAaron Patterson2019-09-051-2/+4
| | | | | | 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.
* Don't change DSTR nodes to ARRAY nodesAaron Patterson2019-09-051-3/+1
| | | | | DSTR nodes are allocated in to the "markable" bucket where ARRAY nodes are not. Switching buckets can cause errors during GC.
* Create two buckets for allocating NODE structsAaron Patterson2019-09-051-1/+1
| | | | | | | | | 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.
* Stash the imemo buf at the end of the ID listAaron Patterson2019-09-051-16/+8
| | | | | | | 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).
* Mark some tmpbufs via node objectsAaron Patterson2019-09-051-8/+9
| | | | This way we don't need to add the tmpbufs to a Ruby array for marking
* Directly mark node objects instead of using a mark arrayAaron Patterson2019-09-051-1/+12
| | | | | | | | 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).
* Fix code locations of array node inside hash node when multiple kw splatsJeremy Evans2019-09-051-0/+2
| | | | | | | | | | 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.
* Make m(**{}) mean call without keywordsJeremy Evans2019-09-051-2/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 ```
* Make pattern matching support **nil syntaxKazuki Tsujimoto2019-09-011-2/+19
|
* Made :nil static IDNobuyoshi Nakada2019-09-011-3/+3
|
* Add back missing warning for duplicate keys in splatted hashesJeremy Evans2019-08-301-1/+11
| | | | | | | 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.
* Make ripper support **nil syntaxJeremy Evans2019-08-301-3/+9
| | | | | | | | | 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.
* Support **nil syntax for specifying a method does not accept keyword argumentsJeremy Evans2019-08-301-0/+14
| | | | | | | | | 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.
* Separate keyword arguments from positional argumentsYusuke Endoh2019-08-301-11/+1
| | | | And, allow non-symbol keys as a keyword arugment
* Refined warnings against literal in flip-flopNobuyoshi Nakada2019-08-291-59/+27
|
* Revert "Add pipeline operator [Feature #15799]"Nobuyoshi Nakada2019-08-291-40/+2
| | | | | | | | | | | | | This reverts commits: * d365fd5a024254d7c105a62a015a7ea29ccf3e5d * d780c3662484d6072b3a6945b840049de72c2096 * aa7211836b769231a2a8ef6b6ec2fd0ec882ef29 * 043f010c28e82ea38978bf8ed885416f133b5b75 * bb4dd7c6af05c7821d572e2592ea3d0cc748d81f * 043f010c28e82ea38978bf8ed885416f133b5b75 * f169043d81524b5b529f2c1e9c35437ba5bc3a7a http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/94645
* Directly mark compile options from the AST objectAaron Patterson2019-08-271-2/+1
| | | | | | | `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.
* Fix typosKazuhiro NISHIYAMA2019-08-241-8/+8
|
* Named numbered parameter indexesNobuyoshi Nakada2019-08-241-10/+14
|