Skip to content

Commit

Permalink
fix(ios): add exception handle process for jsc (Tencent#3976)
Browse files Browse the repository at this point in the history
* fix(ios): add exception handle process for jsc

* chore(ios): remove unnecessary exception check log
  • Loading branch information
wwwcg committed Aug 2, 2024
1 parent bc7e611 commit c44584e
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 9 deletions.
19 changes: 19 additions & 0 deletions driver/js/include/driver/scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,24 @@ class Scope : public std::enable_shared_from_this<Scope> {
inline std::any GetTurbo() { return turbo_; }
inline void SetTurbo(std::any turbo) { turbo_ = turbo; }
inline std::weak_ptr<Engine> GetEngine() { return engine_; }
inline std::unique_ptr<RegisterMap>& GetRegisterMap() { return extra_function_map_; }

inline bool RegisterExtraCallback(const std::string& key, RegisterFunction func) {
if (!func) {
return false;
}
(*extra_function_map_)[key] = std::move(func);
return true;
}

inline bool GetExtraCallback(const std::string& key, RegisterFunction& outFunc) const {
auto it = extra_function_map_->find(key);
if (it != extra_function_map_->end()) {
outFunc = it->second;
return true;
}
return false;
}

inline std::any GetClassTemplate(const string_view& name) {
auto engine = engine_.lock();
Expand Down Expand Up @@ -466,6 +484,7 @@ class Scope : public std::enable_shared_from_this<Scope> {
std::any bridge_;
std::any turbo_;
std::string name_;
std::unique_ptr<RegisterMap> extra_function_map_; // store some callback functions
uint32_t call_ui_function_callback_id_;
std::unordered_map<uint32_t, std::shared_ptr<CtxValue>> call_ui_function_callback_holder_;
std::unordered_map<uint32_t, std::unordered_map<std::string, std::unordered_map<uint64_t, std::shared_ptr<CtxValue>>>>
Expand Down
9 changes: 9 additions & 0 deletions driver/js/src/modules/timer_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,15 @@ std::shared_ptr<hippy::napi::CtxValue> TimerModule::Start(
}
std::shared_ptr<hippy::napi::Ctx> context = scope->GetContext();
context->CallFunction(function, context->GetGlobalObject(), 0, nullptr);

#if defined(JS_JSC)
// exception check for jsc
RegisterFunction func;
if (scope->GetExtraCallback(kAsyncTaskEndKey, func)) {
func(nullptr);
}
#endif /* defined(JS_JSC) */

if (!repeat) {
timer_map->erase(task_id);
}
Expand Down
8 changes: 1 addition & 7 deletions driver/js/src/napi/jsc/jsc_ctx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,6 @@ std::shared_ptr<CtxValue> JSCCtx::DefineClass(const string_view& name,
JSObjectCallAsFunction(context_, define_property, object, 3, values, &exception);
if (exception) {
SetException(std::make_shared<JSCCtxValue>(context_, exception));
FOOTSTONE_LOG(ERROR) << GetExceptionMessage(exception_);
return nullptr;
}
}
Expand Down Expand Up @@ -895,23 +894,20 @@ std::shared_ptr<CtxValue> JSCCtx::CallFunction(const std::shared_ptr<CtxValue>&
auto function_object = JSValueToObject(context_, function_value->value_, &exception);
if (exception) {
SetException(std::make_shared<JSCCtxValue>(context_, exception));
FOOTSTONE_LOG(ERROR) << GetExceptionMessage(exception_);
return nullptr;
}

auto receiver_value = std::static_pointer_cast<JSCCtxValue>(receiver);
auto receiver_object = JSValueToObject(context_, receiver_value->value_, &exception);
if (exception) {
SetException(std::make_shared<JSCCtxValue>(context_, exception));
FOOTSTONE_LOG(ERROR) << GetExceptionMessage(exception_);
return nullptr;
}

if (argc <= 0) {
auto ret_value_ref = JSObjectCallAsFunction(context_, function_object, receiver_object, 0, nullptr, &exception);
if (exception) {
SetException(std::make_shared<JSCCtxValue>(context_, exception));
FOOTSTONE_LOG(ERROR) << GetExceptionMessage(exception_);
return nullptr;
}
return std::make_shared<JSCCtxValue>(context_, ret_value_ref);
Expand All @@ -926,7 +922,6 @@ std::shared_ptr<CtxValue> JSCCtx::CallFunction(const std::shared_ptr<CtxValue>&
auto ret_value_ref = JSObjectCallAsFunction(context_, function_object, receiver_object, argc, values, &exception);
if (exception) {
SetException(std::make_shared<JSCCtxValue>(context_, exception));
FOOTSTONE_LOG(ERROR) << GetExceptionMessage(exception_);
return nullptr;
}

Expand All @@ -939,7 +934,7 @@ std::shared_ptr<CtxValue> JSCCtx::CallFunction(const std::shared_ptr<CtxValue>&

string_view JSCCtx::GetExceptionMessage(const std::shared_ptr<CtxValue>& exception) {
if (!exception) {
return string_view();
return string_view("");
}

std::shared_ptr<CtxValue> msg_obj = CopyNamedProperty(exception, string_view(kMessageStr, ARRAY_SIZE(kMessageStr) - 1));
Expand Down Expand Up @@ -1142,7 +1137,6 @@ std::shared_ptr<CtxValue> JSCCtx::RunScript(const string_view& data,

if (exception) {
SetException(std::make_shared<JSCCtxValue>(context_, exception));
FOOTSTONE_LOG(ERROR) << GetExceptionMessage(exception_);
return nullptr;
}

Expand Down
1 change: 1 addition & 0 deletions driver/js/src/scope.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ Scope::Scope(std::weak_ptr<Engine> engine,
context_(nullptr),
name_(std::move(name)),
call_ui_function_callback_id_(0),
extra_function_map_(std::make_unique<RegisterMap>()),
performance_(std::make_shared<Performance>()) {}

Scope::~Scope() {
Expand Down
39 changes: 37 additions & 2 deletions framework/ios/base/executors/HippyJSExecutor.mm
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
constexpr char kGlobalKey[] = "global";
constexpr char kHippyKey[] = "Hippy";
static NSString * const kHippyNativeGlobalKey = @"__HIPPYNATIVEGLOBAL__";

static const char * kHippyExceptionEventName = "uncaughtException";


@interface HippyJSExecutor () {
Expand All @@ -102,8 +102,18 @@ - (void)setup {
const char *pName = [self.enginekey UTF8String] ?: "";
auto scope = engine->GetEngine()->CreateScope(pName);

__weak __typeof(self)weakSelf = self;
hippy::base::RegisterFunction taskEndCB = [weakSelf](void *) {
@autoreleasepool {
HippyJSExecutor *strongSelf = weakSelf;
if (strongSelf) {
handleJsExcepiton(strongSelf->_pScope);
}
}
};
scope->RegisterExtraCallback(hippy::kAsyncTaskEndKey, taskEndCB);

dispatch_semaphore_t scopeSemaphore = dispatch_semaphore_create(0);
__weak HippyJSExecutor *weakSelf = self;
footstone::TimePoint startPoint = footstone::TimePoint::SystemNow();
engine->GetEngine()->GetJsTaskRunner()->PostTask([weakSelf, scopeSemaphore, startPoint](){
@autoreleasepool {
Expand Down Expand Up @@ -727,4 +737,29 @@ - (NSString *)completeWSURLWithBridge:(HippyBridge *)bridge {
return [devInfo assembleFullWSURLWithClientId:clientId contextName:bridge.contextName];
}


#pragma mark - Exception Handle

static void handleJsExcepiton(std::shared_ptr<hippy::Scope> scope) {
if (!scope) {
return;
}
std::shared_ptr<hippy::napi::JSCCtx> context = std::static_pointer_cast<hippy::napi::JSCCtx>(scope->GetContext());
std::shared_ptr<hippy::napi::JSCCtxValue> exception = std::static_pointer_cast<hippy::napi::JSCCtxValue>(context->GetException());
if (exception) {
// if native does not handled, rethrow to js
if (!context->IsExceptionHandled()) {
hippy::vm::VM::HandleException(context, kHippyExceptionEventName, exception);
}
string_view exceptionStrView = context->GetExceptionMessage(exception);
auto errU8Str = StringViewUtils::ConvertEncoding(exceptionStrView, string_view::Encoding::Utf8).utf8_value();
std::string errStr = StringViewUtils::ToStdString(errU8Str);
NSError *error = HippyErrorWithMessage([NSString stringWithUTF8String:errStr.c_str()]);
HippyFatal(error);
context->SetException(nullptr);
context->SetExceptionHandled(true);
}
}


@end

0 comments on commit c44584e

Please sign in to comment.