From 9111709cf7c2a6cf9fecdcef2eecaf13b44857d6 Mon Sep 17 00:00:00 2001
From: stepan <stepan.sindelar@oracle.com>
Date: Mon, 5 Mar 2018 11:22:51 +0100
Subject: [PATCH] RFFI: implement Rf_any_duplicated3

---
 .../ffi/impl/common/JavaUpCallsRFFIImpl.java  |  16 +-
 .../r/ffi/impl/nodes/DuplicateNodes.java      |  53 +++++
 .../r/ffi/impl/nodes/FFIUpCallNode.java       |  17 +-
 .../r/ffi/impl/upcalls/StdUpCallsRFFI.java    |   8 +-
 .../fficall/src/common/rffi_upcalls.h         |   1 +
 .../fficall/src/common/rffi_upcallsindex.h    | 185 +++++++++---------
 .../Rinternals_truffle_common.h               |   7 +
 com.oracle.truffle.r.native/version.source    |   2 +-
 .../com/oracle/truffle/r/runtime/Utils.java   |  17 ++
 .../truffle/r/runtime/data/RExternalPtr.java  |   3 +-
 10 files changed, 206 insertions(+), 103 deletions(-)

diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
index 523b80e3b1..b88e5f750f 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java
@@ -635,18 +635,20 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI {
     }
 
     @Override
-    @TruffleBoundary
     public long Rf_any_duplicated(Object x, int fromLast) {
-        RAbstractVector vec = (RAbstractVector) x;
-        if (vec.getLength() <= 1) {
-            return 0;
-        } else {
-            return DuplicationHelper.analyze(vec, null, true, fromLast != 0).getIndex();
-        }
+        throw implementedAsNode();
+    }
+
+    @Override
+    public long Rf_any_duplicated3(Object x, Object incomparables, int fromLast) {
+        throw implementedAsNode();
     }
 
     @Override
     public Object PRINTNAME(Object x) {
+        if (x == RNull.instance) {
+            return x;
+        }
         guaranteeInstanceOf(x, RSymbol.class);
         return CharSXPWrapper.create(((RSymbol) x).getName());
     }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/DuplicateNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/DuplicateNodes.java
index 4eab0d8673..ff0dbb981c 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/DuplicateNodes.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/DuplicateNodes.java
@@ -23,14 +23,21 @@
 package com.oracle.truffle.r.ffi.impl.nodes;
 
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
+import com.oracle.truffle.api.dsl.Cached;
+import com.oracle.truffle.api.dsl.Fallback;
 import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.api.profiles.ConditionProfile;
 import com.oracle.truffle.r.ffi.impl.nodes.DuplicateNodesFactory.DuplicateNodeGen;
+import com.oracle.truffle.r.ffi.impl.nodes.DuplicateNodesFactory.RfAnyDuplicated3NodeGen;
+import com.oracle.truffle.r.ffi.impl.nodes.DuplicateNodesFactory.RfAnyDuplicatedNodeGen;
 import com.oracle.truffle.r.runtime.data.RExternalPtr;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RSequence;
 import com.oracle.truffle.r.runtime.data.RShareable;
 import com.oracle.truffle.r.runtime.data.RSymbol;
+import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
+import com.oracle.truffle.r.runtime.nodes.DuplicationHelper;
 
 public final class DuplicateNodes {
 
@@ -58,6 +65,11 @@ public final class DuplicateNodes {
             return val;
         }
 
+        @Fallback
+        public Object doOther(Object x, Object y) {
+            throw unsupportedTypes("Rf_duplicate", x, y);
+        }
+
         protected static boolean isReusableForDuplicate(Object o) {
             return o == RNull.instance || o instanceof REnvironment || o instanceof RSymbol;
         }
@@ -67,4 +79,45 @@ public final class DuplicateNodes {
         }
     }
 
