Skip to content

Commit ad5cede

Browse files
committed
Refactor CheckArityNode to make it reusable
1 parent a69aab9 commit ad5cede

File tree

3 files changed

+47
-32
lines changed

3 files changed

+47
-32
lines changed

src/main/java/org/truffleruby/language/arguments/CheckArityNode.java

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
*/
1010
package org.truffleruby.language.arguments;
1111

12+
import com.oracle.truffle.api.CompilerAsserts;
13+
import com.oracle.truffle.api.TruffleLanguage.ContextReference;
14+
import com.oracle.truffle.api.nodes.Node;
15+
import org.truffleruby.RubyContext;
1216
import org.truffleruby.language.RubyContextSourceNode;
1317
import org.truffleruby.language.RubyNode;
1418
import org.truffleruby.language.control.RaiseException;
@@ -31,49 +35,47 @@ public CheckArityNode(Arity arity, RubyNode body) {
3135

3236
@Override
3337
public void doExecuteVoid(VirtualFrame frame) {
34-
checkArity(frame);
38+
checkArity(arity, RubyArguments.getArgumentsCount(frame), checkFailedProfile, getContextReference(), this);
3539
body.doExecuteVoid(frame);
3640
}
3741

3842
@Override
3943
public Object execute(VirtualFrame frame) {
40-
checkArity(frame);
44+
checkArity(arity, RubyArguments.getArgumentsCount(frame), checkFailedProfile, getContextReference(), this);
4145
return body.execute(frame);
4246
}
4347

44-
private void checkArity(VirtualFrame frame) {
45-
final int given = RubyArguments.getArgumentsCount(frame);
46-
47-
if (!checkArity(arity, given)) {
48+
public static void checkArity(Arity arity, int given,
49+
BranchProfile checkFailedProfile,
50+
ContextReference<RubyContext> contextRef,
51+
Node currentNode) {
52+
CompilerAsserts.partialEvaluationConstant(arity);
53+
if (!arity.check(given)) {
4854
checkFailedProfile.enter();
49-
if (arity.hasRest()) {
50-
throw new RaiseException(
51-
getContext(),
52-
coreExceptions().argumentErrorPlus(given, arity.getRequired(), this));
53-
} else if (arity.getOptional() > 0) {
54-
throw new RaiseException(
55-
getContext(),
56-
coreExceptions().argumentError(given, arity.getRequired(), arity.getOptional(), this));
57-
} else {
58-
throw new RaiseException(
59-
getContext(),
60-
coreExceptions().argumentError(given, arity.getRequired(), this));
61-
}
55+
checkArityError(arity, given, contextRef, currentNode);
6256
}
6357
}
6458

65-
static boolean checkArity(Arity arity, int given) {
66-
final int required = arity.getRequired();
67-
68-
if (required != 0 && given < required) {
69-
return false;
59+
private static void checkArityError(Arity arity, int given, ContextReference<RubyContext> contextRef,
60+
Node currentNode) {
61+
final RubyContext context = contextRef.get();
62+
if (arity.hasRest()) {
63+
throw new RaiseException(
64+
context,
65+
context.getCoreExceptions().argumentErrorPlus(given, arity.getRequired(), currentNode));
66+
} else if (arity.getOptional() > 0) {
67+
throw new RaiseException(
68+
context,
69+
context.getCoreExceptions().argumentError(
70+
given,
71+
arity.getRequired(),
72+
arity.getOptional(),
73+
currentNode));
74+
} else {
75+
throw new RaiseException(
76+
context,
77+
context.getCoreExceptions().argumentError(given, arity.getRequired(), currentNode));
7078
}
71-
72-
if (!arity.hasRest() && given > required + arity.getOptional()) {
73-
return false;
74-
}
75-
76-
return true;
7779
}
7880

7981
@Override

src/main/java/org/truffleruby/language/arguments/CheckKeywordArityNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ private void checkArity(VirtualFrame frame) {
6767
given -= 1;
6868
}
6969

70-
if (!CheckArityNode.checkArity(arity, given)) {
70+
if (!arity.basicCheck(given)) {
7171
basicArityCheckFailedProfile.enter();
7272
throw new RaiseException(getContext(), coreExceptions().argumentError(given, arity.getRequired(), this));
7373
}

src/main/java/org/truffleruby/language/methods/Arity.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import org.truffleruby.parser.ArgumentDescriptor;
1919
import org.truffleruby.parser.ArgumentType;
2020

21-
public class Arity {
21+
public final class Arity {
2222

2323
public static final String[] NO_KEYWORDS = StringUtils.EMPTY_STRING_ARRAY;
2424
public static final Arity NO_ARGUMENTS = new Arity(0, 0, false);
@@ -84,6 +84,19 @@ public Arity consumingFirstRequired() {
8484
hasKeywordsRest);
8585
}
8686

87+
public boolean check(int given) {
88+
assert !acceptsKeywords();
89+
90+
int required = getRequired();
91+
return given >= required && (hasRest || given <= required + optional);
92+
}
93+
94+
/** Same as above but without the assert for CheckKeywordArityNode */
95+
public boolean basicCheck(int given) {
96+
int required = getRequired();
97+
return given >= required && (hasRest || given <= required + optional);
98+
}
99+
87100
public int getPreRequired() {
88101
return preRequired;
89102
}

0 commit comments

Comments
 (0)