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());
|
||||
}
|
||||
double k = 0;
|
||||
if (thisObjVal->IsStableJSArray(thread)) {
|
||||
JSStableArray::Concat(thread, newArrayHandle, thisObjHandle, k, n);
|
||||
}
|
||||
while (k < thisLen) {
|
||||
fromKey.Update(JSTaggedValue(k));
|
||||
toKey.Update(JSTaggedValue(n));
|
||||
@ -474,6 +477,10 @@ JSTaggedValue BuiltinsArray::Concat(EcmaRuntimeCallInfo *argv)
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "out of range.", JSTaggedValue::Exception());
|
||||
}
|
||||
double k = 0;
|
||||
JSHandle<JSTaggedValue> addObjVal(addObjHandle);
|
||||
if (addObjVal->IsStableJSArray(thread)) {
|
||||
JSStableArray::Concat(thread, newArrayHandle, addObjHandle, k, n);
|
||||
}
|
||||
// v. Repeat, while k < len
|
||||
while (k < len) {
|
||||
fromKey.Update(JSTaggedValue(k));
|
||||
@ -880,6 +887,12 @@ JSTaggedValue BuiltinsArray::Filter(EcmaRuntimeCallInfo *argv)
|
||||
JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<JSTaggedValue> toIndexHandle(thread, JSTaggedValue::Undefined());
|
||||
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) {
|
||||
bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, k);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
@ -887,16 +900,12 @@ JSTaggedValue BuiltinsArray::Filter(EcmaRuntimeCallInfo *argv)
|
||||
JSHandle<JSTaggedValue> kValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, k);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
key.Update(JSTaggedValue(k));
|
||||
const int32_t argsLength = 3; // 3: «kValue, k, O»
|
||||
JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
|
||||
EcmaRuntimeCallInfo *info =
|
||||
EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
info->SetCallArg(kValue.GetTaggedValue(), key.GetTaggedValue(), thisObjVal.GetTaggedValue());
|
||||
JSTaggedValue callResult = JSFunction::Call(info);
|
||||
bool boolResult = callResult.ToBoolean();
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
if (boolResult) {
|
||||
callResult = JSFunction::Call(info);
|
||||
if (callResult.ToBoolean()) {
|
||||
toIndexHandle.Update(JSTaggedValue(toIndex));
|
||||
JSObject::CreateDataPropertyOrThrow(thread, newArrayHandle, toIndexHandle, kValue);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
@ -1425,9 +1434,14 @@ JSTaggedValue BuiltinsArray::Map(EcmaRuntimeCallInfo *argv)
|
||||
// v. Let status be CreateDataPropertyOrThrow (A, Pk, mappedValue).
|
||||
// vi. ReturnIfAbrupt(status).
|
||||
// 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> 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) {
|
||||
bool exists = JSTaggedValue::HasProperty(thread, thisObjVal, k);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
@ -1435,8 +1449,6 @@ JSTaggedValue BuiltinsArray::Map(EcmaRuntimeCallInfo *argv)
|
||||
JSHandle<JSTaggedValue> kValue = JSArray::FastGetPropertyByValue(thread, thisObjVal, k);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
key.Update(JSTaggedValue(k));
|
||||
const int32_t argsLength = 3; // 3: «kValue, k, O»
|
||||
JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
|
||||
EcmaRuntimeCallInfo *info =
|
||||
EcmaInterpreter::NewRuntimeCallInfo(thread, callbackFnHandle, thisArgHandle, undefined, argsLength);
|
||||
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
|
||||
@ -1839,6 +1851,9 @@ JSTaggedValue BuiltinsArray::Reverse(EcmaRuntimeCallInfo *argv)
|
||||
JSMutableHandle<JSTaggedValue> upperP(thread, JSTaggedValue::Undefined());
|
||||
JSHandle<JSTaggedValue> lowerValueHandle(thread, JSTaggedValue::Undefined());
|
||||
JSHandle<JSTaggedValue> upperValueHandle(thread, JSTaggedValue::Undefined());
|
||||
if (thisObjVal->IsStableJSArray(thread)) {
|
||||
JSStableArray::Reverse(thread, thisObjHandle, thisHandle, lower, len);
|
||||
}
|
||||
while (lower != middle) {
|
||||
double upper = len - lower - 1;
|
||||
lowerP.Update(JSTaggedValue(lower));
|
||||
|
@ -420,4 +420,153 @@ JSTaggedValue JSStableArray::IndexOf(JSThread *thread, JSHandle<JSTaggedValue> r
|
||||
}
|
||||
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
|
||||
|
@ -42,6 +42,14 @@ public:
|
||||
JSHandle<JSTaggedValue> thisArgHandle, uint32_t &k);
|
||||
static JSTaggedValue IndexOf(JSThread *thread, JSHandle<JSTaggedValue> receiver,
|
||||
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
|
||||
#endif // ECMASCRIPT_JS_STABLE_ARRAY_H
|
||||
|
Loading…
Reference in New Issue
Block a user