!1893 [optimization] Array slice

Merge pull request !1893 from xliu/array_slice
This commit is contained in:
openharmony_ci 2022-07-27 07:39:42 +00:00 committed by Gitee
commit f9f27ebd23
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
4 changed files with 48 additions and 24 deletions

View File

@ -1976,12 +1976,17 @@ JSTaggedValue BuiltinsArray::Slice(EcmaRuntimeCallInfo *argv)
// 4. ReturnIfAbrupt(len).
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
// 5. Let relativeStart be ToInteger(start).
JSHandle<JSTaggedValue> msg0 = GetCallArg(argv, 0);
JSTaggedNumber argStartTemp = JSTaggedValue::ToInteger(thread, msg0);
// 6. ReturnIfAbrupt(relativeStart).
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
double argStart = argStartTemp.GetNumber();
double argStart;
if (msg0->IsInt()) {
argStart = msg0->GetInt();
} else {
// 5. Let relativeStart be ToInteger(start).
JSTaggedNumber argStartTemp = JSTaggedValue::ToInteger(thread, msg0);
// 6. ReturnIfAbrupt(relativeStart).
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
argStart = argStartTemp.GetNumber();
}
double k;
// 7. If relativeStart < 0, let k be max((len + relativeStart),0); else let k be min(relativeStart, len).
@ -1996,9 +2001,13 @@ JSTaggedValue BuiltinsArray::Slice(EcmaRuntimeCallInfo *argv)
JSHandle<JSTaggedValue> msg1 = GetCallArg(argv, 1);
double argEnd = len;
if (!msg1->IsUndefined()) {
JSTaggedNumber argEndTemp = JSTaggedValue::ToInteger(thread, msg1);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
argEnd = argEndTemp.GetNumber();
if (msg1->IsInt()) {
argEnd = msg1->GetInt();
} else {
JSTaggedNumber argEndTemp = JSTaggedValue::ToInteger(thread, msg1);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
argEnd = argEndTemp.GetNumber();
}
}
double final;
if (argEnd < 0) {
@ -2006,11 +2015,23 @@ JSTaggedValue BuiltinsArray::Slice(EcmaRuntimeCallInfo *argv)
} else {
final = argEnd < len ? argEnd : len;
}
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
// 11. Let count be max(final k, 0).
double count = (final - k) > 0 ? (final - k) : 0;
if (thisHandle->IsStableJSArray(thread) && !thisObjHandle->GetJSHClass()->HasConstructor()) {
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<TaggedArray> destElements = factory->NewTaggedArray(count);
JSHandle<JSArray> newArrayHandle = factory->NewJSStableArrayWithElements(destElements);
TaggedArray *srcElements = TaggedArray::Cast(thisObjHandle->GetElements().GetTaggedObject());
for (uint32_t idx = 0; idx < count; idx++) {
destElements->Set(thread, idx, srcElements->Get(k + idx));
}
return newArrayHandle.GetTaggedValue();
}
// 12. Let A be ArraySpeciesCreate(O, count).
JSTaggedValue newArray = JSArray::ArraySpeciesCreate(thread, thisObjHandle, JSTaggedNumber(count));
// 13. ReturnIfAbrupt(A).
@ -2020,18 +2041,6 @@ JSTaggedValue BuiltinsArray::Slice(EcmaRuntimeCallInfo *argv)
}
JSHandle<JSObject> newArrayHandle(thread, newArray);
if (thisHandle->IsStableJSArray(thread) && newArray.IsStableJSArray(thread)) {
TaggedArray *destElements = *JSObject::GrowElementsCapacity(thread, newArrayHandle, count);
TaggedArray *srcElements = TaggedArray::Cast(thisObjHandle->GetElements().GetTaggedObject());
for (uint32_t idx = 0; idx < count; idx++) {
destElements->Set(thread, idx, srcElements->Get(k + idx));
}
JSHandle<JSArray>::Cast(newArrayHandle)->SetArrayLength(thread, count);
return newArrayHandle.GetTaggedValue();
}
// 14. Let n be 0.
// 15. Repeat, while k < final
// a. Let Pk be ToString(k).

View File

@ -1347,15 +1347,14 @@ JSHandle<TaggedArray> JSObject::EnumerableOwnNames(JSThread *thread, const JSHan
{
ASSERT_PRINT(obj->IsECMAObject(), "obj is not object");
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<TaggedArray> keys;
JSHandle<JSTaggedValue> tagObj(obj);
// fast mode
if (tagObj->IsJSObject() && !tagObj->IsTypedArray() && !tagObj->IsModuleNamespace()) {
keys = GetOwnEnumerableNamesInFastMode(thread, obj);
return GetOwnEnumerableNamesInFastMode(thread, obj);
}
uint32_t copyLength = 0;
keys = JSTaggedValue::GetOwnPropertyKeys(thread, tagObj);
JSHandle<TaggedArray> keys = JSTaggedValue::GetOwnPropertyKeys(thread, tagObj);
RETURN_HANDLE_IF_ABRUPT_COMPLETION(TaggedArray, thread);
uint32_t length = keys->GetLength();

View File

@ -3633,4 +3633,17 @@ JSHandle<TaggedArray> ObjectFactory::NewOldSpaceTaggedArray(uint32_t length, JST
{
return NewTaggedArray(length, initVal, MemSpaceType::OLD_SPACE);
}
JSHandle<JSArray> ObjectFactory::NewJSStableArrayWithElements(const JSHandle<TaggedArray> &elements)
{
JSHandle<JSHClass> cls(thread_,
JSHandle<JSFunction>::Cast(vm_->GetGlobalEnv()->GetArrayFunction())->GetProtoOrDynClass());
JSHandle<JSArray> array = JSHandle<JSArray>::Cast(NewJSObject(cls));
array->SetElements(thread_, elements);
array->SetLength(thread_, JSTaggedValue(elements->GetLength()));
auto accessor = thread_->GlobalConstants()->GetArrayLengthAccessor();
array->SetPropertyInlinedProps(thread_, JSArray::LENGTH_INLINE_PROPERTY_INDEX, accessor);
return array;
}
} // namespace panda::ecmascript

View File

@ -552,6 +552,9 @@ public:
TaggedObject *NewOldSpaceDynObject(const JSHandle<JSHClass> &dynclass);
JSHandle<TaggedArray> NewOldSpaceTaggedArray(uint32_t length, JSTaggedValue initVal = JSTaggedValue::Hole());
// ---------------------------------New objects used internally--------------------------------------
JSHandle<JSArray> NewJSStableArrayWithElements(const JSHandle<TaggedArray> &elements);
private:
friend class GlobalEnv;
friend class GlobalEnvConstants;