summaryrefslogtreecommitdiff
path: root/runtime/interpreter/interpreter_common.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/interpreter/interpreter_common.h')
-rw-r--r--runtime/interpreter/interpreter_common.h46
1 files changed, 45 insertions, 1 deletions
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 9f6699f730..2de8e7e6be 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -888,12 +888,56 @@ static inline bool DoBoxLambda(Thread* self, ShadowFrame& shadow_frame, const In
return false;
}
+ StackHandleScope<1> hs{self}; // NOLINT: [readability/braces] [4];
+
+ // Use the lambda method's class loader since it's close enough.
+ // TODO: create-lambda should capture the current method's class loader and use that instead.
+ // TODO: Do we want create-lambda to work for static methods outside of the declaring class?
+ // --> then we need to store a classloader in the lambda method. otherwise we don't
+ // because it would always use the declaring class's class loader.
+ // TODO: add a GetClassLoader to the lambda closure which knows how to do this,
+ // don't hardcode this here.
+ Handle<ClassLoader> current_class_loader = hs.NewHandle(
+ lambda_closure->GetTargetMethod()->GetDeclaringClass()->GetClassLoader());
+
+ // TODO: get the type ID from the instruction
+ std::string class_name;
+ {
+ // Temporary hack to read the interface corresponding to a box-lambda.
+ // TODO: The box-lambda should encode the type ID instead, so we don't need to do this.
+ {
+ // Do a hack where we read from const-string the interface name
+ mirror::Object* string_reference = shadow_frame.GetVRegReference(vreg_target_object);
+
+ CHECK(string_reference != nullptr)
+ << "box-lambda needs the type name stored in string vA (target), but it was null";
+
+ CHECK(string_reference->IsString())
+ << "box-lambda needs the type name stored in string vA (target)";
+
+ mirror::String* as_string = string_reference->AsString();
+ class_name = as_string->ToModifiedUtf8();
+ }
+
+ // Trigger class loading of the functional interface.
+ // TODO: This should actually be done by the create-lambda...
+ if (Runtime::Current()->GetClassLinker()
+ ->FindClass(self, class_name.c_str(), current_class_loader) == nullptr) {
+ CHECK(self->IsExceptionPending());
+ self->AssertPendingException();
+ return false;
+ }
+ }
+
mirror::Object* closure_as_object =
- Runtime::Current()->GetLambdaBoxTable()->BoxLambda(lambda_closure);
+ Runtime::Current()->GetLambdaBoxTable()->BoxLambda(lambda_closure,
+ class_name.c_str(),
+ current_class_loader.Get());
// Failed to box the lambda, an exception was raised.
if (UNLIKELY(closure_as_object == nullptr)) {
CHECK(self->IsExceptionPending());
+ shadow_frame.SetVRegReference(vreg_target_object, nullptr);
return false;
}