Skip to content

Commit cc3deb1

Browse files
committed
[GR-19220] Pack missing block argument as nil instead of null (#2232)
PullRequest: truffleruby/2372
2 parents df8d21a + f36bcec commit cc3deb1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+214
-231
lines changed

spec/ruby/core/string/split_spec.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,14 @@
471471
a.should == ["Chunky", "Bacon"]
472472
end
473473

474+
it "yields each split substring with default pattern for a non-ASCII string" do
475+
a = []
476+
returned_object = "l'été arrive bientôt".split { |str| a << str }
477+
478+
returned_object.should == "l'été arrive bientôt"
479+
a.should == ["l'été", "arrive", "bientôt"]
480+
end
481+
474482
it "yields the string when limit is 1" do
475483
a = []
476484
returned_object = "chunky bacon".split("", 1) { |str| a << str.capitalize }

src/main/java/org/truffleruby/RubyContext.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
import org.truffleruby.language.CallStackManager;
6464
import org.truffleruby.core.string.ImmutableRubyString;
6565
import org.truffleruby.language.LexicalScope;
66+
import org.truffleruby.language.Nil;
6667
import org.truffleruby.language.RubyBaseNode;
6768
import org.truffleruby.language.SafepointManager;
6869
import org.truffleruby.language.arguments.RubyArguments;
@@ -445,7 +446,7 @@ public Object send(Object object, String methodName, Object... arguments) {
445446

446447
return IndirectCallNode.getUncached().call(
447448
method.getCallTarget(),
448-
RubyArguments.pack(null, null, method, null, object, null, arguments));
449+
RubyArguments.pack(null, null, method, null, object, Nil.INSTANCE, arguments));
449450
}
450451

451452
@TruffleBoundary

src/main/java/org/truffleruby/builtins/CoreMethodNodeManager.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.truffleruby.core.string.StringUtils;
2727
import org.truffleruby.core.support.TypeNodes;
2828
import org.truffleruby.language.LexicalScope;
29-
import org.truffleruby.language.NotProvided;
3029
import org.truffleruby.language.RubyNode;
3130
import org.truffleruby.language.RubyRootNode;
3231
import org.truffleruby.language.methods.Split;
@@ -304,7 +303,11 @@ public RubyNode createCoreMethodNode(NodeFactory<? extends RubyNode> nodeFactory
304303
}
305304

306305
if (method.needsBlock()) {
307-
argumentsNodes[i++] = new ReadBlockFromCurrentFrameArgumentsNode(NotProvided.INSTANCE);
306+
/* The way we write specializations for getting a block or not is that we use NotProvided like a missing
307+
* argument. The block coming into the method is actually always Nil or RubyProc, so here we check which and
308+
* convert Nil to NotProvided. */
309+
argumentsNodes[i++] = new ReadBlockFromCurrentFrameArgumentsNode.ConvertNilBlockToNotProvidedNode(
310+
new ReadBlockFromCurrentFrameArgumentsNode());
308311
}
309312

