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