五大项整改:JSArray::SetCapacity();

Signed-off-by: 杨云飞 <yangyunfei19@h-partners.com>
This commit is contained in:
杨云飞 2024-05-28 16:02:09 +08:00
parent 0fc1a33cbe
commit 7912d55c91
2 changed files with 56 additions and 32 deletions

View File

@ -205,43 +205,60 @@ JSTaggedValue JSArray::ArraySpeciesCreate(JSThread *thread, const JSHandle<JSObj
return result;
}
void JSArray::SetCapacity(JSThread *thread, const JSHandle<JSObject> &array, uint32_t oldLen, uint32_t newLen,
bool isNew)
void JSArray::SetCapacity(JSThread *thread, const JSHandle<JSObject> &array,
uint32_t oldLen, uint32_t newLen, bool isNew)
{
TaggedArray *element = TaggedArray::Cast(array->GetElements().GetTaggedObject());
if (element->IsDictionaryMode()) {
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
uint32_t numOfElements = array->GetNumberOfElements();
uint32_t newNumOfElements = newLen;
if (newLen < oldLen && numOfElements != 0U) {
JSHandle<NumberDictionary> dictHandle(thread, element);
JSHandle<TaggedArray> newArr = factory->NewTaggedArray(numOfElements);
GetAllElementKeys(thread, array, 0, newArr);
for (uint32_t i = numOfElements - 1; i >= newLen; i--) {
JSTaggedValue value = newArr->Get(i);
uint32_t output = 0;
JSTaggedValue::StringToElementIndex(value, &output);
JSTaggedValue key(static_cast<int>(output));
int entry = dictHandle->FindEntry(key);
auto attr = dictHandle->GetAttributes(entry).GetValue();
PropertyAttributes propAttr(attr);
if (propAttr.IsConfigurable()) {
JSHandle<NumberDictionary> newDict = NumberDictionary::Remove(thread, dictHandle, entry);
array->SetElements(thread, newDict);
if (i == 0) {
newNumOfElements = i;
break;
}
} else {
newNumOfElements = i + 1;
break;
}
}
}
JSArray::Cast(*array)->SetArrayLength(thread, newNumOfElements);
HandleDictionaryMode(thread, array, oldLen, newLen, element);
return;
}
HandleNormalMode(thread, array, oldLen, newLen, isNew, element);
JSArray::Cast(*array)->SetArrayLength(thread, newLen);
UpdateElementsKind(thread, array, newLen);
}
void JSArray::HandleDictionaryMode(JSThread *thread, const JSHandle<JSObject> &array,
uint32_t &oldLen, uint32_t &newLen, TaggedArray *element)
{
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
uint32_t numOfElements = array->GetNumberOfElements();
uint32_t newNumOfElements = newLen;
if (newLen < oldLen && numOfElements != 0U) {
JSHandle<NumberDictionary> dictHandle(thread, element);
JSHandle<TaggedArray> newArr = factory->NewTaggedArray(numOfElements);
GetAllElementKeys(thread, array, 0, newArr);
for (uint32_t i = numOfElements - 1; i >= newLen; i--) {
JSTaggedValue value = newArr->Get(i);
uint32_t output = 0;
JSTaggedValue::StringToElementIndex(value, &output);
JSTaggedValue key(static_cast<int>(output));
int entry = dictHandle->FindEntry(key);
auto attr = dictHandle->GetAttributes(entry).GetValue();
PropertyAttributes propAttr(attr);
if (propAttr.IsConfigurable()) {
JSHandle<NumberDictionary> newDict = NumberDictionary::Remove(thread, dictHandle, entry);
array->SetElements(thread, newDict);
if (i == 0) {
newNumOfElements = i;
break;
}
} else {
newNumOfElements = i + 1;
break;
}
}
}
JSArray::Cast(*array)->SetArrayLength(thread, newNumOfElements);
return;
}
void JSArray::HandleNormalMode(JSThread *thread, const JSHandle<JSObject> &array,
uint32_t &oldLen, uint32_t &newLen, bool &isNew, TaggedArray *element)
{
uint32_t capacity = element->GetLength();
if (newLen <= capacity) {
// judge if need to cut down the array size, else fill the unused tail with holes
@ -253,8 +270,10 @@ void JSArray::SetCapacity(JSThread *thread, const JSHandle<JSObject> &array, uin
} else if (newLen > capacity) {
JSObject::GrowElementsCapacity(thread, array, newLen, isNew);
}
JSArray::Cast(*array)->SetArrayLength(thread, newLen);
}
void JSArray::UpdateElementsKind(JSThread *thread, const JSHandle<JSObject> &array, uint32_t &newLen)
{
// Update ElementsKind after reset array length.
// Add this switch because we do not support ElementsKind for instance from new Array
if (thread->GetEcmaVM()->IsEnableElementsKind() && !array->IsElementDict()) {

View File

@ -108,6 +108,11 @@ public:
static void PUBLIC_API CheckAndCopyArray(const JSThread *thread, JSHandle<JSArray> obj);
static void SetCapacity(JSThread *thread, const JSHandle<JSObject> &array, uint32_t oldLen, uint32_t newLen,
bool isNew = false);
static void HandleDictionaryMode(JSThread *thread, const JSHandle<JSObject> &array,
uint32_t &oldLen, uint32_t &newLen, TaggedArray *element);
static void HandleNormalMode(JSThread *thread, const JSHandle<JSObject> &array,
uint32_t &oldLen, uint32_t &newLen, bool &isNew, TaggedArray *element);
static void UpdateElementsKind(JSThread *thread, const JSHandle<JSObject> &array, uint32_t &newLen);
static void SortElements(JSThread *thread, const JSHandle<TaggedArray> &elements,
const JSHandle<JSTaggedValue> &fn);
static void SortElementsByObject(JSThread *thread, const JSHandle<JSObject> &thisObjHandle,