Last active
February 10, 2026 15:08
-
-
Save Xenakios/2455b3eedba0c61da571ab4ef700bc64 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/choc/javascript/choc_javascript.h b/choc/javascript/choc_javascript.h | |
| index 95f1678..3abefcf 100644 | |
| --- a/choc/javascript/choc_javascript.h | |
| +++ b/choc/javascript/choc_javascript.h | |
| @@ -97,6 +97,7 @@ namespace choc::javascript | |
| operator bool() const { return pimpl != nullptr; } | |
| //============================================================================== | |
| + | |
| /// This callback is used by the run() method. | |
| using CompletionHandler = std::function<void(const std::string& error, | |
| const choc::value::ValueView& result)>; | |
| @@ -162,6 +163,14 @@ namespace choc::javascript | |
| /// Pumps the message loop in an engine-specific way - may have no effect on some platforms. | |
| void pumpMessageLoop(); | |
| + /// If supported by the engine, attempts tp cancel the execution of the JS code. | |
| + /// If the JS code is stuck in a blocking call itself, this won't work, but will | |
| + /// work if the JS code is running a loop, for example. | |
| + /// This obviously has to be called from another thread, so for example if your JS engine | |
| + /// is running in a worker thread, the GUI thread can call this. | |
| + /// If the cancellation worked, an exception will be thrown. | |
| + /// Currently only implemented in the QuickJS engine. | |
| + void cancel(); | |
| //============================================================================== | |
| /// @internal | |
| struct Pimpl; | |
| @@ -235,7 +244,7 @@ struct Context::Pimpl | |
| virtual void pushArg (double) = 0; | |
| virtual void pushArg (bool) = 0; | |
| virtual void pumpMessageLoop() = 0; | |
| - | |
| + virtual void cancel() {}; | |
| void pushArg (const std::string& v) { pushArg (std::string_view (v)); } | |
| void pushArg (const char* v) { pushArg (std::string_view (v)); } | |
| void pushArg (uint64_t v) { pushArg (static_cast<int64_t> (v)); } | |
| @@ -318,6 +327,12 @@ inline void Context::pumpMessageLoop() | |
| pimpl->pumpMessageLoop(); | |
| } | |
| +inline void Context::cancel() | |
| +{ | |
| + CHOC_ASSERT (pimpl != nullptr); // cannot call this on a moved-from context! | |
| + pimpl->cancel(); | |
| +} | |
| + | |
| inline std::string makeSafeIdentifier (std::string s) | |
| { | |
| constexpr static std::string_view reservedWords[] = | |
| diff --git a/choc/javascript/choc_javascript_QuickJS.h b/choc/javascript/choc_javascript_QuickJS.h | |
| index 0617307..94982f5 100644 | |
| --- a/choc/javascript/choc_javascript_QuickJS.h | |
| +++ b/choc/javascript/choc_javascript_QuickJS.h | |
| @@ -64052,10 +64052,23 @@ struct QuickJSContext : public Context::Pimpl | |
| context = JS_NewContext (runtime); | |
| CHOC_ASSERT (context != nullptr); | |
| JS_SetContextOpaque (context, this); | |
| + JS_SetInterruptHandler(runtime, [](JSRuntime *, void *opaque) | |
| + { | |
| + auto qjctx = static_cast<QuickJSContext*>(opaque); | |
| + if (qjctx && qjctx->shouldCancel.load()) | |
| + { | |
| + qjctx->shouldCancel.store(false); | |
| + return 1; | |
| + } | |
| + return 0;}, this); | |
| } | |
| void pumpMessageLoop() override {} | |
| - | |
| + void cancel() override | |
| + { | |
| + shouldCancel.store(true); | |
| + } | |
| + | |
| void pushObjectOrArray (const choc::value::ValueView& v) override { functionArgs.push_back (valueToJS (v).release()); } | |
| void pushArg (std::string_view v) override { functionArgs.push_back (stringToJS (v).release()); } | |
| void pushArg (int32_t v) override { functionArgs.push_back (JS_NewInt32 (context, v)); } | |
| @@ -64350,7 +64363,7 @@ struct QuickJSContext : public Context::Pimpl | |
| std::vector<Context::NativeFunction> registeredFunctions; | |
| std::vector<JSValue> functionArgs; | |
| JSAtom functionToCall = {}; | |
| - | |
| + std::atomic<bool> shouldCancel{false}; | |
| static constexpr const char* objectNameAttribute = "_objectName"; | |
| }; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment