Skip to content

Commit

Permalink
fix(core): fix multi-context mode exception handling crash
Browse files Browse the repository at this point in the history
  • Loading branch information
churchill-zhang committed Mar 7, 2022
1 parent 86804e5 commit e03372d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 19 deletions.
45 changes: 28 additions & 17 deletions android/sdk/src/main/jni/src/bridge/entry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,11 @@ static std::unordered_map<int64_t, std::pair<std::shared_ptr<Engine>, uint32_t>>
reuse_engine_map;
static std::mutex engine_mutex;

static const int64_t kDefaultEngineId = -1;
static const int64_t kDebuggerEngineId = -9999;
static const uint32_t kRuntimeSlotIndex = 0;
constexpr int64_t kDefaultEngineId = -1;
constexpr int64_t kDebuggerEngineId = -9999;
constexpr uint32_t kRuntimeSlotIndex = 0;
// -1 means single isolate multi-context mode
constexpr int32_t kReuseRuntimeId = -1;

enum INIT_CB_STATE {
RUN_SCRIPT_ERROR = -1,
Expand Down Expand Up @@ -348,16 +350,23 @@ void HandleUncaughtJsError(v8::Local<v8::Message> message,
return;
}

std::shared_ptr<hippy::napi::V8Ctx> ctx =
std::static_pointer_cast<hippy::napi::V8Ctx>(
runtime->GetScope()->GetContext());
TDF_BASE_LOG(ERROR) << "HandleUncaughtJsError error desc = "
auto scope = runtime->GetScope();
if (!scope) {
return;
}
auto context = scope->GetContext();
if (!context) {
return;
}
std::shared_ptr<hippy::napi::V8Ctx> ctx = std::static_pointer_cast<hippy::napi::V8Ctx>(context);
TDF_BASE_LOG(ERROR) << "HandleUncaughtJsError, runtime_id = "
<< runtime->GetId()
<< ", desc = "
<< ctx->GetMsgDesc(message)
<< ", stack = " << ctx->GetStackInfo(message);
ExceptionHandler::ReportJsException(runtime, ctx->GetMsgDesc(message),
ctx->GetStackInfo(message));
ctx->ThrowExceptionToJS(
std::make_shared<hippy::napi::V8CtxValue>(isolate, error));
ctx->ThrowExceptionToJS(std::make_shared<hippy::napi::V8CtxValue>(isolate, error));

TDF_BASE_DLOG(INFO) << "HandleUncaughtJsError end";
}
Expand All @@ -373,7 +382,7 @@ jlong InitInstance(JNIEnv* j_env,
jobject j_vm_init_param) {
TDF_BASE_LOG(INFO) << "InitInstance begin, j_single_thread_mode = "
<< static_cast<uint32_t>(j_single_thread_mode)
<< ", j_bridge_param_json = "
<< ", j_enable_v8_serialization = "
<< static_cast<uint32_t>(j_enable_v8_serialization)
<< ", j_is_dev_module = "
<< static_cast<uint32_t>(j_is_dev_module)
Expand All @@ -383,12 +392,19 @@ jlong InitInstance(JNIEnv* j_env,
j_enable_v8_serialization, j_is_dev_module);
int32_t runtime_id = runtime->GetId();
Runtime::Insert(runtime);
RegisterFunction vm_cb = [runtime_id](void* vm) {
int64_t group = j_group_id;
RegisterFunction vm_cb = [group, runtime_id](void* vm) {
V8VM* v8_vm = reinterpret_cast<V8VM*>(vm);
v8::Isolate* isolate = v8_vm->isolate_;
v8::HandleScope handle_scope(isolate);
if (group == kDefaultEngineId) {
TDF_BASE_LOG(INFO) << "isolate->SetData runtime_id = " << runtime_id;
isolate->SetData(kRuntimeSlotIndex, reinterpret_cast<void*>(runtime_id));
} else {
TDF_BASE_LOG(INFO) << "isolate->SetData runtime_id = " << kReuseRuntimeId;
isolate->SetData(kRuntimeSlotIndex, reinterpret_cast<void*>(kReuseRuntimeId));
}
isolate->AddMessageListener(HandleUncaughtJsError);
isolate->SetData(kRuntimeSlotIndex, reinterpret_cast<void*>(runtime_id));
};

std::unique_ptr<RegisterMap> engine_cb_map = std::make_unique<RegisterMap>();
Expand Down Expand Up @@ -450,7 +466,6 @@ jlong InitInstance(JNIEnv* j_env,
scope_cb_map->insert(
std::make_pair(hippy::base::KScopeInitializedCBKey, scope_cb));

int64_t group = j_group_id;
std::shared_ptr<V8VMInitParam> param;
if (j_vm_init_param) {
param = std::make_shared<V8VMInitParam>();
Expand Down Expand Up @@ -491,10 +506,6 @@ jlong InitInstance(JNIEnv* j_env,
engine = std::get<std::shared_ptr<Engine>>(it->second);
runtime->SetEngine(engine);
std::get<uint32_t>(it->second) += 1;
std::shared_ptr<V8VM> v8_vm = std::static_pointer_cast<V8VM>(engine->GetVM());
v8::Isolate* isolate = v8_vm->isolate_;
isolate->SetData(kRuntimeSlotIndex, reinterpret_cast<void*>(-1));
// -1 means single isolate multi-context mode
TDF_BASE_DLOG(INFO) << "engine cnt = " << std::get<uint32_t>(it->second)
<< ", use_count = " << engine.use_count();
} else {
Expand Down
10 changes: 8 additions & 2 deletions android/sdk/src/main/jni/src/bridge/runtime.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include <mutex>
#include <unordered_map>

constexpr int32_t kReuseRuntimeId = -1;

using V8Ctx = hippy::napi::V8Ctx;

static std::unordered_map<int32_t, std::shared_ptr<Runtime>> RuntimeMap;
Expand Down Expand Up @@ -59,11 +61,15 @@ std::shared_ptr<Runtime> Runtime::Find(v8::Isolate *isolate) {
}
auto runtime_id =
static_cast<int32_t>(reinterpret_cast<int64_t>(isolate->GetData(kRuntimeSlotIndex)));
if (runtime_id == -1) {// -1 means single isolate multi context mode
TDF_BASE_LOG(INFO) << "Runtime::Find runtime_id = " << runtime_id;
if (runtime_id == kReuseRuntimeId) {// -1 means single isolate multi context mode
v8::Local<v8::Context> context = isolate->GetCurrentContext();
std::lock_guard<std::mutex> lock(mutex);
for (const auto& p: RuntimeMap) {
std::shared_ptr<Scope> scope = p.second->GetScope();
auto scope = p.second->GetScope();
if (!scope) {
continue;
}
std::shared_ptr<V8Ctx> ctx = std::static_pointer_cast<V8Ctx>(scope->GetContext());
if (ctx->context_persistent_ == context) {
return p.second;
Expand Down

0 comments on commit e03372d

Please sign in to comment.