1/*
2 * Copyright (c) 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/ecma_vm.h"
17#include "ecmascript/shared_objects/js_sendable_arraybuffer.h"
18#include "ecmascript/object_factory-inl.h"
19#include "ecmascript/tests/test_helper.h"
20
21
22using namespace panda::ecmascript;
23
24namespace panda::test {
25class JsSendableArrayBufferTest : public BaseTestWithScope<false> {
26};
27
28/**
29 * @tc.name: CopyDataBlockBytes
30 * @tc.type: FUNC
31 * @tc.require:
32 */
33HWTEST_F_L0(JsSendableArrayBufferTest, CopyDataBlockBytesTest001)
34{
35    auto vm = thread->GetEcmaVM();
36    auto factory = vm->GetFactory();
37
38    uint8_t value = 100;
39    size_t length = 5;
40    void *toBuffer = vm->GetNativeAreaAllocator()->AllocateBuffer(length);
41    JSHandle<JSNativePointer> toNativePointer = factory->NewJSNativePointer(toBuffer, nullptr, nullptr);
42    uint8_t *data = static_cast<uint8_t *>(vm->GetNativeAreaAllocator()->AllocateBuffer(length));
43    if (memset_s(data, length, value, length) != EOK) {
44        LOG_ECMA(FATAL) << "this branch is unreachable";
45        UNREACHABLE();
46    }
47    void *formBuffer = vm->GetNativeAreaAllocator()->AllocateBuffer(length);
48    JSHandle<JSNativePointer> fromNativePointer =
49        factory->NewJSNativePointer(formBuffer, nullptr, reinterpret_cast<void *>(data));
50    int32_t fromIndex = 0;
51    int32_t count = 5;
52    JSSendableArrayBuffer::CopyDataBlockBytes(JSHandle<JSTaggedValue>::Cast(toNativePointer).GetTaggedValue(),
53        JSHandle<JSTaggedValue>::Cast(fromNativePointer).GetTaggedValue(), fromIndex, count);
54    auto toData = reinterpret_cast<uint8_t *>(toNativePointer->GetExternalPointer());
55    auto fromData = reinterpret_cast<uint8_t *>(fromNativePointer->GetExternalPointer());
56    for (uint32_t i = 0; i < length; i++) {
57        EXPECT_EQ(*(toData + i), *(fromData + i));
58    }
59    vm->GetNativeAreaAllocator()->FreeBuffer(toBuffer);
60    vm->GetNativeAreaAllocator()->FreeBuffer(data);
61    vm->GetNativeAreaAllocator()->FreeBuffer(formBuffer);
62}
63
64/**
65 * @tc.name: CopyDataPointBytes
66 * @tc.type: FUNC
67 * @tc.require:
68 */
69HWTEST_F_L0(JsSendableArrayBufferTest, CopyDataPointBytesTest001)
70{
71    auto vm = thread->GetEcmaVM();
72
73    size_t length = 5;
74    void *toBuffer = vm->GetNativeAreaAllocator()->AllocateBuffer(length);
75    uint8_t *fromData = static_cast<uint8_t *>(vm->GetNativeAreaAllocator()->AllocateBuffer(length));
76    uint8_t *toData = static_cast<uint8_t *>(vm->GetNativeAreaAllocator()->AllocateBuffer(length));
77    *(fromData + 1) = 1;
78
79    int32_t fromIndex = 0;
80    int32_t count = 5;
81    JSSendableArrayBuffer::CopyDataPointBytes(fromData, toData, fromIndex, count);
82    for (uint32_t i = 0; i < length; i++) {
83        EXPECT_EQ(*(toData + i), *(fromData + i));
84    }
85    vm->GetNativeAreaAllocator()->FreeBuffer(toBuffer);
86    vm->GetNativeAreaAllocator()->FreeBuffer(fromData);
87    vm->GetNativeAreaAllocator()->FreeBuffer(toData);
88}
89
90/**
91 * @tc.name: Attach
92 * @tc.type: FUNC
93 * @tc.require:
94 */
95HWTEST_F_L0(JsSendableArrayBufferTest, AttachTest001)
96{
97    auto vm = thread->GetEcmaVM();
98    auto factory = vm->GetFactory();
99
100    size_t length = 5;
101    const JSHandle<JSSendableArrayBuffer> arrBuf = factory->NewJSSendableArrayBuffer(5);
102    factory->NewJSSendableArrayBufferData(arrBuf, 5);
103    JSTaggedValue taggedValue = arrBuf->GetArrayBufferData();
104    arrBuf->Attach(thread, length + 1, taggedValue);
105    ASSERT_EQ(arrBuf->GetArrayBufferByteLength(), 6U);
106    ASSERT_EQ(arrBuf->GetArrayBufferData().GetRawData(), taggedValue.GetRawData());
107}
108
109/**
110 * @tc.name: Attach
111 * @tc.type: FUNC
112 * @tc.require:
113 */
114HWTEST_F_L0(JsSendableArrayBufferTest, AttachTest002)
115{
116    auto vm = thread->GetEcmaVM();
117    auto factory = vm->GetFactory();
118
119    size_t length = 5;
120    const JSHandle<JSSendableArrayBuffer> arrBuf = factory->NewJSSendableArrayBuffer(5);
121    factory->NewJSSendableArrayBufferData(arrBuf, 5);
122    JSTaggedValue taggedValue = arrBuf->GetArrayBufferData();
123    arrBuf->Attach(thread, length + 1, taggedValue, true);
124    ASSERT_EQ(arrBuf->GetArrayBufferByteLength(), 6U);
125    ASSERT_EQ(arrBuf->GetArrayBufferData().GetRawData(), taggedValue.GetRawData());
126}
127
128/**
129 * @tc.name: Detach
130 * @tc.type: FUNC
131 * @tc.require:
132 */
133HWTEST_F_L0(JsSendableArrayBufferTest, DetachTest001)
134{
135    auto vm = thread->GetEcmaVM();
136    auto factory = vm->GetFactory();
137
138    size_t length = 5;
139    const JSHandle<JSSendableArrayBuffer> arrBuf = factory->NewJSSendableArrayBuffer(5);
140    factory->NewJSSendableArrayBufferData(arrBuf, 5);
141    JSTaggedValue taggedValue = arrBuf->GetArrayBufferData();
142    arrBuf->Attach(thread, length + 1, taggedValue);
143    ASSERT_EQ(arrBuf->GetArrayBufferByteLength(), 6U);
144    ASSERT_EQ(arrBuf->GetArrayBufferData().GetRawData(), taggedValue.GetRawData());
145
146    arrBuf->Detach(thread);
147    EXPECT_EQ(arrBuf->GetArrayBufferByteLength(), 0U);
148    EXPECT_EQ(arrBuf->GetArrayBufferData().GetRawData(), JSTaggedValue::Null().GetRawData());
149    EXPECT_TRUE(arrBuf->IsDetach());
150}
151
152/**
153 * @tc.name: Detach
154 * @tc.type: FUNC
155 * @tc.require:
156 */
157HWTEST_F_L0(JsSendableArrayBufferTest, DetachTest002)
158{
159    auto vm = thread->GetEcmaVM();
160    auto factory = vm->GetFactory();
161
162    size_t length = 5;
163    const JSHandle<JSSendableArrayBuffer> arrBuf = factory->NewJSSendableArrayBuffer(5);
164    factory->NewJSSendableArrayBufferData(arrBuf, 5);
165    JSTaggedValue taggedValue = arrBuf->GetArrayBufferData();
166    arrBuf->Attach(thread, length + 1, taggedValue, true);
167    ASSERT_EQ(arrBuf->GetArrayBufferByteLength(), 6U);
168    ASSERT_EQ(arrBuf->GetArrayBufferData().GetRawData(), taggedValue.GetRawData());
169
170    arrBuf->Detach(thread, true);
171    EXPECT_EQ(arrBuf->GetArrayBufferByteLength(), 0U);
172    EXPECT_EQ(arrBuf->GetArrayBufferData().GetRawData(), JSTaggedValue::Null().GetRawData());
173    EXPECT_TRUE(arrBuf->IsDetach());
174}
175
176/**
177 * @tc.name: Detach
178 * @tc.type: FUNC
179 * @tc.require:
180 */
181HWTEST_F_L0(JsSendableArrayBufferTest, DetachTest003)
182{
183    auto vm = thread->GetEcmaVM();
184    auto factory = vm->GetFactory();
185
186    size_t length = 5;
187    const JSHandle<JSSendableArrayBuffer> arrBuf = factory->NewJSSendableArrayBuffer(5);
188    factory->NewJSSendableArrayBufferData(arrBuf, 5);
189    JSTaggedValue taggedValue = arrBuf->GetArrayBufferData();
190    arrBuf->Attach(thread, length + 1, taggedValue);
191
192    arrBuf->Detach(thread);
193    EXPECT_EQ(arrBuf->GetArrayBufferByteLength(), 0U);
194
195    arrBuf->Detach(thread);
196}
197
198HWTEST_F_L0(JsSendableArrayBufferTest, AttachTest003)
199{
200    auto vm = thread->GetEcmaVM();
201    auto factory = vm->GetFactory();
202    size_t length = 5;
203    const JSHandle<JSSendableArrayBuffer> arrBuf = factory->NewJSSendableArrayBuffer(5);
204    factory->NewJSSendableArrayBufferData(arrBuf, 5);
205    JSTaggedValue taggedValue = arrBuf->GetArrayBufferData();
206    arrBuf->Attach(thread, length + 1, taggedValue, false);
207    ASSERT_EQ(arrBuf->GetArrayBufferByteLength(), 6U);
208}
209
210} // namespace panda::test