Added ref detection for the napi call interpreter

Issue: IAMXFX
Signed-off-by: shaoyijiang <shaoyijiang@huawei.com>
Change-Id: I4b34608771f2513e8a6abacc62b022de12ad3732
This commit is contained in:
shaoyijiang 2024-08-27 22:13:47 +08:00
parent ae41b08505
commit baa8d6c63d
4 changed files with 91 additions and 5 deletions

View File

@ -68,6 +68,8 @@ namespace panda::ecmascript {
#define ECMASCRIPT_ENABLE_NEW_HANDLE_CHECK 1
#define ECMASCRIPT_ENABLE_BARRIER_CHECK 1
#define ECMASCRIPT_ENABLE_NAPI_SPECIAL_CHECK 1
#define ECMASCRIPT_ENABLE_STUB_ARGV_CHECK 1
#define ECMASCRIPT_ENABLE_STUB_RESULT_CHECK 1
#elif defined(ECMASCRIPT_ENABLE_ASAN_DFX_CONFIG)
#define ECMASCRIPT_ENABLE_IC 1
#define ECMASCRIPT_ENABLE_ZAP_MEM 0
@ -76,6 +78,8 @@ namespace panda::ecmascript {
#define ECMASCRIPT_ENABLE_NEW_HANDLE_CHECK 0
#define ECMASCRIPT_ENABLE_BARRIER_CHECK 0
#define ECMASCRIPT_ENABLE_NAPI_SPECIAL_CHECK 1
#define ECMASCRIPT_ENABLE_STUB_ARGV_CHECK 0
#define ECMASCRIPT_ENABLE_STUB_RESULT_CHECK 0
#elif defined(ECMASCRIPT_ENABLE_GC_DFX_OPTIONS)
#define ECMASCRIPT_ENABLE_IC 1
#define ECMASCRIPT_ENABLE_ZAP_MEM 1
@ -84,6 +88,8 @@ namespace panda::ecmascript {
#define ECMASCRIPT_ENABLE_NEW_HANDLE_CHECK 1
#define ECMASCRIPT_ENABLE_BARRIER_CHECK 1
#define ECMASCRIPT_ENABLE_NAPI_SPECIAL_CHECK 0
#define ECMASCRIPT_ENABLE_STUB_ARGV_CHECK 1
#define ECMASCRIPT_ENABLE_STUB_RESULT_CHECK 1
#else
#define ECMASCRIPT_ENABLE_IC 1
#define ECMASCRIPT_ENABLE_ZAP_MEM 0
@ -92,6 +98,8 @@ namespace panda::ecmascript {
#define ECMASCRIPT_ENABLE_NEW_HANDLE_CHECK 0
#define ECMASCRIPT_ENABLE_BARRIER_CHECK 0
#define ECMASCRIPT_ENABLE_NAPI_SPECIAL_CHECK 0
#define ECMASCRIPT_ENABLE_STUB_ARGV_CHECK 0
#define ECMASCRIPT_ENABLE_STUB_RESULT_CHECK 0
#endif
#if ECMASCRIPT_ENABLE_ZAP_MEM

View File

@ -634,6 +634,9 @@ JSTaggedValue EcmaInterpreter::ExecuteNative(EcmaRuntimeCallInfo *info)
InterpretedEntryFrame *entryState = GET_ENTRY_FRAME(sp);
JSTaggedType *prevSp = entryState->base.prev;
thread->SetCurrentSPFrame(prevSp);
#if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
thread->CheckJSTaggedType(tagged.GetRawData());
#endif
return tagged;
}
#endif
@ -649,6 +652,11 @@ JSTaggedValue EcmaInterpreter::Execute(EcmaRuntimeCallInfo *info)
INTERPRETER_TRACE(thread, Execute);
// check stack overflow before re-enter interpreter
STACK_LIMIT_CHECK(thread, JSTaggedValue::Exception());
#if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
for (uint32_t i = 0; i < info->GetArgsNumber(); i++) {
thread->CheckJSTaggedType(info->GetCallArgValue(i).GetRawData());
}
#endif
if (thread->IsAsmInterpreter()) {
return InterpreterAssembly::Execute(info);
}
@ -754,11 +762,17 @@ JSTaggedValue EcmaInterpreter::Execute(EcmaRuntimeCallInfo *info)
if (thread->IsEntryFrameDroppedTrue()) {
thread->PendingEntryFrameDroppedState();
InterpretedFrame *prevState = GET_FRAME(prevSp);
#if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
thread->CheckJSTaggedType(prevState->acc.GetRawData());
#endif
return prevState->acc;
}
// pop frame
thread->SetCurrentSPFrame(prevSp);
#if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
thread->CheckJSTaggedType(resAcc.GetRawData());
#endif
return resAcc;
#else
return JSTaggedValue::Exception();

View File

@ -246,6 +246,9 @@ JSTaggedValue InterpreterAssembly::Execute(EcmaRuntimeCallInfo *info)
if (thread->HasPendingException()) {
return thread->GetException();
}
#if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
thread->CheckJSTaggedType(JSTaggedValue(res).GetRawData());
#endif
return JSTaggedValue(res);
}
#if ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER
@ -269,6 +272,9 @@ JSTaggedValue InterpreterAssembly::Execute(EcmaRuntimeCallInfo *info)
auto prevEntry = InterpretedEntryFrame::GetFrameFromSp(sp)->GetPrevFrameFp();
thread->SetCurrentSPFrame(prevEntry);
#if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
thread->CheckJSTaggedType(JSTaggedValue(acc).GetRawData());
#endif
return JSTaggedValue(acc);
}

View File

@ -1906,6 +1906,9 @@ bool PromiseCapabilityRef::Resolve(const EcmaVM *vm, uintptr_t value)
const GlobalEnvConstants *constants = thread->GlobalConstants();
JSTaggedValue arg = *reinterpret_cast<JSTaggedValue *>(value);
#if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
thread->CheckJSTaggedType(arg.GetRawData());
#endif
JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(capacity, FATAL);
JSTaggedValue resolve = capacity->GetResolve();
@ -1930,6 +1933,9 @@ bool PromiseCapabilityRef::Resolve(const EcmaVM *vm, Local<JSValueRef> value)
const GlobalEnvConstants *constants = thread->GlobalConstants();
JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(value);
#if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
thread->CheckJSTaggedType(arg.GetTaggedValue().GetRawData());
#endif
JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(capacity, FATAL);
JSHandle<JSTaggedValue> resolve(thread, capacity->GetResolve());
@ -1954,6 +1960,9 @@ bool PromiseCapabilityRef::Reject(const EcmaVM *vm, uintptr_t reason)
const GlobalEnvConstants *constants = thread->GlobalConstants();
JSTaggedValue arg = *reinterpret_cast<JSTaggedValue *>(reason);
#if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
thread->CheckJSTaggedType(arg.GetRawData());
#endif
JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(capacity, FATAL);
JSTaggedValue reject = capacity->GetReject();
@ -1979,6 +1988,9 @@ bool PromiseCapabilityRef::Reject(const EcmaVM *vm, Local<JSValueRef> reason)
const GlobalEnvConstants *constants = thread->GlobalConstants();
JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(reason);
#if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
thread->CheckJSTaggedType(arg.GetTaggedValue().GetRawData());
#endif
JSHandle<PromiseCapability> capacity(JSNApiHelper::ToJSHandle(this));
LOG_IF_SPECIAL(capacity, FATAL);
JSHandle<JSTaggedValue> reject(thread, capacity->GetReject());
@ -3438,9 +3450,15 @@ Local<JSValueRef> FunctionRef::Call(const EcmaVM *vm, Local<JSValueRef> thisObj,
RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
for (int32_t i = 0; i < length; i++) {
JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(argv[i]);
#if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
thread->CheckJSTaggedType(arg.GetTaggedValue().GetRawData());
#endif
info->SetCallArg(i, arg.GetTaggedValue());
}
JSTaggedValue result = JSFunction::Call(info);
#if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
thread->CheckJSTaggedType(result.GetRawData());
#endif
if (thread->HasPendingException()) {
ecmascript::JsStackInfo::BuildCrashInfo(thread);
}
@ -3479,6 +3497,9 @@ JSValueRef* FunctionRef::CallForNapi(const EcmaVM *vm, JSValueRef *thisObj,
RETURN_VALUE_IF_ABRUPT(thread, *JSValueRef::Hole(vm));
for (int32_t i = 0; i < length; i++) {
if (argv[i]) {
#if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
thread->CheckJSTaggedType(JSNApiHelper::ToJSTaggedValue(argv[i]).GetRawData());
#endif
// NewRuntimeCallInfo has set Undefined defaultly in Argv's slot.
info->SetCallArg(i, JSNApiHelper::ToJSTaggedValue(argv[i]));
}
@ -3495,6 +3516,9 @@ JSValueRef* FunctionRef::CallForNapi(const EcmaVM *vm, JSValueRef *thisObj,
} else {
result = JSFunction::Call(info);
}
#if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
thread->CheckJSTaggedType(result.GetRawData());
#endif
RETURN_VALUE_IF_ABRUPT(thread, *JSValueRef::Hole(vm));
if (thread->GetCurrentEcmaContext()->HasKeptObjects()) {
thread->GetCurrentEcmaContext()->ClearKeptObjects();
@ -3526,10 +3550,15 @@ Local<JSValueRef> FunctionRef::Constructor(const EcmaVM *vm,
RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
for (int32_t i = 0; i < length; i++) {
JSHandle<JSTaggedValue> arg = JSNApiHelper::ToJSHandle(argv[i]);
#if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
thread->CheckJSTaggedType(arg.GetTaggedValue().GetRawData());
#endif
info->SetCallArg(i, arg.GetTaggedValue());
}
JSTaggedValue result = JSFunction::Construct(info);
#if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
thread->CheckJSTaggedType(result.GetRawData());
#endif
RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
JSHandle<JSTaggedValue> resultValue(thread, result);
return JSNApiHelper::ToLocal<JSValueRef>(resultValue);
@ -3555,11 +3584,17 @@ JSValueRef* FunctionRef::ConstructorOptimize(const EcmaVM *vm,
for (int32_t i = 0; i < length; ++i) {
JSTaggedValue arg =
argv[i] == nullptr ? JSTaggedValue::Undefined() : JSNApiHelper::ToJSTaggedValue(argv[i]);
#if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
thread->CheckJSTaggedType(arg.GetRawData());
#endif
info->SetCallArg(i, arg);
}
result = JSFunction::ConstructInternal(info);
RETURN_VALUE_IF_ABRUPT(thread, *JSValueRef::Undefined(vm));
}
#if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
thread->CheckJSTaggedType(result.GetRawData());
#endif
JSHandle<JSTaggedValue> resultValue(thread, result);
return reinterpret_cast<JSValueRef*>(resultValue.GetAddress());
}
@ -5725,9 +5760,14 @@ Local<PromiseRef> PromiseRef::Catch(const EcmaVM *vm, Local<FunctionRef> handler
EcmaRuntimeCallInfo *info =
ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, promise, undefined, 1);
RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
#if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
thread->CheckJSTaggedType(reject.GetTaggedValue().GetRawData());
#endif
info->SetCallArg(reject.GetTaggedValue());
JSTaggedValue result = JSFunction::Invoke(info, catchKey);
#if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
thread->CheckJSTaggedType(result.GetRawData());
#endif
RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result));
}
@ -5746,9 +5786,15 @@ Local<PromiseRef> PromiseRef::Finally(const EcmaVM *vm, Local<FunctionRef> handl
EcmaRuntimeCallInfo *info =
ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, promise, undefined, 2); // 2: two args
RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
#if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
thread->CheckJSTaggedType(resolver.GetTaggedValue().GetRawData());
thread->CheckJSTaggedType(undefined.GetTaggedValue().GetRawData());
#endif
info->SetCallArg(resolver.GetTaggedValue(), undefined.GetTaggedValue());
JSTaggedValue result = JSFunction::Invoke(info, finallyKey);
#if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
thread->CheckJSTaggedType(result.GetRawData());
#endif
RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result));
}
@ -5767,9 +5813,15 @@ Local<PromiseRef> PromiseRef::Then(const EcmaVM *vm, Local<FunctionRef> handler)
EcmaRuntimeCallInfo *info =
ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, promise, undefined, 2); // 2: two args
RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
#if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
thread->CheckJSTaggedType(resolver.GetTaggedValue().GetRawData());
thread->CheckJSTaggedType(undefined.GetTaggedValue().GetRawData());
#endif
info->SetCallArg(resolver.GetTaggedValue(), undefined.GetTaggedValue());
JSTaggedValue result = JSFunction::Invoke(info, thenKey);
#if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
thread->CheckJSTaggedType(result.GetRawData());
#endif
RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result));
}
@ -5789,9 +5841,15 @@ Local<PromiseRef> PromiseRef::Then(const EcmaVM *vm, Local<FunctionRef> onFulfil
EcmaRuntimeCallInfo *info =
ecmascript::EcmaInterpreter::NewRuntimeCallInfo(thread, undefined, promise, undefined, 2); // 2: two args
RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
#if ECMASCRIPT_ENABLE_STUB_ARGV_CHECK
thread->CheckJSTaggedType(resolver.GetTaggedValue().GetRawData());
thread->CheckJSTaggedType(reject.GetTaggedValue().GetRawData());
#endif
info->SetCallArg(resolver.GetTaggedValue(), reject.GetTaggedValue());
JSTaggedValue result = JSFunction::Invoke(info, thenKey);
#if ECMASCRIPT_ENABLE_STUB_RESULT_CHECK
thread->CheckJSTaggedType(result.GetRawData());
#endif
RETURN_VALUE_IF_ABRUPT(thread, JSValueRef::Undefined(vm));
return JSNApiHelper::ToLocal<PromiseRef>(JSHandle<JSTaggedValue>(thread, result));
}