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

fix(ios): add exception handle process for jsc #3976

Merged
merged 2 commits into from
Aug 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
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
Loading