Commit graph

1961 commits

Author SHA1 Message Date
Nobuyoshi Nakada
2698f13a1f
Fixed reserved numbered parameter warning 2019-09-19 19:40:44 +09:00
Nobuyoshi Nakada
3a3f48fb8f
Comment lines can be placed between fluent dot now 2019-09-15 23:12:24 +09:00
Aaron Patterson
515b1989b1
Make NODE_ARYPTN layout consistent between Ripper and AST
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:

  1febb6f4a1/parse.y (L757-L761)

Where parse.y will normally assign other things:

  1febb6f4a1/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:

  1febb6f4a1/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-11 14:58:51 -07:00
Aaron Patterson
14e3731059
Make sure WB executes after object is reachable 2019-09-11 11:57:57 -07:00
Nobuyoshi Nakada
343b0a281d
Made a short-circuit expression w/o result into an if-statement 2019-09-11 16:27:30 +09:00
卜部昌平
655c65d65b &$$->nd_lit is uninitialized at this point
See also 583031687 (L1874)
2019-09-11 16:01:18 +09:00
Aaron Patterson
91ee9584f9
Macros can't be expressions, so make a function
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-10 14:00:48 -07:00
Aaron Patterson
139510238b
WB needs to be executed after object is reachable 2019-09-10 12:42:35 -07:00
Aaron Patterson
d8a4af47a5
Only use add_mark_object in Ripper
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-09 14:26:57 -07:00
Aaron Patterson
4524780d17
Revert "Reverting node marking until I can fix GC problem."
This reverts commit 092f31e7e2.
2019-09-09 14:26:51 -07:00
Yusuke Endoh
a3f5265fd1 parse.y: Use the correct alias for brace flag of hash literal
nd_alen and nd_brace is the same field, but nd_brace is more suitable
for this case.
2019-09-08 00:28:03 +09:00
Yusuke Endoh
a7a2be7a31 Rename some function/definition names that handles NODE_LIST
from array to list.
Follow up to ac50ac03aeb210763730cdc45f230e236519223d
2019-09-07 13:56:41 +09:00
Yusuke Endoh
99c9431ea1 Rename NODE_ARRAY to NODE_LIST to reflect its actual use cases
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-07 13:56:29 +09:00
Nobuyoshi Nakada
3754e15530
Warn local variables which conflict with new numbered parameters 2019-09-06 09:02:12 +09:00
Aaron Patterson
092f31e7e2
Reverting node marking until I can fix GC problem.
Looks like we're getting WB misses during stressful GC on startup.  I am
investigating.
2019-09-05 12:44:23 -07:00
Aaron Patterson
8f096226e1
Stash tmpbuffer inside internal structs
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-05 11:04:43 -07:00
Aaron Patterson
429ed8d587
Don't change DSTR nodes to ARRAY nodes
DSTR nodes are allocated in to the "markable" bucket where ARRAY nodes
are not.  Switching buckets can cause errors during GC.
2019-09-05 10:13:50 -07:00
Aaron Patterson
545b6db3fb
Create two buckets for allocating NODE structs
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-05 10:13:50 -07:00
Aaron Patterson
f0fd1c0cd8
Stash the imemo buf at the end of the ID list
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-05 10:13:50 -07:00
Aaron Patterson
64817a7cfd
Mark some tmpbufs via node objects
This way we don't need to add the tmpbufs to a Ruby array for marking
2019-09-05 10:13:50 -07:00
Aaron Patterson
581fcde088
Directly mark node objects instead of using a mark array
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-05 10:13:49 -07:00
Jeremy Evans
c6464c44c0 Fix code locations of array node inside hash node when multiple kw splats
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.
2019-09-05 09:57:43 -07:00
Jeremy Evans
1d5066efb0 Make m(**{}) mean call without keywords
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
```
2019-09-05 09:57:43 -07:00
Kazuki Tsujimoto
94d6ec1d90
Make pattern matching support **nil syntax 2019-09-01 16:39:34 +09:00
Nobuyoshi Nakada
e80a6f65c8
Made :nil static ID 2019-09-01 13:37:28 +09:00
Jeremy Evans
42adc5bc6b Add back missing warning for duplicate keys in splatted hashes
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.
2019-08-30 12:39:31 -07:00
Jeremy Evans
4d64693c70 Make ripper support **nil syntax
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.
2019-08-30 12:39:31 -07:00
Jeremy Evans
6a9ce1fea8 Support **nil syntax for specifying a method does not accept keyword arguments
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.
2019-08-30 12:39:31 -07:00
Yusuke Endoh
16c6984bb9 Separate keyword arguments from positional arguments
And, allow non-symbol keys as a keyword arugment
2019-08-30 12:39:31 -07:00
Nobuyoshi Nakada
01b723ba6d
Refined warnings against literal in flip-flop 2019-08-29 23:06:27 +09:00
Nobuyoshi Nakada
2ed68d0ff9
Revert "Add pipeline operator [Feature #15799]"
This reverts commits:
* d365fd5a02
* d780c36624
* aa7211836b
* 043f010c28
* bb4dd7c6af05c7821d572e2592ea3d0cc748d81f
* 043f010c28
* f169043d81

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/94645
2019-08-29 15:27:59 +09:00
Aaron Patterson
932a471d38
Directly mark compile options from the AST object
`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-27 11:43:18 -07:00
Kazuhiro NISHIYAMA
5d5502dc85
Fix typos 2019-08-24 21:26:24 +09:00
Nobuyoshi Nakada
d5b917d500
Named numbered parameter indexes 2019-08-24 01:10:42 +09:00
Jeremy Evans
53b3be5d58 Fix parsing of mutiple assignment with rescue modifier
Single assignment with rescue modifier applies rescue to the RHS:

  a = raise rescue 1 # a = (raise rescue 1)

