summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorLinus Groh <mail@linusgroh.de>2021-04-24 17:56:16 +0200
committerAndreas Kling <kling@serenityos.org>2021-04-24 20:11:04 +0200
commit5caab0148cac327fa969ba30736a286697363ef0 (patch)
treef51b946d2762c1e5520c030e804b1a234f2ae533 /Userland
parent3a4d42bbbbd2b664d8178b4ac2726bf19e7ca24a (diff)
downloadserenity-5caab0148cac327fa969ba30736a286697363ef0.zip
LibJS: Add TemporaryClearException helper class
This is very similar to AK::TemporaryChange (and in fact replaces one use of it), but since we can't directly set VM's m_exception from outside of the VM, we need something more sophisticated. Sometimes we need to temporarily remove the stored exception for some other operation to succeed (e.g. anything that uses call(), as well as get_without_side_effects()) and later restore it - the boilerplate code required for this is annoying enough to justify a helper.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibJS/Runtime/TemporaryClearException.h34
-rw-r--r--Userland/Libraries/LibJS/Runtime/VM.cpp4
2 files changed, 36 insertions, 2 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/TemporaryClearException.h b/Userland/Libraries/LibJS/Runtime/TemporaryClearException.h
new file mode 100644
index 0000000000..a10d34afc6
--- /dev/null
+++ b/Userland/Libraries/LibJS/Runtime/TemporaryClearException.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2021, Linus Groh <mail@linusgroh.de>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <LibJS/Runtime/Exception.h>
+#include <LibJS/Runtime/VM.h>
+
+namespace JS {
+
+class TemporaryClearException {
+public:
+ explicit TemporaryClearException(VM& vm)
+ : m_vm(vm)
+ , m_previous_exception(vm.exception())
+ {
+ m_vm.clear_exception();
+ }
+
+ ~TemporaryClearException()
+ {
+ if (m_previous_exception)
+ m_vm.set_exception(*m_previous_exception);
+ }
+
+private:
+ VM& m_vm;
+ Exception* m_previous_exception;
+};
+
+}
diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp
index b7fc15c781..c1a38a6def 100644
--- a/Userland/Libraries/LibJS/Runtime/VM.cpp
+++ b/Userland/Libraries/LibJS/Runtime/VM.cpp
@@ -8,7 +8,6 @@
#include <AK/Debug.h>
#include <AK/ScopeGuard.h>
#include <AK/StringBuilder.h>
-#include <AK/TemporaryChange.h>
#include <LibJS/Interpreter.h>
#include <LibJS/Runtime/Array.h>
#include <LibJS/Runtime/Error.h>
@@ -18,6 +17,7 @@
#include <LibJS/Runtime/Reference.h>
#include <LibJS/Runtime/ScriptFunction.h>
#include <LibJS/Runtime/Symbol.h>
+#include <LibJS/Runtime/TemporaryClearException.h>
#include <LibJS/Runtime/VM.h>
namespace JS {
@@ -376,7 +376,7 @@ void VM::run_queued_promise_jobs()
dbgln_if(PROMISE_DEBUG, "Running queued promise jobs");
// Temporarily get rid of the exception, if any - job functions must be called
// either way, and that can't happen if we already have an exception stored.
- TemporaryChange change(m_exception, static_cast<Exception*>(nullptr));
+ TemporaryClearException clear_exception(*this);
while (!m_promise_jobs.is_empty()) {
auto* job = m_promise_jobs.take_first();
dbgln_if(PROMISE_DEBUG, "Calling promise job function @ {}", job);