From 8e272f6b46e3919327df979755cf7e079b1f4cf1 Mon Sep 17 00:00:00 2001
From: Lukas Stadler <lukas.stadler@oracle.com>
Date: Mon, 30 Mar 2015 13:51:59 +0200
Subject: [PATCH] new UseMethodInternalNode for internal generics

---
 .../r/nodes/builtin/base/AsCharacter.java     | 10 ++---
 .../truffle/r/nodes/builtin/base/Bind.java    | 10 ++---
 .../truffle/r/nodes/builtin/base/Dim.java     | 11 +++--
 .../r/nodes/builtin/base/DimNames.java        |  9 ++--
 .../builtin/base/InfixEmulationFunctions.java | 39 ++++++++--------
 .../r/nodes/builtin/base/UpdateLength.java    |  9 ++--
 .../access/array/read/AccessArrayNode.java    | 22 +++++-----
 .../array/write/UpdateArrayHelperNode.java    | 14 +++---
 .../r/nodes/function/EvaluatedArguments.java  |  3 +-
 .../nodes/function/UseMethodInternalNode.java | 44 +++++++++++++++++++
 10 files changed, 102 insertions(+), 69 deletions(-)
 create mode 100644 com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodInternalNode.java

diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java
index 79c34b0c8f..63a74e0b05 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java
@@ -29,8 +29,6 @@ import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.DispatchType;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.NoGenericMethodException;
 import com.oracle.truffle.r.nodes.unary.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
