Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Hermes] Bump Hermes #45220

Merged
merged 2 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions packages/react-native/ReactCommon/jsc/JSCRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
#include <atomic>
#include <condition_variable>
#include <cstdlib>
#include <deque>
#include <mutex>
#include <queue>
#include <sstream>
#include <thread>

Expand Down Expand Up @@ -51,6 +51,12 @@ class JSCRuntime : public jsi::Runtime {
const std::shared_ptr<const jsi::Buffer>& buffer,
const std::string& sourceURL) override;

// If we use this interface to implement microtasks in the host we need to
// polyfill `Promise` to use these methods, because JSC doesn't currently
// support providing a custom queue for its built-in implementation.
// Not doing this would result in a non-compliant behavior, as microtasks
// wouldn't execute in the order in which they were queued.
void queueMicrotask(const jsi::Function& callback) override;
bool drainMicrotasks(int maxMicrotasksHint = -1) override;

jsi::Object global() override;
Expand Down Expand Up @@ -265,6 +271,7 @@ class JSCRuntime : public jsi::Runtime {
std::atomic<bool> ctxInvalid_;
std::string desc_;
JSValueRef nativeStateSymbol_ = nullptr;
std::deque<jsi::Function> microtaskQueue_;
#ifndef NDEBUG
mutable std::atomic<intptr_t> objectCounter_;
mutable std::atomic<intptr_t> symbolCounter_;
Expand Down Expand Up @@ -380,6 +387,10 @@ JSCRuntime::JSCRuntime(JSGlobalContextRef ctx)
}

JSCRuntime::~JSCRuntime() {
// We need to clear the microtask queue to remove all references to the
// callbacks, so objectCounter_ would be 0 below.
microtaskQueue_.clear();

// On shutting down and cleaning up: when JSC is actually torn down,
// it calls JSC::Heap::lastChanceToFinalize internally which
// finalizes anything left over. But at this point,
Expand Down Expand Up @@ -436,7 +447,24 @@ jsi::Value JSCRuntime::evaluateJavaScript(
return createValue(res);
}

bool JSCRuntime::drainMicrotasks(int maxMicrotasksHint) {
void JSCRuntime::queueMicrotask(const jsi::Function& callback) {
microtaskQueue_.emplace_back(
jsi::Value(*this, callback).asObject(*this).asFunction(*this));
}

bool JSCRuntime::drainMicrotasks(int /*maxMicrotasksHint*/) {
// Note that new jobs can be enqueued during the draining.
while (!microtaskQueue_.empty()) {
jsi::Function callback = std::move(microtaskQueue_.front());

// We need to pop before calling the callback because that might throw.
// When that happens, the host will call `drainMicrotasks` again to execute
// the remaining microtasks, and this one shouldn't run again.
microtaskQueue_.pop_front();

callback.call(*this);
}

return true;
}

Expand Down
7 changes: 7 additions & 0 deletions packages/react-native/ReactCommon/jsi/jsi/decorator.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation {
const std::shared_ptr<const PreparedJavaScript>& js) override {
return plain().evaluatePreparedJavaScript(js);
}
void queueMicrotask(const jsi::Function& callback) override {
return plain().queueMicrotask(callback);
}
Comment on lines +129 to +131
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

facebook/hermes@0a632b7 adds this change in JSI. We need it in React Native as well

bool drainMicrotasks(int maxMicrotasksHint) override {
return plain().drainMicrotasks(maxMicrotasksHint);
}
Expand Down Expand Up @@ -544,6 +547,10 @@ class WithRuntimeDecorator : public RuntimeDecorator<Plain, Base> {
Around around{with_};
return RD::evaluatePreparedJavaScript(js);
}
void queueMicrotask(const Function& callback) override {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

facebook/hermes@0a632b7 adds this change in JSI. We need it in React Native as well

Around around{with_};
RD::queueMicrotask(callback);
}
bool drainMicrotasks(int maxMicrotasksHint) override {
Around around{with_};
return RD::drainMicrotasks(maxMicrotasksHint);
Expand Down
7 changes: 7 additions & 0 deletions packages/react-native/ReactCommon/jsi/jsi/jsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,13 @@ class JSI_EXPORT Runtime {
virtual Value evaluatePreparedJavaScript(
const std::shared_ptr<const PreparedJavaScript>& 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.
///
/// \param callback a function to be executed as a microtask.
virtual void queueMicrotask(const jsi::Function& callback) = 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

facebook/hermes@7bda0c2 adds this change in JSI. We need it in React Native as well


/// Drain the JavaScript VM internal Microtask (a.k.a. Job in ECMA262) queue.
///
/// \param maxMicrotasksHint a hint to tell an implementation that it should
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native/sdks/.hermesversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
hermes-2024-06-03-RNv0.74.2-bb1e74fe1e95c2b5a2f4f9311152da052badc2bc
hermes-2024-06-28-RNv0.74.3-7bda0c267e76d11b68a585f84cfdd65000babf85
Loading