[vm, simarm64] Handle exceptions during FFI callbacks.

TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/60204
Change-Id: If746fe07a10c9c71d228ca9591f398054635fea2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/413900
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak
2025-03-10 10:14:15 -07:00
committed by Commit Queue
parent d9bd6a09f8
commit 530fff90c0
5 changed files with 25 additions and 1 deletions
+3
View File
@@ -55,6 +55,9 @@ class RuntimeEntry : public BaseRuntimeEntry {
bool is_float() const { return is_float_; }
bool can_lazy_deopt() const { return can_lazy_deopt_; }
uword GetEntryPoint() const;
uword GetEntryPointNoRedirect() const {
return reinterpret_cast<uword>(function());
}
static uword InterpretCallEntry();
+11
View File
@@ -4088,6 +4088,17 @@ void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) {
// Keep the following code in sync with `StubCode::JumpToFrameStub()`.
// Check if we exited generated from FFI. If so do transition - this is needed
// because normally runtime calls transition back to generated via destructor
// of TransitionGeneratedToVM/Native that is part of runtime boilerplate
// code (see DEFINE_RUNTIME_ENTRY_IMPL in runtime_entry.h). Ffi calls don't
// have this boilerplate, don't have this stack resource, have to transition
// explicitly.
if (thread->exit_through_ffi() == dart::Thread::kExitThroughFfi) {
thread->ExitSafepoint();
thread->set_execution_state(Thread::kThreadInGenerated);
}
// Unwind the C++ stack and continue simulation in the target frame.
set_pc(static_cast<int64_t>(pc));
set_register(nullptr, SP, static_cast<int64_t>(sp));
+7
View File
@@ -218,6 +218,13 @@ void Thread::InitVMConstants() {
LEAF_RUNTIME_ENTRY_LIST(INIT_VALUE)
#undef INIT_VALUE
#if defined(SIMULATOR_FFI)
// FfiCallInstr calls this through the CallNativeThroughSafepoint stub instead
// of like a normal leaf runtime call.
PropagateError_entry_point_ =
kPropagateErrorRuntimeEntry.GetEntryPointNoRedirect();
#endif
// Setup the thread specific reusable handles.
#define REUSABLE_HANDLE_ALLOCATION(object) \
this->object##_handle_ = this->AllocateReusableHandle<object>();
+1
View File
@@ -485,6 +485,7 @@ class Thread : public ThreadState {
kExitThroughRuntimeCall = 2,
};
uword exit_through_ffi() { return exit_through_ffi_; }
static intptr_t exit_through_ffi_offset() {
return OFFSET_OF(Thread, exit_through_ffi_);
}
+3 -1
View File
@@ -18,7 +18,9 @@ void testCurrent() {
}
void testPlatformVersionCompatibility() {
final abiStringFromPlatformVersion = Platform.version.split('"')[1];
final abiStringFromPlatformVersion = Platform.version
.split('"')[1]
.replaceAll("sim", "");
final abiStringFromCurrent = Abi.current().toString();
Expect.equals(abiStringFromPlatformVersion, abiStringFromCurrent);
}