Skip to content

Commit

Permalink
Remove use of fastcall() from Eval.java
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 719841015
Change-Id: I811a8c944bcd6e073715e177d23c2df42f65ccf6
  • Loading branch information
pzembrod authored and copybara-github committed Jan 26, 2025
1 parent dd70e4d commit 56bf547
Showing 1 changed file with 8 additions and 109 deletions.
117 changes: 8 additions & 109 deletions src/main/java/net/starlark/java/eval/Eval.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@
package net.starlark.java.eval;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -656,40 +652,21 @@ private static Object evalCall(StarlarkThread.Frame fr, CallExpression call)

// StarStar and Star args are guaranteed to be last, if they occur.
ImmutableList<Argument> arguments = call.getArguments();
int n = arguments.size();
int numNonStarArgs = arguments.size();
Argument.StarStar starstar = null;
if (n > 0 && arguments.get(n - 1) instanceof Argument.StarStar) {
starstar = (Argument.StarStar) arguments.get(n - 1);
n--;
if (numNonStarArgs > 0 && arguments.get(numNonStarArgs - 1) instanceof Argument.StarStar) {
starstar = (Argument.StarStar) arguments.get(numNonStarArgs - 1);
numNonStarArgs--;
}
Argument.Star star = null;
if (n > 0 && arguments.get(n - 1) instanceof Argument.Star) {
star = (Argument.Star) arguments.get(n - 1);
n--;
if (numNonStarArgs > 0 && arguments.get(numNonStarArgs - 1) instanceof Argument.Star) {
star = (Argument.Star) arguments.get(numNonStarArgs - 1);
numNonStarArgs--;
}
// Inv: n = |positional| + |named|
// Inv: numNonStarArgs = |positional| + |named|

StarlarkCallable.ArgumentProcessor argumentProcessor =
Starlark.requestArgumentProcessor(fr.thread, fn);
if (argumentProcessor != null) {
return evalCallWithArgumentProcessor(
fr, call, argumentProcessor, arguments, star, starstar, n);
}
return evalFastcall(fr, fn, call, arguments, star, starstar, n);
}

// TODO(b/380824219): Inline this method into evalCall() and remove evalFastcall() once all
// implementations of StarlarkCallable.fastcall() (i.e. BuiltinFunction, StarlarkProvider, the
// default on StarlarkCallable and a few tests) have a callViaArgumentProcessor alternative.
private static Object evalCallWithArgumentProcessor(
StarlarkThread.Frame fr,
CallExpression call,
StarlarkCallable.ArgumentProcessor argumentProcessor,
ImmutableList<Argument> arguments,
Argument.Star star,
Argument.StarStar starstar,
int numNonStarArgs)
throws EvalException, InterruptedException {

int numPositionalArguments = call.getNumPositionalArguments();

Expand Down Expand Up @@ -752,84 +729,6 @@ private static Object evalCallWithArgumentProcessor(
}
}

// TODO(b/380824219): Remove evalFastcall() once all implementations of
// StarlarkCallable.fastcall() (i.e. BuiltinFunction, StarlarkProvider, the default on
// StarlarkCallable and a few tests) have a callViaArgumentProcessor alternative.
private static Object evalFastcall(
StarlarkThread.Frame fr,
Object fn,
CallExpression call,
ImmutableList<Argument> arguments,
Argument.Star star,
Argument.StarStar starstar,
int numNonStarArgs)
throws EvalException, InterruptedException {

// Allocate assuming no *args/**kwargs.
int npos = call.getNumPositionalArguments();

// f(expr) -- positional args
Object[] positional = npos == 0 ? EMPTY : new Object[npos];
int i;
for (i = 0; i < npos; i++) {
Argument arg = arguments.get(i);
Object value = eval(fr, arg.getValue());
positional[i] = value;
}

// f(id=expr) -- named args
Object[] named = numNonStarArgs == npos ? EMPTY : new Object[2 * (numNonStarArgs - npos)];
for (int j = 0; i < numNonStarArgs; i++) {
Argument.Keyword arg = (Argument.Keyword) arguments.get(i);
Object value = eval(fr, arg.getValue());
named[j++] = arg.getName();
named[j++] = value;
}

// f(*args) -- varargs
if (star != null) {
Object value = eval(fr, star.getValue());
if (!(value instanceof StarlarkIterable<?> iter)) {
fr.setErrorLocation(star.getStartLocation());
throw Starlark.errorf("argument after * must be an iterable, not %s", Starlark.type(value));
}
ArrayList<Object> list = new ArrayList<>();
Collections.addAll(list, positional);
Iterables.addAll(list, iter);
positional = list.toArray();
}

// f(**kwargs)
if (starstar != null) {
Object value = eval(fr, starstar.getValue());
// Unlike *args, we don't have a Starlark-specific mapping interface to check for in **kwargs,
// so check for Java's Map instead.
if (!(value instanceof Map<?, ?> kwargs)) {
fr.setErrorLocation(starstar.getStartLocation());
throw Starlark.errorf("argument after ** must be a dict, not %s", Starlark.type(value));
}
int j = named.length;
named = Arrays.copyOf(named, j + 2 * kwargs.size());
for (Map.Entry<?, ?> e : kwargs.entrySet()) {
if (!(e.getKey() instanceof String)) {
fr.setErrorLocation(starstar.getStartLocation());
throw Starlark.errorf("keywords must be strings, not %s", Starlark.type(e.getKey()));
}
named[j++] = e.getKey();
named[j++] = e.getValue();
}
}

Location loc = call.getLparenLocation(); // (Location is prematerialized)
fr.setLocation(loc);
try {
return Starlark.fastcall(fr.thread, fn, positional, named);
} catch (EvalException ex) {
fr.setErrorLocation(loc);
throw ex;
}
}

private static Object evalIdentifier(StarlarkThread.Frame fr, Identifier id)
throws EvalException, InterruptedException {
Resolver.Binding bind = id.getBinding();
Expand Down

0 comments on commit 56bf547

Please sign in to comment.