+    public abstract static class RfAnyDuplicated extends FFIUpCallNode.Arg2 {
+        @Specialization
+        public int doDuplicate(RAbstractVector vec, int fromLast,
+                        @Cached("createBinaryProfile()") ConditionProfile isEmptyProfile) {
+            if (isEmptyProfile.profile(vec.getLength() <= 1)) {
+                return 0;
+            } else {
+                return DuplicationHelper.analyze(vec, null, true, fromLast != 0).getIndex();
+            }
+        }
+
+        @Fallback
+        public Object doOthers(Object vec, Object fromLast) {
+            throw unsupportedTypes("Rf_any_duplicated", vec, fromLast);
+        }
+
+        public static RfAnyDuplicated create() {
+            return RfAnyDuplicatedNodeGen.create();
+        }
+    }
+
+    public abstract static class RfAnyDuplicated3 extends FFIUpCallNode.Arg3 {
+        @Specialization
+        public int doDuplicate(RAbstractVector vec, RAbstractVector incomparables, int fromLast,
+                        @Cached("createBinaryProfile()") ConditionProfile isEmptyProfile) {
+            if (isEmptyProfile.profile(vec.getLength() <= 1)) {
+                return 0;
+            } else {
+                return DuplicationHelper.analyze(vec, incomparables, true, fromLast != 0).getIndex();
+            }
+        }
+
+        @Fallback
+        public Object doOthers(Object vec, Object incomparables, Object fromLast) {
+            throw unsupportedTypes("Rf_any_duplicated3", vec, incomparables, fromLast);
+        }
+
+        public static RfAnyDuplicated3 create() {
+            return RfAnyDuplicated3NodeGen.create();
+        }
+    }
 }
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallNode.java
index 5df825b06b..4a86d30d42 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallNode.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallNode.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,11 +22,26 @@
  */
 package com.oracle.truffle.r.ffi.impl.nodes;
 
