1 /*
2 * Copyright (c) 2021 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_dataview.h"
18
19 #include "ecmascript/builtins/builtins_arraybuffer.h"
20 #include "ecmascript/ecma_runtime_call_info.h"
21 #include "ecmascript/ecma_vm.h"
22 #include "ecmascript/global_env.h"
23 #include "ecmascript/js_arraybuffer.h"
24 #include "ecmascript/js_dataview.h"
25 #include "ecmascript/js_handle.h"
26 #include "ecmascript/js_tagged_value.h"
27 #include "ecmascript/tests/test_helper.h"
28
29 using namespace panda::ecmascript;
30 using namespace panda::ecmascript::builtins;
31
32 namespace panda::test {
33 using DataViewType = ecmascript::DataViewType;
34 class BuiltinsDataViewTest : public BaseTestWithScope<false> {
35 };
36
37 enum class AlgorithmType {
38 GET_OFFSET,
39 GET_BYTELENGTH,
40 GET_BUFFER,
41 GET_INT8,
42 SET_INT8,
43 GET_UINT8,
44 SET_UINT8,
45 GET_UINT16,
46 SET_UINT16,
47 GET_INT16,
48 SET_INT16,
49 GET_UINT32,
50 SET_UINT32,
51 GET_INT32,
52 SET_INT32,
53 GET_FLOAT32,
54 SET_FLOAT32,
55 GET_FLOAT64,
56 SET_FLOAT64,
57 GET_BIGINT64,
58 SET_BIGINT64,
59 };
60
DataViewAlgorithmGet(AlgorithmType type,EcmaRuntimeCallInfo * ecmaRuntimeCallInfo)61 static JSTaggedValue DataViewAlgorithmGet(AlgorithmType type, EcmaRuntimeCallInfo* ecmaRuntimeCallInfo)
62 {
63 JSTaggedValue result;
64 switch (type) {
65 case AlgorithmType::GET_OFFSET:
66 result = BuiltinsDataView::GetOffset(ecmaRuntimeCallInfo);
67 break;
68 case AlgorithmType::GET_BYTELENGTH:
69 result = BuiltinsDataView::GetByteLength(ecmaRuntimeCallInfo);
70 break;
71 case AlgorithmType::GET_BUFFER:
72 result = BuiltinsDataView::GetBuffer(ecmaRuntimeCallInfo);
73 break;
74 case AlgorithmType::GET_INT8:
75 result = BuiltinsDataView::GetInt8(ecmaRuntimeCallInfo);
76 break;
77 case AlgorithmType::GET_UINT16:
78 result = BuiltinsDataView::GetUint16(ecmaRuntimeCallInfo);
79 break;
80 case AlgorithmType::GET_INT16:
81 result = BuiltinsDataView::GetInt16(ecmaRuntimeCallInfo);
82 break;
83 case AlgorithmType::GET_UINT32:
84 result = BuiltinsDataView::GetUint32(ecmaRuntimeCallInfo);
85 break;
86 case AlgorithmType::GET_INT32:
87 result = BuiltinsDataView::GetInt32(ecmaRuntimeCallInfo);
88 break;
89 case AlgorithmType::GET_FLOAT32:
90 result = BuiltinsDataView::GetFloat32(ecmaRuntimeCallInfo);
91 break;
92 case AlgorithmType::GET_FLOAT64:
93 result = BuiltinsDataView::GetFloat64(ecmaRuntimeCallInfo);
94 break;
95 case AlgorithmType::GET_BIGINT64:
96 result = BuiltinsDataView::GetBigInt64(ecmaRuntimeCallInfo);
97 break;
98 default:
99 break;
100 }
101 return result;
102 }
103
DataViewAlgorithm(JSThread * thread,std::vector<JSTaggedValue> & args,int32_t maxArgLen,AlgorithmType type,JSTaggedValue thisValue=JSTaggedValue::Undefined ())104 static JSTaggedValue DataViewAlgorithm(JSThread *thread, std::vector<JSTaggedValue>& args, int32_t maxArgLen,
105 AlgorithmType type, JSTaggedValue thisValue = JSTaggedValue::Undefined())
106 {
107 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, args, maxArgLen, thisValue);
108 auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
109 JSTaggedValue result;
110 switch (type) {
111 case AlgorithmType::SET_INT8:
112 result = BuiltinsDataView::SetInt8(ecmaRuntimeCallInfo);
113 break;
114 case AlgorithmType::GET_UINT8:
115 result = BuiltinsDataView::GetUint8(ecmaRuntimeCallInfo);
116 break;
117 case AlgorithmType::SET_UINT8:
118 result = BuiltinsDataView::SetUint8(ecmaRuntimeCallInfo);
119 break;
120 case AlgorithmType::SET_UINT16:
121 result = BuiltinsDataView::SetUint16(ecmaRuntimeCallInfo);
122 break;
123 case AlgorithmType::SET_INT16:
124 result = BuiltinsDataView::SetInt16(ecmaRuntimeCallInfo);
125 break;
126 case AlgorithmType::SET_UINT32:
127 result = BuiltinsDataView::SetUint32(ecmaRuntimeCallInfo);
128 break;
129 case AlgorithmType::SET_INT32:
130 result = BuiltinsDataView::SetInt32(ecmaRuntimeCallInfo);
131 break;
132 case AlgorithmType::SET_FLOAT32:
133 result = BuiltinsDataView::SetFloat32(ecmaRuntimeCallInfo);
134 break;
135 case AlgorithmType::SET_FLOAT64:
136 result = BuiltinsDataView::SetFloat64(ecmaRuntimeCallInfo);
137 break;
138 case AlgorithmType::SET_BIGINT64:
139 result = BuiltinsDataView::SetBigInt64(ecmaRuntimeCallInfo);
140 break;
141 default:
142 result = DataViewAlgorithmGet(type, ecmaRuntimeCallInfo);
143 break;
144 }
145 TestHelper::TearDownFrame(thread, prev);
146 return result;
147 }
148
CreateBuiltinsDataviewArrayBuffer(JSThread * thread,int32_t length)149 JSTaggedValue CreateBuiltinsDataviewArrayBuffer(JSThread *thread, int32_t length)
150 {
151 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
152 JSHandle<JSFunction> arrayBuffer(thread, env->GetArrayBufferFunction().GetTaggedValue());
153 JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
154 // 6 : test case
155 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*arrayBuffer), 6);
156 ecmaRuntimeCallInfo->SetFunction(arrayBuffer.GetTaggedValue());
157 ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
158 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(length));
159
160 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
161 JSTaggedValue result = BuiltinsArrayBuffer::ArrayBufferConstructor(ecmaRuntimeCallInfo);
162 TestHelper::TearDownFrame(thread, prev);
163 return result;
164 }
165
CreateBuiltinsDataView(JSThread * thread,int32_t length,int32_t byte_offset)166 JSTaggedValue CreateBuiltinsDataView(JSThread *thread, int32_t length, int32_t byte_offset)
167 {
168 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
169 JSHandle<JSFunction> dataView(thread, env->GetDataViewFunction().GetTaggedValue());
170 JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
171 JSTaggedValue tagged = CreateBuiltinsDataviewArrayBuffer(thread, length);
172 JSHandle<JSArrayBuffer> arrBuf(thread, JSArrayBuffer::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
173 // 8 : test case
174 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*dataView), 8);
175 ecmaRuntimeCallInfo->SetFunction(dataView.GetTaggedValue());
176 ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
177 ecmaRuntimeCallInfo->SetCallArg(0, arrBuf.GetTaggedValue());
178 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(byte_offset));
179
180 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
181 JSTaggedValue result = BuiltinsDataView::DataViewConstructor(ecmaRuntimeCallInfo);
182 TestHelper::TearDownFrame(thread, prev);
183 return result;
184 }
185
SetUint8(JSThread * thread,const JSHandle<JSDataView> & view,int32_t offset,JSTaggedValue value)186 void SetUint8(JSThread *thread, const JSHandle<JSDataView> &view, int32_t offset, JSTaggedValue value)
187 {
188 std::vector<JSTaggedValue> vals{JSTaggedValue(offset), value};
189 DataViewAlgorithm(thread, vals, 8, AlgorithmType::SET_UINT8, view.GetTaggedValue()); // 8: data max len
190 }
191
192 // new DataView(new ArrayBuffer(10), 1)
HWTEST_F_L0(BuiltinsDataViewTest,Constructor)193 HWTEST_F_L0(BuiltinsDataViewTest, Constructor)
194 {
195 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
196 JSHandle<JSFunction> dataView(thread, env->GetDataViewFunction().GetTaggedValue());
197 JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
198 JSTaggedValue tagged = CreateBuiltinsDataviewArrayBuffer(thread, 10);
199 JSHandle<JSArrayBuffer> arrBuf(thread, JSArrayBuffer::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
200 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*dataView), 8);
201 ecmaRuntimeCallInfo->SetFunction(dataView.GetTaggedValue());
202 ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
203 ecmaRuntimeCallInfo->SetCallArg(0, arrBuf.GetTaggedValue());
204 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(1));
205
206 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
207 JSTaggedValue result = BuiltinsDataView::DataViewConstructor(ecmaRuntimeCallInfo);
208 ASSERT_TRUE(result.IsECMAObject());
209 TestHelper::TearDownFrame(thread, prev);
210
211 // case: Detached Buffer
212 arrBuf->SetArrayBufferData(thread, JSTaggedValue::Null());
213 ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*dataView), 8);
214 ecmaRuntimeCallInfo->SetFunction(dataView.GetTaggedValue());
215 ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
216 ecmaRuntimeCallInfo->SetCallArg(0, arrBuf.GetTaggedValue());
217 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(1));
218
219 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
220 result = BuiltinsDataView::DataViewConstructor(ecmaRuntimeCallInfo);
221 TestHelper::TearDownFrame(thread, prev);
222 EXPECT_TRUE(thread->HasPendingException());
223 EXPECT_EQ(result, JSTaggedValue::Exception());
224 thread->ClearException();
225 }
226
227 // new DataView(new ArrayBuffer(10), 1).byteOffset
HWTEST_F_L0(BuiltinsDataViewTest,byteOffset)228 HWTEST_F_L0(BuiltinsDataViewTest, byteOffset)
229 {
230 JSTaggedValue tagged = CreateBuiltinsDataView(thread, 10, 1);
231 JSHandle<JSDataView> view(thread, JSDataView::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
232
233 std::vector<JSTaggedValue> vals{};
234 auto result = DataViewAlgorithm(thread, vals, 4, AlgorithmType::GET_OFFSET, view.GetTaggedValue());
235 ASSERT_EQ(result.GetRawData(), JSTaggedValue(1).GetRawData());
236
237 // case: Detached Buffer
238 JSTaggedValue tagged1 = BuiltTestUtil::CreateBuiltinsArrayBuffer(thread, 10);
239 JSHandle<JSArrayBuffer> arrBuf(thread, JSArrayBuffer::Cast(reinterpret_cast<TaggedObject *>(tagged1.GetRawData())));
240 arrBuf->SetArrayBufferData(thread, JSTaggedValue::Null());
241 view->SetViewedArrayBuffer(thread, arrBuf);
242
243 result = DataViewAlgorithm(thread, vals, 4, AlgorithmType::GET_OFFSET, view.GetTaggedValue());
244 EXPECT_TRUE(thread->HasPendingException());
245 EXPECT_EQ(result, JSTaggedValue::Exception());
246 thread->ClearException();
247 }
248
249 // new DataView(new ArrayBuffer(10), 2).byteLength
HWTEST_F_L0(BuiltinsDataViewTest,byteLength)250 HWTEST_F_L0(BuiltinsDataViewTest, byteLength)
251 {
252 JSTaggedValue tagged = CreateBuiltinsDataView(thread, 10, 2);
253 JSHandle<JSDataView> view(thread, JSDataView::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
254
255 std::vector<JSTaggedValue> vals{};
256 auto result = DataViewAlgorithm(thread, vals, 4, AlgorithmType::GET_BYTELENGTH, view.GetTaggedValue());
257 ASSERT_EQ(result.GetRawData(), JSTaggedValue(8).GetRawData());
258
259 // case: Detached Buffer
260 JSTaggedValue tagged1 = BuiltTestUtil::CreateBuiltinsArrayBuffer(thread, 10);
261 JSHandle<JSArrayBuffer> arrBuf(thread, JSArrayBuffer::Cast(reinterpret_cast<TaggedObject *>(tagged1.GetRawData())));
262 arrBuf->SetArrayBufferData(thread, JSTaggedValue::Null());
263 view->SetViewedArrayBuffer(thread, arrBuf);
264 result = DataViewAlgorithm(thread, vals, 4, AlgorithmType::GET_BYTELENGTH, view.GetTaggedValue());
265 EXPECT_TRUE(thread->HasPendingException());
266 EXPECT_EQ(result, JSTaggedValue::Exception());
267 thread->ClearException();
268 }
269
270 // new DataView(new ArrayBuffer(10), 1).buffer
HWTEST_F_L0(BuiltinsDataViewTest,buffer)271 HWTEST_F_L0(BuiltinsDataViewTest, buffer)
272 {
273 JSTaggedValue tagged = CreateBuiltinsDataView(thread, 10, 1);
274 JSHandle<JSDataView> view(thread, JSDataView::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
275 std::vector<JSTaggedValue> vals{};
276 auto result = DataViewAlgorithm(thread, vals, 4, AlgorithmType::GET_BUFFER, view.GetTaggedValue());
277 ASSERT_EQ(result.IsArrayBuffer(), true);
278 }
279
280 // new DataView(new ArrayBuffer(8), 0).SetUint16/GetUint16
HWTEST_F_L0(BuiltinsDataViewTest,getUint16)281 HWTEST_F_L0(BuiltinsDataViewTest, getUint16)
282 {
283 JSTaggedValue tagged = CreateBuiltinsDataView(thread, 8, 0);
284 JSHandle<JSDataView> view(thread, JSDataView::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
285
286 std::vector<JSTaggedValue> vals{JSTaggedValue(0), JSTaggedValue(-1870724872), JSTaggedValue::False()};
287 auto result = DataViewAlgorithm(thread, vals, 10, AlgorithmType::SET_UINT16, view.GetTaggedValue());
288 ASSERT_EQ(result.GetRawData(), JSTaggedValue::VALUE_UNDEFINED);
289
290 std::vector<JSTaggedValue> vals2{JSTaggedValue(0), JSTaggedValue::True()};
291 auto result1 = DataViewAlgorithm(thread, vals2, 8, AlgorithmType::GET_UINT16, view.GetTaggedValue());
292 ASSERT_EQ(result1.GetRawData(), JSTaggedValue(63488).GetRawData());
293 }
294
295 // new DataView(new ArrayBuffer(8), 0).SetInt16/GetInt16
HWTEST_F_L0(BuiltinsDataViewTest,getInt16)296 HWTEST_F_L0(BuiltinsDataViewTest, getInt16)
297 {
298 JSTaggedValue tagged = CreateBuiltinsDataView(thread, 8, 0);
299 JSHandle<JSDataView> view(thread, JSDataView::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
300 std::vector<JSTaggedValue> vals{JSTaggedValue(0), JSTaggedValue(-1870724872), JSTaggedValue::False()};
301 auto result = DataViewAlgorithm(thread, vals, 10, AlgorithmType::SET_INT16, view.GetTaggedValue());
302 ASSERT_EQ(result.GetRawData(), JSTaggedValue::VALUE_UNDEFINED);
303
304 std::vector<JSTaggedValue> vals2{JSTaggedValue(0), JSTaggedValue::True()};
305 auto result1 = DataViewAlgorithm(thread, vals2, 8, AlgorithmType::GET_INT16, view.GetTaggedValue());
306 ASSERT_EQ(result1.GetRawData(), JSTaggedValue(-2048).GetRawData());
307 }
308
309 // new DataView(new ArrayBuffer(8), 0).SetUint8/GetUint32
GetCommonInt32(JSThread * thread)310 static JSHandle<JSDataView> GetCommonInt32(JSThread *thread)
311 {
312 JSTaggedValue tagged = CreateBuiltinsDataView(thread, 8, 0); // 8: data len
313 JSHandle<JSDataView> view(thread, JSDataView::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
314 SetUint8(thread, view, 0, JSTaggedValue(127)); // 127:value
315 SetUint8(thread, view, 1, JSTaggedValue(255)); // 1: the second value, 255:value
316 SetUint8(thread, view, 2, JSTaggedValue(255)); // 2: the third value, 255:value
317 SetUint8(thread, view, 3, JSTaggedValue(255)); // 3: the forth value, 255:value
318 return view;
319 }
320
HWTEST_F_L0(BuiltinsDataViewTest,GetUint32)321 HWTEST_F_L0(BuiltinsDataViewTest, GetUint32)
322 {
323 auto view = GetCommonInt32(thread);
324 std::vector<JSTaggedValue> vals{JSTaggedValue(0), JSTaggedValue::False()};
325 auto result = DataViewAlgorithm(thread, vals, 8, AlgorithmType::GET_UINT32, view.GetTaggedValue());
326 ASSERT_EQ(result.GetRawData(), JSTaggedValue(2147483647).GetRawData());
327 }
328
329 // new DataView(new ArrayBuffer(8), 0).SetUint8/GetInt32
HWTEST_F_L0(BuiltinsDataViewTest,GetInt32)330 HWTEST_F_L0(BuiltinsDataViewTest, GetInt32)
331 {
332 auto view = GetCommonInt32(thread);
333 std::vector<JSTaggedValue> vals{JSTaggedValue(0), JSTaggedValue::False()};
334 auto result = DataViewAlgorithm(thread, vals, 8, AlgorithmType::GET_INT32, view.GetTaggedValue());
335
336 ASSERT_EQ(result.GetRawData(), JSTaggedValue(2147483647).GetRawData());
337 }
338
339 // new DataView(new ArrayBuffer(8), 0).SetUint8/GetInt8
HWTEST_F_L0(BuiltinsDataViewTest,GetInt8)340 HWTEST_F_L0(BuiltinsDataViewTest, GetInt8)
341 {
342 JSTaggedValue tagged = CreateBuiltinsDataView(thread, 8, 0);
343 JSHandle<JSDataView> view(thread, JSDataView::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
344 SetUint8(thread, view, 0, JSTaggedValue(255));
345
346 std::vector<JSTaggedValue> vals{JSTaggedValue(0)};
347 auto result = DataViewAlgorithm(thread, vals, 6, AlgorithmType::GET_INT8, view.GetTaggedValue());
348
349 ASSERT_EQ(result.GetRawData(), JSTaggedValue(-1).GetRawData());
350 }
351
352 // new DataView(new ArrayBuffer(8), 0).SetUint8/GetUint8
HWTEST_F_L0(BuiltinsDataViewTest,GetUint8)353 HWTEST_F_L0(BuiltinsDataViewTest, GetUint8)
354 {
355 JSTaggedValue tagged = CreateBuiltinsDataView(thread, 8, 0);
356 JSHandle<JSDataView> view(thread, JSDataView::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
357 SetUint8(thread, view, 0, JSTaggedValue(127));
358
359 std::vector<JSTaggedValue> vals{JSTaggedValue(0)};
360 auto result = DataViewAlgorithm(thread, vals, 6, AlgorithmType::GET_UINT8, view.GetTaggedValue());
361 ASSERT_EQ(result.GetRawData(), JSTaggedValue(127).GetRawData());
362 }
363
364 // new DataView(new ArrayBuffer(8), 4).SetUint8/GetFloat32
HWTEST_F_L0(BuiltinsDataViewTest,GetFloat32)365 HWTEST_F_L0(BuiltinsDataViewTest, GetFloat32)
366 {
367 JSTaggedValue tagged = CreateBuiltinsDataView(thread, 8, 0);
368 JSHandle<JSDataView> view(thread, JSDataView::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
369 SetUint8(thread, view, 4, JSTaggedValue(75));
370 SetUint8(thread, view, 5, JSTaggedValue(75));
371 SetUint8(thread, view, 6, JSTaggedValue(75));
372 SetUint8(thread, view, 7, JSTaggedValue(75));
373
374 std::vector<JSTaggedValue> vals{JSTaggedValue(4), JSTaggedValue::False()};
375 auto result = DataViewAlgorithm(thread, vals, 8, AlgorithmType::GET_FLOAT32, view.GetTaggedValue());
376
377 ASSERT_EQ(result.GetRawData(), JSTaggedValue(static_cast<double>(13323083)).GetRawData());
378 }
379
380 // new DataView(new ArrayBuffer(12), 4).SetUint8/GetFloat64
HWTEST_F_L0(BuiltinsDataViewTest,GetFloat64)381 HWTEST_F_L0(BuiltinsDataViewTest, GetFloat64)
382 {
383 JSTaggedValue tagged = CreateBuiltinsDataView(thread, 12, 0);
384 JSHandle<JSDataView> view(thread, JSDataView::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
385 SetUint8(thread, view, 4, JSTaggedValue(67));
386 SetUint8(thread, view, 5, JSTaggedValue(67));
387 SetUint8(thread, view, 6, JSTaggedValue(68));
388 SetUint8(thread, view, 7, JSTaggedValue(68));
389 SetUint8(thread, view, 8, JSTaggedValue(67));
390 SetUint8(thread, view, 9, JSTaggedValue(67));
391 SetUint8(thread, view, 10, JSTaggedValue(68));
392 SetUint8(thread, view, 11, JSTaggedValue(68));
393
394 std::vector<JSTaggedValue> vals{JSTaggedValue(4), JSTaggedValue::False()};
395 auto result = DataViewAlgorithm(thread, vals, 8, AlgorithmType::GET_FLOAT64, view.GetTaggedValue());
396 ASSERT_EQ(result.GetRawData(), JSTaggedValue(static_cast<double>(10846169068898440)).GetRawData());
397 }
398
399 // new DataView(new ArrayBuffer(8), 0).SetUint32/GetUint32
HWTEST_F_L0(BuiltinsDataViewTest,SetUint32)400 HWTEST_F_L0(BuiltinsDataViewTest, SetUint32)
401 {
402 JSTaggedValue tagged = CreateBuiltinsDataView(thread, 8, 0);
403 JSHandle<JSDataView> view(thread, JSDataView::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
404
405 std::vector<JSTaggedValue> vals{JSTaggedValue(0), JSTaggedValue(0x907f00f8), JSTaggedValue::True()};
406 auto result = DataViewAlgorithm(thread, vals, 10, AlgorithmType::SET_UINT32, view.GetTaggedValue());
407 ASSERT_EQ(result.GetRawData(), JSTaggedValue::VALUE_UNDEFINED);
408
409 std::vector<JSTaggedValue> vals2{JSTaggedValue(0), JSTaggedValue::False()};
410 auto result1 = DataViewAlgorithm(thread, vals2, 8, AlgorithmType::GET_UINT32, view.GetTaggedValue());
411 ASSERT_EQ(result1.GetRawData(), JSTaggedValue(static_cast<double>(0xf8007f90)).GetRawData());
412 }
413
414 // new DataView(new ArrayBuffer(8), 0).SetInt32/GetInt32
HWTEST_F_L0(BuiltinsDataViewTest,SetInt32)415 HWTEST_F_L0(BuiltinsDataViewTest, SetInt32)
416 {
417 JSTaggedValue tagged = CreateBuiltinsDataView(thread, 8, 0);
418 JSHandle<JSDataView> view(thread, JSDataView::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
419
420 std::vector<JSTaggedValue> vals{JSTaggedValue(0), JSTaggedValue(-1870724872), JSTaggedValue::True()};
421 auto result = DataViewAlgorithm(thread, vals, 10, AlgorithmType::SET_INT32, view.GetTaggedValue());
422 ASSERT_EQ(result.GetRawData(), JSTaggedValue::VALUE_UNDEFINED);
423
424 std::vector<JSTaggedValue> vals2{JSTaggedValue(0), JSTaggedValue::False()};
425 auto result1 = DataViewAlgorithm(thread, vals2, 8, AlgorithmType::GET_INT32, view.GetTaggedValue());
426 ASSERT_EQ(result1.GetRawData(), JSTaggedValue(-134185072).GetRawData());
427 }
428
429 // new DataView(new ArrayBuffer(8), 0).SetInt8/GetUint8
HWTEST_F_L0(BuiltinsDataViewTest,SetInt8)430 HWTEST_F_L0(BuiltinsDataViewTest, SetInt8)
431 {
432 JSTaggedValue tagged = CreateBuiltinsDataView(thread, 8, 0);
433 JSHandle<JSDataView> view(thread, JSDataView::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
434
435 std::vector<JSTaggedValue> vals{JSTaggedValue(0), JSTaggedValue(-1)};
436 auto result = DataViewAlgorithm(thread, vals, 8, AlgorithmType::SET_INT8, view.GetTaggedValue());
437 ASSERT_EQ(result.GetRawData(), JSTaggedValue::VALUE_UNDEFINED);
438
439 std::vector<JSTaggedValue> vals2{JSTaggedValue(0)};
440 auto result1 = DataViewAlgorithm(thread, vals2, 6, AlgorithmType::GET_UINT8, view.GetTaggedValue());
441
442 ASSERT_EQ(result1.GetRawData(), JSTaggedValue(255).GetRawData());
443 }
444
445 // new DataView(new ArrayBuffer(4), 0).SetFloat32/GetFloat32
HWTEST_F_L0(BuiltinsDataViewTest,SetFloat32)446 HWTEST_F_L0(BuiltinsDataViewTest, SetFloat32)
447 {
448 JSTaggedValue tagged = CreateBuiltinsDataView(thread, 4, 0);
449 JSHandle<JSDataView> view(thread, JSDataView::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
450 std::vector<JSTaggedValue> vals{JSTaggedValue(0), JSTaggedValue(42), JSTaggedValue::True()};
451 auto result = DataViewAlgorithm(thread, vals, 10, AlgorithmType::SET_FLOAT32, view.GetTaggedValue());
452 ASSERT_EQ(result.GetRawData(), JSTaggedValue::VALUE_UNDEFINED);
453
454 std::vector<JSTaggedValue> vals2{JSTaggedValue(0), JSTaggedValue::False()};
455 auto result1 = DataViewAlgorithm(thread, vals2, 8, AlgorithmType::GET_FLOAT32, view.GetTaggedValue());
456 ASSERT_EQ(result1.GetRawData(), JSTaggedValue(static_cast<double>(1.4441781973331565e-41)).GetRawData());
457 }
458
459 // new DataView(new ArrayBuffer(8), 0).SetFloat64/GetFloat64
HWTEST_F_L0(BuiltinsDataViewTest,SetFloat64)460 HWTEST_F_L0(BuiltinsDataViewTest, SetFloat64)
461 {
462 JSTaggedValue tagged = CreateBuiltinsDataView(thread, 8, 0);
463 JSHandle<JSDataView> view(thread, JSDataView::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
464
465 std::vector<JSTaggedValue> vals{JSTaggedValue(0), JSTaggedValue(42), JSTaggedValue::True()};
466 auto result = DataViewAlgorithm(thread, vals, 10, AlgorithmType::SET_FLOAT64, view.GetTaggedValue());
467 ASSERT_EQ(result.GetRawData(), JSTaggedValue::VALUE_UNDEFINED);
468
469 std::vector<JSTaggedValue> vals2{JSTaggedValue(0), JSTaggedValue::False()};
470 auto result1 = DataViewAlgorithm(thread, vals2, 8, AlgorithmType::GET_FLOAT64, view.GetTaggedValue());
471
472 ASSERT_EQ(result1.GetRawData(), JSTaggedValue(static_cast<double>(8.759e-320)).GetRawData());
473 }
474
BigInt64Common(JSThread * thread)475 static JSHandle<JSDataView> BigInt64Common(JSThread *thread)
476 {
477 JSTaggedValue tagged = CreateBuiltinsDataView(thread, 10, 2);
478 JSHandle<JSDataView> view(thread, JSDataView::Cast(reinterpret_cast<TaggedObject *>(tagged.GetRawData())));
479 JSTaggedValue tagged1 = BuiltTestUtil::CreateBuiltinsArrayBuffer(thread, 10);
480 JSHandle<JSArrayBuffer> arrBuf(thread, JSArrayBuffer::Cast(reinterpret_cast<TaggedObject *>(tagged1.GetRawData())));
481 arrBuf->SetArrayBufferData(thread, JSTaggedValue::Null());
482 view->SetViewedArrayBuffer(thread, arrBuf);
483 return view;
484 }
485
HWTEST_F_L0(BuiltinsDataViewTest,GetBigInt64)486 HWTEST_F_L0(BuiltinsDataViewTest, GetBigInt64)
487 {
488 // case: Detached Buffer
489 auto view = BigInt64Common(thread);
490 std::vector<JSTaggedValue> vals{JSTaggedValue(0), JSTaggedValue::False()};
491 auto result = DataViewAlgorithm(thread, vals, 8, AlgorithmType::GET_BIGINT64, view.GetTaggedValue());
492 EXPECT_TRUE(thread->HasPendingException());
493 EXPECT_EQ(result, JSTaggedValue::Exception());
494 thread->ClearException();
495 }
496
HWTEST_F_L0(BuiltinsDataViewTest,SetBigInt64)497 HWTEST_F_L0(BuiltinsDataViewTest, SetBigInt64)
498 {
499 auto view = BigInt64Common(thread);
500 std::vector<JSTaggedValue> vals{JSTaggedValue(0), JSTaggedValue(10)};
501 auto result = DataViewAlgorithm(thread, vals, 8, AlgorithmType::SET_BIGINT64, view.GetTaggedValue());
502 EXPECT_TRUE(thread->HasPendingException());
503 EXPECT_EQ(result, JSTaggedValue::Exception());
504 thread->ClearException();
505 // case index < 0 is unreachable
506 }
507 } // namespace panda::test
508