Add log for MaTchFieldType and Fix review comments

1.Add log for MaTchFieldType
2.Fix review comments

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IANE9I

Signed-off-by: lijiamin2019 <lijiamin24@huawei.com>
Change-Id: Ibb7691d5f055670b3d87f995789838a31dbf9b66
This commit is contained in:
lijiamin2019 2024-08-29 16:16:03 +08:00
parent ff983b3c05
commit da1d7055f0
13 changed files with 136 additions and 12 deletions

View File

@ -2507,11 +2507,11 @@ void StringToListResultCache::SetCachedResult(const JSThread *thread, const JSHa
// clone to cache array // clone to cache array
uint32_t arrayLength = resultArray->GetLength(); uint32_t arrayLength = resultArray->GetLength();
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSMutableHandle<TaggedArray> newElements(thread, JSTaggedValue::Undefined()); JSHandle<TaggedArray> newElements;
if (resultArray.GetTaggedValue().IsInSharedHeap()) { if (resultArray.GetTaggedValue().IsInSharedHeap()) {
newElements.Update(factory->NewSCOWTaggedArray(arrayLength)); newElements = JSHandle<TaggedArray>(factory->NewSCOWTaggedArray(arrayLength));
} else { } else {
newElements.Update(factory->NewCOWTaggedArray(arrayLength)); newElements = JSHandle<TaggedArray>(factory->NewCOWTaggedArray(arrayLength));
} }
for (uint32_t i = 0; i < arrayLength; i++) { for (uint32_t i = 0; i < arrayLength; i++) {
newElements->Set(thread, i, resultArray->Get(i)); newElements->Set(thread, i, resultArray->Get(i));

View File

@ -2361,7 +2361,7 @@ inline void StubBuilder::CheckUpdateSharedType(bool isDicMode, Variable *result,
{ {
Label typeMismatch(env); Label typeMismatch(env);
GateRef fieldType = isDicMode ? GetDictSharedFieldTypeInPropAttr(attr) : GetSharedFieldTypeInPropAttr(attr); GateRef fieldType = isDicMode ? GetDictSharedFieldTypeInPropAttr(attr) : GetSharedFieldTypeInPropAttr(attr);
MatchFieldType(fieldType, value, executeSetProp, &typeMismatch); MatchFieldType(glue, fieldType, value, executeSetProp, &typeMismatch);
Bind(&typeMismatch); Bind(&typeMismatch);
{ {
GateRef taggedId = Int32(GET_MESSAGE_STRING_ID(SetTypeMismatchedSharedProperty)); GateRef taggedId = Int32(GET_MESSAGE_STRING_ID(SetTypeMismatchedSharedProperty));
@ -2382,7 +2382,7 @@ inline void StubBuilder::CheckUpdateSharedType(bool isDicMode, Variable *result,
{ {
Label typeMismatch(env); Label typeMismatch(env);
GateRef fieldType = isDicMode ? GetDictSharedFieldTypeInPropAttr(attr) : GetSharedFieldTypeInPropAttr(attr); GateRef fieldType = isDicMode ? GetDictSharedFieldTypeInPropAttr(attr) : GetSharedFieldTypeInPropAttr(attr);
MatchFieldType(fieldType, value, executeSetProp, &typeMismatch); MatchFieldType(glue, fieldType, value, executeSetProp, &typeMismatch);
Bind(&typeMismatch); Bind(&typeMismatch);
{ {
GateRef taggedId = Int32(GET_MESSAGE_STRING_ID(SetTypeMismatchedSharedProperty)); GateRef taggedId = Int32(GET_MESSAGE_STRING_ID(SetTypeMismatchedSharedProperty));
@ -2398,7 +2398,7 @@ inline void StubBuilder::MatchFieldType(Variable *result, GateRef glue, GateRef
{ {
auto *env = GetEnvironment(); auto *env = GetEnvironment();
Label typeMismatch(env); Label typeMismatch(env);
MatchFieldType(fieldType, value, executeSetProp, &typeMismatch); MatchFieldType(glue, fieldType, value, executeSetProp, &typeMismatch);
Bind(&typeMismatch); Bind(&typeMismatch);
{ {
GateRef taggedId = Int32(GET_MESSAGE_STRING_ID(SetTypeMismatchedSharedProperty)); GateRef taggedId = Int32(GET_MESSAGE_STRING_ID(SetTypeMismatchedSharedProperty));

View File

@ -146,7 +146,8 @@ void StubBuilder::LoopEnd(Label *loopHead)
env_->SetCurrentLabel(nullptr); env_->SetCurrentLabel(nullptr);
} }
void StubBuilder::MatchFieldType(GateRef fieldType, GateRef value, Label *executeSetProp, Label *typeMismatch) void StubBuilder::MatchFieldType(
GateRef glue, GateRef fieldType, GateRef value, Label *executeSetProp, Label *typeMismatch)
{ {
auto *env = GetEnvironment(); auto *env = GetEnvironment();
Label isNumber(env); Label isNumber(env);
@ -165,6 +166,8 @@ void StubBuilder::MatchFieldType(GateRef fieldType, GateRef value, Label *execut
Label checkUndefined(env); Label checkUndefined(env);
Label isUndefined(env); Label isUndefined(env);
Label exit(env); Label exit(env);
Label Mismatch(env);
Label CheckMatch(env);
DEFVARIABLE(result, VariableType::BOOL(), False()); DEFVARIABLE(result, VariableType::BOOL(), False());
GateRef checkType = BoolAnd( GateRef checkType = BoolAnd(
Int32NotEqual(Int32And(fieldType, Int32(static_cast<int32_t>(SharedFieldType::NUMBER))), Int32(0)), Int32NotEqual(Int32And(fieldType, Int32(static_cast<int32_t>(SharedFieldType::NUMBER))), Int32(0)),
@ -262,6 +265,13 @@ void StubBuilder::MatchFieldType(GateRef fieldType, GateRef value, Label *execut
} }
} }
Bind(&exit); Bind(&exit);
Branch(BoolNot(*result), &Mismatch, &CheckMatch);
Bind(&Mismatch);
{
CallRuntime(glue, RTSTUB_ID(MismatchError), {IntToTaggedInt(fieldType), value});
Jump(&CheckMatch);
}
Bind(&CheckMatch);
BRANCH(*result, executeSetProp, typeMismatch); BRANCH(*result, executeSetProp, typeMismatch);
} }

View File

@ -605,7 +605,7 @@ ShortcutBoolOr([&]{ return first; }, [&]{ return second; })
GateRef GetPropertyMetaDataFromAttr(GateRef attr); GateRef GetPropertyMetaDataFromAttr(GateRef attr);
GateRef TranslateToRep(GateRef value); GateRef TranslateToRep(GateRef value);
GateRef GetKeyFromLayoutInfo(GateRef layout, GateRef entry); GateRef GetKeyFromLayoutInfo(GateRef layout, GateRef entry);
void MatchFieldType(GateRef fieldType, GateRef value, Label *executeSetProp, Label *typeMismatch); void MatchFieldType(GateRef glue, GateRef fieldType, GateRef value, Label *executeSetProp, Label *typeMismatch);
GateRef FindElementWithCache(GateRef glue, GateRef layoutInfo, GateRef hClass, GateRef FindElementWithCache(GateRef glue, GateRef layoutInfo, GateRef hClass,
GateRef key, GateRef propsNum, GateRef hir = Circuit::NullGate()); GateRef key, GateRef propsNum, GateRef hir = Circuit::NullGate());
GateRef FindElementFromNumberDictionary(GateRef glue, GateRef elements, GateRef index); GateRef FindElementFromNumberDictionary(GateRef glue, GateRef elements, GateRef index);

View File

@ -1325,6 +1325,21 @@ void JSTaggedValue::DumpTaggedValue(std::ostream &os) const
} }
} }
void JSTaggedValue::DumpTaggedValueType(std::ostream &os) const
{
if (IsInt()) {
os << "[Int]";
} else if (IsDouble()) {
os << "[Double]";
} else if (IsSpecial()) {
DumpSpecialValue(os);
} else {
ASSERT(IsWeak() || IsHeapObject());
TaggedObject *obj = IsWeak() ? GetTaggedWeakRef() : GetTaggedObject();
os << "[" + JSHClass::DumpJSType(obj->GetClass()->GetObjectType()) + "]";
}
}
void JSTaggedValue::Dump(std::ostream &os) const void JSTaggedValue::Dump(std::ostream &os) const
{ {
DumpTaggedValue(os); DumpTaggedValue(os);

View File

@ -712,6 +712,7 @@ public:
static JSTaggedValue TryCastDoubleToInt32(double d); static JSTaggedValue TryCastDoubleToInt32(double d);
void DumpTaggedValue(std::ostream &os) const DUMP_API_ATTR; void DumpTaggedValue(std::ostream &os) const DUMP_API_ATTR;
void DumpTaggedValueType(std::ostream &os) const DUMP_API_ATTR;
void Dump(std::ostream &os) const DUMP_API_ATTR; void Dump(std::ostream &os) const DUMP_API_ATTR;
void D() const DUMP_API_ATTR; void D() const DUMP_API_ATTR;
void DumpForSnapshot(std::vector<Reference> &vec, bool isVmMode = true) const; void DumpForSnapshot(std::vector<Reference> &vec, bool isVmMode = true) const;

View File

@ -675,9 +675,41 @@ bool ClassHelper::MatchFieldType(SharedFieldType fieldType, JSTaggedValue value)
} else if ((sharedFieldType & static_cast<uint32_t>(SharedFieldType::UNDEFINED)) != 0 && value.IsUndefined()) { } else if ((sharedFieldType & static_cast<uint32_t>(SharedFieldType::UNDEFINED)) != 0 && value.IsUndefined()) {
return true; return true;
} }
std::stringstream oss;
value.DumpTaggedValueType(oss);
LOG_ECMA(ERROR) << "Sendable obj Match field type fail. expected type: " <<
StaticFieldTypeToString(sharedFieldType) << ", actual type: " << oss.str();
return false; return false;
} }
CString ClassHelper::StaticFieldTypeToString(uint32_t fieldType)
{
switch (fieldType) {
case static_cast<uint32_t>(SharedFieldType::NONE):
return "[None]";
case static_cast<uint32_t>(SharedFieldType::NUMBER):
return "[Number]";
case static_cast<uint32_t>(SharedFieldType::STRING):
return "[String]";
case static_cast<uint32_t>(SharedFieldType::BOOLEAN):
return "[Boolean]";
case static_cast<uint32_t>(SharedFieldType::SENDABLE):
return "[Sendable Object]";
case static_cast<uint32_t>(SharedFieldType::BIG_INT):
return "[BigInt]";
case static_cast<uint32_t>(SharedFieldType::GENERIC):
return "[Generic]";
case static_cast<uint32_t>(SharedFieldType::NULL_TYPE):
return "[Null]";
case static_cast<uint32_t>(SharedFieldType::UNDEFINED):
return "[Undefined]";
default: {
CString ret = "unknown type ";
return ret.append(std::to_string(fieldType));
}
}
}
void ClassHelper::HandleElementsProperties(JSThread *thread, const JSHandle<JSObject> &object, void ClassHelper::HandleElementsProperties(JSThread *thread, const JSHandle<JSObject> &object,
JSHandle<TaggedArray> &elements) JSHandle<TaggedArray> &elements)
{ {

View File

@ -121,6 +121,7 @@ public:
const JSHandle<JSTaggedValue> &constructorHClassVal); const JSHandle<JSTaggedValue> &constructorHClassVal);
static bool PUBLIC_API MatchFieldType(SharedFieldType fieldType, JSTaggedValue value); static bool PUBLIC_API MatchFieldType(SharedFieldType fieldType, JSTaggedValue value);
static CString StaticFieldTypeToString(uint32_t fieldType);
private: private:
static JSHandle<NameDictionary> BuildDictionaryProperties(JSThread *thread, const JSHandle<JSObject> &object, static JSHandle<NameDictionary> BuildDictionaryProperties(JSThread *thread, const JSHandle<JSObject> &object,
JSHandle<TaggedArray> &keys, JSHandle<TaggedArray> &keys,

View File

@ -285,9 +285,9 @@ public:
return DeoptTypeBits::Update(extraLiteralInfo, type); return DeoptTypeBits::Update(extraLiteralInfo, type);
} }
uint64_t SetIsSendable(uint64_t extraLiteralInfo, bool isShared) uint64_t SetIsSendable(uint64_t extraLiteralInfo, bool isSendable)
{ {
return IsSharedBit::Update(extraLiteralInfo, isShared); return IsSharedBit::Update(extraLiteralInfo, isSendable);
} }
uint64_t SetFpDelta(uint64_t extraLitearalInfo, int32_t delta) uint64_t SetFpDelta(uint64_t extraLitearalInfo, int32_t delta)
@ -417,10 +417,10 @@ public:
return IsSharedBit::Decode(extraLiteralInfo); return IsSharedBit::Decode(extraLiteralInfo);
} }
void SetIsSendable(bool isShared) void SetIsSendable(bool isSendable)
{ {
uint64_t extraLiteralInfo = GetExtraLiteralInfo(); uint64_t extraLiteralInfo = GetExtraLiteralInfo();
uint64_t newValue = SetIsSendable(extraLiteralInfo, isShared); uint64_t newValue = SetIsSendable(extraLiteralInfo, isSendable);
SetExtraLiteralInfo(newValue); SetExtraLiteralInfo(newValue);
} }

View File

@ -201,6 +201,7 @@ namespace panda::ecmascript {
V(StGlobalRecord) \ V(StGlobalRecord) \
V(ThrowReferenceError) \ V(ThrowReferenceError) \
V(ThrowTypeError) \ V(ThrowTypeError) \
V(MismatchError) \
V(ThrowSyntaxError) \ V(ThrowSyntaxError) \
V(NewClassFunc) \ V(NewClassFunc) \
V(DefineClass) \ V(DefineClass) \

View File

@ -210,6 +210,7 @@ namespace panda::ecmascript {
V(ToPropertyKeyConfigurable) \ V(ToPropertyKeyConfigurable) \
V(NewJSPrimitiveRef) \ V(NewJSPrimitiveRef) \
V(ThrowTypeError) \ V(ThrowTypeError) \
V(MismatchError) \
V(GetHash32) \ V(GetHash32) \
V(ComputeHashcode) \ V(ComputeHashcode) \
V(NewInternalString) \ V(NewInternalString) \

View File

@ -2010,6 +2010,18 @@ DEF_RUNTIME_STUBS(ThrowTypeError)
THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error.GetTaggedValue(), JSTaggedValue::Hole().GetRawData()); THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error.GetTaggedValue(), JSTaggedValue::Hole().GetRawData());
} }
DEF_RUNTIME_STUBS(MismatchError)
{
RUNTIME_STUBS_HEADER(MismatchError);
JSTaggedValue shareFieldType = GetArg(argv, argc, 0); // 0: means the zeroth parameter
JSTaggedValue value = GetArg(argv, argc, 1); // 1: means the first parameter
std::stringstream oss;
value.DumpTaggedValueType(oss);
LOG_ECMA(ERROR) << "Sendable obj Match field type fail. expected type: " <<
ClassHelper::StaticFieldTypeToString(shareFieldType.GetInt()) << ", actual type: " << oss.str();
return JSTaggedValue::Undefined().GetRawData();
}
DEF_RUNTIME_STUBS(NewJSPrimitiveRef) DEF_RUNTIME_STUBS(NewJSPrimitiveRef)
{ {
RUNTIME_STUBS_HEADER(NewJSPrimitiveRef); RUNTIME_STUBS_HEADER(NewJSPrimitiveRef);

View File

@ -14,6 +14,7 @@
*/ */
#include "ecmascript/accessor_data.h" #include "ecmascript/accessor_data.h"
#include "ecmascript/builtins/builtins_array.h"
#include "ecmascript/dfx/hprof/heap_profiler.h" #include "ecmascript/dfx/hprof/heap_profiler.h"
#include "ecmascript/dfx/hprof/heap_profiler_interface.h" #include "ecmascript/dfx/hprof/heap_profiler_interface.h"
#include "ecmascript/dfx/hprof/heap_snapshot.h" #include "ecmascript/dfx/hprof/heap_snapshot.h"
@ -134,9 +135,11 @@
#include "ecmascript/require/js_cjs_module.h" #include "ecmascript/require/js_cjs_module.h"
#include "ecmascript/require/js_cjs_require.h" #include "ecmascript/require/js_cjs_require.h"
#include "ecmascript/require/js_cjs_exports.h" #include "ecmascript/require/js_cjs_exports.h"
#include <sstream>
using namespace panda::ecmascript; using namespace panda::ecmascript;
using namespace panda::ecmascript::base; using namespace panda::ecmascript::base;
using Array = panda::ecmascript::builtins::BuiltinsArray;
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CHECK_DUMP_FIELDS(begin, end, num); \ #define CHECK_DUMP_FIELDS(begin, end, num); \
@ -167,6 +170,54 @@ HWTEST_F_L0(EcmaDumpTest, Dump)
} }
#endif // #ifndef NDEBUG #endif // #ifndef NDEBUG
HWTEST_F_L0(EcmaDumpTest, DumpTaggedValueType)
{
std::vector<JSHandle<JSTaggedValue>> loopVal {};
std::vector<std::string> loopRes {};
// [Int]
int32_t a = 1;
JSTaggedValue intVal = JSTaggedValue(a);
loopVal.push_back(JSHandle<JSTaggedValue>(thread, intVal));
loopRes.push_back("[Int]");
// [Double]
double b = 3.14;
JSTaggedValue doubleVal = JSTaggedValue(b);
loopVal.push_back(JSHandle<JSTaggedValue>(thread, doubleVal));
loopRes.push_back("[Double]");
// [Undefine]
JSTaggedValue undefineVal = JSTaggedValue::Undefined();
loopVal.push_back(JSHandle<JSTaggedValue>(thread, undefineVal));
loopRes.push_back("[Special Value] : Undefined");
// [Null]
JSTaggedValue nullVal = JSTaggedValue::Null();
loopVal.push_back(JSHandle<JSTaggedValue>(thread, nullVal));
loopRes.push_back("[Special Value] : Null");
// JSArray
JSHandle<JSFunction> array(thread->GetEcmaVM()->GetGlobalEnv()->GetArrayFunction());
JSHandle<JSObject> globalObject(thread, thread->GetEcmaVM()->GetGlobalEnv()->GetGlobalObject());
auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
ecmaRuntimeCallInfo1->SetFunction(array.GetTaggedValue());
ecmaRuntimeCallInfo1->SetThis(globalObject.GetTaggedValue());
[[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
JSTaggedValue arrVal = Array::ArrayConstructor(ecmaRuntimeCallInfo1);
TestHelper::TearDownFrame(thread, prev);
loopVal.push_back(JSHandle<JSTaggedValue>(thread, arrVal));
loopRes.push_back("[Array]");
// Object
JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
JSHandle<JSTaggedValue> objFun = globalEnv->GetObjectFunction();
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<JSTaggedValue> obj(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun));
loopVal.push_back(obj);
loopRes.push_back("[Object]");
for (int i = 0; i < loopVal.size(); i++) {
std::stringstream oss;
loopVal[i].GetTaggedValue().DumpTaggedValueType(oss);
ASSERT_EQ(oss.str(), loopRes[i]);
}
}
static JSHandle<JSMap> NewJSMap(JSThread *thread, ObjectFactory *factory, JSHandle<JSTaggedValue> proto) static JSHandle<JSMap> NewJSMap(JSThread *thread, ObjectFactory *factory, JSHandle<JSTaggedValue> proto)
{ {
JSHandle<JSHClass> mapClass = factory->NewEcmaHClass(JSMap::SIZE, JSType::JS_MAP, proto); JSHandle<JSHClass> mapClass = factory->NewEcmaHClass(JSMap::SIZE, JSType::JS_MAP, proto);