1/* 2 * Copyright (c) 2022-2024 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#include "ecmascript/base/atomic_helper.h" 17#include "ecmascript/global_env.h" 18#include "ecmascript/js_typed_array.h" 19#include "ecmascript/tests/test_helper.h" 20 21using namespace panda::ecmascript; 22using namespace panda::ecmascript::base; 23 24namespace panda::test { 25class AtomicHelperTest : public BaseTestWithScope<false> { 26}; 27 28HWTEST_F_L0(AtomicHelperTest, ValidateIntegerTypedArray) 29{ 30 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 31 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 32 33 bool waitable = false; 34 uint32_t bufferSize = 10; 35 JSHandle<JSTaggedValue> func = env->GetInt8ArrayFunction(); 36 JSHandle<JSTypedArray> array = 37 JSHandle<JSTypedArray>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(func), func)); 38 JSHandle<JSArrayBuffer> buffer = factory->NewJSArrayBuffer(bufferSize); 39 JSHandle<JSTaggedValue> bufferVal = JSHandle<JSTaggedValue>::Cast(buffer); 40 array->SetViewedArrayBufferOrByteArray(thread, bufferVal); 41 JSHandle<JSTaggedValue> arrayVal = JSHandle<JSTaggedValue>::Cast(array); 42 JSHandle<JSTaggedValue> resultBuffer(thread, AtomicHelper::ValidateIntegerTypedArray(thread, arrayVal, waitable)); 43 EXPECT_EQ(resultBuffer.GetTaggedValue(), buffer.GetTaggedValue()); 44} 45 46HWTEST_F_L0(AtomicHelperTest, ValidateAtomicAccess) 47{ 48 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 49 const GlobalEnvConstants *globalConst = thread->GlobalConstants(); 50 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 51 52 uint32_t bufferSize = 256; 53 uint32_t byteOffset = 7; 54 uint32_t arrayLength = 3; 55 JSHandle<JSTaggedValue> func = env->GetInt8ArrayFunction(); 56 JSHandle<JSTypedArray> array = 57 JSHandle<JSTypedArray>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(func), func)); 58 JSHandle<JSArrayBuffer> buffer = factory->NewJSArrayBuffer(bufferSize); 59 JSHandle<JSTaggedValue> bufferVal = JSHandle<JSTaggedValue>::Cast(buffer); 60 array->SetViewedArrayBufferOrByteArray(thread, bufferVal); 61 array->SetTypedArrayName(thread, globalConst->GetHandledInt8ArrayString()); // test int8 array 62 array->SetByteOffset(byteOffset); 63 array->SetArrayLength(arrayLength); 64 JSHandle<JSTaggedValue> arrayVal = JSHandle<JSTaggedValue>::Cast(array); 65 uint32_t index0 = 66 AtomicHelper::ValidateAtomicAccess(thread, arrayVal, JSHandle<JSTaggedValue>(thread, JSTaggedValue(0))); 67 uint32_t index1 = 68 AtomicHelper::ValidateAtomicAccess(thread, arrayVal, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1))); 69 uint32_t index2 = 70 AtomicHelper::ValidateAtomicAccess(thread, arrayVal, JSHandle<JSTaggedValue>(thread, JSTaggedValue(2))); 71 EXPECT_EQ(index0, 0 * sizeof(int8_t) + byteOffset); 72 EXPECT_EQ(index1, 1 * sizeof(int8_t) + byteOffset); 73 EXPECT_EQ(index2, 2 * sizeof(int8_t) + byteOffset); 74} 75 76HWTEST_F_L0(AtomicHelperTest, Atomic_Store_Load) 77{ 78 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 79 const GlobalEnvConstants *globalConst = thread->GlobalConstants(); 80 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 81 82 uint32_t bufferSize = 256; 83 uint32_t byteOffset = 7; 84 uint32_t arrayLength = 3; 85 JSHandle<JSTaggedValue> func = env->GetUint32ArrayFunction(); 86 JSHandle<JSTypedArray> array = 87 JSHandle<JSTypedArray>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(func), func)); 88 JSHandle<JSArrayBuffer> buffer = factory->NewJSArrayBuffer(bufferSize); 89 JSHandle<JSTaggedValue> bufferVal = JSHandle<JSTaggedValue>::Cast(buffer); 90 array->SetViewedArrayBufferOrByteArray(thread, bufferVal); 91 array->SetTypedArrayName(thread, globalConst->GetHandledUint32ArrayString()); // test uint32_t array 92 array->SetByteOffset(byteOffset); 93 array->SetArrayLength(arrayLength); 94 JSHandle<JSTaggedValue> arrayVal = JSHandle<JSTaggedValue>::Cast(array); 95 JSHandle<JSTaggedValue> index0(thread, JSTaggedValue(0)); 96 JSHandle<JSTaggedValue> index1(thread, JSTaggedValue(1)); 97 JSHandle<JSTaggedValue> index2(thread, JSTaggedValue(2)); 98 JSHandle<JSTaggedValue> value0(thread, JSTaggedValue(-1)); // to uint32_t : 4294967295 99 JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1)); 100#ifdef PANDA_TARGET_MACOS 101 JSHandle<JSTaggedValue> value2(thread, static_cast<JSTaggedValue>(static_cast<uint32_t>(4294967295 + 1))); // to uint32_t : 0 102#else 103 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(4294967295 + 1)); 104#endif 105 JSHandle<JSTaggedValue> bufferTag0(thread, AtomicHelper::AtomicStore(thread, arrayVal, index0, value0)); 106 JSHandle<JSTaggedValue> bufferTag1(thread, AtomicHelper::AtomicStore(thread, arrayVal, index1, value1)); 107 JSHandle<JSTaggedValue> bufferTag2(thread, AtomicHelper::AtomicStore(thread, arrayVal, index2, value2)); 108 EXPECT_EQ(value0.GetTaggedValue().GetNumber(), -1); 109 EXPECT_EQ(value1.GetTaggedValue().GetNumber(), 1); 110 EXPECT_EQ(value2.GetTaggedValue().GetNumber(), 4294967296); 111 112 JSHandle<JSTaggedValue> result0(thread, AtomicHelper::AtomicLoad(thread, arrayVal, index0)); 113 JSHandle<JSTaggedValue> result1(thread, AtomicHelper::AtomicLoad(thread, arrayVal, index1)); 114 JSHandle<JSTaggedValue> result2(thread, AtomicHelper::AtomicLoad(thread, arrayVal, index2)); 115 EXPECT_EQ(result0.GetTaggedValue().GetNumber(), 4294967295); // 4294967295 : -1 to uint32_t 116 EXPECT_EQ(result1.GetTaggedValue().GetNumber(), 1); 117 EXPECT_EQ(result2.GetTaggedValue().GetNumber(), 0); // 0 : 4294967296 to uint32_t 118} 119} // namespace panda::test 120