From ef762bd69205d383b8908dcc41f302bfc2868d17 Mon Sep 17 00:00:00 2001
From: Mick Jordan <mick.jordan@oracle.com>
Date: Wed, 30 Nov 2016 15:01:53 -0800
Subject: [PATCH] forward dll info to CallRFFI/CRFFI

---
 .../truffle/r/library/graphics/RGraphics.java |  2 +-
 .../nodes/builtin/base/DynLoadFunctions.java  |  2 +-
 .../builtin/base/HiddenInternalFunctions.java |  3 +-
 .../r/nodes/builtin/base/foreign/DotC.java    | 24 +++++++++--
 .../base/foreign/ForeignFunctions.java        | 40 +++++++++++++------
 .../r/runtime/ffi/generic/Generic_Grid.java   |  4 +-
 .../r/runtime/ffi/generic/Generic_Tools.java  |  2 +-
 .../truffle/r/runtime/ffi/jni/JNI_C.java      |  3 +-
 .../truffle/r/runtime/ffi/jni/JNI_Call.java   |  5 ++-
 .../truffle/r/runtime/data/RExternalPtr.java  | 12 +++++-
 .../oracle/truffle/r/runtime/ffi/CRFFI.java   |  4 +-
 .../truffle/r/runtime/ffi/CallRFFI.java       |  7 +++-
 .../com/oracle/truffle/r/runtime/ffi/DLL.java | 38 +++++++-----------
 13 files changed, 94 insertions(+), 52 deletions(-)

diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics.java
index c87b109962..4ebff81208 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics.java
@@ -63,7 +63,7 @@ public class RGraphics {
                 DLL.RegisteredNativeSymbol rns = DLL.RegisteredNativeSymbol.any();
                 DLL.SymbolHandle func = DLL.findSymbol("InitGraphics", null, rns);
                 assert func != DLL.SYMBOL_NOT_FOUND;
-                RFFIFactory.getRFFI().getCallRFFI().invokeVoidCall(func, "InitGraphics", new Object[0]);
+                RFFIFactory.getRFFI().getCallRFFI().invokeVoidCall(func, "InitGraphics", DLL.findLibrary("graphics"), new Object[0]);
             }
         }
     }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java