Previously, multiple assignment with rescue modifier applied rescue
to the entire expression:

  a, b = raise rescue [1, 2] # (a, b = raise) rescue [1, 2]

This makes multiple assignment with rescue modifier consistent with
single assignment with rescue modifier, applying rescue to the RHS:

  a, b = raise rescue [1, 2] # a, b = (raise rescue [1, 2])

Implements [Feature #8239]
Fixes [Bug #8279]
2019-08-09 09:25:30 -07:00
Takashi Kokubun
a3188f43a8
Revert "Revert "Fix dangling path name from fstring""
This reverts commit 326c00b6f8.

We also confirmed that test_gced_eval_location fails without the changes:
567417818
20190804T000003Z.fail.html.gz
20190804T003005Z.fail.html.gz
20190804T000007Z.fail.html.gz
20190804T001806Z.fail.html.gz
20190804T003005Z.fail.html.gz
2019-08-04 10:08:17 +09:00
Takashi Kokubun
326c00b6f8
Revert "Fix dangling path name from fstring"
This reverts commit 5931857281 temporarily,
leaving `TestEval#test_gced_eval_location` to see the impact for missing
the changes.

That's because too many CIs are failing for `require` behaviors:
20190803T063004Z.fail.html.gz
20190803T051806Z.fail.html.gz
20190803T052406Z.fail.html.gz
20190803T111909Z.fail.html.gz
20190803T062506Z.fail.html.gz
20190803T052505Z.fail.html.gz
5d4512c921
5d4512c921
http://ci.rvm.jp/results/trunk_gcc4@silicon-docker/2177591
http://ci.rvm.jp/results/trunk_gcc6@silicon-docker/2177596
http://ci.rvm.jp/results/trunk_clang_60@silicon-docker/2178802
http://ci.rvm.jp/results/trunk-theap-asserts@silicon-docker/2177555
http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/2178747

Mostly `TestRequire#test_race_exception` failures, but in ci.rvm.jp
`require` inside rubyspec hangs very often.
2019-08-04 08:52:41 +09:00
Nobuyoshi Nakada
5931857281
Fix dangling path name from fstring
* parse.y (yycompile): make sure in advance that the `__FILE__`
  object shares a fstring, to get rid of dangling path name.
  Fixed up 53e9908d8a.  [Bug #16041]

* vm_eval.c (eval_make_iseq): ditto.
2019-08-03 13:48:29 +09:00
Nobuyoshi Nakada
688a59f8ac
Show the location of eval which uses __FILE__/__LINE__ 2019-08-03 11:32:37 +09:00
Yusuke Endoh
e9e17cbc05 parse.y: make a warning for __FILE__ in eval by default
[Bug #4352]
2019-08-02 23:17:19 +09:00
Nobuyoshi Nakada
d488464106
Use predefined idOr 2019-08-01 16:35:43 +09:00
Nobuyoshi Nakada
fd461dea06
Ripper#validate_object: check if the object is hidden 2019-07-19 07:57:17 +09:00
Nobuyoshi Nakada
59d6ce4f4b
Moved RIPPER_DEBUG methods to Ripper from Kernel 2019-07-19 07:50:32 +09:00
Nobuyoshi Nakada
18bce998dd
Fixed build error with RIPPER_DEBUG 2019-07-19 07:50:32 +09:00
Nobuyoshi Nakada
a027c4b5b0
Use Qnull instead of 0 and Qundef 2019-07-19 06:23:19 +09:00
Nobuyoshi Nakada
0e23e0c3a0
Adjust indent [ci skip] 2019-07-17 17:04:37 +09:00
Yusuke Endoh
711dfec3fa parse.y (here_document): remove dead code
str is always zero when evaluating the branch.
Found by Coverity Scan.
2019-07-15 14:08:17 +09:00
Yusuke Endoh
9e3971c3ad Add a /* fall through */ comment 2019-07-15 00:29:56 +09:00
Yusuke Endoh
20a3fb3c4b Add a /* fall through */ comment 2019-07-14 21:34:32 +09:00
Nobuyoshi Nakada
4e038a7e64
Revert "parse.y: Deprecate flip-flops"
This reverts commit bae638ad5b.

[Feature #5400]
2019-07-11 14:52:02 +09:00