310313
if (!method.keywordAsOptional().isEmpty()) {

src/main/java/org/truffleruby/builtins/EnumeratorSizeNode.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
*/
1010
package org.truffleruby.builtins;
1111

12-
import org.truffleruby.core.proc.RubyProc;
1312
import org.truffleruby.core.symbol.RubySymbol;
1413
import org.truffleruby.language.RubyContextSourceNode;
1514
import org.truffleruby.language.RubyNode;
@@ -38,9 +37,9 @@ public EnumeratorSizeNode(RubySymbol enumeratorSize, RubySymbol methodName, Ruby
3837

3938
@Override
4039
public Object execute(VirtualFrame frame) {
41-
final RubyProc block = RubyArguments.getBlock(frame);
40+
final Object block = RubyArguments.getBlock(frame);
4241

43-
if (noBlockProfile.profile(block == null)) {
42+
if (noBlockProfile.profile(block == nil)) {
4443
if (toEnumWithSize == null) {
4544
CompilerDirectives.transferToInterpreterAndInvalidate();
4645
toEnumWithSize = insert(DispatchNode.create());

src/main/java/org/truffleruby/builtins/ReturnEnumeratorIfNoBlockNode.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
package org.truffleruby.builtins;
1111

1212
import org.truffleruby.core.array.ArrayUtils;
13-
import org.truffleruby.core.proc.RubyProc;
1413
import org.truffleruby.core.symbol.RubySymbol;
1514
import org.truffleruby.language.RubyContextSourceNode;
1615
import org.truffleruby.language.RubyNode;
@@ -37,9 +36,9 @@ public ReturnEnumeratorIfNoBlockNode(String methodName, RubyNode method) {
3736

3837
@Override
3938
public Object execute(VirtualFrame frame) {
40-
final RubyProc block = RubyArguments.getBlock(frame);
39+
final Object block = RubyArguments.getBlock(frame);
4140

42-
if (noBlockProfile.profile(block == null)) {
41+
if (noBlockProfile.profile(block == nil)) {
4342
if (toEnumNode == null) {
4443
CompilerDirectives.transferToInterpreterAndInvalidate();
4544
toEnumNode = insert(DispatchNode.create());

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ protected Object callSuper(VirtualFrame frame, Object[] args) {
870870
final MethodLookupResult superMethodLookup = ModuleOperations
871871
.lookupSuperMethod(callingMethod, callingMetaclass);
872872
final InternalMethod superMethod = superMethodLookup.getMethod();
873-
return callSuperMethodNode.execute(frame, callingSelf, superMethod, args, null);
873+
return callSuperMethodNode.execute(frame, callingSelf, superMethod, args, nil);
874874
}
875875

876876
@TruffleBoundary

src/main/java/org/truffleruby/core/array/ArrayHelpers.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,13 @@ public static void setSize(RubyArray array, int size) {
2929
array.size = size;
3030
}
3131

32+
private static boolean assertNoNullElement(Object store, int size) {
33+
return !(store instanceof Object[]) || ArrayUtils.assertNoNullElement((Object[]) store, size);
34+
}
35+
3236
public static RubyArray createArray(RubyContext context, RubyLanguage language, Object store, int size) {
3337
assert !(store instanceof Object[]) || store.getClass() == Object[].class;
38+
assert assertNoNullElement(store, size);
3439
return new RubyArray(context.getCoreLibrary().arrayClass, language.arrayShape, store, size);
3540
}
3641

src/main/java/org/truffleruby/core/array/ArrayNodes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1415,7 +1415,7 @@ public Object injectSymbolHelper(VirtualFrame frame, RubyArray array, String sym
14151415
loopProfile.profileCounted(array.size - n);
14161416
for (; loopProfile.inject(n < array.size); n++) {
14171417
accumulator = dispatch
1418-
.dispatch(frame, accumulator, symbol, null, new Object[]{ stores.read(store, n) });
1418+
.dispatch(frame, accumulator, symbol, nil, new Object[]{ stores.read(store, n) });
14191419
}
14201420
} finally {
14211421
LoopNode.reportLoopCount(this, n);

src/main/java/org/truffleruby/core/array/ArrayUtils.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,19 @@ public abstract class ArrayUtils {
2020

2121
public static final Object[] EMPTY_ARRAY = new Object[0];
2222

23+
public static boolean assertNoNullElement(Object[] array, int size) {
24+
assert size <= array.length;
25+
for (int i = 0; i < size; i++) {
26+
final Object element = array[i];
27+
assert element != null : element;
28+
}
29+
return true;
30+
}
31+
32+
public static boolean assertNoNullElement(Object[] array) {
33+
return assertNoNullElement(array, array.length);
34+
}
35+
2336
/** Extracts part of an array into a newly allocated byte[] array. Does not perform safety checks on parameters.
2437
*
2538
* @param source the source array whose values should be extracted

src/main/java/org/truffleruby/core/basicobject/BasicObjectNodes.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -619,11 +619,15 @@ public abstract static class SendNode extends CoreMethodArrayArgumentsNode {
619619

620620
@Specialization
621621
protected Object send(VirtualFrame frame, Object self, Object name, Object[] args, NotProvided block) {
622-
return send(frame, self, name, args, (RubyProc) null);
622+
return doSend(frame, self, name, args, nil);
623623
}
624624

625625
@Specialization
626626
protected Object send(VirtualFrame frame, Object self, Object name, Object[] args, RubyProc block) {
627+
return doSend(frame, self, name, args, block);
628+
}
629+
630+
private Object doSend(VirtualFrame frame, Object self, Object name, Object[] args, Object block) {
627631
DeclarationContext context = RubyArguments.getDeclarationContext(readCallerFrame.execute(frame));
628632
RubyArguments.setDeclarationContext(frame, context);
629633

@@ -660,7 +664,7 @@ protected Shape allocateSingleton(RubyClass rubyClass) {
660664

661665
@Override
662666
public Object inlineExecute(VirtualFrame frame, Object self, Object[] args, Object proc) {
663-
return execute(frame, proc);
667+
return execute(frame, self);
664668
}
665669

666670
@Override

0 commit comments

Comments
 (0)