Skip to content
Snippets Groups Projects
Commit fd702b6f authored by Lukas Stadler's avatar Lukas Stadler
Browse files

clean up UseMethodDispatchNode generic case

parent 97220b53
Branches
No related tags found
No related merge requests found
......@@ -26,6 +26,7 @@ import java.util.*;
import com.oracle.truffle.api.*;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.nodes.*;
import com.oracle.truffle.api.source.*;
......@@ -499,6 +500,38 @@ public class ReadVariableNode extends RNode implements VisibilityController {
return lastLevel;
}
@TruffleBoundary
public static RFunction lookupFunction(String identifier, Frame variableFrame) {
Frame current = variableFrame;
do {
// see if the current frame has a value of the given name
FrameSlot frameSlot = current.getFrameDescriptor().findFrameSlot(identifier);
if (frameSlot != null) {
Object value = current.getValue(frameSlot);
if (value != null) {
if (value == RMissing.instance) {
throw RError.error(RError.Message.ARGUMENT_MISSING, identifier);
}
if (value instanceof RPromise) {
RPromise promise = (RPromise) value;
if (promise.isEvaluated()) {
value = promise.getValue();
} else {
value = PromiseHelperNode.evaluateSlowPath(null, promise);
return (RFunction) value;
}
}
if (RRuntime.checkType(value, RType.Function)) {
return (RFunction) value;
}
}
}
current = RArguments.getEnclosingFrame(current);
} while (current != null);
return null;
}
private Object getValue(Frame variableFrame, FrameSlot frameSlot) {
Object value = variableFrame.getValue(frameSlot);
if (variableFrame.isObject(frameSlot)) {
......
......@@ -53,7 +53,7 @@ public class BinaryOpsGroupDispatchNode extends GroupDispatchNode {
@Override
public boolean isSameType(Object[] args) {
return !isExecuted || S3DispatchNode.isEqualType(getArgClass(args[0]), this.typeL) && S3DispatchNode.isEqualType(getArgClass(args[1]), this.typeR);
return !isExecuted || isEqualType(getArgClass(args[0]), this.typeL) && isEqualType(getArgClass(args[1]), this.typeR);
}
protected void executeNoCache(VirtualFrame frame, Object[] evaluatedArgs) {
......
......@@ -285,7 +285,7 @@ class GroupDispatchNode extends S3DispatchLegacyNode {
}
public boolean isSameType(Object[] args) {
return !isExecuted || S3DispatchNode.isEqualType(getArgClass(args[0]), this.type);
return !isExecuted || isEqualType(getArgClass(args[0]), this.type);
}
protected void initBuiltin(VirtualFrame frame) {
......
......@@ -11,11 +11,13 @@
package com.oracle.truffle.r.nodes.function;
import java.util.*;
import com.oracle.truffle.api.*;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.frame.FrameInstance.*;
import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
import com.oracle.truffle.api.nodes.*;
import com.oracle.truffle.api.source.*;
import com.oracle.truffle.api.utilities.*;
......@@ -27,22 +29,14 @@ public abstract class S3DispatchNode extends DispatchNode {
@Child protected PromiseHelperNode promiseHelper = new PromiseHelperNode();
protected final BranchProfile errorProfile = BranchProfile.create();
private final ConditionProfile topLevelFrameProfile = ConditionProfile.createBinaryProfile();
private final ConditionProfile callerFrameSlotPath = ConditionProfile.createBinaryProfile();
protected final BranchProfile errorProfile = BranchProfile.create();
private final ConditionProfile hasVarArgsProfile = ConditionProfile.createBinaryProfile();
private final ValueProfile argumentCountProfile = ValueProfile.createPrimitiveProfile();
@CompilationFinal private String lastFun;
@Child private ReadVariableNode lookup;
protected String targetFunctionName;
protected RFunction targetFunction;
protected final ArgumentsSignature suppliedSignature;
// TODO: the executeHelper methods share quite a bit of code, but is it better or worse from
// having one method with a rather convoluted control flow structure?
public S3DispatchNode(String genericName, ArgumentsSignature suppliedSignature) {
super(genericName);
this.suppliedSignature = suppliedSignature;
......@@ -58,16 +52,26 @@ public abstract class S3DispatchNode extends DispatchNode {
return topLevelFrameProfile.profile(funFrame == null) ? frame.materialize() : funFrame;
}
protected Object[] extractArguments(VirtualFrame frame) {
protected Object[] extractArguments(VirtualFrame frame, boolean fixedLength) {
int argCount = argumentCountProfile.profile(RArguments.getArgumentsLength(frame));
Object[] argValues = new Object[argCount];
extractArgumentsLoop(frame, argCount, argValues);
if (fixedLength) {
extractArgumentsLoopFixedLength(frame, argCount, argValues);
} else {
extractArgumentsLoop(frame, argCount, argValues);
}
return argValues;
}
@ExplodeLoop
private static void extractArgumentsLoop(VirtualFrame frame, int argCount, Object[] argValues) {
for (int i = 0; i < argCount; ++i) {
for (int i = 0; i < argCount; i++) {
argValues[i] = RArguments.getArgument(frame, i);
}
}
@ExplodeLoop
private static void extractArgumentsLoopFixedLength(VirtualFrame frame, int argCount, Object[] argValues) {
for (int i = 0; i < argCount; i++) {
argValues[i] = RArguments.getArgument(frame, i);
}
}
......@@ -126,14 +130,148 @@ public abstract class S3DispatchNode extends DispatchNode {
private final ValueProfile callerFrameProfile = ValueProfile.createClassProfile();
protected final Object[] prepareArguments(Frame callerFrame, MaterializedFrame genericDefFrame, EvaluatedArguments reorderedArgs, RFunction function, RStringVector clazz, String functionName) {
Frame profiledCallerFrame = callerFrameProfile.profile(callerFrame);
protected final Object[] prepareArguments(MaterializedFrame callerFrame, MaterializedFrame genericDefFrame, EvaluatedArguments reorderedArgs, RFunction function, RStringVector clazz,
String functionName) {
MaterializedFrame profiledCallerFrame = callerFrameProfile.profile(callerFrame);
Object[] argObject = RArguments.createS3Args(function, getSourceSection(), null, RArguments.getDepth(profiledCallerFrame) + 1, reorderedArgs.getEvaluatedArgs(), reorderedArgs.getSignature());
defineVarsAsArguments(argObject, genericName, clazz, profiledCallerFrame.materialize(), genericDefFrame);
RArguments.setS3Method(argObject, functionName);
return argObject;
}
protected static Object checkMissing(Object value) {
return RMissingHelper.isMissing(value) || (value instanceof RPromise && RMissingHelper.isMissingName((RPromise) value)) ? null : value;
}
@TruffleBoundary
protected static String functionName(String generic, String className) {
return new StringBuilder(generic).append(RRuntime.RDOT).append(className).toString();
}
protected static void defineVarsAsArguments(Object[] args, String genericName, RStringVector klass, MaterializedFrame genCallEnv, MaterializedFrame genDefEnv) {
RArguments.setS3Generic(args, genericName);
RArguments.setS3Class(args, klass);
RArguments.setS3CallEnv(args, genCallEnv);
RArguments.setS3DefEnv(args, genDefEnv);
}
protected static final class TargetLookupResult {
public final ReadVariableNode[] unsuccessfulReads;
public final ReadVariableNode successfulRead;
public final RFunction targetFunction;
public final String targetFunctionName;
public final RStringVector clazz;
public TargetLookupResult(ReadVariableNode[] unsuccessfulReads, ReadVariableNode successfulRead, RFunction targetFunction, String targetFunctionName, RStringVector clazz) {
this.unsuccessfulReads = unsuccessfulReads;
this.successfulRead = successfulRead;
this.targetFunction = targetFunction;
this.targetFunctionName = targetFunctionName;
this.clazz = clazz;
}
}
protected static TargetLookupResult findTargetFunctionLookup(Frame lookupFrame, RStringVector type, String genericName, boolean createReadVariableNodes) {
CompilerAsserts.neverPartOfCompilation();
RFunction targetFunction = null;
String targetFunctionName = null;
RStringVector clazz = null;
ArrayList<ReadVariableNode> unsuccessfulReads = createReadVariableNodes ? new ArrayList<>() : null;
for (int i = 0; i <= type.getLength(); i++) {
String clazzName = i == type.getLength() ? RRuntime.DEFAULT : type.getDataAt(i);
String functionName = genericName + RRuntime.RDOT + clazzName;
ReadVariableNode rvn;
Object func;
if (createReadVariableNodes) {
rvn = ReadVariableNode.createFunctionLookup(functionName, false);
func = rvn.execute(null, lookupFrame);
} else {
rvn = null;
func = ReadVariableNode.lookupFunction(functionName, lookupFrame);
}
if (func != null) {
assert func instanceof RFunction;
targetFunctionName = functionName;
targetFunction = (RFunction) func;
if (i == 0) {
clazz = type.copyResized(type.getLength(), false);
} else if (i == type.getLength()) {
clazz = null;
} else {
clazz = RDataFactory.createStringVector(Arrays.copyOfRange(type.getDataWithoutCopying(), i, type.getLength()), true);
clazz.setAttr(RRuntime.PREVIOUS_ATTR_KEY, type.copyResized(type.getLength(), false));
}
ReadVariableNode[] array = createReadVariableNodes ? unsuccessfulReads.toArray(new ReadVariableNode[unsuccessfulReads.size()]) : null;
return new TargetLookupResult(array, rvn, targetFunction, targetFunctionName, clazz);
} else {
if (createReadVariableNodes) {
unsuccessfulReads.add(rvn);
}
}
}
if (createReadVariableNodes) {
return new TargetLookupResult(unsuccessfulReads.toArray(new ReadVariableNode[unsuccessfulReads.size()]), null, null, null, null);
} else {
return null;
}
}
}
abstract class S3DispatchLegacyNode extends S3DispatchNode {
protected RStringVector type;
@Child protected IndirectCallNode indirectCallNode = Truffle.getRuntime().createIndirectCallNode();
protected RStringVector klass;
protected MaterializedFrame genCallEnv;
protected MaterializedFrame genDefEnv;
protected boolean isFirst;
@CompilationFinal private String lastFun;
@Child private ReadVariableNode lookup;
protected String targetFunctionName;
protected RFunction targetFunction;
public S3DispatchLegacyNode(String genericName, ArgumentsSignature suppliedSignature) {
super(genericName, suppliedSignature);
}
protected void findFunction(String functionName, Frame frame) {
if (lookup == null || !functionName.equals(lastFun)) {
CompilerDirectives.transferToInterpreterAndInvalidate();
lastFun = functionName;
ReadVariableNode rvn = ReadVariableNode.createFunctionLookup(functionName, false);
lookup = lookup == null ? insert(rvn) : lookup.replace(rvn);
}
targetFunction = null;
targetFunctionName = null;
Object func;
if (frame instanceof VirtualFrame) {
func = lookup.execute((VirtualFrame) frame);
} else {
func = lookup.execute(null, frame);
}
if (func != null) {
assert func instanceof RFunction;
targetFunctionName = functionName;
targetFunction = (RFunction) func;
}
}
protected void findFunction(String generic, String className, Frame frame) {
checkLength(className, generic);
findFunction(functionName(generic, className), frame);
}
private void checkLength(String className, String generic) {
// The magic number two taken from src/main/objects.c
if (className.length() + generic.length() + 2 > RRuntime.LEN_METHOD_NAME) {
throw RError.error(getEncapsulatingSourceSection(), RError.Message.TOO_LONG_CLASS_NAME, generic);
}
}
protected EvaluatedArguments reorderArgs(VirtualFrame frame, RFunction func, Object[] evaluatedArgs, ArgumentsSignature signature, boolean hasVarArgs, SourceSection callSrc) {
Object[] evaluatedArgsValues = evaluatedArgs;
ArgumentsSignature evaluatedSignature;
......@@ -178,10 +316,6 @@ public abstract class S3DispatchNode extends DispatchNode {
return reorderedArgs;
}
protected static Object checkMissing(Object value) {
return RMissingHelper.isMissing(value) || (value instanceof RPromise && RMissingHelper.isMissingName((RPromise) value)) ? null : value;
}
public static boolean isEqualType(RStringVector one, RStringVector two) {
if (one == null && two == null) {
return true;
......@@ -193,74 +327,13 @@ public abstract class S3DispatchNode extends DispatchNode {
if (one.getLength() != two.getLength()) {
return false;
}
for (int i = 0; i < one.getLength(); ++i) {
for (int i = 0; i < one.getLength(); i++) {
if (!one.getDataAt(i).equals(two.getDataAt(i))) {
return false;
}
}
return true;
}
protected void findFunction(String functionName, Frame frame) {
if (lookup == null || !functionName.equals(lastFun)) {
CompilerDirectives.transferToInterpreterAndInvalidate();
lastFun = functionName;
ReadVariableNode rvn = ReadVariableNode.createFunctionLookup(functionName, false);
lookup = lookup == null ? insert(rvn) : lookup.replace(rvn);
}
targetFunction = null;
targetFunctionName = null;
Object func;
if (frame instanceof VirtualFrame) {
func = lookup.execute((VirtualFrame) frame);
} else {
func = lookup.execute(null, frame);
}
if (func != null) {
assert func instanceof RFunction;
targetFunctionName = functionName;
targetFunction = (RFunction) func;
}
}
protected void findFunction(String generic, String className, Frame frame) {
checkLength(className, generic);
findFunction(functionName(generic, className), frame);
}
@TruffleBoundary
private static String functionName(String generic, String className) {
return new StringBuilder(generic).append(RRuntime.RDOT).append(className).toString();
}
protected static void defineVarsAsArguments(Object[] args, String genericName, RStringVector klass, MaterializedFrame genCallEnv, MaterializedFrame genDefEnv) {
RArguments.setS3Generic(args, genericName);
RArguments.setS3Class(args, klass);
RArguments.setS3CallEnv(args, genCallEnv);
RArguments.setS3DefEnv(args, genDefEnv);
}
private void checkLength(String className, String generic) {
// The magic number two taken from src/main/objects.c
if (className.length() + generic.length() + 2 > RRuntime.LEN_METHOD_NAME) {
throw RError.error(getEncapsulatingSourceSection(), RError.Message.TOO_LONG_CLASS_NAME, generic);
}
}
}
abstract class S3DispatchLegacyNode extends S3DispatchNode {
protected RStringVector type;
@Child protected IndirectCallNode indirectCallNode = Truffle.getRuntime().createIndirectCallNode();
protected RStringVector klass;
protected MaterializedFrame genCallEnv;
protected MaterializedFrame genDefEnv;
protected boolean isFirst;
public S3DispatchLegacyNode(String genericName, ArgumentsSignature suppliedSignature) {
super(genericName, suppliedSignature);
}
}
abstract class S3DispatchCachedNode extends S3DispatchNode {
......@@ -274,12 +347,6 @@ abstract class S3DispatchCachedNode extends S3DispatchNode {
abstract class S3DispatchGenericNode extends S3DispatchNode {
@Child protected IndirectCallNode indirectCallNode = Truffle.getRuntime().createIndirectCallNode();
protected RStringVector klass;
protected MaterializedFrame genCallEnv;
protected MaterializedFrame genDefEnv;
protected boolean isFirst;
public S3DispatchGenericNode(String genericName, ArgumentsSignature suppliedSignature) {
super(genericName, suppliedSignature);
}
......
......@@ -11,17 +11,13 @@
package com.oracle.truffle.r.nodes.function;
import java.util.*;
import com.oracle.truffle.api.*;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.frame.*;
import com.oracle.truffle.api.nodes.*;
import com.oracle.truffle.api.source.*;
import com.oracle.truffle.r.nodes.*;
import com.oracle.truffle.r.nodes.access.variables.*;
import com.oracle.truffle.r.nodes.function.ArgumentMatcher.*;
import com.oracle.truffle.r.nodes.function.ArgumentMatcher.MatchPermutation;
import com.oracle.truffle.r.nodes.function.DispatchedCallNode.NoGenericMethodException;
import com.oracle.truffle.r.runtime.*;
......@@ -141,7 +137,7 @@ final class UseMethodDispatchCachedNode extends S3DispatchCachedNode {
@Override
public Object execute(VirtualFrame frame) {
Object[] arguments = extractArguments(frame);
Object[] arguments = extractArguments(frame, true);
ArgumentsSignature signature = RArguments.getSignature(frame);
MaterializedFrame genericDefFrame = RArguments.getEnclosingFrame(frame);
MaterializedFrame callerFrame = getCallerFrame(frame);
......@@ -182,13 +178,13 @@ final class UseMethodDispatchCachedNode extends S3DispatchCachedNode {
private void specialize(Frame callerFrame, MaterializedFrame genericDefFrame, ArgumentsSignature signature, Object[] arguments, boolean throwsRError) {
CompilerAsserts.neverPartOfCompilation();
// look for a match in the caller frame hierarchy
TargetLookupResult result = findTargetFunctionLookup(callerFrame, type, genericName);
TargetLookupResult result = findTargetFunctionLookup(callerFrame, type, genericName, true);
ReadVariableNode[] unsuccessfulReadsCaller = result.unsuccessfulReads;
ReadVariableNode[] unsuccessfulReadsDef = null;
if (result.successfulRead == null) {
if (genericDefFrame != null) {
// look for a match in the generic def frame hierarchy
result = findTargetFunctionLookup(genericDefFrame, type, genericName);
result = findTargetFunctionLookup(genericDefFrame, type, genericName, true);
unsuccessfulReadsDef = result.unsuccessfulReads;
}
if (result.successfulRead == null) {
......@@ -275,7 +271,7 @@ final class UseMethodDispatchCachedNode extends S3DispatchCachedNode {
if (cached.function.isBuiltin()) {
ArgumentMatcher.evaluatePromises(frame, promiseHelper, reorderedArgs);
}
Object[] argObject = prepareArguments(frame, null, reorderedArgs, cached.function, cached.clazz, cached.functionName);
Object[] argObject = prepareArguments(frame.materialize(), null, reorderedArgs, cached.function, cached.clazz, cached.functionName);
return call.call(frame, argObject);
}
......@@ -284,58 +280,12 @@ final class UseMethodDispatchCachedNode extends S3DispatchCachedNode {
throw RInternalError.shouldNotReachHere();
}
private static final class TargetLookupResult {
private final ReadVariableNode[] unsuccessfulReads;
private final ReadVariableNode successfulRead;
private final RFunction targetFunction;
private final String targetFunctionName;
private final RStringVector clazz;
public TargetLookupResult(ReadVariableNode[] unsuccessfulReads, ReadVariableNode successfulRead, RFunction targetFunction, String targetFunctionName, RStringVector clazz) {
this.unsuccessfulReads = unsuccessfulReads;
this.successfulRead = successfulRead;
this.targetFunction = targetFunction;
this.targetFunctionName = targetFunctionName;
this.clazz = clazz;
}
}
private static TargetLookupResult findTargetFunctionLookup(Frame callerFrame, RStringVector type, String genericName) {
CompilerAsserts.neverPartOfCompilation();
RFunction targetFunction = null;
String targetFunctionName = null;
RStringVector clazz = null;
ArrayList<ReadVariableNode> unsuccessfulReads = new ArrayList<>();
for (int i = 0; i <= type.getLength(); ++i) {
String clazzName = i == type.getLength() ? RRuntime.DEFAULT : type.getDataAt(i);
String functionName = genericName + RRuntime.RDOT + clazzName;
ReadVariableNode rvn = ReadVariableNode.createFunctionLookup(functionName, false);
Object func = rvn.execute(null, callerFrame);
if (func != null) {
assert func instanceof RFunction;
targetFunctionName = functionName;
targetFunction = (RFunction) func;
if (i == 0) {
clazz = type.copyResized(type.getLength(), false);
} else if (i == type.getLength()) {
clazz = null;
} else {
clazz = RDataFactory.createStringVector(Arrays.copyOfRange(type.getDataWithoutCopying(), i, type.getLength()), true);
clazz.setAttr(RRuntime.PREVIOUS_ATTR_KEY, type.copyResized(type.getLength(), false));
}
return new TargetLookupResult(unsuccessfulReads.toArray(new ReadVariableNode[unsuccessfulReads.size()]), rvn, targetFunction, targetFunctionName, clazz);
} else {
unsuccessfulReads.add(rvn);
}
}
return new TargetLookupResult(unsuccessfulReads.toArray(new ReadVariableNode[unsuccessfulReads.size()]), null, null, null, null);
}
}
final class UseMethodDispatchGenericNode extends S3DispatchGenericNode {
@Child protected IndirectCallNode indirectCallNode = Truffle.getRuntime().createIndirectCallNode();
public UseMethodDispatchGenericNode(String genericName, ArgumentsSignature suppliedSignature) {
super(genericName, suppliedSignature);
}
......@@ -347,9 +297,14 @@ final class UseMethodDispatchGenericNode extends S3DispatchGenericNode {
@Override
public Object executeGeneric(VirtualFrame frame, RStringVector type) {
Frame callerFrame = getCallerFrame(frame);
findTargetFunction(RArguments.getEnclosingFrame(frame), type, true);
return executeHelper(frame, callerFrame, extractArguments(frame), RArguments.getSignature(frame), getSourceSection());
Object[] arguments = extractArguments(frame, false);
ArgumentsSignature signature = RArguments.getSignature(frame);
MaterializedFrame genericDefFrame = RArguments.getEnclosingFrame(frame);
MaterializedFrame callerFrame = getCallerFrame(frame);
TargetLookupResult lookupResult = findTargetFunction(callerFrame, genericDefFrame, type, true);
Object[] callArguments = executeHelper(frame, callerFrame, genericDefFrame, lookupResult, arguments, signature, getSourceSection());
return indirectCallNode.call(frame, lookupResult.targetFunction.getTarget(), callArguments);
}
@Override
......@@ -358,54 +313,49 @@ final class UseMethodDispatchGenericNode extends S3DispatchGenericNode {
}
@Override
public Object executeInternalGeneric(VirtualFrame frame, RStringVector type, Object[] args) {
// TBD getEnclosing?
findTargetFunction(frame, type, false);
return executeHelper(frame, frame, args, suppliedSignature, getEncapsulatingSourceSection());
public Object executeInternalGeneric(VirtualFrame frame, RStringVector type, Object[] arguments) {
MaterializedFrame genericDefFrame = RArguments.getEnclosingFrame(frame);
MaterializedFrame callerFrame = getCallerFrame(frame);
TargetLookupResult lookupResult = findTargetFunction(callerFrame, genericDefFrame, type, true);
Object[] callArguments = executeHelper(frame, callerFrame, genericDefFrame, lookupResult, arguments, suppliedSignature, getEncapsulatingSourceSection());
return indirectCallNode.call(frame, lookupResult.targetFunction.getTarget(), callArguments);
}
private Object executeHelper(VirtualFrame frame, Frame callerFrame, Object[] args, ArgumentsSignature paramSignature, SourceSection errorSourceSection) {
EvaluatedArguments reorderedArgs = reorderArguments(args, targetFunction, paramSignature, errorSourceSection);
if (targetFunction.isBuiltin()) {
private Object[] executeHelper(VirtualFrame frame, MaterializedFrame callerFrame, MaterializedFrame genericDefFrame, TargetLookupResult lookupResult, Object[] args,
ArgumentsSignature paramSignature, SourceSection errorSourceSection) {
RFunction function = lookupResult.targetFunction;
EvaluatedArguments reorderedArgs = reorderArguments(args, function, paramSignature, errorSourceSection);
if (function.isBuiltin()) {
ArgumentMatcher.evaluatePromises(frame, promiseHelper, reorderedArgs);
}
Object[] argObject = prepareArguments(callerFrame, RArguments.getEnclosingFrame(frame), reorderedArgs, targetFunction, klass, targetFunctionName);
return indirectCallNode.call(frame, targetFunction.getTarget(), argObject);
return prepareArguments(callerFrame, genericDefFrame, lookupResult, function, reorderedArgs);
}
private void findTargetFunction(Frame callerFrame, RStringVector type, boolean throwsRError) {
findTargetFunctionLookup(callerFrame, type);
if (targetFunction == null) {
errorProfile.enter();
if (throwsRError) {
throw RError.error(getEncapsulatingSourceSection(), RError.Message.UNKNOWN_FUNCTION_USE_METHOD, genericName, RRuntime.toString(type));
} else {
throw new NoGenericMethodException();
}
}
@Override
@TruffleBoundary
protected EvaluatedArguments reorderArguments(Object[] args, RFunction function, ArgumentsSignature paramSignature, SourceSection errorSourceSection) {
return super.reorderArguments(args, function, paramSignature, errorSourceSection);
}
@TruffleBoundary
private Object[] prepareArguments(MaterializedFrame callerFrame, MaterializedFrame genericDefFrame, TargetLookupResult lookupResult, RFunction function, EvaluatedArguments reorderedArgs) {
return super.prepareArguments(callerFrame, genericDefFrame, reorderedArgs, function, lookupResult.clazz, lookupResult.targetFunctionName);
}
@TruffleBoundary
private void findTargetFunctionLookup(Frame callerFrame, RStringVector type) {
for (int i = 0; i < type.getLength(); ++i) {
findFunction(genericName, type.getDataAt(i), callerFrame);
if (targetFunction != null) {
RStringVector classVec = null;
if (i > 0) {
isFirst = false;
classVec = RDataFactory.createStringVector(Arrays.copyOfRange(type.getDataWithoutCopying(), i, type.getLength()), true);
classVec.setAttr(RRuntime.PREVIOUS_ATTR_KEY, type.copyResized(type.getLength(), false));
private TargetLookupResult findTargetFunction(MaterializedFrame callerFrame, MaterializedFrame genericDefFrame, RStringVector type, boolean throwsRError) {
TargetLookupResult lookupResult = findTargetFunctionLookup(callerFrame, type, genericName, false);
if (lookupResult == null) {
lookupResult = findTargetFunctionLookup(genericDefFrame, type, genericName, false);
if (lookupResult == null) {
if (throwsRError) {
throw RError.error(getEncapsulatingSourceSection(), RError.Message.UNKNOWN_FUNCTION_USE_METHOD, genericName, RRuntime.toString(type));
} else {
isFirst = true;
classVec = type.copyResized(type.getLength(), false);
throw new NoGenericMethodException();
}
klass = classVec;
break;
}
}
if (targetFunction != null) {
return;
}
findFunction(genericName, RRuntime.DEFAULT, callerFrame);
return lookupResult;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment