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_BUILTINS_BUILTINS_ARRAYBUFFER_H 17 #define ECMASCRIPT_BUILTINS_BUILTINS_ARRAYBUFFER_H 18 19 #include "ecmascript/base/builtins_base.h" 20 #include "ecmascript/base/number_helper.h" 21 #include "ecmascript/js_dataview.h" 22 #include "ecmascript/js_typed_array.h" 23 24 namespace panda::ecmascript::builtins { 25 static constexpr double NUMBER_HALF = 0.5; 26 static constexpr uint32_t BITS_EIGHT = 8; 27 static constexpr uint32_t BITS_TWENTY_FOUR = 24; 28 static constexpr uint32_t BITS_FORTY = 40; 29 static constexpr uint32_t BITS_FIFTY_SIX = 56; 30 static constexpr uint32_t BITS_THIRTY_ONE = 31; 31 using DataViewType = ecmascript::DataViewType; 32 union UnionType32 { 33 uint32_t uValue; 34 float value; 35 }; 36 union UnionType64 { 37 uint64_t uValue; 38 double value; 39 }; 40 class BuiltinsArrayBuffer : public base::BuiltinsBase { 41 public: 42 enum NumberSize : uint8_t { 43 UINT16 = 2, INT16 = 2, UINT32 = 4, INT32 = 4, FLOAT32 = 4, FLOAT64 = 8, BIGINT64 = 8, BIGUINT64 = 8 44 }; 45 46 // 24.1.2.1 ArrayBuffer(length) 47 static JSTaggedValue ArrayBufferConstructor(EcmaRuntimeCallInfo *argv); 48 // 24.1.3.1 ArrayBuffer.isView(arg) 49 static JSTaggedValue IsView(EcmaRuntimeCallInfo *argv); 50 // 24.1.3.3 get ArrayBuffer[@@species] 51 static JSTaggedValue Species(EcmaRuntimeCallInfo *argv); 52 // 24.1.4.1 get ArrayBuffer.prototype.byteLength 53 static JSTaggedValue GetByteLength(EcmaRuntimeCallInfo *argv); 54 // 24.1.4.3 ArrayBuffer.prototype.slice() 55 static JSTaggedValue Slice(EcmaRuntimeCallInfo *argv); 56 // 24.1.1.2 IsDetachedBuffer(arrayBuffer) 57 static bool IsDetachedBuffer(JSTaggedValue arrayBuffer); 58 // 24.1.1.5 GetValueFromBuffer ( arrayBuffer, byteIndex, type, isLittleEndian ) 59 static JSTaggedValue GetValueFromBuffer(JSThread *thread, JSTaggedValue arrBuf, uint32_t byteIndex, 60 DataViewType type, bool littleEndian); 61 // 24.1.1.6 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isLittleEndian ) 62 static JSTaggedValue SetValueInBuffer(JSThread *thread, JSTaggedValue arrBuf, uint32_t byteIndex, 63 DataViewType type, const JSHandle<JSTaggedValue> &value, bool littleEndian); 64 // 24.1.1.4 CloneArrayBuffer( srcBuffer, srcByteOffset [, cloneConstructor] ) 65 static JSTaggedValue CloneArrayBuffer(JSThread *thread, const JSHandle<JSTaggedValue> &srcBuffer, 66 uint32_t srcByteOffset, JSHandle<JSTaggedValue> constructor); 67 // 24.1.1.1 AllocateArrayBuffer(constructor, byteLength) 68 static JSTaggedValue AllocateArrayBuffer(JSThread *thread, const JSHandle<JSTaggedValue> &newTarget, 69 uint64_t byteLength); 70 // es12 25.1.2.6 IsUnclampedIntegerElementType ( type ) 71 static bool IsUnclampedIntegerElementType(DataViewType type); 72 // es12 25.1.2.7 IsBigIntElementType ( type ) 73 static bool IsBigIntElementType(DataViewType type); 74 75 static JSTaggedValue FastSetValueInBuffer(JSThread* thread, JSTaggedValue arrBuf, uint32_t byteIndex, 76 DataViewType type, double val, bool littleEndian); 77 static JSTaggedValue TryFastSetValueInBuffer(JSThread *thread, JSTaggedValue arrBuf, uint32_t byteBeginOffset, 78 uint32_t byteEndOffset, DataViewType type, 79 double val, bool littleEndian); 80 template<typename T> 81 static void FastSetValueInBufferForByte(uint8_t *byteBeginOffset, uint8_t *byteEndOffset, 82 double val); 83 static void FastSetValueInBufferForUint8Clamped(uint8_t *byteBeginOffset, uint8_t *byteEndOffset, 84 double val); 85 template<typename T> 86 static void FastSetValueInBufferForInteger(uint8_t *byteBeginOffset, uint8_t *byteEndOffset, 87 double val, bool littleEndian); 88 template<typename T> 89 static void FastSetValueInBufferForFloat(uint8_t *byteBeginOffset, uint8_t *byteEndOffset, 90 double val, bool littleEndian); 91 template<typename T> 92 static void FastSetValueInBufferForBigInt(JSThread *thread, uint8_t *byteBeginOffset, uint8_t *byteEndOffset, 93 double val, bool littleEndian); 94 static JSTaggedValue SetValueInBuffer(JSThread *thread, uint32_t byteIndex, uint8_t *block, 95 DataViewType type, double val, bool littleEndian); 96 static JSTaggedValue GetValueFromBuffer(JSThread *thread, uint32_t byteIndex, uint8_t *block, 97 DataViewType type, bool littleEndian); 98 static void *GetDataPointFromBuffer(JSTaggedValue arrBuf, uint32_t byteOffset = 0); 99 100 private: 101 template <typename T> 102 static T LittleEndianToBigEndian(T liValue); 103 template<typename T> 104 static T LittleEndianToBigEndian64Bit(T liValue); 105 106 template<typename T> 107 static void SetTypeData(uint8_t *block, T value, uint32_t index); 108 109 template<typename T> 110 static void FastSetTypeData(uint8_t *byteBeginOffset, uint8_t *byteEndOffset, T value); 111 112 template<typename T, NumberSize size> 113 static JSTaggedValue GetValueFromBufferForInteger(uint8_t *block, uint32_t byteIndex, bool littleEndian); 114 115 template<typename T, typename UnionType, NumberSize size> 116 static JSTaggedValue GetValueFromBufferForFloat(uint8_t *block, uint32_t byteIndex, bool littleEndian); 117 template<typename T1, typename T2> 118 static JSTaggedValue CommonConvert(T1 &value, T2 &res, bool littleEndian); 119 template<typename T, NumberSize size> 120 static JSTaggedValue GetValueFromBufferForBigInt(JSThread *thread, uint8_t *block, 121 uint32_t byteIndex, bool littleEndian); 122 123 template<typename T> 124 static void SetValueInBufferForByte(double val, uint8_t *block, uint32_t byteIndex); 125 126 static void SetValueInBufferForUint8Clamped(double val, uint8_t *block, uint32_t byteIndex); 127 128 template<typename T> 129 static void SetValueInBufferForInteger(double val, uint8_t *block, uint32_t byteIndex, bool littleEndian); 130 131 template<typename T> 132 static void SetValueInBufferForFloat(double val, uint8_t *block, uint32_t byteIndex, bool littleEndian); 133 134 template<typename T> 135 static void SetValueInBufferForBigInt(JSThread *thread, const JSHandle<JSTaggedValue> &val, 136 JSHandle<JSTaggedValue> &arrBuf, uint32_t byteIndex, bool littleEndian); 137 138 template<typename T> 139 static void SetValueInBufferForBigInt(JSThread *thread, double val, 140 uint8_t *block, uint32_t byteIndex, bool littleEndian); 141 142 static JSTaggedValue TypedArrayToList(JSThread *thread, JSHandle<JSTypedArray>& items); 143 144 friend class BuiltinsArray; 145 }; 146 } // namespace panda::ecmascript::builtins 147 148 #endif // ECMASCRIPT_BUILTINS_BUILTINS_ARRAYBUFFER_H 149