ART: Fix call site resolution

Parameter type resolution should use the target method's DEX file.

Bug: 70166093
Test: art/test/run-test --host 714
Change-Id: Ic4961a905144ee85b36d02476506c4078c6cdf7a
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 32d3040..ae707f0 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -8368,7 +8368,6 @@
 
 mirror::MethodHandle* ClassLinker::ResolveMethodHandleForMethod(
     Thread* self,
-    const DexFile* const dex_file,
     const DexFile::MethodHandleItem& method_handle,
     ArtMethod* referrer) {
   DexFile::MethodHandleType handle_type =
@@ -8492,19 +8491,20 @@
     return nullptr;
   }
 
-  Handle<mirror::DexCache> dex_cache(hs.NewHandle(referrer->GetDexCache()));
-  Handle<mirror::ClassLoader> class_loader(hs.NewHandle(referrer->GetClassLoader()));
   int32_t index = 0;
-
   if (receiver_count != 0) {
     // Insert receiver
     method_params->Set(index++, target_method->GetDeclaringClass());
   }
-
-  DexFileParameterIterator it(*dex_file, target_method->GetPrototype());
+  DexFileParameterIterator it(*target_method->GetDexFile(), target_method->GetPrototype());
+  Handle<mirror::DexCache> target_method_dex_cache(hs.NewHandle(target_method->GetDexCache()));
+  Handle<mirror::ClassLoader> target_method_class_loader(hs.NewHandle(target_method->GetClassLoader()));
   while (it.HasNext()) {
+    DCHECK_LT(index, num_params);
     const dex::TypeIndex type_idx = it.GetTypeIdx();
-    ObjPtr<mirror::Class> klass = ResolveType(type_idx, dex_cache, class_loader);
+    ObjPtr<mirror::Class> klass = ResolveType(type_idx,
+                                              target_method_dex_cache,
+                                              target_method_class_loader);
     if (nullptr == klass) {
       DCHECK(self->IsExceptionPending());
       return nullptr;
@@ -8554,7 +8554,7 @@
     case DexFile::MethodHandleType::kInvokeConstructor:
     case DexFile::MethodHandleType::kInvokeDirect:
     case DexFile::MethodHandleType::kInvokeInterface:
-      return ResolveMethodHandleForMethod(self, dex_file, method_handle, referrer);
+      return ResolveMethodHandleForMethod(self, method_handle, referrer);
   }
 }
 
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 3e3425f..16fa1ce 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -979,7 +979,6 @@
       REQUIRES_SHARED(Locks::mutator_lock_);
 
   mirror::MethodHandle* ResolveMethodHandleForMethod(Thread* self,
-                                                     const DexFile* const dex_file,
                                                      const DexFile::MethodHandleItem& method_handle,
                                                      ArtMethod* referrer)
       REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index d53da21..12b8c38 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -1183,10 +1183,9 @@
   }
 
   Handle<mirror::Object> object(hs.NewHandle(result.GetL()));
-
-  // Check the result is not null.
   if (UNLIKELY(object.IsNull())) {
-    ThrowNullPointerException("CallSite == null");
+    // This will typically be for LambdaMetafactory which is not supported.
+    ThrowNullPointerException("Bootstrap method returned null");
     return nullptr;
   }
 
@@ -1202,7 +1201,7 @@
   // Check the call site target is not null as we're going to invoke it.
   Handle<mirror::MethodHandle> target = hs.NewHandle(call_site->GetTarget());
   if (UNLIKELY(target.IsNull())) {
-    ThrowNullPointerException("CallSite target == null");
+    ThrowNullPointerException("Target for call-site is null");
     return nullptr;
   }
 
diff --git a/test/710-varhandle-creation/src-art/Main.java b/test/710-varhandle-creation/src-art/Main.java
index a737b5b..246aac6 100644
--- a/test/710-varhandle-creation/src-art/Main.java
+++ b/test/710-varhandle-creation/src-art/Main.java
@@ -1,21 +1,17 @@
 /*
- * Copyright 2017 Google Inc.
+ * Copyright (C) 2018 The Android Open Source Project
  *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Google designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Google in the LICENSE file that accompanied this code.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 import java.lang.invoke.MethodHandles;
diff --git a/test/714-invoke-custom-lambda-metafactory/build b/test/714-invoke-custom-lambda-metafactory/build
new file mode 100644
index 0000000..b5002ba
--- /dev/null
+++ b/test/714-invoke-custom-lambda-metafactory/build
@@ -0,0 +1,22 @@
+#!/bin/bash
+#
+# Copyright 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Make us exit on a failure
+set -e
+
+# Opt-out from desugaring to ensure offending lambda is in the DEX.
+export USE_DESUGAR=false
+./default-build "$@" --experimental method-handles
diff --git a/test/714-invoke-custom-lambda-metafactory/expected.txt b/test/714-invoke-custom-lambda-metafactory/expected.txt
new file mode 100644
index 0000000..cbe9840
--- /dev/null
+++ b/test/714-invoke-custom-lambda-metafactory/expected.txt
@@ -0,0 +1,4 @@
+Exception in thread "main" java.lang.BootstrapMethodError: Exception from call site #0 bootstrap method
+	at Main.main(Main.java:25)
+Caused by: java.lang.NullPointerException: Bootstrap method returned null
+	... 1 more
diff --git a/test/714-invoke-custom-lambda-metafactory/info.txt b/test/714-invoke-custom-lambda-metafactory/info.txt
new file mode 100644
index 0000000..4ef117b
--- /dev/null
+++ b/test/714-invoke-custom-lambda-metafactory/info.txt
@@ -0,0 +1 @@
+Checks that ART doesn't crash when it encounters LambdaMetafactory.
diff --git a/test/714-invoke-custom-lambda-metafactory/src/Main.java b/test/714-invoke-custom-lambda-metafactory/src/Main.java
new file mode 100644
index 0000000..74e0ad4
--- /dev/null
+++ b/test/714-invoke-custom-lambda-metafactory/src/Main.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+public class Main {
+    public static void main(String[] args) {
+        int requiredLength = 3;
+        List<String> list = Arrays.asList("A", "B", "C", "D", "EEE");
+        Optional<String> result = list.stream().filter(x -> x.length() >= requiredLength).findAny();
+        if (result.isPresent()) {
+            System.out.println("Result is " + result.get());
+        } else {
+            System.out.println("Result is not there.");
+        }
+    }
+}