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 // List of functions in ArrayBuffer, excluding the '@@' properties. 25 // V(name, func, length, stubIndex) 26 // where BuiltinsArrayBuffer::func refers to the native implementation of ArrayBuffer[name]. 27 // kungfu::BuiltinsStubCSigns::stubIndex refers to the builtin stub index, or INVALID if no stub available. 28 #define BUILTIN_ARRAY_BUFFER_FUNCTIONS(V) \ 29 /* ArrayBuffer.isView ( arg ) */ \ 30 V("isView", IsView, 1, ArrayBufferIsView) 31 32 namespace panda::ecmascript::builtins { 33 static constexpr double NUMBER_HALF = 0.5; 34 static constexpr uint32_t BITS_MASK_FF = 0xFF; 35 static constexpr uint32_t BITS_EIGHT = 8; 36 static constexpr uint32_t BITS_TWENTY_FOUR = 24; 37 static constexpr uint32_t BITS_FORTY = 40; 38 static constexpr uint32_t BITS_FIFTY_SIX = 56; 39 static constexpr uint32_t BITS_THIRTY_ONE = 31; 40 using DataViewType = ecmascript::DataViewType; 41 union UnionType32 { 42 uint32_t uValue; 43 float value; 44 }; 45 union UnionType64 { 46 uint64_t uValue; 47 double value; 48 }; 49 class BuiltinsArrayBuffer : public base::BuiltinsBase { 50 public: 51 enum NumberSize : uint8_t { 52 UINT16 = 2, INT16 = 2, UINT32 = 4, INT32 = 4, FLOAT32 = 4, FLOAT64 = 8, BIGINT64 = 8, BIGUINT64 = 8 53 }; 54 55 // 24.1.2.1 ArrayBuffer(length) 56 static JSTaggedValue ArrayBufferConstructor(EcmaRuntimeCallInfo *argv); 57 // 24.1.3.1 ArrayBuffer.isView(arg) 58 static JSTaggedValue IsView(EcmaRuntimeCallInfo *argv); 59 // 24.1.3.3 get ArrayBuffer[@@species] 60 static JSTaggedValue Species(EcmaRuntimeCallInfo *argv); 61 // 24.1.4.1 get ArrayBuffer.prototype.byteLength 62 static JSTaggedValue GetByteLength(EcmaRuntimeCallInfo *argv); 63 // 24.1.4.3 ArrayBuffer.prototype.slice() 64 static JSTaggedValue Slice(EcmaRuntimeCallInfo *argv); 65 // 24.1.1.2 IsDetachedBuffer(arrayBuffer) 66 static void IsDetachedBuffer(JSThread *thread, const JSHandle<JSTypedArray> &arrayBuffer); 67 static bool IsDetachedBuffer(JSTaggedValue arrayBuffer); 68 // 24.1.1.5 GetValueFromBuffer ( arrayBuffer, byteIndex, type, isLittleEndian ) 69 static JSTaggedValue GetValueFromBuffer(JSThread *thread, JSTaggedValue arrBuf, uint32_t byteIndex, 70 DataViewType type, bool littleEndian); 71 // 24.1.1.6 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isLittleEndian ) 72 static JSTaggedValue SetValueInBuffer(JSThread *thread, JSTaggedValue arrBuf, uint32_t byteIndex, 73 DataViewType type, const JSHandle<JSTaggedValue> &value, bool littleEndian); 74 // 24.1.1.4 CloneArrayBuffer( srcBuffer, srcByteOffset [, cloneConstructor] ) 75 static JSTaggedValue CloneArrayBuffer(JSThread *thread, const JSHandle<JSTaggedValue> &srcBuffer, 76 uint32_t srcByteOffset, JSHandle<JSTaggedValue> constructor); 77 // 24.1.1.1 AllocateArrayBuffer(constructor, byteLength) 78 static JSTaggedValue AllocateArrayBuffer(JSThread *thread, const JSHandle<JSTaggedValue> &newTarget, 79 uint64_t byteLength); 80 // es12 25.1.2.6 IsUnclampedIntegerElementType ( type ) 81 static bool IsUnclampedIntegerElementType(DataViewType type); 82 // es12 25.1.2.7 IsBigIntElementType ( type ) 83 static bool IsBigIntElementType(DataViewType type); 84 85 // Excluding the '@@' internal properties GetArrayBufferFunctions()86 static Span<const base::BuiltinFunctionEntry> GetArrayBufferFunctions() 87 { 88 return Span<const base::BuiltinFunctionEntry>(ARRAY_BUFFER_FUNCTIONS); 89 } 90 91 static JSTaggedValue FastSetValueInBuffer(JSThread* thread, JSTaggedValue arrBuf, uint32_t byteIndex, 92 DataViewType type, double val, bool littleEndian); 93 static JSTaggedValue TryFastSetValueInBuffer(JSThread *thread, JSTaggedValue arrBuf, uint32_t byteBeginOffset, 94 uint32_t byteEndOffset, DataViewType type, 95 double val, bool littleEndian); 96 template<typename T> 97 static void FastSetValueInBufferForByte(uint8_t *byteBeginOffset, uint8_t *byteEndOffset, 98 double val); 99 static void FastSetValueInBufferForUint8Clamped(uint8_t *byteBeginOffset, uint8_t *byteEndOffset, 100 double val); 101 template<typename T> 102 static void FastSetValueInBufferForInteger(uint8_t *byteBeginOffset, uint8_t *byteEndOffset, 103 double val, bool littleEndian); 104 template<typename T> 105 static void FastSetValueInBufferForFloat(uint8_t *byteBeginOffset, uint8_t *byteEndOffset, 106 double val, bool littleEndian); 107 template<typename T> 108 static void FastSetValueInBufferForBigInt(JSThread *thread, uint8_t *byteBeginOffset, uint8_t *byteEndOffset, 109 double val, bool littleEndian); 110 static JSTaggedValue SetValueInBuffer(JSThread *thread, uint32_t byteIndex, uint8_t *block, 111 DataViewType type, double val, bool littleEndian); 112 static JSTaggedValue GetValueFromBuffer(JSThread *thread, uint32_t byteIndex, uint8_t *block, 113 DataViewType type, bool littleEndian); 114 static void *GetDataPointFromBuffer(JSTaggedValue arrBuf, uint32_t byteOffset = 0); 115 116 protected: 117 static constexpr uint64_t MAX_NATIVE_SIZE_LIMIT = 4_GB; 118 static constexpr char const *NATIVE_SIZE_OUT_OF_LIMIT_MESSAGE = "total array buffer size out of limit(4_GB)"; 119 120 private: 121 #define BUILTIN_ARRAY_BUFFER_ENTRY(name, func, length, id) \ 122 base::BuiltinFunctionEntry::Create((name), (BuiltinsArrayBuffer::func), (length), (kungfu::BuiltinsStubCSigns::id)), 123 124 static constexpr std::array ARRAY_BUFFER_FUNCTIONS = {BUILTIN_ARRAY_BUFFER_FUNCTIONS(BUILTIN_ARRAY_BUFFER_ENTRY)}; 125 #undef BUILTIN_ARRAY_BUFFER_ENTRY 126 127 template <typename T> 128 static T LittleEndianToBigEndian(T liValue); 129 template<typename T> 130 static T LittleEndianToBigEndian64Bit(T liValue); 131 132 template<typename T> 133 static void SetTypeData(uint8_t *block, T value, uint32_t index); 134 135 template<typename T> 136 static void FastSetTypeData(uint8_t *byteBeginOffset, uint8_t *byteEndOffset, T value); 137 138 template<typename T, NumberSize size> 139 static JSTaggedValue GetValueFromBufferForInteger(uint8_t *block, uint32_t byteIndex, bool littleEndian); 140 141 template<typename T, typename UnionType, NumberSize size> 142 static JSTaggedValue GetValueFromBufferForFloat(uint8_t *block, uint32_t byteIndex, bool littleEndian); 143 template<typename T1, typename T2> 144 static JSTaggedValue CommonConvert(T1 &value, T2 &res, bool littleEndian); 145 template<typename T, NumberSize size> 146 static JSTaggedValue GetValueFromBufferForBigInt(JSThread *thread, uint8_t *block, 147 uint32_t byteIndex, bool littleEndian); 148 149 template<typename T> 150 static void SetValueInBufferForByte(double val, uint8_t *block, uint32_t byteIndex); 151 152 static void SetValueInBufferForUint8Clamped(double val, uint8_t *block, uint32_t byteIndex); 153 154 template<typename T> 155 static void SetValueInBufferForInteger(double val, uint8_t *block, uint32_t byteIndex, bool littleEndian); 156 157 template<typename T> 158 static void SetValueInBufferForFloat(double val, uint8_t *block, uint32_t byteIndex, bool littleEndian); 159 160 template<typename T> 161 static void SetValueInBufferForBigInt(JSThread *thread, const JSHandle<JSTaggedValue> &val, 162 JSHandle<JSTaggedValue> &arrBuf, uint32_t byteIndex, bool littleEndian); 163 164 template<typename T> 165 static void SetValueInBufferForBigInt(JSThread *thread, double val, 166 uint8_t *block, uint32_t byteIndex, bool littleEndian); 167 168 static JSTaggedValue TypedArrayToList(JSThread *thread, JSHandle<JSTypedArray>& items); 169 170 friend class BuiltinsArray; 171 friend class BuiltinsSharedArray; 172 }; 173 } // namespace panda::ecmascript::builtins 174 175 #endif // ECMASCRIPT_BUILTINS_BUILTINS_ARRAYBUFFER_H 176