index 6ef837a033..9edab7fbd3 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java
@@ -175,7 +175,7 @@ public class DynLoadFunctions {
         @Specialization(guards = "isDLLInfo(externalPtr)")
         @TruffleBoundary
         protected Object getSymbolInfo(RAbstractStringVector symbolVec, RExternalPtr externalPtr, boolean withReg) {
-            DLL.DLLInfo dllInfo = DLL.getDLLInfoForId((int) externalPtr.getAddr().asAddress());
+            DLL.DLLInfo dllInfo = (DLLInfo) externalPtr.getExternalObject();
             if (dllInfo == null) {
                 throw RError.error(this, RError.Message.REQUIRES_NAME_DLLINFO);
             }
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
index ff6b649c54..7b1275c1b1 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java
@@ -66,6 +66,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.env.REnvironment.PutException;
 import com.oracle.truffle.r.runtime.ffi.DLL;
+import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
 
 /**
  * Private, undocumented, {@code .Internal} and {@code .Primitive} functions transcribed from GnuR,
@@ -285,7 +286,7 @@ public class HiddenInternalFunctions {
         @TruffleBoundary
         protected RList getRegisteredRoutines(RExternalPtr externalPtr) {
             Object[] data = new Object[NAMES.getLength()];
-            DLL.DLLInfo dllInfo = DLL.getDLLInfoForId((int) externalPtr.getAddr().asAddress());
+            DLL.DLLInfo dllInfo = (DLLInfo) externalPtr.getExternalObject();
             RInternalError.guarantee(dllInfo != null);
             for (DLL.NativeSymbolType nst : DLL.NativeSymbolType.values()) {
                 DLL.DotSymbol[] symbols = dllInfo.getNativeSymbols(nst);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java
index 1b416abe22..cc241faf9f 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java
@@ -22,6 +22,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.dsl.Cached;
 import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.api.frame.VirtualFrame;
+import com.oracle.truffle.api.nodes.Node.Child;
 import com.oracle.truffle.api.profiles.BranchProfile;
 import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode;
 import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode;
@@ -35,6 +36,7 @@ import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RExternalPtr;
 import com.oracle.truffle.r.runtime.data.RList;
+import com.oracle.truffle.r.runtime.data.RLogical;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
@@ -42,6 +44,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.ffi.DLL;
+import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
 import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
 import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
 
@@ -67,6 +70,8 @@ public abstract class DotC extends RBuiltinNode {
 
     @Child private ExtractVectorNode nameExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true);
     @Child private ExtractVectorNode addressExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true);
+    @Child private ExtractVectorNode packageExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true);
+    @Child private ExtractVectorNode infoExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true);
 
     @Override
     public Object[] getDefaultParameterValues() {
@@ -78,7 +83,8 @@ public abstract class DotC extends RBuiltinNode {
     protected RList c(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, byte naok, byte dup, Object rPackage, RMissing encoding) {
         SymbolHandle handle = getAddressFromSymbolInfo(frame, symbol);
         String name = getNameFromSymbolInfo(frame, symbol);
-        return dispatch(this, handle, name, naok, dup, args);
+        DLLInfo dllInfo = getDLLInfoFromSymbolInfo(frame, symbol);
+        return dispatch(this, handle, name, dllInfo, naok, dup, args);
     }
 
     @SuppressWarnings("unused")
@@ -99,7 +105,7 @@ public abstract class DotC extends RBuiltinNode {
             errorProfile.enter();
             throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, f);
         }
-        return dispatch(this, func, f.getDataAt(0), naok, dup, args);
+        return dispatch(this, func, f.getDataAt(0), rns.getDllInfo(), naok, dup, args);
     }
 
     private String getNameFromSymbolInfo(VirtualFrame frame, RList symbol) {
@@ -118,6 +124,16 @@ public abstract class DotC extends RBuiltinNode {
         return ((RExternalPtr) addressExtract.applyAccessField(frame, symbol, "address")).getAddr();
     }
 
+    protected DLLInfo getDLLInfoFromSymbolInfo(VirtualFrame frame, RList symbol) {
+        if (packageExtract == null) {
+            CompilerDirectives.transferToInterpreterAndInvalidate();
+            packageExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true);
+        }
+        // field name may be "package" or "dll", but always at (R) index 3
+        RList packageList = (RList) packageExtract.apply(frame, symbol, new Object[]{3}, RLogical.valueOf(false), RMissing.instance);
+        return (DLLInfo) ((RExternalPtr) addressExtract.applyAccessField(frame, packageList, "info")).getExternalObject();
+    }
+
     private static int[] checkNAs(RBuiltinNode node, int argIndex, int[] data) {
         CompilerAsserts.neverPartOfCompilation();
         for (int i = 0; i < data.length; i++) {
@@ -151,7 +167,7 @@ public abstract class DotC extends RBuiltinNode {
     }
 
     @TruffleBoundary
-    protected static RList dispatch(RBuiltinNode node, SymbolHandle handle, String name, byte naok, byte dup, RArgsValuesAndNames args) {
+    protected static RList dispatch(RBuiltinNode node, SymbolHandle handle, String name, DLLInfo dllInfo, byte naok, byte dup, RArgsValuesAndNames args) {
         @SuppressWarnings("unused")
         boolean dupArgs = RRuntime.fromLogical(dup);
         @SuppressWarnings("unused")
@@ -194,7 +210,7 @@ public abstract class DotC extends RBuiltinNode {
         if (FastROptions.TraceNativeCalls.getBooleanValue()) {
             trace(name, nativeArgs);
         }
-        RFFIFactory.getRFFI().getCRFFI().invoke(handle, nativeArgs);
+        RFFIFactory.getRFFI().getCRFFI().invoke(handle, nativeArgs, dllInfo);
         // we have to assume that the native method updated everything
         RStringVector listNames = validateArgNames(array.length, args.getSignature());
         Object[] results = new Object[array.length];
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java
index 78711bb74f..4fefa3e956 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java
@@ -95,10 +95,12 @@ import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RExternalPtr;
 import com.oracle.truffle.r.runtime.data.RList;
+import com.oracle.truffle.r.runtime.data.RLogical;
 import com.oracle.truffle.r.runtime.data.RMissing;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.ffi.DLL;
+import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
 import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
 import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
 
@@ -189,6 +191,8 @@ public class ForeignFunctions {
 
         @Child private ExtractVectorNode nameExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true);
         @Child private ExtractVectorNode addressExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true);
+        @Child private ExtractVectorNode packageExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true);
+        @Child private ExtractVectorNode infoExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true);
 
         protected String getNameFromSymbolInfo(VirtualFrame frame, RList symbol) {
             if (nameExtract == null) {
@@ -206,6 +210,16 @@ public class ForeignFunctions {
             return ((RExternalPtr) addressExtract.applyAccessField(frame, symbol, "address")).getAddr();
         }
 
+        protected DLLInfo getDLLInfoFromSymbolInfo(VirtualFrame frame, RList symbol) {
+            if (packageExtract == null) {
+                CompilerDirectives.transferToInterpreterAndInvalidate();
+                packageExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true);
+            }
+            // field name may be "package" or "dll", but always at (R) index 3
+            RList packageList = (RList) packageExtract.apply(frame, symbol, new Object[]{3}, RLogical.valueOf(false), RMissing.instance);
+            return (DLLInfo) ((RExternalPtr) addressExtract.applyAccessField(frame, packageList, "info")).getExternalObject();
+        }
+
         protected String checkPackageArg(Object rPackage, BranchProfile errorProfile) {
             String libName = null;
             if (!(rPackage instanceof RMissing)) {
@@ -259,7 +273,7 @@ public class ForeignFunctions {
         @Specialization(guards = "lookupBuiltin(symbol) == null")
         protected RList c(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, byte naok, byte dup, @SuppressWarnings("unused") Object rPackage,
                         @SuppressWarnings("unused") RMissing encoding) {
-            return DotC.dispatch(this, getAddressFromSymbolInfo(frame, symbol), getNameFromSymbolInfo(frame, symbol), naok, dup, args);
+            return DotC.dispatch(this, getAddressFromSymbolInfo(frame, symbol), getNameFromSymbolInfo(frame, symbol), getDLLInfoFromSymbolInfo(frame, symbol), naok, dup, args);
         }
 
         @Specialization
@@ -272,7 +286,7 @@ public class ForeignFunctions {
                 errorProfile.enter();
                 throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, f);
             }
-            return DotC.dispatch(this, func, f.getDataAt(0), naok, dup, args);
+            return DotC.dispatch(this, func, f.getDataAt(0), rns.getDllInfo(), naok, dup, args);
         }
 
         @SuppressWarnings("unused")
@@ -549,7 +563,8 @@ public class ForeignFunctions {
 
         @Specialization
         protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") Object packageName) {
-            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(getAddressFromSymbolInfo(frame, symbol), getNameFromSymbolInfo(frame, symbol), args.getArguments());
+            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(getAddressFromSymbolInfo(frame, symbol), getNameFromSymbolInfo(frame, symbol), getDLLInfoFromSymbolInfo(frame, symbol),
+                            args.getArguments());
         }
 
         @Specialization
@@ -565,7 +580,7 @@ public class ForeignFunctions {
                 errorProfile.enter();
                 throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, name);
             }
-            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(func, name, args.getArguments());
+            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(func, name, rns.getDllInfo(), args.getArguments());
         }
 
         @Fallback
@@ -636,7 +651,7 @@ public class ForeignFunctions {
         protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") Object packageName) {
             String name = getNameFromSymbolInfo(frame, symbol);
             Object list = encodeArgumentPairList(args, name);
-            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(getAddressFromSymbolInfo(frame, symbol), name, new Object[]{list});
+            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(getAddressFromSymbolInfo(frame, symbol), name, getDLLInfoFromSymbolInfo(frame, symbol), new Object[]{list});
         }
 
         @Specialization
@@ -653,7 +668,7 @@ public class ForeignFunctions {
                 throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, name);
             }
             Object list = encodeArgumentPairList(args, name);
-            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(func, name, new Object[]{list});
+            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(func, name, rns.getDllInfo(), new Object[]{list});
         }
 
         @Fallback
@@ -709,7 +724,7 @@ public class ForeignFunctions {
             String name = getNameFromSymbolInfo(frame, symbol);
             Object list = encodeArgumentPairList(args, name);
             // TODO: provide proper values for the CALL, OP and RHO parameters
-            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(getAddressFromSymbolInfo(frame, symbol), name, new Object[]{CALL, OP, list, RHO});
+            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(getAddressFromSymbolInfo(frame, symbol), name, getDLLInfoFromSymbolInfo(frame, symbol), new Object[]{CALL, OP, list, RHO});
         }
 
         @Specialization
@@ -727,7 +742,7 @@ public class ForeignFunctions {
             }
             Object list = encodeArgumentPairList(args, name);
             // TODO: provide proper values for the CALL, OP and RHO parameters
-            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(func, name, new Object[]{CALL, OP, list, RHO});
+            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(func, name, rns.getDllInfo(), new Object[]{CALL, OP, list, RHO});
         }
 
         @Fallback
@@ -767,7 +782,7 @@ public class ForeignFunctions {
         protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") Object packageName) {
             String name = getNameFromSymbolInfo(frame, symbol);
             Object list = encodeArgumentPairList(args, name);
-            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(getAddressFromSymbolInfo(frame, symbol), name, new Object[]{list});
+            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(getAddressFromSymbolInfo(frame, symbol), name, getDLLInfoFromSymbolInfo(frame, symbol), new Object[]{list});
         }
 
         @Specialization
@@ -784,7 +799,7 @@ public class ForeignFunctions {
                 throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, name);
             }
             Object list = encodeArgumentPairList(args, name);
-            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(func, name, new Object[]{list});
+            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(func, name, rns.getDllInfo(), new Object[]{list});
         }
 
         @Fallback
@@ -822,7 +837,8 @@ public class ForeignFunctions {
 
         @Specialization
         protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") Object packageName) {
-            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(getAddressFromSymbolInfo(frame, symbol), getNameFromSymbolInfo(frame, symbol), args.getArguments());
+            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(getAddressFromSymbolInfo(frame, symbol), getNameFromSymbolInfo(frame, symbol), getDLLInfoFromSymbolInfo(frame, symbol),
+                            args.getArguments());
         }
 
         @Specialization
@@ -839,7 +855,7 @@ public class ForeignFunctions {
                 errorProfile.enter();
                 throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, name);
             }
-            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(func, name, args.getArguments());
+            return RFFIFactory.getRFFI().getCallRFFI().invokeCall(func, name, rns.getDllInfo(), args.getArguments());
         }
 
         @Fallback
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Grid.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Grid.java
index 5abe50b8ca..13caad9845 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Grid.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Grid.java
@@ -65,12 +65,12 @@ public class Generic_Grid implements GridRFFI {
     @Override
     public Object initGrid(REnvironment gridEvalEnv) {
         long initGrid = GridProvider.gridProvider().getInitGrid();
-        return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new SymbolHandle(initGrid), "L_initGrid", new Object[]{gridEvalEnv});
+        return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new SymbolHandle(initGrid), "L_initGrid", DLL.findLibrary("grid"), new Object[]{gridEvalEnv});
     }
 
     @Override
     public Object killGrid() {
         long killGrid = GridProvider.gridProvider().getKillGrid();
-        return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new SymbolHandle(killGrid), "L_killGrid", new Object[0]);
+        return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new SymbolHandle(killGrid), "L_killGrid", DLL.findLibrary("grid"), new Object[0]);
     }
 }
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Tools.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Tools.java
index a97616f45f..58d17f87c5 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Tools.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Tools.java
@@ -72,7 +72,7 @@ public class Generic_Tools implements ToolsRFFI {
             parseRdCritical.acquire();
             long parseRd = ToolsProvider.toolsProvider().getParseRd();
             return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new SymbolHandle(parseRd), ToolsProvider.C_PARSE_RD,
-                            new Object[]{con, srcfile, verbose, fragment, basename, warningCalls, macros, warndups});
+                            DLL.findLibrary("tools"), new Object[]{con, srcfile, verbose, fragment, basename, warningCalls, macros, warndups});
         } catch (Throwable ex) {
             throw RInternalError.shouldNotReachHere(ex, "error during Rd parsing");
         } finally {
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_C.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_C.java
index 174ad3844f..a5bf3fa3a7 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_C.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_C.java
@@ -24,6 +24,7 @@ package com.oracle.truffle.r.runtime.ffi.jni;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.r.runtime.ffi.CRFFI;
+import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
 import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
 
 public class JNI_C implements CRFFI {
@@ -36,7 +37,7 @@ public class JNI_C implements CRFFI {
      */
     @Override
     @TruffleBoundary
-    public synchronized void invoke(SymbolHandle symbolHandle, Object[] args) {
+    public synchronized void invoke(SymbolHandle symbolHandle, Object[] args, DLLInfo dllInfo) {
         c(symbolHandle.asAddress(), args);
     }
 
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java
index 16aabaea92..d09ff0ab62 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java
@@ -31,6 +31,7 @@ import com.oracle.truffle.r.runtime.RInternalError;
 import com.oracle.truffle.r.runtime.ffi.CallRFFI;
 import com.oracle.truffle.r.runtime.ffi.DLL;
 import com.oracle.truffle.r.runtime.ffi.DLL.DLLException;
+import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
 import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
 import com.oracle.truffle.r.runtime.ffi.DLLRFFI;
 import com.oracle.truffle.r.runtime.ffi.LibPaths;
@@ -91,7 +92,7 @@ public class JNI_Call implements CallRFFI {
 
     @Override
     @TruffleBoundary
-    public synchronized Object invokeCall(SymbolHandle handleArg, String name, Object[] args) {
+    public synchronized Object invokeCall(SymbolHandle handleArg, String name, DLLInfo dllInfo, Object[] args) {
         long address = handleArg.asAddress();
         Object result = null;
         if (traceEnabled()) {
@@ -152,7 +153,7 @@ public class JNI_Call implements CallRFFI {
 
     @Override
     @TruffleBoundary
-    public synchronized void invokeVoidCall(SymbolHandle handle, String name, Object[] args) {
+    public synchronized void invokeVoidCall(SymbolHandle handle, String name, DLLInfo dllInfo, Object[] args) {
         if (traceEnabled()) {
             traceDownCall(name, args);
         }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExternalPtr.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExternalPtr.java
index 2932ecbe2b..eddf195c7b 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExternalPtr.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExternalPtr.java
@@ -26,12 +26,22 @@ import com.oracle.truffle.r.runtime.RType;
 import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
 
 /**
- * The rarely seen {@code externalptr} type.
+ * The rarely seen {@code externalptr} type used in native code.
  */
 public class RExternalPtr extends RAttributeStorage implements RTypedValue {
+    /**
+     * In GNU R, typically the address of some C structure, so a {@code void*}. Represented here as
+     * our abstraction of a "native symbol" (even though there may not actually be a symbol
+     * associated with the address).
+     */
     private SymbolHandle handle;
     private Object tag;
     private Object prot;
+    /**
+     * Has no GNU R counterpart. Used internally to store a Java object that, for example,
+     * corresponds to the C state in {@link #handle}. Evidently, the R FFI never accesses this
+     * field.
+     */
     private Object externalObject;
 
     RExternalPtr(SymbolHandle handle, Object externalObject, Object tag, Object prot) {
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java
index a1b7d4fc55..0097b0f92e 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.runtime.ffi;
 
+import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
 import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
 
 /**
@@ -35,6 +36,7 @@ public interface CRFFI {
      *
      * @param handle of the native method
      * @param args native arguments
+     * @param dllInfo info on the library containing {@code handle}
      */
-    void invoke(SymbolHandle handle, Object[] args);
+    void invoke(SymbolHandle handle, Object[] args, DLLInfo dllInfo);
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java
index 6baeebaae6..84890a85b5 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.r.runtime.ffi;
 
+import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
 import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
 
 /**
@@ -35,14 +36,16 @@ public interface CallRFFI {
      *
      * @param handle the address of the native function
      * @param name the name of the native function
+     * @param dllInfo TODO
      * @param args arguments
      */
-    Object invokeCall(SymbolHandle handle, String name, Object[] args);
+    Object invokeCall(SymbolHandle handle, String name, DLLInfo dllInfo, Object[] args);
 
     /**
      * Variant that does not return a result (primarily for library "init" methods).
+     * @param dllInfo TODO
      */
-    void invokeVoidCall(SymbolHandle handle, String name, Object[] args);
+    void invokeVoidCall(SymbolHandle handle, String name, DLLInfo dllInfo, Object[] args);
 
     /**
      * This interface is instantiated very early and sets the FFI global variables as part of that
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java
index ec74693d7f..46d8d64749 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java
@@ -30,6 +30,7 @@ import com.oracle.truffle.r.runtime.context.RContext;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RExternalPtr;
 import com.oracle.truffle.r.runtime.data.RList;
+import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RSymbol;
 import com.oracle.truffle.r.runtime.data.RTruffleObject;
@@ -188,16 +189,16 @@ public class DLL {
             data[0] = name;
             data[1] = path;
             data[2] = RRuntime.asLogical(dynamicLookup);
-            data[3] = createExternalPtr(new SymbolHandle(new Long(System.identityHashCode(handle))), HANDLE_CLASS);
+            data[3] = createExternalPtr(new SymbolHandle(new Long(System.identityHashCode(handle))), HANDLE_CLASS, handle);
             /*
-             * GnuR sets the info member to an externalptr whose value is the DllInfo structure
-             * itself. We can't do that, but we need a way to get back to it from R code that uses
-             * the value, e.g. getRegisteredRoutines. So we use the id value.
+             * GnuR sets the info member to an externalptr whose value is the C DllInfo structure
+             * itself. We use the internal "externalObject" slot instead, and we use the "id" for
+             * the "addr" slot.
              */
-            data[4] = createExternalPtr(new SymbolHandle(new Long(id)), INFO_REFERENCE_CLASS);
-            RList dllInfo = RDataFactory.createList(data, DLLInfo.NAMES);
-            dllInfo.setClassAttr(RDataFactory.createStringVectorFromScalar(DLLINFO_CLASS));
-            return dllInfo;
+            data[4] = createExternalPtr(new SymbolHandle(new Long(id)), INFO_REFERENCE_CLASS, this);
+            RList result = RDataFactory.createList(data, DLLInfo.NAMES);
+            result.setClassAttr(RDataFactory.createStringVectorFromScalar(DLLINFO_CLASS));
+            return result;
         }
 
         @Override
@@ -241,11 +242,11 @@ public class DLL {
                 /*
                  * GnuR stores this as an externalptr whose value is the C RegisteredNativeType
                  * struct. We can't do that, and it's not clear any code uses that fact, so we
-                 * stored the registered address.
+                 * stored the registered address. TODO use externalObject slot?
                  */
-                data[1] = DLL.createExternalPtr(rnt.dotSymbol.fun, REGISTERED_NATIVE_SYMBOL_CLASS);
+                data[1] = DLL.createExternalPtr(rnt.dotSymbol.fun, REGISTERED_NATIVE_SYMBOL_CLASS, null);
             } else {
-                data[1] = DLL.createExternalPtr(address, NATIVE_SYMBOL_CLASS);
+                data[1] = DLL.createExternalPtr(address, NATIVE_SYMBOL_CLASS, null);
             }
             data[2] = libInfo.toRList();
             if (n > 3) {
@@ -288,23 +289,14 @@ public class DLL {
 
     public static final SymbolHandle SYMBOL_NOT_FOUND = null;
 
-    public static synchronized DLLInfo getDLLInfoForId(int id) {
-        for (DLLInfo dllInfo : list) {
-            if (dllInfo.id == id) {
-                return dllInfo;
-            }
-        }
-        return null;
-    }
-
     public static boolean isDLLInfo(RExternalPtr info) {
         RSymbol tag = (RSymbol) info.getTag();
         return tag.getName().equals(DLLInfo.DLL_INFO_REFERENCE);
     }
 
-    public static RExternalPtr createExternalPtr(SymbolHandle value, RStringVector rClass) {
+    public static RExternalPtr createExternalPtr(SymbolHandle value, RStringVector rClass, Object externalObject) {
         CompilerAsserts.neverPartOfCompilation(); // for interning
-        RExternalPtr result = RDataFactory.createExternalPtr(value, RDataFactory.createSymbolInterned(rClass.getDataAt(0)));
+        RExternalPtr result = RDataFactory.createExternalPtr(value, externalObject, RDataFactory.createSymbolInterned(rClass.getDataAt(0)), RNull.instance);
         result.setClassAttr(rClass);
         return result;
     }
@@ -363,7 +355,7 @@ public class DLL {
         if (initFunc != SYMBOL_NOT_FOUND) {
             synchronized (DLL.class) {
                 try {
-                    RFFIFactory.getRFFI().getCallRFFI().invokeVoidCall(initFunc, pkgInit, new Object[]{dllInfo});
+                    RFFIFactory.getRFFI().getCallRFFI().invokeVoidCall(initFunc, pkgInit, dllInfo, new Object[]{dllInfo});
                 } catch (ReturnException ex) {
                     // An error call can, due to condition handling, throw this which we must
                     // propogate
-- 
GitLab