Fix 0xa SIGSEGV for pending exception

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I8OD2F
Signed-off-by: Gymee <yumeijie@huawei.com>
Change-Id: I75f4a0804c93148e0f4c9803d85b36e1be7da08b
This commit is contained in:
Gymee 2023-12-14 17:39:58 +08:00
parent 64f4d87b08
commit f626f9a739
4 changed files with 326 additions and 414 deletions

View File

@ -790,8 +790,8 @@ public:
static Local<BigIntRef> New(const EcmaVM *vm, uint64_t input);
static Local<BigIntRef> New(const EcmaVM *vm, int64_t input);
static Local<JSValueRef> CreateBigWords(const EcmaVM *vm, bool sign, uint32_t size, const uint64_t* words);
void BigIntToInt64(const EcmaVM *vm, int64_t *cValue, bool *lossless);
void BigIntToUint64(const EcmaVM *vm, uint64_t *cValue, bool *lossless);
void BigIntToInt64(const EcmaVM *vm, int64_t *value, bool *lossless);
void BigIntToUint64(const EcmaVM *vm, uint64_t *value, bool *lossless);
void GetWordsArray(bool* signBit, size_t wordCount, uint64_t* words);
uint32_t GetWordsArraySize();
};

View File

@ -195,40 +195,12 @@ using JSMutableHandle = ecmascript::JSMutableHandle<T>;
using PathHelper = ecmascript::base::PathHelper;
using ModulePathHelper = ecmascript::ModulePathHelper;
#define CHECK_HAS_PENDING_EXCEPTION(vm, returnVal) \
do { \
if (vm->GetAndFastCheckJSThread()->HasPendingException()) { \
LOG_ECMA(ERROR) << "pending exception before jsnapi interface called" << \
", which is " << __FUNCTION__ << " in line: " << __LINE__; \
LOG_ECMA(ERROR) << panda::ecmascript::previewerTag << \
"print exception info:"; \
JSNApi::PrintExceptionInfo(vm); \
return returnVal; \
} \
} while (false)
#define CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm) \
CHECK_HAS_PENDING_EXCEPTION(vm, JSValueRef::Undefined(vm))
#define CHECK_HAS_PENDING_EXCEPTION_WITHOUT_RETURN(vm) \
do { \
if (vm->GetAndFastCheckJSThread()->HasPendingException()) { \
LOG_ECMA(ERROR) << "pending exception before jsnapi interface called" << \
", which is " << __FUNCTION__ << " in line: " << __LINE__; \
LOG_ECMA(ERROR) << panda::ecmascript::previewerTag << \
"print exception info:"; \
JSNApi::PrintExceptionInfo(vm); \
return; \
} \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define TYPED_ARRAY_NEW(Type) \
Local<Type##Ref> Type##Ref::New( \
const EcmaVM *vm, Local<ArrayBufferRef> buffer, int32_t byteOffset, int32_t length) \
{ \
CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm); \
JSThread *thread = vm->GetJSThread(); \
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm)); \
JSHandle<GlobalEnv> env = vm->GetGlobalEnv(); \
\
JSHandle<JSTaggedValue> func = env->Get##Type##Function(); \
@ -252,8 +224,7 @@ TYPED_ARRAY_ALL(TYPED_ARRAY_NEW)
// ---------------------------------- JSON ------------------------------------------
Local<JSValueRef> JSON::Parse(const EcmaVM *vm, Local<StringRef> string)
{
CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm);
JSThread *thread = vm->GetJSThread();
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
auto ecmaStr = EcmaString::Cast(JSNApiHelper::ToJSTaggedValue(*string).GetTaggedObject());
JSHandle<JSTaggedValue> result;
if (EcmaStringAccessor(ecmaStr).IsUtf8()) {
@ -269,8 +240,7 @@ Local<JSValueRef> JSON::Parse(const EcmaVM *vm, Local<StringRef> string)
Local<JSValueRef> JSON::Stringify(const EcmaVM *vm, Local<JSValueRef> json)
{
CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm);
JSThread *thread = vm->GetJSThread();
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
auto constants = thread->GlobalConstants();
JsonStringifier stringifier(thread);
JSHandle<JSTaggedValue> str = stringifier.Stringify(
@ -281,8 +251,7 @@ Local<JSValueRef> JSON::Stringify(const EcmaVM *vm, Local<JSValueRef> json)
Local<StringRef> RegExpRef::GetOriginalSource(const EcmaVM *vm)
{
CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm);
JSThread *thread = vm->GetJSThread();
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(regExp, FATAL);
JSTaggedValue source = regExp->GetOriginalSource();
@ -296,6 +265,7 @@ Local<StringRef> RegExpRef::GetOriginalSource(const EcmaVM *vm)
std::string RegExpRef::GetOriginalFlags()
{
DCHECK_SPECIAL_VALUE_WITH_RETURN(this, "");
JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(regExp, FATAL);
JSTaggedValue regExpFlags = regExp->GetOriginalFlags();
@ -325,7 +295,7 @@ std::string RegExpRef::GetOriginalFlags()
Local<JSValueRef> RegExpRef::IsGlobal(const EcmaVM *vm)
{
CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm);
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(regExp, FATAL);
JSTaggedValue flags = regExp->GetOriginalFlags();
@ -336,7 +306,7 @@ Local<JSValueRef> RegExpRef::IsGlobal(const EcmaVM *vm)
Local<JSValueRef> RegExpRef::IsIgnoreCase(const EcmaVM *vm)
{
CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm);
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(regExp, FATAL);
JSTaggedValue flags = regExp->GetOriginalFlags();
@ -347,7 +317,7 @@ Local<JSValueRef> RegExpRef::IsIgnoreCase(const EcmaVM *vm)
Local<JSValueRef> RegExpRef::IsMultiline(const EcmaVM *vm)
{
CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm);
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(regExp, FATAL);
JSTaggedValue flags = regExp->GetOriginalFlags();
@ -358,7 +328,7 @@ Local<JSValueRef> RegExpRef::IsMultiline(const EcmaVM *vm)
Local<JSValueRef> RegExpRef::IsDotAll(const EcmaVM *vm)
{
CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm);
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(regExp, FATAL);
JSTaggedValue flags = regExp->GetOriginalFlags();
@ -369,7 +339,7 @@ Local<JSValueRef> RegExpRef::IsDotAll(const EcmaVM *vm)
Local<JSValueRef> RegExpRef::IsUtf16(const EcmaVM *vm)
{
CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm);
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(regExp, FATAL);
JSTaggedValue flags = regExp->GetOriginalFlags();
@ -380,7 +350,7 @@ Local<JSValueRef> RegExpRef::IsUtf16(const EcmaVM *vm)
Local<JSValueRef> RegExpRef::IsStick(const EcmaVM *vm)
{
CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm);
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
JSHandle<JSRegExp> regExp(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(regExp, FATAL);
JSTaggedValue flags = regExp->GetOriginalFlags();
@ -391,12 +361,14 @@ Local<JSValueRef> RegExpRef::IsStick(const EcmaVM *vm)
bool GeneratorFunctionRef::IsGenerator()
{
// Omit exception check because ark calls here may not
// cause side effect even pending exception exists.
return IsGeneratorFunction();
}
Local<JSValueRef> GeneratorObjectRef::GetGeneratorState(const EcmaVM *vm)
{
CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm);
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
JSHandle<JSGeneratorObject> jsGenerator(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(jsGenerator, FATAL);
if (jsGenerator->GetGeneratorState() == JSGeneratorState::COMPLETED) {
@ -407,8 +379,7 @@ Local<JSValueRef> GeneratorObjectRef::GetGeneratorState(const EcmaVM *vm)
Local<JSValueRef> GeneratorObjectRef::GetGeneratorFunction(const EcmaVM *vm)
{
CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm);
JSThread *thread = vm->GetJSThread();
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
JSHandle<JSGeneratorObject> jsGenerator(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(jsGenerator, FATAL);
JSHandle<GeneratorContext> generatorContext(thread, jsGenerator->GetGeneratorContext());
@ -418,8 +389,7 @@ Local<JSValueRef> GeneratorObjectRef::GetGeneratorFunction(const EcmaVM *vm)
Local<JSValueRef> GeneratorObjectRef::GetGeneratorReceiver(const EcmaVM *vm)
{
CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm);
JSThread *thread = vm->GetJSThread();
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
JSHandle<JSGeneratorObject> jsGenerator(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(jsGenerator, FATAL);
JSHandle<GeneratorContext> generatorContext(thread, jsGenerator->GetGeneratorContext());
@ -429,8 +399,7 @@ Local<JSValueRef> GeneratorObjectRef::GetGeneratorReceiver(const EcmaVM *vm)
Local<JSValueRef> CollatorRef::GetCompareFunction(const EcmaVM *vm)
{
CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm);
JSThread *thread = vm->GetJSThread();
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
#ifdef ARK_SUPPORT_INTL
JSHandle<JSCollator> jsCollator(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(jsCollator, FATAL);
@ -444,8 +413,7 @@ Local<JSValueRef> CollatorRef::GetCompareFunction(const EcmaVM *vm)
Local<JSValueRef> DataTimeFormatRef::GetFormatFunction(const EcmaVM *vm)
{
CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm);
JSThread *thread = vm->GetJSThread();
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
#ifdef ARK_SUPPORT_INTL
JSHandle<JSDateTimeFormat> jsDateTimeFormat(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(jsDateTimeFormat, FATAL);
@ -459,8 +427,7 @@ Local<JSValueRef> DataTimeFormatRef::GetFormatFunction(const EcmaVM *vm)
Local<JSValueRef> NumberFormatRef::GetFormatFunction(const EcmaVM *vm)
{
CHECK_HAS_PENDING_EXCEPTION_RETURN_UNDEFINED(vm);
JSThread *thread = vm->GetJSThread();
CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, JSValueRef::Undefined(vm));
#ifdef ARK_SUPPORT_INTL
JSHandle<JSNumberFormat> jsNumberFormat(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(jsNumberFormat, FATAL);

File diff suppressed because it is too large Load Diff

View File

@ -42,6 +42,49 @@
#define LOG_IF_SPECIAL(handleValue, level) static_cast<void>(0)
#endif
#define CROSS_THREAD_CHECK(vm) \
[[maybe_unused]] JSThread *thread = (vm)->GetAndFastCheckJSThread()
#define CROSS_THREAD_AND_EXCEPTION_CHECK_WITH_RETURN(vm, returnVal) \
CROSS_THREAD_CHECK(vm); \
do { \
if (thread->HasPendingException()) { \
LOG_ECMA(ERROR) << "Pending exception before " << __FUNCTION__ << " called in line:" \
<< __LINE__ << ", exception details as follows:"; \
JSNApi::PrintExceptionInfo(vm); \
return returnVal; \
} \
} while (false)
#define CROSS_THREAD_AND_EXCEPTION_CHECK(vm) \
CROSS_THREAD_CHECK(vm); \
do { \
if (thread->HasPendingException()) { \
LOG_ECMA(ERROR) << "Pending exception before " << __FUNCTION__ << " called, in line:" \
<< __LINE__ << ", exception details as follows:"; \
JSNApi::PrintExceptionInfo(vm); \
return; \
} \
} while (false)
#define DCHECK_SPECIAL_VALUE(jsValueRef) \
do { \
auto val = reinterpret_cast<JSTaggedValue *>(jsValueRef); \
if (UNLIKELY(val->IsSpecial())) { \
LOG_FULL(ERROR) << "JSNApi special value:0x" << val->GetRawData() << " checked"; \
return; \
} \
} while (false)
#define DCHECK_SPECIAL_VALUE_WITH_RETURN(jsValueRef, retValue) \
do { \
auto val = reinterpret_cast<JSTaggedValue *>(jsValueRef); \
if (UNLIKELY(val->IsSpecial())) { \
LOG_FULL(ERROR) << "JSNApi special value:0x" << val->GetRawData() << " checked"; \
return (retValue); \
} \
} while (false)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define TYPED_ARRAY_ALL(V) \
V(Int8Array) \