14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_BUILTINS_BUILTINS_ARRAYBUFFER_H
174514f5e3Sopenharmony_ci#define ECMASCRIPT_BUILTINS_BUILTINS_ARRAYBUFFER_H
184514f5e3Sopenharmony_ci
194514f5e3Sopenharmony_ci#include "ecmascript/base/builtins_base.h"
204514f5e3Sopenharmony_ci#include "ecmascript/base/number_helper.h"
214514f5e3Sopenharmony_ci#include "ecmascript/js_dataview.h"
224514f5e3Sopenharmony_ci#include "ecmascript/js_typed_array.h"
234514f5e3Sopenharmony_ci
244514f5e3Sopenharmony_ci// List of functions in ArrayBuffer, excluding the '@@' properties.
254514f5e3Sopenharmony_ci// V(name, func, length, stubIndex)
264514f5e3Sopenharmony_ci// where BuiltinsArrayBuffer::func refers to the native implementation of ArrayBuffer[name].
274514f5e3Sopenharmony_ci//       kungfu::BuiltinsStubCSigns::stubIndex refers to the builtin stub index, or INVALID if no stub available.
284514f5e3Sopenharmony_ci#define BUILTIN_ARRAY_BUFFER_FUNCTIONS(V)                                           \
294514f5e3Sopenharmony_ci    /* ArrayBuffer.isView ( arg ) */                                                \
304514f5e3Sopenharmony_ci    V("isView", IsView, 1, ArrayBufferIsView)
314514f5e3Sopenharmony_ci
324514f5e3Sopenharmony_cinamespace panda::ecmascript::builtins {
334514f5e3Sopenharmony_cistatic constexpr double NUMBER_HALF = 0.5;
344514f5e3Sopenharmony_cistatic constexpr uint32_t BITS_MASK_FF = 0xFF;
354514f5e3Sopenharmony_cistatic constexpr uint32_t BITS_EIGHT = 8;
364514f5e3Sopenharmony_cistatic constexpr uint32_t BITS_TWENTY_FOUR = 24;
374514f5e3Sopenharmony_cistatic constexpr uint32_t BITS_FORTY = 40;
384514f5e3Sopenharmony_cistatic constexpr uint32_t BITS_FIFTY_SIX = 56;
394514f5e3Sopenharmony_cistatic constexpr uint32_t BITS_THIRTY_ONE = 31;
404514f5e3Sopenharmony_ciusing DataViewType = ecmascript::DataViewType;
414514f5e3Sopenharmony_ciunion UnionType32 {
424514f5e3Sopenharmony_ci    uint32_t uValue;
434514f5e3Sopenharmony_ci    float value;
444514f5e3Sopenharmony_ci};
454514f5e3Sopenharmony_ciunion UnionType64 {
464514f5e3Sopenharmony_ci    uint64_t uValue;
474514f5e3Sopenharmony_ci    double value;
484514f5e3Sopenharmony_ci};
494514f5e3Sopenharmony_ciclass BuiltinsArrayBuffer : public base::BuiltinsBase {
504514f5e3Sopenharmony_cipublic:
514514f5e3Sopenharmony_ci    enum NumberSize : uint8_t {
524514f5e3Sopenharmony_ci        UINT16 = 2, INT16 = 2, UINT32 = 4, INT32 = 4, FLOAT32 = 4, FLOAT64 = 8, BIGINT64 = 8, BIGUINT64 = 8
534514f5e3Sopenharmony_ci    };
544514f5e3Sopenharmony_ci
554514f5e3Sopenharmony_ci    // 24.1.2.1 ArrayBuffer(length)
564514f5e3Sopenharmony_ci    static JSTaggedValue ArrayBufferConstructor(EcmaRuntimeCallInfo *argv);
574514f5e3Sopenharmony_ci    // 24.1.3.1 ArrayBuffer.isView(arg)
584514f5e3Sopenharmony_ci    static JSTaggedValue IsView(EcmaRuntimeCallInfo *argv);
594514f5e3Sopenharmony_ci    // 24.1.3.3 get ArrayBuffer[@@species]
604514f5e3Sopenharmony_ci    static JSTaggedValue Species(EcmaRuntimeCallInfo *argv);
614514f5e3Sopenharmony_ci    // 24.1.4.1 get ArrayBuffer.prototype.byteLength
624514f5e3Sopenharmony_ci    static JSTaggedValue GetByteLength(EcmaRuntimeCallInfo *argv);
634514f5e3Sopenharmony_ci    // 24.1.4.3 ArrayBuffer.prototype.slice()
644514f5e3Sopenharmony_ci    static JSTaggedValue Slice(EcmaRuntimeCallInfo *argv);
654514f5e3Sopenharmony_ci    // 24.1.1.2 IsDetachedBuffer(arrayBuffer)
664514f5e3Sopenharmony_ci    static void IsDetachedBuffer(JSThread *thread, const JSHandle<JSTypedArray> &arrayBuffer);
674514f5e3Sopenharmony_ci    static bool IsDetachedBuffer(JSTaggedValue arrayBuffer);
684514f5e3Sopenharmony_ci    // 24.1.1.5 GetValueFromBuffer ( arrayBuffer, byteIndex, type, isLittleEndian )
694514f5e3Sopenharmony_ci    static JSTaggedValue GetValueFromBuffer(JSThread *thread, JSTaggedValue arrBuf, uint32_t byteIndex,
704514f5e3Sopenharmony_ci                                            DataViewType type, bool littleEndian);
714514f5e3Sopenharmony_ci    // 24.1.1.6 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isLittleEndian )
724514f5e3Sopenharmony_ci    static JSTaggedValue SetValueInBuffer(JSThread *thread, JSTaggedValue arrBuf, uint32_t byteIndex,
734514f5e3Sopenharmony_ci                                          DataViewType type, const JSHandle<JSTaggedValue> &value, bool littleEndian);
744514f5e3Sopenharmony_ci    // 24.1.1.4 CloneArrayBuffer( srcBuffer, srcByteOffset [, cloneConstructor] )
754514f5e3Sopenharmony_ci    static JSTaggedValue CloneArrayBuffer(JSThread *thread, const JSHandle<JSTaggedValue> &srcBuffer,
764514f5e3Sopenharmony_ci                                          uint32_t srcByteOffset, JSHandle<JSTaggedValue> constructor);
774514f5e3Sopenharmony_ci    // 24.1.1.1 AllocateArrayBuffer(constructor, byteLength)
784514f5e3Sopenharmony_ci    static JSTaggedValue AllocateArrayBuffer(JSThread *thread, const JSHandle<JSTaggedValue> &newTarget,
794514f5e3Sopenharmony_ci                                             uint64_t byteLength);
804514f5e3Sopenharmony_ci    // es12 25.1.2.6 IsUnclampedIntegerElementType ( type )
814514f5e3Sopenharmony_ci    static bool IsUnclampedIntegerElementType(DataViewType type);
824514f5e3Sopenharmony_ci    // es12 25.1.2.7 IsBigIntElementType ( type )
834514f5e3Sopenharmony_ci    static bool IsBigIntElementType(DataViewType type);
844514f5e3Sopenharmony_ci
854514f5e3Sopenharmony_ci    // Excluding the '@@' internal properties
864514f5e3Sopenharmony_ci    static Span<const base::BuiltinFunctionEntry> GetArrayBufferFunctions()
874514f5e3Sopenharmony_ci    {
884514f5e3Sopenharmony_ci        return Span<const base::BuiltinFunctionEntry>(ARRAY_BUFFER_FUNCTIONS);
894514f5e3Sopenharmony_ci    }
904514f5e3Sopenharmony_ci
914514f5e3Sopenharmony_ci    static JSTaggedValue FastSetValueInBuffer(JSThread* thread, JSTaggedValue arrBuf, uint32_t byteIndex,
924514f5e3Sopenharmony_ci                                              DataViewType type, double val, bool littleEndian);
934514f5e3Sopenharmony_ci    static JSTaggedValue TryFastSetValueInBuffer(JSThread *thread, JSTaggedValue arrBuf, uint32_t byteBeginOffset,
944514f5e3Sopenharmony_ci                                                 uint32_t byteEndOffset, DataViewType type,
954514f5e3Sopenharmony_ci                                                 double val, bool littleEndian);
964514f5e3Sopenharmony_ci    template<typename T>
974514f5e3Sopenharmony_ci    static void FastSetValueInBufferForByte(uint8_t *byteBeginOffset, uint8_t *byteEndOffset,
984514f5e3Sopenharmony_ci                                            double val);
994514f5e3Sopenharmony_ci    static void FastSetValueInBufferForUint8Clamped(uint8_t *byteBeginOffset, uint8_t *byteEndOffset,
1004514f5e3Sopenharmony_ci                                                    double val);
1014514f5e3Sopenharmony_ci    template<typename T>
1024514f5e3Sopenharmony_ci    static void FastSetValueInBufferForInteger(uint8_t *byteBeginOffset, uint8_t *byteEndOffset,
1034514f5e3Sopenharmony_ci                                               double val, bool littleEndian);
1044514f5e3Sopenharmony_ci    template<typename T>
1054514f5e3Sopenharmony_ci    static void FastSetValueInBufferForFloat(uint8_t *byteBeginOffset, uint8_t *byteEndOffset,
1064514f5e3Sopenharmony_ci                                             double val, bool littleEndian);
1074514f5e3Sopenharmony_ci    template<typename T>
1084514f5e3Sopenharmony_ci    static void FastSetValueInBufferForBigInt(JSThread *thread, uint8_t *byteBeginOffset, uint8_t *byteEndOffset,
1094514f5e3Sopenharmony_ci                                              double val, bool littleEndian);
1104514f5e3Sopenharmony_ci    static JSTaggedValue SetValueInBuffer(JSThread *thread, uint32_t byteIndex, uint8_t *block,
1114514f5e3Sopenharmony_ci                                          DataViewType type, double val, bool littleEndian);
1124514f5e3Sopenharmony_ci    static JSTaggedValue GetValueFromBuffer(JSThread *thread, uint32_t byteIndex, uint8_t *block,
1134514f5e3Sopenharmony_ci                                            DataViewType type, bool littleEndian);
1144514f5e3Sopenharmony_ci    static void *GetDataPointFromBuffer(JSTaggedValue arrBuf, uint32_t byteOffset = 0);
1154514f5e3Sopenharmony_ci
1164514f5e3Sopenharmony_ciprotected:
1174514f5e3Sopenharmony_ci    static constexpr uint64_t MAX_NATIVE_SIZE_LIMIT = 4_GB;
1184514f5e3Sopenharmony_ci    static constexpr char const *NATIVE_SIZE_OUT_OF_LIMIT_MESSAGE = "total array buffer size out of limit(4_GB)";
1194514f5e3Sopenharmony_ci
1204514f5e3Sopenharmony_ciprivate:
1214514f5e3Sopenharmony_ci#define BUILTIN_ARRAY_BUFFER_ENTRY(name, func, length, id)                                                             \
1224514f5e3Sopenharmony_ci    base::BuiltinFunctionEntry::Create((name), (BuiltinsArrayBuffer::func), (length), (kungfu::BuiltinsStubCSigns::id)),
1234514f5e3Sopenharmony_ci
1244514f5e3Sopenharmony_ci    static constexpr std::array ARRAY_BUFFER_FUNCTIONS = {BUILTIN_ARRAY_BUFFER_FUNCTIONS(BUILTIN_ARRAY_BUFFER_ENTRY)};
1254514f5e3Sopenharmony_ci#undef BUILTIN_ARRAY_BUFFER_ENTRY
1264514f5e3Sopenharmony_ci
1274514f5e3Sopenharmony_ci    template <typename T>
1284514f5e3Sopenharmony_ci    static T LittleEndianToBigEndian(T liValue);
1294514f5e3Sopenharmony_ci    template<typename T>
1304514f5e3Sopenharmony_ci    static T LittleEndianToBigEndian64Bit(T liValue);
1314514f5e3Sopenharmony_ci
1324514f5e3Sopenharmony_ci    template<typename T>
1334514f5e3Sopenharmony_ci    static void SetTypeData(uint8_t *block, T value, uint32_t index);
1344514f5e3Sopenharmony_ci
1354514f5e3Sopenharmony_ci    template<typename T>
1364514f5e3Sopenharmony_ci    static void FastSetTypeData(uint8_t *byteBeginOffset, uint8_t *byteEndOffset, T value);
1374514f5e3Sopenharmony_ci
1384514f5e3Sopenharmony_ci    template<typename T, NumberSize size>
1394514f5e3Sopenharmony_ci    static JSTaggedValue GetValueFromBufferForInteger(uint8_t *block, uint32_t byteIndex, bool littleEndian);
1404514f5e3Sopenharmony_ci
1414514f5e3Sopenharmony_ci    template<typename T, typename UnionType, NumberSize size>
1424514f5e3Sopenharmony_ci    static JSTaggedValue GetValueFromBufferForFloat(uint8_t *block, uint32_t byteIndex, bool littleEndian);
1434514f5e3Sopenharmony_ci    template<typename T1, typename T2>
1444514f5e3Sopenharmony_ci    static JSTaggedValue CommonConvert(T1 &value, T2 &res, bool littleEndian);
1454514f5e3Sopenharmony_ci    template<typename T, NumberSize size>
1464514f5e3Sopenharmony_ci    static JSTaggedValue GetValueFromBufferForBigInt(JSThread *thread, uint8_t *block,
1474514f5e3Sopenharmony_ci                                                     uint32_t byteIndex, bool littleEndian);
1484514f5e3Sopenharmony_ci
1494514f5e3Sopenharmony_ci    template<typename T>
1504514f5e3Sopenharmony_ci    static void SetValueInBufferForByte(double val, uint8_t *block, uint32_t byteIndex);
1514514f5e3Sopenharmony_ci
1524514f5e3Sopenharmony_ci    static void SetValueInBufferForUint8Clamped(double val, uint8_t *block, uint32_t byteIndex);
1534514f5e3Sopenharmony_ci
1544514f5e3Sopenharmony_ci    template<typename T>
1554514f5e3Sopenharmony_ci    static void SetValueInBufferForInteger(double val, uint8_t *block, uint32_t byteIndex, bool littleEndian);
1564514f5e3Sopenharmony_ci
1574514f5e3Sopenharmony_ci    template<typename T>
1584514f5e3Sopenharmony_ci    static void SetValueInBufferForFloat(double val, uint8_t *block, uint32_t byteIndex, bool littleEndian);
1594514f5e3Sopenharmony_ci
1604514f5e3Sopenharmony_ci    template<typename T>
1614514f5e3Sopenharmony_ci    static void SetValueInBufferForBigInt(JSThread *thread, const JSHandle<JSTaggedValue> &val,
1624514f5e3Sopenharmony_ci                                          JSHandle<JSTaggedValue> &arrBuf, uint32_t byteIndex, bool littleEndian);
1634514f5e3Sopenharmony_ci
1644514f5e3Sopenharmony_ci    template<typename T>
1654514f5e3Sopenharmony_ci    static void SetValueInBufferForBigInt(JSThread *thread, double val,
1664514f5e3Sopenharmony_ci                                          uint8_t *block, uint32_t byteIndex, bool littleEndian);
1674514f5e3Sopenharmony_ci
1684514f5e3Sopenharmony_ci    static JSTaggedValue TypedArrayToList(JSThread *thread, JSHandle<JSTypedArray>& items);
1694514f5e3Sopenharmony_ci
1704514f5e3Sopenharmony_ci    friend class BuiltinsArray;
1714514f5e3Sopenharmony_ci    friend class BuiltinsSharedArray;
1724514f5e3Sopenharmony_ci};
1734514f5e3Sopenharmony_ci}  // namespace panda::ecmascript::builtins
1744514f5e3Sopenharmony_ci
1754514f5e3Sopenharmony_ci#endif  // ECMASCRIPT_BUILTINS_BUILTINS_ARRAYBUFFER_H
176