Skip to content
This repository was archived by the owner on Nov 9, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions Core/Node-API/Source/env_hermes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ namespace Napi
// exceptions thrown FROM user callbacks are already handled in
// AppRuntime::Dispatch's try/catch.
(void)runtime->drainJobs();
// WeakRef targets are kept alive only until the current job finishes.
runtime->clearKeptObjects();
}

Napi::Value Eval(Napi::Env env, const char* source, const char* sourceUrl)
Expand Down
37 changes: 37 additions & 0 deletions Tests/UnitTests/Source/Tests.NodeApi.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,47 @@
#include <Babylon/AppRuntime.h>
#include <gtest/gtest.h>
#include <napi/env.h>
#include <chrono>
#include <cstdint>
#include <future>
#include <stdexcept>
#include <string>
#include <string_view>

TEST(NodeApi, HermesDrainJobsReleasesWeakRefTargets)
{
if (std::string_view{NAPI_JAVASCRIPT_ENGINE} != "Hermes")
{
GTEST_SKIP() << "Uses Hermes heap statistics.";
}

std::promise<double> externalBytes;
auto completed = externalBytes.get_future();
Babylon::AppRuntime runtime{};
runtime.Dispatch([&](Napi::Env env) {
try
{
for (size_t i = 0; i < 256; ++i)
{
{
Napi::HandleScope scope{env};
Napi::Eval(env, "new WeakRef(new Uint8Array(1024 * 1024));", "weakref-job.js");
}
Napi::DrainJobs(env);
Comment thread
bkaradzic-microsoft marked this conversation as resolved.
Resolved
}
externalBytes.set_value(Napi::Eval(env,
"HermesInternal.getInstrumentedStats().js_externalBytes",
"weakref-heap.js").As<Napi::Number>().DoubleValue());
}
catch (const Napi::Error& error)
{
externalBytes.set_exception(std::make_exception_ptr(std::runtime_error{error.Message()}));
}
});
ASSERT_EQ(completed.wait_for(std::chrono::seconds{30}), std::future_status::ready);
EXPECT_LT(completed.get(), 64 * 1024 * 1024);
}

// The V8JSI Node-API shim does not implement napi_create_dataview /
// napi_get_dataview_info (its DataView::New throws "TODO"), so this native test
// only builds on the Chakra, V8, and JavaScriptCore backends. The size_t-width
Expand Down
Loading