+import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.Message;
+import com.oracle.truffle.r.runtime.Utils;
 
 public abstract class FFIUpCallNode extends Node {
     protected abstract int numArgs();
 
+    @TruffleBoundary
+    protected final RError unsupportedTypes(String name, Object... args) {
+        assert args.length > 0;
+        StringBuilder sb = new StringBuilder(args.length * 15);
+        sb.append("wrong argument types provided to Rf_duplicated: ").append(Utils.getTypeName(args[0]));
+        for (int i = 1; i < args.length; i++) {
+            sb.append(',').append(Utils.getTypeName(args[i]));
+        }
+        throw RError.error(RError.NO_CALLER, Message.GENERIC, sb);
+    }
+
     public abstract static class Arg0 extends FFIUpCallNode {
         public abstract Object executeObject();
 
diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java
index a576084b4f..c74c973809 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java
@@ -34,9 +34,11 @@ import com.oracle.truffle.r.ffi.impl.nodes.CoerceNodes.CoerceVectorNode;
 import com.oracle.truffle.r.ffi.impl.nodes.CoerceNodes.VectorToPairListNode;
 import com.oracle.truffle.r.ffi.impl.nodes.DoMakeClassNode;
 import com.oracle.truffle.r.ffi.impl.nodes.DuplicateNodes;
-import com.oracle.truffle.r.ffi.impl.nodes.GetClassDefNode;
+import com.oracle.truffle.r.ffi.impl.nodes.DuplicateNodes.RfAnyDuplicated;
+import com.oracle.truffle.r.ffi.impl.nodes.DuplicateNodes.RfAnyDuplicated3;
 import com.oracle.truffle.r.ffi.impl.nodes.EnvNodes.LockBindingNode;
 import com.oracle.truffle.r.ffi.impl.nodes.EnvNodes.UnlockBindingNode;
+import com.oracle.truffle.r.ffi.impl.nodes.GetClassDefNode;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CAARNode;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CAD4RNode;
 import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CADDDRNode;
@@ -206,8 +208,12 @@ public interface StdUpCallsRFFI {
     @RFFIUpCallNode(DuplicateNodes.DuplicateNode.class)
     Object Rf_duplicate(Object x, int deep);
 
+    @RFFIUpCallNode(RfAnyDuplicated.class)
     long Rf_any_duplicated(Object x, int fromLast);
 
+    @RFFIUpCallNode(RfAnyDuplicated3.class)
+    long Rf_any_duplicated3(Object x, Object incomparables, int fromLast);
+
     Object PRINTNAME(Object x);
 
     @RFFIUpCallNode(TAG.class)
diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h
index 1a6bc2c49b..e60dcbfe7f 100644
--- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h
+++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h
@@ -57,6 +57,7 @@ typedef SEXP (*call_Rf_duplicate)(SEXP x, int v);
 typedef SEXP (*call_Rf_shallow_duplicate)(SEXP x);
 typedef SEXP (*call_Rf_coerceVector)(SEXP x, SEXPTYPE mode);
 typedef R_xlen_t (*call_Rf_any_duplicated)(SEXP x, Rboolean from_last);
+typedef R_xlen_t (*call_Rf_any_duplicated3)(SEXP x, SEXP y, Rboolean from_last);
 typedef SEXP (*call_Rf_duplicated)(SEXP x, Rboolean y);
 typedef SEXP (*call_Rf_applyClosure)(SEXP x, SEXP y, SEXP z, SEXP a, SEXP b);
 typedef int (*call_Rf_copyMostAttrib)(SEXP x, SEXP y);
diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h
index 8c6c129944..1dc742abd6 100644
--- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h
+++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h
@@ -104,98 +104,99 @@
 #define Rf_allocMatrix_x 99
 #define Rf_allocVector_x 100
 #define Rf_any_duplicated_x 101
-#define Rf_asChar_x 102
-#define Rf_asCharacterFactor_x 103
-#define Rf_asInteger_x 104
-#define Rf_asLogical_x 105
-#define Rf_asReal_x 106
-#define Rf_classgets_x 107
-#define Rf_coerceVector_x 108
-#define Rf_cons_x 109
-#define Rf_copyListMatrix_x 110
-#define Rf_copyMatrix_x 111
-#define Rf_copyMostAttrib_x 112
-#define Rf_dchisq_x 113
-#define Rf_defineVar_x 114
-#define Rf_dnchisq_x 115
-#define Rf_dunif_x 116
-#define Rf_duplicate_x 117
-#define Rf_error_x 118
-#define Rf_errorcall_x 119
-#define Rf_eval_x 120
-#define Rf_findFun_x 121
-#define Rf_findVar_x 122
-#define Rf_findVarInFrame_x 123
-#define Rf_findVarInFrame3_x 124
-#define Rf_getAttrib_x 125
-#define Rf_gsetVar_x 126
-#define Rf_inherits_x 127
-#define Rf_install_x 128
-#define Rf_installChar_x 129
-#define Rf_isNull_x 130
-#define Rf_isString_x 131
-#define Rf_lengthgets_x 132
-#define Rf_match_x 133
-#define Rf_mkCharLenCE_x 134
-#define Rf_namesgets_x 135
-#define Rf_ncols_x 136
-#define Rf_nrows_x 137
-#define Rf_pchisq_x 138
-#define Rf_pnchisq_x 139
-#define Rf_protect_x 140
-#define Rf_punif_x 141
-#define Rf_qchisq_x 142
-#define Rf_qnchisq_x 143
-#define Rf_qunif_x 144
-#define Rf_rchisq_x 145
-#define Rf_rnchisq_x 146
-#define Rf_runif_x 147
-#define Rf_setAttrib_x 148
-#define Rf_str2type_x 149
-#define Rf_unprotect_x 150
-#define Rf_unprotect_ptr_x 151
-#define Rf_warning_x 152
-#define Rf_warningcall_x 153
-#define Rprintf_x 154
-#define SETCAD4R_x 155
-#define SETCADDDR_x 156
-#define SETCADDR_x 157
-#define SETCADR_x 158
-#define SETCAR_x 159
-#define SETCDR_x 160
-#define SET_BODY_x 161
-#define SET_CLOENV_x 162
-#define SET_FORMALS_x 163
-#define SET_NAMED_FASTR_x 164
-#define SET_RDEBUG_x 165
-#define SET_RSTEP_x 166
-#define SET_S4_OBJECT_x 167
-#define SET_STRING_ELT_x 168
-#define SET_SYMVALUE_x 169
-#define SET_TAG_x 170
-#define SET_TYPEOF_FASTR_x 171
-#define SET_VECTOR_ELT_x 172
-#define STRING_ELT_x 173
-#define SYMVALUE_x 174
-#define TAG_x 175
-#define TYPEOF_x 176
-#define UNSET_S4_OBJECT_x 177
-#define VECTOR_ELT_x 178
-#define forceSymbols_x 179
-#define getCCallable_x 180
-#define getConnectionClassString_x 181
-#define getEmbeddingDLLInfo_x 182
-#define getOpenModeString_x 183
-#define getSummaryDescription_x 184
-#define isSeekable_x 185
-#define octsize_x 186
-#define registerCCallable_x 187
-#define registerRoutines_x 188
-#define restoreHandlerStacks_x 189
-#define setDotSymbolValues_x 190
-#define unif_rand_x 191
-#define useDynamicSymbols_x 192
+#define Rf_any_duplicated3_x 102
+#define Rf_asChar_x 103
+#define Rf_asCharacterFactor_x 104
+#define Rf_asInteger_x 105
+#define Rf_asLogical_x 106
+#define Rf_asReal_x 107
+#define Rf_classgets_x 108
+#define Rf_coerceVector_x 109
+#define Rf_cons_x 110
+#define Rf_copyListMatrix_x 111
+#define Rf_copyMatrix_x 112
+#define Rf_copyMostAttrib_x 113
+#define Rf_dchisq_x 114
+#define Rf_defineVar_x 115
+#define Rf_dnchisq_x 116
+#define Rf_dunif_x 117
+#define Rf_duplicate_x 118
+#define Rf_error_x 119
+#define Rf_errorcall_x 120
+#define Rf_eval_x 121
+#define Rf_findFun_x 122
+#define Rf_findVar_x 123
+#define Rf_findVarInFrame_x 124
+#define Rf_findVarInFrame3_x 125
+#define Rf_getAttrib_x 126
+#define Rf_gsetVar_x 127
+#define Rf_inherits_x 128
+#define Rf_install_x 129
+#define Rf_installChar_x 130
+#define Rf_isNull_x 131
+#define Rf_isString_x 132
+#define Rf_lengthgets_x 133
+#define Rf_match_x 134
+#define Rf_mkCharLenCE_x 135
+#define Rf_namesgets_x 136
+#define Rf_ncols_x 137
+#define Rf_nrows_x 138
+#define Rf_pchisq_x 139
+#define Rf_pnchisq_x 140
+#define Rf_protect_x 141
+#define Rf_punif_x 142
+#define Rf_qchisq_x 143
+#define Rf_qnchisq_x 144
+#define Rf_qunif_x 145
+#define Rf_rchisq_x 146
+#define Rf_rnchisq_x 147
+#define Rf_runif_x 148
+#define Rf_setAttrib_x 149
+#define Rf_str2type_x 150
+#define Rf_unprotect_x 151
+#define Rf_unprotect_ptr_x 152
+#define Rf_warning_x 153
+#define Rf_warningcall_x 154
+#define Rprintf_x 155
+#define SETCAD4R_x 156
+#define SETCADDDR_x 157
+#define SETCADDR_x 158
+#define SETCADR_x 159
+#define SETCAR_x 160
+#define SETCDR_x 161
+#define SET_BODY_x 162
+#define SET_CLOENV_x 163
+#define SET_FORMALS_x 164
+#define SET_NAMED_FASTR_x 165
+#define SET_RDEBUG_x 166
+#define SET_RSTEP_x 167
+#define SET_S4_OBJECT_x 168
+#define SET_STRING_ELT_x 169
+#define SET_SYMVALUE_x 170
+#define SET_TAG_x 171
+#define SET_TYPEOF_FASTR_x 172
+#define SET_VECTOR_ELT_x 173
+#define STRING_ELT_x 174
+#define SYMVALUE_x 175
+#define TAG_x 176
+#define TYPEOF_x 177
+#define UNSET_S4_OBJECT_x 178
+#define VECTOR_ELT_x 179
+#define forceSymbols_x 180
+#define getCCallable_x 181
+#define getConnectionClassString_x 182
+#define getEmbeddingDLLInfo_x 183
+#define getOpenModeString_x 184
+#define getSummaryDescription_x 185
+#define isSeekable_x 186
+#define octsize_x 187
+#define registerCCallable_x 188
+#define registerRoutines_x 189
+#define restoreHandlerStacks_x 190
+#define setDotSymbolValues_x 191
+#define unif_rand_x 192
+#define useDynamicSymbols_x 193
 
-#define UPCALLS_TABLE_SIZE 193
+#define UPCALLS_TABLE_SIZE 194
 
 #endif // RFFI_UPCALLSINDEX_H
diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h
index 82bf7b8f64..628f5974c6 100644
--- a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h
+++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h
@@ -448,6 +448,13 @@ R_xlen_t Rf_any_duplicated(SEXP x, Rboolean from_last) {
     return result;
 }
 
+R_xlen_t Rf_any_duplicated3(SEXP x, SEXP incomp, Rboolean from_last) {
+    TRACE0();
+    R_xlen_t result = (R_xlen_t) ((call_Rf_any_duplicated3) callbacks[Rf_any_duplicated3_x])(x, incomp, from_last);
+    checkExitCall();
+    return result;
+}
+
 SEXP Rf_duplicated(SEXP x, Rboolean y) {
     TRACE0();
     unimplemented("Rf_duplicated");
diff --git a/com.oracle.truffle.r.native/version.source b/com.oracle.truffle.r.native/version.source
index fb1e7bc869..c3f407c095 100644
--- a/com.oracle.truffle.r.native/version.source
+++ b/com.oracle.truffle.r.native/version.source
@@ -1 +1 @@
-54
+55
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java
index 9f542e9f7a..aad7079a81 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java
@@ -37,6 +37,7 @@ import java.util.function.Function;
 
 import com.oracle.truffle.api.CallTarget;
 import com.oracle.truffle.api.CompilerAsserts;
+import com.oracle.truffle.api.CompilerDirectives;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.Truffle;
 import com.oracle.truffle.api.TruffleRuntime;
@@ -57,6 +58,7 @@ import com.oracle.truffle.r.runtime.data.RLanguage;
 import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RPairList;
 import com.oracle.truffle.r.runtime.data.RStringVector;
+import com.oracle.truffle.r.runtime.data.RTypedValue;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
 import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor.MultiSlotData;
 import com.oracle.truffle.r.runtime.ffi.BaseRFFI;
@@ -678,6 +680,21 @@ public final class Utils {
         return String.format(format, objects);
     }
 
+    /**
+     * Makes the best effort to create end user understandable String representation of the type of
+     * the parameter. When the parameter is null, returns "null".
+     */
+    public static String getTypeName(Object value) {
+        // Typically part of error reporting. The whole error reporting should be behind TB.
+        CompilerAsserts.neverPartOfCompilation();
+        if (value == null) {
+            return "null";
+        } else if (value instanceof RTypedValue) {
+            return ((RTypedValue) value).getRType().getName();
+        }
+        return value.getClass().getSimpleName();
+    }
+
     private static boolean isWriteableDirectory(String path) {
         File f = new File(path);
         return f.exists() && f.isDirectory() && f.canWrite();
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 fa03686af9..5112b66313 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
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -56,6 +56,7 @@ public final class RExternalPtr extends RAttributeStorage implements RTypedValue
     }
 
     public SymbolHandle getAddr() {
+        // TODO: can be null? Callers do dereference the return value.
         return handle;
     }
 
-- 
GitLab