diff --git a/API/hermes/TimerStats.cpp b/API/hermes/TimerStats.cpp index b6d156d938c..ac14c2ea681 100644 --- a/API/hermes/TimerStats.cpp +++ b/API/hermes/TimerStats.cpp @@ -263,6 +263,8 @@ class TimedRuntime final : public jsi::RuntimeDecorator { return RD::callAsConstructor(func, args, count); } + void queueMicrotask(const jsi::Function & /*callback*/) override {} + bool drainMicrotasks(int maxMicrotasksHint) override { auto timer = rts_.incomingTimer("drainMicrotasks"); return RD::drainMicrotasks(maxMicrotasksHint); diff --git a/API/hermes/TracingRuntime.cpp b/API/hermes/TracingRuntime.cpp index b2c6afca316..ac20dbfd979 100644 --- a/API/hermes/TracingRuntime.cpp +++ b/API/hermes/TracingRuntime.cpp @@ -185,6 +185,8 @@ jsi::Value TracingRuntime::evaluateJavaScript( return res; } +void TracingRuntime::queueMicrotask(const jsi::Function &callback) {} + bool TracingRuntime::drainMicrotasks(int maxMicrotasksHint) { auto res = RD::drainMicrotasks(maxMicrotasksHint); trace_.emplace_back( diff --git a/API/hermes/TracingRuntime.h b/API/hermes/TracingRuntime.h index 2256a64ba4b..ed1d8644024 100644 --- a/API/hermes/TracingRuntime.h +++ b/API/hermes/TracingRuntime.h @@ -43,6 +43,7 @@ class TracingRuntime : public jsi::RuntimeDecorator { const std::shared_ptr &buffer, const std::string &sourceURL) override; + void queueMicrotask(const jsi::Function &callback) override; bool drainMicrotasks(int maxMicrotasksHint = -1) override; jsi::Object createObject() override; diff --git a/API/hermes/hermes.cpp b/API/hermes/hermes.cpp index a40cdb13e63..5bde94f02ea 100644 --- a/API/hermes/hermes.cpp +++ b/API/hermes/hermes.cpp @@ -573,6 +573,7 @@ class HermesRuntimeImpl final : public HermesRuntime, jsi::Value evaluateJavaScript( const std::shared_ptr &buffer, const std::string &sourceURL) override; + void queueMicrotask(const jsi::Function &callback) override; bool drainMicrotasks(int maxMicrotasksHint = -1) override; jsi::Object global() override; @@ -1502,6 +1503,8 @@ jsi::Value HermesRuntimeImpl::evaluateJavaScript( return evaluateJavaScriptWithSourceMap(buffer, nullptr, sourceURL); } +void HermesRuntimeImpl::queueMicrotask(const jsi::Function & /*callback*/) {} + bool HermesRuntimeImpl::drainMicrotasks(int maxMicrotasksHint) { if (runtime_.hasMicrotaskQueue()) { checkStatus(runtime_.drainJobs()); diff --git a/API/hermes_abi/HermesABIRuntimeWrapper.cpp b/API/hermes_abi/HermesABIRuntimeWrapper.cpp index e927ea8145c..3b10668386d 100644 --- a/API/hermes_abi/HermesABIRuntimeWrapper.cpp +++ b/API/hermes_abi/HermesABIRuntimeWrapper.cpp @@ -710,6 +710,8 @@ class HermesABIRuntimeWrapper : public Runtime { return evaluateJavaScript(sjp, sjp->sourceURL()); } + void queueMicrotask(const Function & /*callback*/) override {} + bool drainMicrotasks(int maxMicrotasksHint = -1) override { return unwrap(vtable_->drain_microtasks(abiRt_, maxMicrotasksHint)); } diff --git a/API/hermes_sandbox/HermesSandboxRuntime.cpp b/API/hermes_sandbox/HermesSandboxRuntime.cpp index fb817b9560d..790bd29f581 100644 --- a/API/hermes_sandbox/HermesSandboxRuntime.cpp +++ b/API/hermes_sandbox/HermesSandboxRuntime.cpp @@ -1701,6 +1701,8 @@ class HermesSandboxRuntimeImpl : public facebook::hermes::HermesSandboxRuntime, return evaluateJavaScript(sjp, sjp->sourceURL()); } + void queueMicrotask(const Function & /*callback*/) override {} + bool drainMicrotasks(int maxMicrotasksHint = -1) override { SandboxBoolOrError resBoolOrError{ vt_.drain_microtasks(this, srt_, maxMicrotasksHint)}; diff --git a/API/jsi/jsi/decorator.h b/API/jsi/jsi/decorator.h index 7bddd1fad80..6f4351a420d 100644 --- a/API/jsi/jsi/decorator.h +++ b/API/jsi/jsi/decorator.h @@ -126,6 +126,9 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation { const std::shared_ptr& js) override { return plain().evaluatePreparedJavaScript(js); } + void queueMicrotask(const jsi::Function& callback) override { + return plain().queueMicrotask(callback); + } bool drainMicrotasks(int maxMicrotasksHint) override { return plain().drainMicrotasks(maxMicrotasksHint); } @@ -544,6 +547,10 @@ class WithRuntimeDecorator : public RuntimeDecorator { Around around{with_}; return RD::evaluatePreparedJavaScript(js); } + void queueMicrotask(const Function& callback) override { + Around around{with_}; + RD::queueMicrotask(callback); + } bool drainMicrotasks(int maxMicrotasksHint) override { Around around{with_}; return RD::drainMicrotasks(maxMicrotasksHint); diff --git a/API/jsi/jsi/jsi.h b/API/jsi/jsi/jsi.h index 962dae93609..276fdef6c86 100644 --- a/API/jsi/jsi/jsi.h +++ b/API/jsi/jsi/jsi.h @@ -209,6 +209,11 @@ class JSI_EXPORT Runtime { virtual Value evaluatePreparedJavaScript( const std::shared_ptr& js) = 0; + // Queues a microtask in the JavaScript VM internal Microtask (a.k.a. Job in + // ECMA262) queue, to be executed when the host drains microtasks in + // its event loop implementation. + virtual void queueMicrotask(const jsi::Function& callback) = 0; + /// Drain the JavaScript VM internal Microtask (a.k.a. Job in ECMA262) queue. /// /// \param maxMicrotasksHint a hint to tell an implementation that it should