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 #include "builtin_test_util.h"
17 #include "ecmascript/builtins/builtins_sharedarraybuffer.h"
18
19 #include "ecmascript/ecma_runtime_call_info.h"
20 #include "ecmascript/ecma_vm.h"
21 #include "ecmascript/global_env.h"
22 #include "ecmascript/js_arraybuffer.h"
23 #include "ecmascript/js_handle.h"
24 #include "ecmascript/js_tagged_value.h"
25 #include "ecmascript/tests/test_helper.h"
26 #include "ecmascript/builtins/builtins_arraybuffer.h"
27
28 using namespace panda::ecmascript;
29 using namespace panda::ecmascript::builtins;
30 using BuiltinsArrayBuffer = builtins::BuiltinsArrayBuffer;
31
32 namespace panda::test {
33 class BuiltinsSharedArrayBufferTest : public BaseTestWithScope<false> {
34 };
35
CreateJSArrayBuffer(JSThread *thread)36 JSArrayBuffer *CreateJSArrayBuffer(JSThread *thread)
37 {
38 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
39 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
40 JSHandle<JSTaggedValue> target = env->GetArrayBufferFunction();
41 JSHandle<JSArrayBuffer> jsArrayBuffer =
42 JSHandle<JSArrayBuffer>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(target), target));
43 return *jsArrayBuffer;
44 }
45
46 // new ArrayBuffer(20)
HWTEST_F_L0(BuiltinsSharedArrayBufferTest, Constructor1)47 HWTEST_F_L0(BuiltinsSharedArrayBufferTest, Constructor1)
48 {
49 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
50 JSHandle<JSFunction> sharedArrayBuffer(thread, env->GetSharedArrayBufferFunction().GetTaggedValue());
51 JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
52 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, sharedArrayBuffer.GetTaggedValue(), 6);
53 ecmaRuntimeCallInfo->SetFunction(sharedArrayBuffer.GetTaggedValue());
54 ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
55 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(20)));
56
57 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
58 JSTaggedValue result = BuiltinsSharedArrayBuffer::SharedArrayBufferConstructor(ecmaRuntimeCallInfo);
59 ASSERT_TRUE(result.IsECMAObject());
60 }
61
62 // (new ArrayBuffer(18)).byteLength
HWTEST_F_L0(BuiltinsSharedArrayBufferTest, byteLength1)63 HWTEST_F_L0(BuiltinsSharedArrayBufferTest, byteLength1)
64 {
65 JSTaggedValue tagged = BuiltTestUtil::CreateBuiltinsSharedArrayBuffer(thread, 18);
66 JSHandle<JSArrayBuffer> arrBuf(thread, JSArrayBuffer::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
67 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
68 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
69 ecmaRuntimeCallInfo->SetThis(arrBuf.GetTaggedValue());
70
71 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
72 JSTaggedValue result = BuiltinsSharedArrayBuffer::GetByteLength(ecmaRuntimeCallInfo);
73 ASSERT_EQ(result.GetRawData(), JSTaggedValue(18).GetRawData());
74 }
75
76 // (new ArrayBuffer(10)).slice(1, 5).bytelength
HWTEST_F_L0(BuiltinsSharedArrayBufferTest, slice1)77 HWTEST_F_L0(BuiltinsSharedArrayBufferTest, slice1)
78 {
79 JSTaggedValue tagged = BuiltTestUtil::CreateBuiltinsSharedArrayBuffer(thread, 10);
80 JSHandle<JSArrayBuffer> arrBuf(thread, JSArrayBuffer::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
81 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
82 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
83 ecmaRuntimeCallInfo->SetThis(arrBuf.GetTaggedValue());
84 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(1)));
85 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(5)));
86
87 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
88 JSTaggedValue result1 = BuiltinsSharedArrayBuffer::Slice(ecmaRuntimeCallInfo);
89 TestHelper::TearDownFrame(thread, prev);
90 JSHandle<JSArrayBuffer> arrBuf1(thread,
91 JSArrayBuffer::Cast(reinterpret_cast<TaggedObject *>(result1.GetRawData())));
92 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
93 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
94 ecmaRuntimeCallInfo1->SetThis(arrBuf1.GetTaggedValue());
95 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
96 JSTaggedValue result2 = BuiltinsSharedArrayBuffer::GetByteLength(ecmaRuntimeCallInfo1);
97 TestHelper::TearDownFrame(thread, prev);
98 ASSERT_EQ(result2.GetRawData(), JSTaggedValue(4).GetRawData());
99
100 // IsShared false
101 JSTaggedValue tagged1 = BuiltTestUtil::CreateBuiltinsSharedArrayBuffer(thread, 10);
102 JSHandle<JSArrayBuffer> arrBuf2(thread, JSArrayBuffer::Cast(
103 reinterpret_cast<TaggedObject *>(tagged1.GetRawData())));
104 arrBuf2->SetShared(false);
105 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
106 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
107 ecmaRuntimeCallInfo2->SetThis(arrBuf2.GetTaggedValue());
108 ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(1)));
109 ecmaRuntimeCallInfo2->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(5)));
110
111 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
112 JSTaggedValue result3 = BuiltinsSharedArrayBuffer::Slice(ecmaRuntimeCallInfo2);
113 TestHelper::TearDownFrame(thread, prev);
114 EXPECT_TRUE(thread->HasPendingException());
115 EXPECT_EQ(result3, JSTaggedValue::Exception());
116 thread->ClearException();
117 }
118
HWTEST_F_L0(BuiltinsSharedArrayBufferTest, IsSharedArrayBuffer)119 HWTEST_F_L0(BuiltinsSharedArrayBufferTest, IsSharedArrayBuffer)
120 {
121 JSTaggedValue tagged = BuiltTestUtil::CreateBuiltinsSharedArrayBuffer(thread, 10);
122 JSHandle<JSArrayBuffer> arrBuf(thread,
123 JSArrayBuffer::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
124 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
125 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
126 ecmaRuntimeCallInfo->SetThis(arrBuf.GetTaggedValue());
127 ecmaRuntimeCallInfo->SetCallArg(0, arrBuf.GetTaggedValue()); // JSTaggedValue(static_cast<int32_t>(1))
128
129 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
130 JSTaggedValue result = BuiltinsSharedArrayBuffer::IsSharedArrayBuffer(ecmaRuntimeCallInfo);
131 TestHelper::TearDownFrame(thread, prev);
132 ASSERT_EQ(result, JSTaggedValue::True());
133 // Is Not ECMAObject
134 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
135 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
136 ecmaRuntimeCallInfo->SetThis(arrBuf.GetTaggedValue());
137 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue::Undefined());
138
139 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
140 result = BuiltinsSharedArrayBuffer::IsSharedArrayBuffer(ecmaRuntimeCallInfo);
141 TestHelper::TearDownFrame(thread, prev);
142 ASSERT_EQ(result, JSTaggedValue::False());
143 // Is Not sharedbuffer
144 JSHandle<JSArrayBuffer> jsArrayBuffer(thread, CreateJSArrayBuffer(thread));
145 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
146 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
147 ecmaRuntimeCallInfo->SetThis(arrBuf.GetTaggedValue());
148 ecmaRuntimeCallInfo->SetCallArg(0, jsArrayBuffer.GetTaggedValue());
149
150 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
151 result = BuiltinsSharedArrayBuffer::IsSharedArrayBuffer(ecmaRuntimeCallInfo);
152 TestHelper::TearDownFrame(thread, prev);
153 ASSERT_EQ(result, JSTaggedValue::False());
154
155 // sharedbuffer IsNull
156 JSTaggedValue tagged1 = BuiltTestUtil::CreateBuiltinsSharedArrayBuffer(thread, 0);
157 JSHandle<JSArrayBuffer> arrBuf1(thread,
158 JSArrayBuffer::Cast(reinterpret_cast<TaggedObject *>(tagged1.GetRawData())));
159 arrBuf1->SetArrayBufferData(thread, JSTaggedValue::Null());
160 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
161 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
162 ecmaRuntimeCallInfo->SetThis(arrBuf.GetTaggedValue());
163 ecmaRuntimeCallInfo->SetCallArg(0, arrBuf1.GetTaggedValue());
164
165 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
166 result = BuiltinsSharedArrayBuffer::IsSharedArrayBuffer(ecmaRuntimeCallInfo);
167 TestHelper::TearDownFrame(thread, prev);
168 ASSERT_EQ(result, JSTaggedValue::False());
169
170 // ArrayBuffer is not shared
171 JSTaggedValue tagged2 = BuiltTestUtil::CreateBuiltinsSharedArrayBuffer(thread, 0);
172 JSHandle<JSArrayBuffer> arrBuf2(thread,
173 JSArrayBuffer::Cast(reinterpret_cast<TaggedObject *>(tagged2.GetRawData())));
174 arrBuf2->SetShared(false);
175 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
176 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
177 ecmaRuntimeCallInfo->SetThis(arrBuf.GetTaggedValue());
178 ecmaRuntimeCallInfo->SetCallArg(0, arrBuf2.GetTaggedValue());
179
180 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
181 JSTaggedValue result1 = BuiltinsSharedArrayBuffer::IsSharedArrayBuffer(ecmaRuntimeCallInfo);
182 TestHelper::TearDownFrame(thread, prev);
183 ASSERT_EQ(result1, JSTaggedValue::False());
184 }
185
HWTEST_F_L0(BuiltinsSharedArrayBufferTest, IsShared)186 HWTEST_F_L0(BuiltinsSharedArrayBufferTest, IsShared)
187 {
188 // is not SharedBuffer
189 JSHandle<JSArrayBuffer> jsArrayBuffer(thread, CreateJSArrayBuffer(thread));
190 bool result = BuiltinsSharedArrayBuffer::IsShared(jsArrayBuffer.GetTaggedValue());
191 ASSERT_EQ(result, false);
192 // no BufferData
193 JSTaggedValue tagged1 = BuiltTestUtil::CreateBuiltinsSharedArrayBuffer(thread, 0);
194 JSHandle<JSArrayBuffer> arrBuf1(thread,
195 JSArrayBuffer::Cast(reinterpret_cast<TaggedObject *>(tagged1.GetRawData())));
196 arrBuf1->SetArrayBufferData(thread, JSTaggedValue::Null());
197 bool result1 = BuiltinsSharedArrayBuffer::IsShared(arrBuf1.GetTaggedValue());
198 ASSERT_EQ(result1, false);
199 }
200 } // namespace panda::test
201