Skip to content

Commit b0f7cef

Browse files
committed
[GR-30301] Backports for 21.1
PullRequest: truffleruby/2530
2 parents 93a971a + 03eb8d8 commit b0f7cef

File tree

9 files changed

+67
-10
lines changed

9 files changed

+67
-10
lines changed

.gitattributes

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
# Merge options
2-
3-
/CHANGELOG.md merge=union
4-
51
# Rules for GitHub's Linguist language-classification system. We're abusing the
62
# 'vendored' attribute to exclude files as a lot of this isn't really vendored,
73
# and a whole lot of actually vendored code isn't listed! What we want to do is

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Bug fixes:
2222
* Fixed `TruffleRuby.synchronized` to handle guest safepoints (#2277).
2323
* Fix control flow bug when assigning constants using ||= (#1489).
2424
* Fix `Kernel#raise` argument handling for hashes (#2298).
25+
* Set errinfo when `rb_protect` captures a Ruby exception (#2245).
26+
* Fixed handling of multiple optional arguments and keywords when passed a positional `Hash` (#2302).
2527

2628
Compatibility:
2729

lib/patches/rubygems/ext/builder.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
require 'rubygems/ext/builder'
2+
3+
# nokogiri 1.11.2 defaults to --disable-static, so this is noop on recent nokogiri.
4+
# This fixes a compilation issue on older macOS for older nokogiri releases (GR-30240).
5+
# About 2x faster to build than without --disable-static for older nokogiri releases on macOS.
6+
# Also gives more flexibility to control what is run natively and on Sulong.
7+
module Truffle::NokogiriDefaultBuildsArgs
8+
def initialize(*args)
9+
super
10+
11+
if @spec.name == 'nokogiri' and @build_args.empty?
12+
@build_args = ['--disable-static']
13+
end
14+
end
15+
end
16+
17+
class Gem::Ext::Builder
18+
prepend Truffle::NokogiriDefaultBuildsArgs
19+
end

lib/truffle/truffle/cext.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,7 @@ def rb_protect(function, arg, write_status, status)
992992
unless Primitive.object_equal(nil, e)
993993
store = (Thread.current[:__stored_exceptions__] ||= [])
994994
pos = store.push(e).size
995+
Primitive.thread_set_exception(extract_ruby_exception(e))
995996
end
996997

997998
Truffle::Interop.execute_without_conversion(write_status, status, pos)

spec/ruby/language/method_spec.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,6 +1758,17 @@ def m(a: nil); a; end
17581758
end
17591759
end
17601760
end
1761+
1762+
it "assigns the last Hash to the last optional argument if the Hash contains non-Symbol keys and is not passed as keywords" do
1763+
def m(a = nil, b = {}, v: false)
1764+
[a, b, v]
1765+
end
1766+
1767+
h = { "key" => "value" }
1768+
m(:a, h).should == [:a, h, false]
1769+
m(:a, h, v: true).should == [:a, h, true]
1770+
m(v: true).should == [nil, {}, true]
1771+
end
17611772
end
17621773

17631774
describe "A method call with a space between method name and parentheses" do

spec/ruby/optional/capi/ext/kernel_spec.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,14 @@ static VALUE kernel_spec_rb_protect_yield(VALUE self, VALUE obj, VALUE ary) {
191191
return res;
192192
}
193193

194+
static VALUE kernel_spec_rb_protect_errinfo(VALUE self, VALUE obj, VALUE ary) {
195+
int status = 0;
196+
VALUE res = rb_protect(rb_yield, obj, &status);
197+
rb_ary_store(ary, 0, INT2NUM(23));
198+
rb_ary_store(ary, 1, res);
199+
return rb_errinfo();
200+
}
201+
194202
static VALUE kernel_spec_rb_protect_null_status(VALUE self, VALUE obj) {
195203
return rb_protect(rb_yield, obj, NULL);
196204
}
@@ -345,6 +353,7 @@ void Init_kernel_spec(void) {
345353
rb_define_method(cls, "rb_rescue", kernel_spec_rb_rescue, 4);
346354
rb_define_method(cls, "rb_rescue2", kernel_spec_rb_rescue2, -1);
347355
rb_define_method(cls, "rb_protect_yield", kernel_spec_rb_protect_yield, 2);
356+
rb_define_method(cls, "rb_protect_errinfo", kernel_spec_rb_protect_errinfo, 2);
348357
rb_define_method(cls, "rb_protect_null_status", kernel_spec_rb_protect_null_status, 1);
349358
rb_define_method(cls, "rb_eval_string_protect", kernel_spec_rb_eval_string_protect, 2);
350359
rb_define_method(cls, "rb_catch", kernel_spec_rb_catch, 2);

spec/ruby/optional/capi/kernel_spec.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,14 @@
312312
@s.rb_protect_null_status(42) { |x| x + 1 }.should == 43
313313
@s.rb_protect_null_status(42) { |x| raise }.should == nil
314314
end
315+
316+
it "populates errinfo with the captured exception" do
317+
proof = []
318+
@s.rb_protect_errinfo(77, proof) { |x| raise NameError }.class.should == NameError
319+
proof[0].should == 23
320+
proof[1].should == nil
321+
end
322+
315323
end
316324

317325
describe "rb_eval_string_protect" do

src/main/java/org/truffleruby/cext/CExtNodes.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,21 @@ protected Object executeWithProtect(RubyProc block,
11851185
}
11861186
}
11871187

1188+
@CoreMethod(names = "extract_ruby_exception", onSingleton = true, required = 1)
1189+
public abstract static class ExtractRubyException extends CoreMethodArrayArgumentsNode {
1190+
1191+
@Specialization
1192+
protected Object executeThrow(CapturedException captured,
1193+
@Cached ConditionProfile rubyExceptionProfile) {
1194+
final Throwable e = captured.getException();
1195+
if (rubyExceptionProfile.profile(e instanceof RaiseException)) {
1196+
return ((RaiseException) e).getException();
1197+
} else {
1198+
return nil;
1199+
}
1200+
}
1201+
}
1202+
11881203
@CoreMethod(names = "raise_exception", onSingleton = true, required = 1)
11891204
public abstract static class RaiseExceptionNode extends CoreMethodArrayArgumentsNode {
11901205

src/main/java/org/truffleruby/parser/LoadArgumentsTranslator.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ private enum State {
105105
private int index;
106106
private int indexFromEnd = 1;
107107
private State state;
108-
private boolean firstOpt = false;
109108

110109
public LoadArgumentsTranslator(
111110
Node currentNode,
@@ -180,7 +179,6 @@ public RubyNode translate() {
180179
index = argsNode.getPreCount();
181180
final int optArgIndex = argsNode.getOptArgIndex();
182181
for (int i = 0; i < optArgCount; i++) {
183-
firstOpt = i == 0;
184182
sequence.add(args[optArgIndex + i].accept(this));
185183
++index;
186184
}
@@ -349,8 +347,7 @@ public RubyNode visitRestArgNode(RestArgParseNode node) {
349347
if (useArray()) {
350348
readNode = ArraySliceNodeGen.create(from, to, loadArray(sourceSection));
351349
} else {
352-
boolean considerRejectedKWArgs = considerRejectedKWArgs();
353-
readNode = new ReadRestArgumentNode(from, -to, hasKeywordArguments, considerRejectedKWArgs, required);
350+
readNode = new ReadRestArgumentNode(from, -to, hasKeywordArguments, considerRejectedKWArgs(), required);
354351
}
355352

356353
final FrameSlot slot = methodBodyTranslator.getEnvironment().getFrameDescriptor().findFrameSlot(node.getName());
@@ -440,11 +437,10 @@ private RubyNode translateLocalAssignment(SourceIndexLength sourcePosition, Stri
440437
minimum += 1;
441438
}
442439

443-
final boolean considerRejectedKWArgs = firstOpt && considerRejectedKWArgs();
444440
readNode = new ReadOptionalArgumentNode(
445441
index,
446442
minimum,
447-
considerRejectedKWArgs,
443+
considerRejectedKWArgs(),
448444
argsNode.hasKwargs(),
449445
required,
450446
defaultValue);

0 commit comments

Comments
 (0)