mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
Optimize filter, reverse and sort in Array
Optimize filter, reverse and sort in Array issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I5LWPV Signed-off-by: xdmal <maxiaodong16@huawei.com>
This commit is contained in:
parent
494f699de4
commit
46dd7d0add
@ -430,6 +430,9 @@ JSTaggedValue BuiltinsArray::Concat(EcmaRuntimeCallInfo *argv)
|
|||||||
THROW_TYPE_ERROR_AND_RETURN(thread, "out of range.", JSTaggedValue::Exception());
|
THROW_TYPE_ERROR_AND_RETURN(thread, "out of range.", JSTaggedValue::Exception());
|
||||||
}
|
}
|
||||||
double k = 0;
|
double k = 0;
|
||||||
|
if (thisObjVal->IsStableJSArray(thread)) {
|
||||||
|
JSStableArray::Concat(thread, newArrayHandle, thisObjHandle, k, n);
|
||||||
|
}
|
||||||
while (k < thisLen) {
|
while (k < thisLen) {
|
||||||
fromKey.Update(JSTaggedValue(k));
|
fromKey.Update(JSTaggedValue(k));
|
||||||
toKey.Update(JSTaggedValue(n));
|
toKey.Update(JSTaggedValue(n));
|
||||||
@ -474,6 +477,10 @@ JSTaggedValue BuiltinsArray::Concat(EcmaRuntimeCallInfo *argv)
|
|||||||
THROW_TYPE_ERROR_AND_RETURN(thread, "out of range.", JSTaggedValue::Exception());
|
THROW_TYPE_ERROR_AND_RETURN(thread, "out of range.", JSTaggedValue::Exception());
|
||||||
}
|
}
|
||||||
double k = 0;
|
double k = 0;
|
||||||
|
JSHandle<JSTaggedValue> addObjVal(addObjHandle);
|
||||||
|
if (addObjVal->IsStableJSArray(thread)) {
|
||||||
|
JSStableArray::Concat(thread, newArrayHandle, addObjHandle, k, n);
|
||||||
|
}
|
||||||
// v. Repeat, while k < len
|
// v. Repeat, while k < len
|
||||||
while (k < len) {
|
while (k < len) {
|
||||||
fromKey.Update(JSTaggedValue(k));
|
fromKey.Update(JSTaggedValue(k));
|
||||||
@ -880,6 +887,12 @@ JSTaggedValue BuiltinsArray::Filter(EcmaRuntimeCallInfo *argv)
|
|||||||
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||||
JSMutableHandle<JSTaggedValue> toIndexHandle(thread, JSTaggedValue::Undefined());
|
JSMutableHandle<JSTaggedValue> toIndexHandle(thread, JSTaggedValue::Undefined());
|
||||||
uint32_t k = 0;
|
uint32_t k = 0;
|
||||||
|
if (thisObjVal->IsStableJSArray(thread)) {
|
||||||
|
JSStableArray::Filter(newArrayHandle, thisObjHandle, argv, k, toIndex);
|
||||||
|
}
|
||||||
|
JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
|
||||||
|
const int32_t argsLength = 3; // 3: «kValue, k, O»
|
||||||
|
JSTaggedValue callResult = GetTaggedBoolean(true);
|
||||||
while (k < len) {
|
while (k < len) {
|
||||||
bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, k);
|
bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, k);
|
||||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
@ -887,16 +900,12 @@ JSTaggedValue BuiltinsArray::Filter(EcmaRuntimeCallInfo *argv)
|
|||||||
JSHandle<JSTaggedValue> kValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, k);
|
JSHandle<JSTaggedValue> kValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, k);
|
||||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
key.Update(JSTaggedValue(k));
|
key.Update(JSTaggedValue(k));
|
||||||
const int32_t argsLength = 3; // 3: «kValue, k, O»
|
|
||||||
JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
|
|
||||||
EcmaRuntimeCallInfo *info =
|
EcmaRuntimeCallInfo *info =
|
||||||
EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
|
EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
|
||||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue(), thisObjVal.GetTaggedValue());
|
info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue(), thisObjVal.GetTaggedValue());
|
||||||
JSTaggedValue callResult = JSFunction::Call(info);
|
callResult = JSFunction::Call(info);
|
||||||
bool boolResult = callResult.ToBoolean();
|
if (callResult.ToBoolean()) {
|
||||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
|
||||||
if (boolResult) {
|
|
||||||
toIndexHandle.Update(JSTaggedValue(toIndex));
|
toIndexHandle.Update(JSTaggedValue(toIndex));
|
||||||
JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, toIndexHandle, kValue);
|
JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, toIndexHandle, kValue);
|
||||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
@ -1425,9 +1434,14 @@ JSTaggedValue BuiltinsArray::Map(EcmaRuntimeCallInfo *argv)
|
|||||||
// v. Let status be CreateDataPropertyOrThrow (A, Pk, mappedValue).
|
// v. Let status be CreateDataPropertyOrThrow (A, Pk, mappedValue).
|
||||||
// vi. ReturnIfAbrupt(status).
|
// vi. ReturnIfAbrupt(status).
|
||||||
// e. Increase k by 1.
|
// e. Increase k by 1.
|
||||||
|
uint32_t k = 0;
|
||||||
|
if (thisObjVal->IsStableJSArray(thread)) {
|
||||||
|
JSStableArray::Map(newArrayHandle, thisObjHandle, argv, k, len);
|
||||||
|
}
|
||||||
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||||
JSMutableHandle<JSTaggedValue> mapResultHandle(thread, JSTaggedValue::Undefined());
|
JSMutableHandle<JSTaggedValue> mapResultHandle(thread, JSTaggedValue::Undefined());
|
||||||
uint32_t k = 0;
|
JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
|
||||||
|
const int32_t argsLength = 3; // 3: «kValue, k, O»
|
||||||
while (k < len) {
|
while (k < len) {
|
||||||
bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, k);
|
bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, k);
|
||||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
@ -1435,8 +1449,6 @@ JSTaggedValue BuiltinsArray::Map(EcmaRuntimeCallInfo *argv)
|
|||||||
JSHandle<JSTaggedValue> kValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, k);
|
JSHandle<JSTaggedValue> kValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, k);
|
||||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
key.Update(JSTaggedValue(k));
|
key.Update(JSTaggedValue(k));
|
||||||
const int32_t argsLength = 3; // 3: «kValue, k, O»
|
|
||||||
JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
|
|
||||||
EcmaRuntimeCallInfo *info =
|
EcmaRuntimeCallInfo *info =
|
||||||
EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
|
EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
|
||||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
@ -1839,6 +1851,9 @@ JSTaggedValue BuiltinsArray::Reverse(EcmaRuntimeCallInfo *argv)
|
|||||||
JSMutableHandle<JSTaggedValue> upperP(thread, JSTaggedValue::Undefined());
|
JSMutableHandle<JSTaggedValue> upperP(thread, JSTaggedValue::Undefined());
|
||||||
JSHandle<JSTaggedValue> lowerValueHandle(thread, JSTaggedValue::Undefined());
|
JSHandle<JSTaggedValue> lowerValueHandle(thread, JSTaggedValue::Undefined());
|
||||||
JSHandle<JSTaggedValue> upperValueHandle(thread, JSTaggedValue::Undefined());
|
JSHandle<JSTaggedValue> upperValueHandle(thread, JSTaggedValue::Undefined());
|
||||||
|
if (thisObjVal->IsStableJSArray(thread)) {
|
||||||
|
JSStableArray::Reverse(thread, thisObjHandle, thisHandle, lower, len);
|
||||||
|
}
|
||||||
while (lower != middle) {
|
while (lower != middle) {
|
||||||
double upper = len - lower - 1;
|
double upper = len - lower - 1;
|
||||||
lowerP.Update(JSTaggedValue(lower));
|
lowerP.Update(JSTaggedValue(lower));
|
||||||
|
@ -420,4 +420,153 @@ JSTaggedValue JSStableArray::IndexOf(JSThread *thread, JSHandle<JSTaggedValue> r
|
|||||||
}
|
}
|
||||||
return JSTaggedValue(-1);
|
return JSTaggedValue(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSTaggedValue JSStableArray::Filter(JSHandle<JSObject> newArrayHandle, JSHandle<JSObject> thisObjHandle,
|
||||||
|
EcmaRuntimeCallInfo *argv, uint32_t &k, double &toIndex)
|
||||||
|
{
|
||||||
|
JSThread *thread = argv->GetThread();
|
||||||
|
JSHandle<JSTaggedValue> callbackFnHandle = base::BuiltinsBase::GetCallArg(argv, 0);
|
||||||
|
JSHandle<JSTaggedValue> thisArgHandle = base::BuiltinsBase::GetCallArg(argv, 1);
|
||||||
|
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
|
||||||
|
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||||
|
JSMutableHandle<JSTaggedValue> toIndexHandle(thread, JSTaggedValue::Undefined());
|
||||||
|
JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
|
||||||
|
const int32_t argsLength = 3; // 3: ?kValue, k, O?
|
||||||
|
double len = base::ArrayHelper::GetArrayLength(thread, thisObjVal);
|
||||||
|
JSHandle<TaggedArray> array(thread, thisObjHandle->GetElements());
|
||||||
|
while (k < len) {
|
||||||
|
JSTaggedValue kValue = array->Get(k);
|
||||||
|
if (!kValue.IsHole()) {
|
||||||
|
key.Update(JSTaggedValue(k));
|
||||||
|
EcmaRuntimeCallInfo *info =
|
||||||
|
EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
|
||||||
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
|
info->SetCallArg(kValue, key.GetTaggedValue(), thisObjVal.GetTaggedValue());
|
||||||
|
JSTaggedValue callResult = JSFunction::Call(info);
|
||||||
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
|
if (array->GetLength() < len) {
|
||||||
|
len = array->GetLength();
|
||||||
|
}
|
||||||
|
bool boolResult = callResult.ToBoolean();
|
||||||
|
if (boolResult) {
|
||||||
|
toIndexHandle.Update(JSTaggedValue(toIndex));
|
||||||
|
JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle,
|
||||||
|
toIndexHandle, JSHandle<JSTaggedValue>(thread, kValue));
|
||||||
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
|
toIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
k++;
|
||||||
|
if (!thisObjVal->IsStableJSArray(thread)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return base::BuiltinsBase::GetTaggedDouble(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSTaggedValue JSStableArray::Map(JSHandle<JSObject> newArrayHandle, JSHandle<JSObject> thisObjHandle,
|
||||||
|
EcmaRuntimeCallInfo *argv, uint32_t &k, uint32_t len)
|
||||||
|
{
|
||||||
|
JSThread *thread = argv->GetThread();
|
||||||
|
JSHandle<JSTaggedValue> callbackFnHandle = base::BuiltinsBase::GetCallArg(argv, 0);
|
||||||
|
JSHandle<JSTaggedValue> thisArgHandle = base::BuiltinsBase::GetCallArg(argv, 1);
|
||||||
|
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
|
||||||
|
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||||
|
JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
|
||||||
|
JSMutableHandle<JSTaggedValue> mapResultHandle(thread, JSTaggedValue::Undefined());
|
||||||
|
const int32_t argsLength = 3; // 3: ?kValue, k, O?
|
||||||
|
JSHandle<TaggedArray> array(thread, thisObjHandle->GetElements());
|
||||||
|
while (k < len) {
|
||||||
|
JSTaggedValue kValue = array->Get(k);
|
||||||
|
if (!kValue.IsHole()) {
|
||||||
|
key.Update(JSTaggedValue(k));
|
||||||
|
EcmaRuntimeCallInfo *info =
|
||||||
|
EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
|
||||||
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
|
info->SetCallArg(kValue, key.GetTaggedValue(), thisObjVal.GetTaggedValue());
|
||||||
|
JSTaggedValue mapResult = JSFunction::Call(info);
|
||||||
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
|
mapResultHandle.Update(mapResult);
|
||||||
|
JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, k, mapResultHandle);
|
||||||
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
|
if (array->GetLength() < len) {
|
||||||
|
len = array->GetLength();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
k++;
|
||||||
|
if (!thisObjVal->IsStableJSArray(thread)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return base::BuiltinsBase::GetTaggedDouble(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSTaggedValue JSStableArray::Reverse(JSThread *thread, JSHandle<JSObject> thisObjHandle,
|
||||||
|
JSHandle<JSTaggedValue> thisHandle, double &lower, uint32_t len)
|
||||||
|
{
|
||||||
|
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
|
||||||
|
JSHandle<TaggedArray> array(thread, thisObjHandle->GetElements());
|
||||||
|
JSMutableHandle<JSTaggedValue> lowerP(thread, JSTaggedValue::Undefined());
|
||||||
|
JSMutableHandle<JSTaggedValue> upperP(thread, JSTaggedValue::Undefined());
|
||||||
|
JSMutableHandle<JSTaggedValue> lowerValueHandle(thread, JSTaggedValue::Undefined());
|
||||||
|
JSMutableHandle<JSTaggedValue> upperValueHandle(thread, JSTaggedValue::Undefined());
|
||||||
|
double middle = std::floor(len / 2);
|
||||||
|
while (lower != middle) {
|
||||||
|
if (array->GetLength() != len) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
double upper = len - lower - 1;
|
||||||
|
lowerP.Update(JSTaggedValue(lower));
|
||||||
|
upperP.Update(JSTaggedValue(upper));
|
||||||
|
bool lowerExists = (thisHandle->IsTypedArray() || JSTaggedValue::HasProperty(thread, thisObjVal, lowerP));
|
||||||
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
|
if (lowerExists) {
|
||||||
|
lowerValueHandle.Update(array->Get(lower));
|
||||||
|
}
|
||||||
|
bool upperExists = (thisHandle->IsTypedArray() || JSTaggedValue::HasProperty(thread, thisObjVal, upperP));
|
||||||
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
|
if (upperExists) {
|
||||||
|
upperValueHandle.Update(array->Get(upper));
|
||||||
|
}
|
||||||
|
if (lowerExists && upperExists) {
|
||||||
|
array->Set(thread, lower, upperValueHandle.GetTaggedValue());
|
||||||
|
array->Set(thread, upper, lowerValueHandle.GetTaggedValue());
|
||||||
|
} else if (upperExists) {
|
||||||
|
array->Set(thread, lower, upperValueHandle.GetTaggedValue());
|
||||||
|
JSTaggedValue::SetProperty(thread, thisObjVal, lowerP, upperValueHandle, true);
|
||||||
|
JSTaggedValue::DeletePropertyOrThrow(thread, thisObjVal, upperP);
|
||||||
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
|
} else if (lowerExists) {
|
||||||
|
array->Set(thread, upper, lowerValueHandle.GetTaggedValue());
|
||||||
|
JSTaggedValue::SetProperty(thread, thisObjVal, upperP, lowerValueHandle, true);
|
||||||
|
JSTaggedValue::DeletePropertyOrThrow(thread, thisObjVal, lowerP);
|
||||||
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
|
}
|
||||||
|
lower++;
|
||||||
|
}
|
||||||
|
return base::BuiltinsBase::GetTaggedDouble(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSTaggedValue JSStableArray::Concat(JSThread *thread, JSHandle<JSObject> newArrayHandle,
|
||||||
|
JSHandle<JSObject> thisObjHandle, double &k, double &n)
|
||||||
|
{
|
||||||
|
JSHandle<JSTaggedValue> thisObjVal(thisObjHandle);
|
||||||
|
double thisLen = base::ArrayHelper::GetArrayLength(thread, thisObjVal);
|
||||||
|
JSHandle<TaggedArray> arrayFrom(thread, thisObjHandle->GetElements());
|
||||||
|
JSMutableHandle<JSTaggedValue> toKey(thread, JSTaggedValue::Undefined());
|
||||||
|
while (k < thisLen) {
|
||||||
|
if (arrayFrom->GetLength() != thisLen) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
toKey.Update(JSTaggedValue(n));
|
||||||
|
JSTaggedValue kValue = arrayFrom->Get(k);
|
||||||
|
if (!kValue.IsHole()) {
|
||||||
|
JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, toKey, JSHandle<JSTaggedValue>(thread, kValue));
|
||||||
|
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||||
|
}
|
||||||
|
n++;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
return base::BuiltinsBase::GetTaggedDouble(true);
|
||||||
|
}
|
||||||
} // namespace panda::ecmascript
|
} // namespace panda::ecmascript
|
||||||
|
@ -42,6 +42,14 @@ public:
|
|||||||
JSHandle<JSTaggedValue> thisArgHandle, uint32_t &k);
|
JSHandle<JSTaggedValue> thisArgHandle, uint32_t &k);
|
||||||
static JSTaggedValue IndexOf(JSThread *thread, JSHandle<JSTaggedValue> receiver,
|
static JSTaggedValue IndexOf(JSThread *thread, JSHandle<JSTaggedValue> receiver,
|
||||||
JSHandle<JSTaggedValue> searchElement, uint32_t from, uint32_t len);
|
JSHandle<JSTaggedValue> searchElement, uint32_t from, uint32_t len);
|
||||||
|
static JSTaggedValue Filter(JSHandle<JSObject> newArrayHandle, JSHandle<JSObject> thisObjHandle,
|
||||||
|
EcmaRuntimeCallInfo *argv, uint32_t &k, double &toIndex);
|
||||||
|
static JSTaggedValue Map(JSHandle<JSObject> newArrayHandle, JSHandle<JSObject> thisObjHandle,
|
||||||
|
EcmaRuntimeCallInfo *argv, uint32_t &k, uint32_t len);
|
||||||
|
static JSTaggedValue Reverse(JSThread *thread, JSHandle<JSObject> thisObjHandle,
|
||||||
|
JSHandle<JSTaggedValue> thisHandle, double &lower, uint32_t len);
|
||||||
|
static JSTaggedValue Concat(JSThread *thread, JSHandle<JSObject> newArrayHandle,
|
||||||
|
JSHandle<JSObject> thisObjHandle, double &k, double &n);
|
||||||
};
|
};
|
||||||
} // namespace panda::ecmascript
|
} // namespace panda::ecmascript
|
||||||
#endif // ECMASCRIPT_JS_STABLE_ARRAY_H
|
#endif // ECMASCRIPT_JS_STABLE_ARRAY_H
|
||||||
|
Loading…
Reference in New Issue
Block a user