1 /* 2 * Copyright (c) 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_ATOMICS_H 17 #define ECMASCRIPT_BUILTINS_BUILTINS_ATOMICS_H 18 19 #include "ecmascript/base/builtins_base.h" 20 #include "ecmascript/js_dataview.h" 21 #include "ecmascript/waiter_list.h" 22 23 // List of functions in Atomics. 24 // V(name, func, length, stubIndex) 25 // where BuiltinsAtomics::func refers to the native implementation of Atomics[name]. 26 // kungfu::BuiltinsStubCSigns::stubIndex refers to the builtin stub index, or INVALID if no stub available. 27 // The following functions are not implemented yet: 28 // - Atomics.waitAsync ( typedArray, index, value, timeout ) 29 #define BUILTIN_ATOMICS_FUNCTIONS(V) \ 30 /* Atomics.add ( typedArray, index, value ) */ \ 31 V("add", Add, 3, INVALID) \ 32 /* Atomics.and ( typedArray, index, value ) */ \ 33 V("and", And, 3, INVALID) \ 34 /* Atomics.compareExchange ( typedArray, index, expectedValue, replacementValue ) */ \ 35 V("compareExchange", CompareExchange, 4, INVALID) \ 36 /* Atomics.exchange ( typedArray, index, value ) */ \ 37 V("exchange", Exchange, 3, INVALID) \ 38 /* Atomics.isLockFree ( size ) */ \ 39 V("isLockFree", IsLockFree, 1, INVALID) \ 40 /* Atomics.load ( typedArray, index ) */ \ 41 V("load", Load, 2, INVALID) \ 42 /* Atomics.notify ( typedArray, index, count ) */ \ 43 V("notify", Notify, 3, INVALID) \ 44 /* Atomics.or ( typedArray, index, value ) */ \ 45 V("or", Or, 3, INVALID) \ 46 /* Atomics.store ( typedArray, index, value ) */ \ 47 V("store", Store, 3, INVALID) \ 48 /* Atomics.sub ( typedArray, index, value ) */ \ 49 V("sub", Sub, 3, INVALID) \ 50 /* Atomics.wait ( typedArray, index, value, timeout ) */ \ 51 V("wait", Wait, 4, INVALID) \ 52 /* Atomics.xor ( typedArray, index, value ) */ \ 53 V("xor", Xor, 3, INVALID) 54 55 namespace panda::ecmascript::builtins { 56 enum class WaitResult: uint8_t {OK = 0, NOT_EQ, TIME_OUT}; 57 58 class BuiltinsAtomics : public base::BuiltinsBase { 59 public: 60 // 25.4.2 Atomics.add ( typedArray, index, value ) 61 static JSTaggedValue Add(EcmaRuntimeCallInfo *argv); 62 // 25.4.3 Atomics.and ( typedArray, index, value ) 63 static JSTaggedValue And(EcmaRuntimeCallInfo *argv); 64 // 25.4.4 Atomics.compareExchange ( typedArray, index, expectedValue, replacementValue) 65 static JSTaggedValue CompareExchange(EcmaRuntimeCallInfo *argv); 66 // 25.4.5 Atomics.exchange ( typedArray, index, value ) 67 static JSTaggedValue Exchange(EcmaRuntimeCallInfo *argv); 68 // 25.4.6 Atomics.isLockFree ( size ) 69 static JSTaggedValue IsLockFree(EcmaRuntimeCallInfo *argv); 70 // 25.4.7 Atomics.load ( typedArray, index ) 71 static JSTaggedValue Load(EcmaRuntimeCallInfo *argv); 72 // 25.4.8 Atomics.or ( typedArray, index, value ) 73 static JSTaggedValue Or(EcmaRuntimeCallInfo *argv); 74 // 25.4.9 Atomics.store ( typedArray, index, value ) 75 static JSTaggedValue Store(EcmaRuntimeCallInfo *argv); 76 // 25.4.10 Atomics.sub ( typedArray, index, value ) 77 static JSTaggedValue Sub(EcmaRuntimeCallInfo *argv); 78 // 25.4.11 Atomics.wait ( typedArray, index, value, timeout) 79 static JSTaggedValue Wait(EcmaRuntimeCallInfo *argv); 80 // 25.4.12 Atomics.notify ( typedArray, index, count) 81 static JSTaggedValue Notify(EcmaRuntimeCallInfo *argv); 82 // 25.4.13 Atomics.xor ( typedArray, index, value ) 83 static JSTaggedValue Xor(EcmaRuntimeCallInfo *argv); 84 GetAtomicsFunctions()85 static Span<const base::BuiltinFunctionEntry> GetAtomicsFunctions() 86 { 87 return Span<const base::BuiltinFunctionEntry>(ATOMICS_FUNCTIONS); 88 } 89 90 private: 91 #define BUILTINS_ATOMICS_FUNCTION_ENTRY(name, method, length, id) \ 92 base::BuiltinFunctionEntry::Create(name, BuiltinsAtomics::method, length, kungfu::BuiltinsStubCSigns::id), 93 94 static constexpr std::array ATOMICS_FUNCTIONS = { 95 BUILTIN_ATOMICS_FUNCTIONS(BUILTINS_ATOMICS_FUNCTION_ENTRY) 96 }; 97 #undef BUILTINS_ATOMICS_FUNCTION_ENTRY 98 99 static uint32_t Signal(JSHandle<JSTaggedValue> &arrayBuffer, const size_t &index, double wakeCount); 100 template <typename T> 101 static WaitResult DoWait(JSThread *thread, JSHandle<JSTaggedValue> &arrayBuffer, 102 size_t index, T execpt, double timeout); 103 template<typename callbackfun> 104 static JSTaggedValue AtomicReadModifyWrite(JSThread *thread, const JSHandle<JSTaggedValue> &typedArray, 105 JSHandle<JSTaggedValue> &index, EcmaRuntimeCallInfo *argv, 106 const callbackfun &op); 107 template<typename callbackfun> 108 static JSTaggedValue AtomicReadModifyWriteCase(JSThread *thread, JSTaggedValue buffer, DataViewType type, 109 uint32_t indexedPosition, EcmaRuntimeCallInfo *argv, 110 const callbackfun &op); 111 template<typename callbackfun> 112 static JSTaggedValue HandleWithUint8(JSThread *thread, uint32_t size, uint8_t *block, uint32_t indexedPosition, 113 EcmaRuntimeCallInfo *argv, const callbackfun &op, uint8_t &tag); 114 template<typename callbackfun> 115 static JSTaggedValue HandleWithInt8(JSThread *thread, uint32_t size, uint8_t *block, uint32_t indexedPosition, 116 EcmaRuntimeCallInfo *argv, const callbackfun &op, int8_t &tag); 117 template<typename callbackfun> 118 static JSTaggedValue HandleWithUint16(JSThread *thread, uint32_t size, uint8_t *block, uint32_t indexedPosition, 119 EcmaRuntimeCallInfo *argv, const callbackfun &op, uint16_t &tag); 120 template<typename callbackfun> 121 static JSTaggedValue HandleWithInt16(JSThread *thread, uint32_t size, uint8_t *block, uint32_t indexedPosition, 122 EcmaRuntimeCallInfo *argv, const callbackfun &op, int16_t &tag); 123 template<typename callbackfun> 124 static JSTaggedValue HandleWithUint32(JSThread *thread, uint32_t size, uint8_t *block, uint32_t indexedPosition, 125 EcmaRuntimeCallInfo *argv, const callbackfun &op, uint32_t &tag); 126 template<typename callbackfun> 127 static JSTaggedValue HandleWithInt32(JSThread *thread, uint32_t size, uint8_t *block, uint32_t indexedPosition, 128 EcmaRuntimeCallInfo *argv, const callbackfun &op, int32_t &tag); 129 template<typename callbackfun> 130 static JSTaggedValue HandleWithBigInt64(JSThread *thread, uint32_t size, uint8_t *block, uint32_t indexedPosition, 131 EcmaRuntimeCallInfo *argv, const callbackfun &op, int64_t &tag, bool &lossless); 132 template<typename callbackfun> 133 static JSTaggedValue HandleWithBigUint64(JSThread *thread, uint32_t size, uint8_t *block, uint32_t indexedPosition, 134 EcmaRuntimeCallInfo *argv, const callbackfun &op, uint64_t &tag, bool &lossless); 135 136 static constexpr int ARGS_NUMBER = 2; 137 }; 138 } // namespace panda::ecmascript::builtins 139 #endif // ECMASCRIPT_BUILTINS_BUILTINS_MATH_H 140