Skip to content

Commit 44d0e97

Browse files
committed
ArityCheckNode, add ExplodeLoop annotations for known sizes of parameter ids and number of keywords defined
1 parent d39d0f4 commit 44d0e97

File tree

2 files changed

+61
-35
lines changed

2 files changed

+61
-35
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/Arity.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,14 @@ public boolean takesOneArgument() {
213213
return takesFixedNumOfPositionalArgs() && minNumOfArgs == 1;
214214
}
215215

216+
public int getNumParameterIds() {
217+
return parameterIds.length;
218+
}
219+
220+
public int getNumKeywordNames() {
221+
return keywordNames.length;
222+
}
223+
216224
public static class KeywordName {
217225
public final String name;
218226
public final boolean required;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/ArityCheckNode.java

Lines changed: 53 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -93,21 +93,31 @@ private String[] extractKeywordNames(PKeyword[] keywords) {
9393
return extractKeywordNames(keywords.length, keywords);
9494
}
9595

96-
@Specialization(guards = {"cachedLen == keywords.length", "cachedDeclLen == arity.getKeywordNames().length"}, limit = "getVariableArgumentInlineCacheLimit()")
96+
@Specialization(guards = {
97+
"cachedLen == keywords.length",
98+
"cachedNumParamIds == arity.getNumParameterIds()",
99+
"cachedDeclLen == arity.getNumKeywordNames()"
100+
}, limit = "getVariableArgumentInlineCacheLimit()")
97101
void arityCheck(Arity arity, Object[] arguments, PKeyword[] keywords,
98-
@Cached("arity.getKeywordNames().length") int cachedDeclLen,
102+
@Cached("arity.getNumParameterIds()") int cachedNumParamIds,
103+
@Cached("arity.getNumKeywordNames()") int cachedDeclLen,
99104
@Cached("keywords.length") int cachedLen) {
100105
String[] kwNames = extractKeywordNames(cachedLen, keywords);
101-
arityCheck(arity, arguments, PArguments.getNumberOfUserArgs(arguments), cachedDeclLen, cachedLen, kwNames);
106+
arityCheck(arity, arguments, cachedNumParamIds, PArguments.getNumberOfUserArgs(arguments), cachedDeclLen, cachedLen, kwNames);
102107
}
103108

104-
@Specialization(guards = {"cachedLen == keywords.length", "cachedDeclLen == callee.getArity().getKeywordNames().length"}, limit = "getVariableArgumentInlineCacheLimit()")
109+
@Specialization(guards = {
110+
"cachedLen == keywords.length",
111+
"cachedNumParamIds == callee.getArity().getNumParameterIds()",
112+
"cachedDeclLen == callee.getArity().getNumKeywordNames()"
113+
}, limit = "getVariableArgumentInlineCacheLimit()")
105114
void arityCheckCallable(PythonCallable callee, Object[] arguments, PKeyword[] keywords,
106-
@Cached("callee.getArity().getKeywordNames().length") int cachedDeclLen,
115+
@Cached("callee.getArity().getNumParameterIds()") int cachedNumParamIds,
116+
@Cached("callee.getArity().getNumKeywordNames()") int cachedDeclLen,
107117
@Cached("keywords.length") int cachedLen) {
108118
String[] kwNames = extractKeywordNames(cachedLen, keywords);
109119
Arity arity = callee.getArity();
110-
arityCheck(arity, arguments, PArguments.getNumberOfUserArgs(arguments), cachedDeclLen, cachedLen, kwNames);
120+
arityCheck(arity, arguments, cachedNumParamIds, PArguments.getNumberOfUserArgs(arguments), cachedDeclLen, cachedLen, kwNames);
111121
}
112122

113123
@Specialization(replaces = "arityCheck")
@@ -122,13 +132,23 @@ void uncachedCheckCallable(PythonCallable callee, Object[] arguments, PKeyword[]
122132
arityCheck(callee.getArity(), arguments, PArguments.getNumberOfUserArgs(arguments), kwNames);
123133
}
124134

135+
@TruffleBoundary
125136
private void arityCheck(Arity arity, Object[] arguments, int numOfArgs, String[] keywords) {
126-
arityCheck(arity, arguments, numOfArgs, arity.getKeywordNames().length, keywords.length, keywords);
137+
arityCheck(arity, arguments, arity.getParameterIds().length, numOfArgs, arity.getKeywordNames().length, keywords.length, keywords);
138+
}
139+
140+
private void arityCheck(Arity arity, Object[] arguments, int numParameterIds, int numOfArgs, int numOfKeywordsDeclared, int numOfKeywordsGiven, String[] keywords) {
141+
checkPositional(arity, arguments, numParameterIds, numOfArgs, keywords);
142+
checkKeywords(arity, numOfKeywordsDeclared, numOfKeywordsGiven, keywords);
127143
}
128144

129-
private void checkPositional(Arity arity, Object[] arguments, int numOfArgs, String[] keywords) {
145+
private void checkPositional(Arity arity, Object[] arguments, int numParameterIds, int numOfArgs, String[] keywords) {
130146
// check missing paramIds
131-
checkMissingPositionalParamIds(arity, arguments);
147+
int cntMissingPositional = countMissingPositionalParamIds(numParameterIds, arguments);
148+
149+
if (missingPositionalArgs.profile(cntMissingPositional > 0)) {
150+
throw raise(TypeError, getMissingPositionalArgsErrorMessage(arity, arguments, cntMissingPositional));
151+
}
132152

133153
if (lessPositionalArgs.profile(numOfArgs < arity.getMinNumOfPositionalArgs())) {
134154
throw raise(TypeError, "%s() takes %s %d positional argument%s (%d given)",
@@ -142,19 +162,38 @@ private void checkPositional(Arity arity, Object[] arguments, int numOfArgs, Str
142162
}
143163
}
144164

165+
private void checkKeywords(Arity arity, int numOfKeywordsDeclared, int numOfKeywordsGiven, String[] keywords) {
166+
int cntGivenRequiredKeywords = countGivenRequiredKeywords(arity, numOfKeywordsDeclared, numOfKeywordsGiven, keywords);
167+
168+
if (missingKeywordArgs.profile(arity.takesRequiredKeywordArgs() && cntGivenRequiredKeywords < arity.getNumOfRequiredKeywords())) {
169+
throw raise(TypeError, getMissingRequiredKeywordsErrorMessage(arity, cntGivenRequiredKeywords, keywords));
170+
} else if (noKeywordArgs.profile(!arity.takesKeywordArgs() && numOfKeywordsGiven > 0)) {
171+
throw raise(TypeError, "%s() takes no keyword arguments",
172+
arity.getFunctionName());
173+
}
174+
}
175+
145176
@ExplodeLoop
146-
private void checkMissingPositionalParamIds(Arity arity, Object[] arguments) {
177+
private int countMissingPositionalParamIds(int numParameterIds, Object[] arguments) {
147178
int cntMissingPositional = 0;
148-
String[] parameterIds = arity.getParameterIds();
149-
for (int i = 0; i < parameterIds.length; i++) {
179+
for (int i = 0; i < numParameterIds; i++) {
150180
if (PArguments.getArgument(arguments, i) == null) {
151181
cntMissingPositional += 1;
152182
}
153183
}
184+
return cntMissingPositional;
185+
}
154186

155-
if (missingPositionalArgs.profile(cntMissingPositional > 0)) {
156-
throw raise(TypeError, getMissingPositionalArgsErrorMessage(arity, arguments, cntMissingPositional));
187+
@ExplodeLoop
188+
private int countGivenRequiredKeywords(Arity arity, int numOfKeywordsDeclared, int numOfKeywordsGiven, String[] keywords) {
189+
int cntGivenRequiredKeywords = 0;
190+
191+
for (int i = 0; i < numOfKeywordsGiven; i++) {
192+
String keyword = keywords[i];
193+
cntGivenRequiredKeywords += checkKeyword(arity, keyword, numOfKeywordsDeclared);
157194
}
195+
196+
return cntGivenRequiredKeywords;
158197
}
159198

160199
@ExplodeLoop(kind = ExplodeLoop.LoopExplosionKind.FULL_EXPLODE_UNTIL_RETURN)
@@ -176,22 +215,6 @@ private int checkKeyword(Arity arity, String keyword, int length) {
176215
return 0;
177216
}
178217

179-
@ExplodeLoop
180-
private void checkKeywords(Arity arity, int numOfKeywordsDeclared, int numOfKeywordsGiven, String[] keywords) {
181-
int cntGivenRequiredKeywords = 0;
182-
183-
for (int i = 0; i < numOfKeywordsGiven; i++) {
184-
String keyword = keywords[i];
185-
cntGivenRequiredKeywords += checkKeyword(arity, keyword, numOfKeywordsDeclared);
186-
}
187-
188-
if (missingKeywordArgs.profile(arity.takesRequiredKeywordArgs() && cntGivenRequiredKeywords < arity.getNumOfRequiredKeywords())) {
189-
throw raise(TypeError, getMissingRequiredKeywordsErrorMessage(arity, cntGivenRequiredKeywords, keywords));
190-
} else if (noKeywordArgs.profile(!arity.takesKeywordArgs() && numOfKeywordsGiven > 0)) {
191-
throw raise(TypeError, "%s() takes no keyword arguments", arity.getFunctionName());
192-
}
193-
}
194-
195218
@TruffleBoundary
196219
private String getMissingRequiredKeywordsErrorMessage(Arity arity, int cntGivenRequiredKeywords, String[] givenKeywords) {
197220
int missingRequiredKeywords = arity.getNumOfRequiredKeywords() - cntGivenRequiredKeywords;
@@ -281,9 +304,4 @@ private String getExtraPositionalArgsErrorMessage(Arity arity, int numOfArgs, St
281304
numOfArgs,
282305
givenCountMessage);
283306
}
284-
285-
private void arityCheck(Arity arity, Object[] arguments, int numOfArgs, int numOfKeywordsDeclared, int numOfKeywordsGiven, String[] keywords) {
286-
checkPositional(arity, arguments, numOfArgs, keywords);
287-
checkKeywords(arity, numOfKeywordsDeclared, numOfKeywordsGiven, keywords);
288-
}
289307
}

0 commit comments

Comments
 (0)