@@ -45,7 +43,7 @@ public abstract class AsCharacter extends RBuiltinNode {
     private static final String NAME = "as.character";
 
     @Child private CastStringNode castStringNode;
-    @Child private DispatchedCallNode dcn;
+    @Child private UseMethodInternalNode dcn;
     private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
     public abstract Object execute(VirtualFrame frame, Object obj);
@@ -149,11 +147,11 @@ public abstract class AsCharacter extends RBuiltinNode {
         controlVisibility();
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(DispatchedCallNode.create(NAME, DispatchType.UseMethod, getSuppliedSignature()));
+            dcn = insert(new UseMethodInternalNode(NAME, getSuppliedSignature()));
         }
         try {
-            return dcn.executeInternal(frame, container.getClassHierarchy(), new Object[]{container});
-        } catch (NoGenericMethodException e) {
+            return dcn.execute(frame, container.getClassHierarchy(), new Object[]{container});
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             return castStringVector(frame, container);
         }
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java
index cd4c420523..e95708b3a9 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java
@@ -34,8 +34,6 @@ import com.oracle.truffle.api.utilities.*;
 import com.oracle.truffle.r.nodes.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.DispatchType;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.NoGenericMethodException;
 import com.oracle.truffle.r.nodes.unary.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
@@ -45,7 +43,7 @@ import com.oracle.truffle.r.runtime.ops.na.*;
 public abstract class Bind extends RPrecedenceBuiltinNode {
 
     @Child private CastToVectorNode castVector;
-    @Child private DispatchedCallNode dcn;
+    @Child private UseMethodInternalNode dcn;
 
     private final ConditionProfile nullNamesProfile = ConditionProfile.createBinaryProfile();
     private final ConditionProfile emptyVectorProfile = ConditionProfile.createBinaryProfile();
@@ -80,11 +78,11 @@ public abstract class Bind extends RPrecedenceBuiltinNode {
     protected Object allDataFrame(VirtualFrame frame, Object deparseLevel, RArgsValuesAndNames args) {
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(DispatchedCallNode.create(getBindType(), DispatchType.UseMethod, SIGNATURE));
+            dcn = insert(new UseMethodInternalNode(getBindType(), SIGNATURE));
         }
         try {
-            return dcn.executeInternal(frame, ((RDataFrame) args.getValues()[0]).getClassHierarchy(), new Object[]{deparseLevel, args});
-        } catch (NoGenericMethodException e) {
+            return dcn.execute(frame, ((RDataFrame) args.getValues()[0]).getClassHierarchy(), new Object[]{deparseLevel, args});
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             throw RInternalError.shouldNotReachHere();
         }
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java
index b92374dc39..266d4e48cb 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java
@@ -30,8 +30,7 @@ import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.r.nodes.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.DispatchType;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.NoGenericMethodException;
+import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode.NoGenericMethodException;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
@@ -45,7 +44,7 @@ public abstract class Dim extends RBuiltinNode {
     private static final String NAME = "dim";
 
     @Child private ShortRowNames shortRowNames;
-    @Child private DispatchedCallNode dcn;
+    @Child private UseMethodInternalNode dcn;
 
     private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
@@ -98,11 +97,11 @@ public abstract class Dim extends RBuiltinNode {
         controlVisibility();
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(DispatchedCallNode.create(NAME, DispatchType.UseMethod, getSuppliedSignature()));
+            dcn = insert(new UseMethodInternalNode(NAME, getSuppliedSignature()));
         }
         try {
-            return dcn.executeInternal(frame, container.getClassHierarchy(), new Object[]{container});
-        } catch (NoGenericMethodException e) {
+            return dcn.execute(frame, container.getClassHierarchy(), new Object[]{container});
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             return hasDimensions(container) ? dimWithDimensions(frame, container) : RNull.instance;
         }
 
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java
index 01f401ae0a..08ee66b248 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java
@@ -29,7 +29,6 @@ import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
@@ -41,7 +40,7 @@ public abstract class DimNames extends RBuiltinNode {
 
     private static final String NAME = "dimnames";
 
-    @Child private DispatchedCallNode dcn;
+    @Child private UseMethodInternalNode dcn;
 
     private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
@@ -69,11 +68,11 @@ public abstract class DimNames extends RBuiltinNode {
         controlVisibility();
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(DispatchedCallNode.create(NAME, DispatchType.UseMethod, getSuppliedSignature()));
+            dcn = insert(new UseMethodInternalNode(NAME, getSuppliedSignature()));
         }
         try {
-            return dcn.executeInternal(frame, container.getClassHierarchy(), new Object[]{container});
-        } catch (NoGenericMethodException e) {
+            return dcn.execute(frame, container.getClassHierarchy(), new Object[]{container});
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             return isNull(container) ? RNull.instance : container.getDimNames();
         }
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/InfixEmulationFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/InfixEmulationFunctions.java
index fadcd66721..34c2d01e17 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/InfixEmulationFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/InfixEmulationFunctions.java
@@ -35,7 +35,6 @@ import com.oracle.truffle.r.nodes.access.array.write.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.builtin.base.InfixEmulationFunctionsFactory.PromiseEvaluatorNodeGen;
 import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
 import com.oracle.truffle.r.runtime.data.model.*;
@@ -241,17 +240,17 @@ public class InfixEmulationFunctions {
 
         private static final String NAME = "[";
 
-        @Child private DispatchedCallNode dcn;
+        @Child private UseMethodInternalNode dcn;
 
         @Specialization(guards = {"!noInd(inds)", "isObject(frame, x)"})
         protected Object getObj(VirtualFrame frame, RAbstractContainer x, RArgsValuesAndNames inds, RAbstractLogicalVector dropVec) {
             if (dcn == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                dcn = insert(DispatchedCallNode.create(NAME, DispatchType.UseMethod, SIGNATURE));
+                dcn = insert(new UseMethodInternalNode(NAME, SIGNATURE));
             }
             try {
-                return dcn.executeInternal(frame, x.getClassHierarchy(), new Object[]{x, inds, dropVec});
-            } catch (NoGenericMethodException e) {
+                return dcn.execute(frame, x.getClassHierarchy(), new Object[]{x, inds, dropVec});
+            } catch (S3FunctionLookupNode.NoGenericMethodException e) {
                 return access(frame, x, RRuntime.LOGICAL_FALSE, inds, dropVec, IS_SUBSET);
             }
         }
@@ -273,11 +272,11 @@ public class InfixEmulationFunctions {
 
             if (dcn == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                dcn = insert(DispatchedCallNode.create(NAME, DispatchType.UseMethod, SIGNATURE));
+                dcn = insert(new UseMethodInternalNode(NAME, SIGNATURE));
             }
             try {
-                return dcn.executeInternal(frame, x.getClassHierarchy(), new Object[]{x, inds, drop});
-            } catch (NoGenericMethodException e) {
+                return dcn.execute(frame, x.getClassHierarchy(), new Object[]{x, inds, drop});
+            } catch (S3FunctionLookupNode.NoGenericMethodException e) {
                 return access(frame, x, RRuntime.LOGICAL_FALSE, inds, drop, IS_SUBSET);
             }
         }
@@ -347,7 +346,7 @@ public class InfixEmulationFunctions {
 
         private static final String NAME = "[[";
 
-        @Child private DispatchedCallNode dcn;
+        @Child private UseMethodInternalNode dcn;
 
         @Override
         public Object[] getDefaultParameterValues() {
@@ -364,11 +363,11 @@ public class InfixEmulationFunctions {
             }
             if (dcn == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                dcn = insert(DispatchedCallNode.create(NAME, DispatchType.UseMethod, SIGNATURE));
+                dcn = insert(new UseMethodInternalNode(NAME, SIGNATURE));
             }
             try {
-                return dcn.executeInternal(frame, x.getClassHierarchy(), new Object[]{x, inds, exactVec});
-            } catch (NoGenericMethodException e) {
+                return dcn.execute(frame, x.getClassHierarchy(), new Object[]{x, inds, exactVec});
+            } catch (S3FunctionLookupNode.NoGenericMethodException e) {
                 return access(frame, x, exact, inds, RRuntime.LOGICAL_TRUE, IS_SUBSET);
             }
         }
@@ -459,17 +458,17 @@ public class InfixEmulationFunctions {
         private static final String NAME = "[<-";
         private static final boolean IS_SUBSET = true;
 
-        @Child private DispatchedCallNode dcn;
+        @Child private UseMethodInternalNode dcn;
 
         @Specialization(guards = {"!noInd(args)", "isObject(frame, x)"})
         protected Object updateObj(VirtualFrame frame, RAbstractContainer x, RArgsValuesAndNames args) {
             if (dcn == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                dcn = insert(DispatchedCallNode.create(NAME, DispatchType.UseMethod, SIGNATURE));
+                dcn = insert(new UseMethodInternalNode(NAME, SIGNATURE));
             }
             try {
-                return dcn.executeInternal(frame, x.getClassHierarchy(), new Object[]{x, args});
-            } catch (NoGenericMethodException e) {
+                return dcn.execute(frame, x.getClassHierarchy(), new Object[]{x, args});
+            } catch (S3FunctionLookupNode.NoGenericMethodException e) {
                 Object value = args.getValues()[args.length() - 1];
                 return update(frame, x, args, value, IS_SUBSET);
             }
@@ -493,17 +492,17 @@ public class InfixEmulationFunctions {
         private static final String NAME = "[[<-";
         private static final boolean IS_SUBSET = false;
 
-        @Child private DispatchedCallNode dcn;
+        @Child private UseMethodInternalNode dcn;
 
         @Specialization(guards = {"!noInd(args)", "isObject(frame, x)"})
         protected Object updateObj(VirtualFrame frame, RAbstractContainer x, RArgsValuesAndNames args) {
             if (dcn == null) {
                 CompilerDirectives.transferToInterpreterAndInvalidate();
-                dcn = insert(DispatchedCallNode.create(NAME, DispatchType.UseMethod, ArgumentsSignature.empty(2)));
+                dcn = insert(new UseMethodInternalNode(NAME, ArgumentsSignature.empty(2)));
             }
             try {
-                return dcn.executeInternal(frame, x.getClassHierarchy(), new Object[]{x, args});
-            } catch (NoGenericMethodException e) {
+                return dcn.execute(frame, x.getClassHierarchy(), new Object[]{x, args});
+            } catch (S3FunctionLookupNode.NoGenericMethodException e) {
                 Object value = args.getValues()[args.length() - 1];
                 return update(frame, x, args, value, IS_SUBSET);
             }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLength.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLength.java
index 8e68fd1b8e..3a6f867400 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLength.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLength.java
@@ -30,7 +30,6 @@ import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.r.nodes.*;
 import com.oracle.truffle.r.nodes.builtin.*;
 import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.*;
 import com.oracle.truffle.r.nodes.unary.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.data.*;
@@ -40,7 +39,7 @@ import com.oracle.truffle.r.runtime.data.model.*;
 // 2nd parameter is "value", but should not be matched against, so ""
 public abstract class UpdateLength extends RInvisibleBuiltinNode {
 
-    @Child private DispatchedCallNode dcn;
+    @Child private UseMethodInternalNode dcn;
 
     private final RAttributeProfiles attrProfiles = RAttributeProfiles.create();
 
@@ -55,11 +54,11 @@ public abstract class UpdateLength extends RInvisibleBuiltinNode {
     protected Object updateLengthObject(VirtualFrame frame, RAbstractContainer container, RAbstractIntVector lengthVector) {
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(DispatchedCallNode.create("length<-", DispatchType.UseMethod, getSuppliedSignature()));
+            dcn = insert(new UseMethodInternalNode("length<-", getSuppliedSignature()));
         }
         try {
-            return dcn.executeInternal(frame, container.getClassHierarchy(), new Object[]{container, lengthVector});
-        } catch (NoGenericMethodException e) {
+            return dcn.execute(frame, container.getClassHierarchy(), new Object[]{container, lengthVector});
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             return updateLength(frame, container, lengthVector);
         }
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/read/AccessArrayNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/read/AccessArrayNode.java
index 2327237e17..c14c9a32b0 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/read/AccessArrayNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/read/AccessArrayNode.java
@@ -34,8 +34,6 @@ import com.oracle.truffle.r.nodes.access.array.*;
 import com.oracle.truffle.r.nodes.access.array.ArrayPositionCast.OperatorConverterNode;
 import com.oracle.truffle.r.nodes.access.array.ArrayPositionCastNodeGen.OperatorConverterNodeGen;
 import com.oracle.truffle.r.nodes.function.*;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.DispatchType;
-import com.oracle.truffle.r.nodes.function.DispatchedCallNode.NoGenericMethodException;
 import com.oracle.truffle.r.nodes.unary.*;
 import com.oracle.truffle.r.runtime.*;
 import com.oracle.truffle.r.runtime.RDeparse.State;
@@ -78,8 +76,8 @@ public abstract class AccessArrayNode extends RNode {
     @Child private GetNamesNode getNamesNode;
     @Child private GetDimNamesNode getDimNamesNode;
 
-    @Child private DispatchedCallNode dcn;
-    @Child private DispatchedCallNode dcnDrop;
+    @Child private UseMethodInternalNode dcn;
+    @Child private UseMethodInternalNode dcnDrop;
 
     public abstract RNode getVector();
 
@@ -253,17 +251,17 @@ public abstract class AccessArrayNode extends RNode {
             if (dropDim != RMissing.instance) {
                 if (dcnDrop == null) {
                     CompilerDirectives.transferToInterpreterAndInvalidate();
-                    dcnDrop = insert(DispatchedCallNode.create("[", DispatchType.UseMethod, DROP_SIGNATURE));
+                    dcnDrop = insert(new UseMethodInternalNode("[", DROP_SIGNATURE));
                 }
-                return dcnDrop.executeInternal(frame, container.getClassHierarchy(), new Object[]{container, inds, dropDim});
+                return dcnDrop.execute(frame, container.getClassHierarchy(), new Object[]{container, inds, dropDim});
             } else {
                 if (dcn == null) {
                     CompilerDirectives.transferToInterpreterAndInvalidate();
-                    dcn = insert(DispatchedCallNode.create("[", DispatchType.UseMethod, SIGNATURE));
+                    dcn = insert(new UseMethodInternalNode("[", SIGNATURE));
                 }
-                return dcn.executeInternal(frame, container.getClassHierarchy(), new Object[]{container, inds});
+                return dcn.execute(frame, container.getClassHierarchy(), new Object[]{container, inds});
             }
-        } catch (NoGenericMethodException e) {
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             return accessRecursive(frame, container, exact, position, recLevel, dropDim);
         }
     }
@@ -272,12 +270,12 @@ public abstract class AccessArrayNode extends RNode {
     protected Object accessObject(VirtualFrame frame, RAbstractContainer container, Object exact, int recLevel, Object position, Object dropDim) {
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(DispatchedCallNode.create("[[", DispatchType.UseMethod, EXACT_SIGNATURE));
+            dcn = insert(new UseMethodInternalNode("[[", EXACT_SIGNATURE));
         }
         try {
             Object inds = position instanceof Object[] ? new RArgsValuesAndNames((Object[]) position, ArgumentsSignature.empty(((Object[]) position).length)) : position;
-            return dcn.executeInternal(frame, container.getClassHierarchy(), new Object[]{container, inds, exact});
-        } catch (NoGenericMethodException e) {
+            return dcn.execute(frame, container.getClassHierarchy(), new Object[]{container, inds, exact});
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             return accessRecursive(frame, container, exact, position, recLevel, dropDim);
         }
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/write/UpdateArrayHelperNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/write/UpdateArrayHelperNode.java
index 2fb339374b..4d294f138a 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/write/UpdateArrayHelperNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/array/write/UpdateArrayHelperNode.java
@@ -79,7 +79,7 @@ public abstract class UpdateArrayHelperNode extends RNode {
     @Child private OperatorConverterNode operatorConverter;
     @Child private SetMultiDimDataNode setMultiDimData;
 
-    @Child private DispatchedCallNode dcn;
+    @Child private UseMethodInternalNode dcn;
 
     private final BranchProfile error = BranchProfile.create();
     private final BranchProfile warning = BranchProfile.create();
@@ -252,12 +252,12 @@ public abstract class UpdateArrayHelperNode extends RNode {
     protected Object updateObjectSubset(VirtualFrame frame, Object v, Object value, int recLevel, Object positions, RAbstractContainer container) {
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(DispatchedCallNode.create("[<-", DispatchType.UseMethod, VALUE_SIGNATURE));
+            dcn = insert(new UseMethodInternalNode("[<-", VALUE_SIGNATURE));
         }
         try {
             Object inds = positions instanceof Object[] ? new RArgsValuesAndNames((Object[]) positions, ArgumentsSignature.empty(((Object[]) positions).length)) : positions;
-            return dcn.executeInternal(frame, container.getClassHierarchy(), new Object[]{container, inds, value});
-        } catch (NoGenericMethodException e) {
+            return dcn.execute(frame, container.getClassHierarchy(), new Object[]{container, inds, value});
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             return updateRecursive(frame, v, value, container, positions, recLevel);
         }
     }
@@ -266,12 +266,12 @@ public abstract class UpdateArrayHelperNode extends RNode {
     protected Object updateObject(VirtualFrame frame, Object v, Object value, int recLevel, Object positions, RAbstractContainer container) {
         if (dcn == null) {
             CompilerDirectives.transferToInterpreterAndInvalidate();
-            dcn = insert(DispatchedCallNode.create("[[<-", DispatchType.UseMethod, VALUE_SIGNATURE));
+            dcn = insert(new UseMethodInternalNode("[[<-", VALUE_SIGNATURE));
         }
         try {
             Object inds = positions instanceof Object[] ? new RArgsValuesAndNames((Object[]) positions, ArgumentsSignature.empty(((Object[]) positions).length)) : positions;
-            return dcn.executeInternal(frame, container.getClassHierarchy(), new Object[]{container, inds, value});
-        } catch (NoGenericMethodException e) {
+            return dcn.execute(frame, container.getClassHierarchy(), new Object[]{container, inds, value});
+        } catch (S3FunctionLookupNode.NoGenericMethodException e) {
             return updateRecursive(frame, v, value, container, positions, recLevel);
         }
     }
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/EvaluatedArguments.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/EvaluatedArguments.java
index eba9932508..acde52fb93 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/EvaluatedArguments.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/EvaluatedArguments.java
@@ -26,8 +26,7 @@ import com.oracle.truffle.r.runtime.*;
 
 /**
  * Simple container class for holding arguments ({@link #getEvaluatedArgs()}) which are ready to be
- * pushed into {@link RArguments} (or are taken from there!). This is used by
- * {@link UseMethodDispatchNode}, e.g.
+ * pushed into {@link RArguments} (or are taken from there!).
  */
 public class EvaluatedArguments extends Arguments<Object> {
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodInternalNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodInternalNode.java
new file mode 100644
index 0000000000..6161a5f1bb
--- /dev/null
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/UseMethodInternalNode.java
@@ -0,0 +1,44 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 2014, Purdue University
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.nodes.function;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.r.nodes.*;
+import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode.Result;
+import com.oracle.truffle.r.runtime.*;
+import com.oracle.truffle.r.runtime.RArguments.S3Args;
+import com.oracle.truffle.r.runtime.data.*;
+
+public final class UseMethodInternalNode extends RNode implements VisibilityController {
+
+    @Child private S3FunctionLookupNode lookup = S3FunctionLookupNode.create(false, false);
+    @Child private CallMatcherNode callMatcher = CallMatcherNode.create(false, false);
+
+    private final String generic;
+    private final ArgumentsSignature signature;
+
+    public UseMethodInternalNode(String generic, ArgumentsSignature signature) {
+        this.generic = generic;
+        this.signature = signature;
+    }
+
+    public Object execute(VirtualFrame frame, RStringVector type, Object[] arguments) {
+        controlVisibility();
+        Result lookupResult = lookup.execute(frame, generic, type, null, frame.materialize(), null);
+        S3Args s3Args = new S3Args(generic, lookupResult.clazz, lookupResult.targetFunctionName, frame.materialize(), null, null);
+        return callMatcher.execute(frame, signature, arguments, lookupResult.function, s3Args);
+    }
+
+    @Override
+    public Object execute(VirtualFrame frame) {
+        throw RInternalError.shouldNotReachHere();
+    }
+}
-- 
GitLab