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