diff options
author | 2018-01-31 18:08:28 +0000 | |
---|---|---|
committer | 2018-02-02 15:39:16 +0000 | |
commit | da1cdd0b1f89ef76def1c5fa8d2bea83c1a6cf48 (patch) | |
tree | 8d7895389f46403c1a0cc8a5ddf8ff92c4355afb | |
parent | 2827ff64c7a385cfb9d6e01e6385708461eb65fc (diff) |
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
-rw-r--r-- | runtime/class_linker.cc | 16 | ||||
-rw-r--r-- | runtime/class_linker.h | 1 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_common.cc | 7 | ||||
-rw-r--r-- | test/710-varhandle-creation/src-art/Main.java | 24 | ||||
-rw-r--r-- | test/714-invoke-custom-lambda-metafactory/build | 22 | ||||
-rw-r--r-- | test/714-invoke-custom-lambda-metafactory/expected.txt | 4 | ||||
-rw-r--r-- | test/714-invoke-custom-lambda-metafactory/info.txt | 1 | ||||
-rw-r--r-- | test/714-invoke-custom-lambda-metafactory/src/Main.java | 32 |
8 files changed, 80 insertions, 27 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 32d304073c..ae707f0eca 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -8368,7 +8368,6 @@ mirror::MethodHandle* ClassLinker::ResolveMethodHandleForField( 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 @@ mirror::MethodHandle* ClassLinker::ResolveMethodHandleForMethod( 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 @@ ObjPtr<mirror::MethodHandle> ClassLinker::ResolveMethodHandle(Thread* self, 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 3e3425f5ac..16fa1ce801 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -979,7 +979,6 @@ class ClassLinker { 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 d53da215a2..12b8c38bbb 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -1183,10 +1183,9 @@ static ObjPtr<mirror::CallSite> InvokeBootstrapMethod(Thread* self, } 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 @@ static ObjPtr<mirror::CallSite> InvokeBootstrapMethod(Thread* self, // 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 a737b5ba9e..246aac6900 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 0000000000..b5002ba79c --- /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 0000000000..cbe98404c5 --- /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 0000000000..4ef117b7e3 --- /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 0000000000..74e0ad4370 --- /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."); + } + } +} |