1 /* 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ECMASCRIPT_BASE_ARRAY_HELPER_H 17 #define ECMASCRIPT_BASE_ARRAY_HELPER_H 18 19 #include <string> 20 21 #include "ecmascript/base/builtins_base.h" 22 #include "ecmascript/ecma_runtime_call_info.h" 23 #include "ecmascript/js_tagged_value.h" 24 25 namespace panda::ecmascript::base { 26 struct FlattenArgs { 27 int64_t sourceLen = 0; 28 int64_t start = 0; 29 double depth = 0; 30 }; 31 32 enum class HolesType { 33 SKIP_HOLES, 34 READ_THROUGH_HOLES, 35 }; 36 class ArrayHelper { 37 public: 38 // Common subprocedure for Array.prototype.at, Array.prototype.indexOf, Array.prototype.slice, etc. 39 // Gets start index that falls in range [0, length]. 40 // length is returned on pending exception. 41 static int64_t GetStartIndex(JSThread *thread, const JSHandle<JSTaggedValue> &startIndexHandle, 42 int64_t length); 43 // If argIndex is out of range [0, argc), then start index = 0 by default. 44 // Otherwise, let startIndexHandle = GetCallArg(argv, argIndex) and call GetStartIndex. 45 static int64_t GetStartIndexFromArgs(JSThread *thread, EcmaRuntimeCallInfo *argv, 46 uint32_t argIndex, int64_t length); 47 // Common subprocedure for Array.prototype.lastIndexOf, etc. 48 // Gets last start index that falls in range [-1, length - 1]. 49 // -1 is returned on pending exception. 50 static int64_t GetLastStartIndex(JSThread *thread, const JSHandle<JSTaggedValue> &startIndexHandle, 51 int64_t length); 52 // If argIndex is out of range [0, argc), then start index = length - 1 by default. 53 // Otherwise, let startIndexHandle = GetCallArg(argv, argIndex) and call GetLastStartIndex. 54 static int64_t GetLastStartIndexFromArgs(JSThread *thread, EcmaRuntimeCallInfo *argv, 55 uint32_t argIndex, int64_t length); 56 // Let thisHandle be the array object. Checks whether array[key] (if exists) is strictly equal to target. 57 // Returns false on pending exception. 58 static bool ElementIsStrictEqualTo(JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle, 59 const JSHandle<JSTaggedValue> &keyHandle, 60 const JSHandle<JSTaggedValue> &target); 61 62 static bool IsConcatSpreadable(JSThread *thread, const JSHandle<JSTaggedValue> &obj); 63 static double SortCompare(JSThread *thread, const JSHandle<JSTaggedValue> &callbackfnHandle, 64 const JSHandle<JSTaggedValue> &valueX, const JSHandle<JSTaggedValue> &valueY); 65 static double StringSortCompare(JSThread *thread, const JSHandle<JSTaggedValue> &valueX, 66 const JSHandle<JSTaggedValue> &valueY); 67 static int64_t GetLength(JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle); 68 static int64_t GetArrayLength(JSThread *thread, const JSHandle<JSTaggedValue> &thisHandle); 69 static JSTaggedValue FlattenIntoArray(JSThread *thread, const JSHandle<JSObject> &newArrayHandle, 70 const JSHandle<JSTaggedValue> &thisObjVal, const FlattenArgs &args, 71 const JSHandle<JSTaggedValue> &mapperFunctionHandle, 72 const JSHandle<JSTaggedValue> &thisArg); 73 static JSHandle<TaggedArray> SortIndexedProperties(JSThread *thread, const JSHandle<JSTaggedValue> &thisObj, 74 int64_t len, const JSHandle<JSTaggedValue> &callbackFnHandle, 75 HolesType holes); 76 }; 77 } // namespace panda::ecmascript::base 78 79 #endif // ECMASCRIPT_BASE_ARRAY_HELPER_H 80