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 "ecmascript/builtins/builtins_bigint.h"
17
18 #include "ecmascript/global_env.h"
19 #include "ecmascript/js_bigint.h"
20 #include "ecmascript/js_primitive_ref.h"
21 #include "ecmascript/tests/test_helper.h"
22
23 using namespace panda::ecmascript;
24 using namespace panda::ecmascript::builtins;
25
26 namespace panda::test {
27 using BigInt = ecmascript::BigInt;
28 class BuiltinsBigIntTest : public testing::Test {
29 public:
SetUpTestCase()30 static void SetUpTestCase()
31 {
32 GTEST_LOG_(INFO) << "SetUpTestCase";
33 }
34
TearDownTestCase()35 static void TearDownTestCase()
36 {
37 GTEST_LOG_(INFO) << "TearDownCase";
38 }
39
SetUp()40 void SetUp() override
41 {
42 JSRuntimeOptions options;
43 #if PANDA_TARGET_LINUX
44 // for consistency requirement, use ohos_icu4j/data as icu-data-path
45 options.SetIcuDataPath(ICU_PATH);
46 #endif
47 options.SetEnableForceGC(true);
48 instance = JSNApi::CreateEcmaVM(options);
49 instance->SetEnableForceGC(true);
50 ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
51 thread = instance->GetJSThread();
52 scope = new EcmaHandleScope(thread);
53 }
54
TearDown()55 void TearDown() override
56 {
57 TestHelper::DestroyEcmaVMWithScope(instance, scope);
58 }
59
60 EcmaVM *instance {nullptr};
61 EcmaHandleScope *scope {nullptr};
62 JSThread *thread {nullptr};
63 };
64
65 // new BigInt(123)
HWTEST_F_L0(BuiltinsBigIntTest,BigIntConstructor_001)66 HWTEST_F_L0(BuiltinsBigIntTest, BigIntConstructor_001)
67 {
68 JSHandle<JSTaggedValue> numericValue(thread, JSTaggedValue(123));
69 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
70 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
71 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
72 ecmaRuntimeCallInfo->SetCallArg(0, numericValue.GetTaggedValue());
73
74 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
75 JSTaggedValue result = BuiltinsBigInt::BigIntConstructor(ecmaRuntimeCallInfo);
76 TestHelper::TearDownFrame(thread, prev);
77
78 EXPECT_TRUE(result.IsBigInt());
79 }
80
81 // new BigInt("456")
HWTEST_F_L0(BuiltinsBigIntTest,BigIntConstructor_002)82 HWTEST_F_L0(BuiltinsBigIntTest, BigIntConstructor_002)
83 {
84 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
85 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("456"));
86
87 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
88 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
89 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
90 ecmaRuntimeCallInfo->SetCallArg(0, numericValue.GetTaggedValue());
91
92 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
93 JSTaggedValue result = BuiltinsBigInt::BigIntConstructor(ecmaRuntimeCallInfo);
94 TestHelper::TearDownFrame(thread, prev);
95
96 EXPECT_TRUE(result.IsBigInt());
97 }
98
99 // AsIntN(64, (2 ^ 63 - 1))
HWTEST_F_L0(BuiltinsBigIntTest,AsIntN_001)100 HWTEST_F_L0(BuiltinsBigIntTest, AsIntN_001)
101 {
102 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
103 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("9223372036854775807"));
104 int bit = 64; // 64-bit
105
106 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
107 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
108 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
109 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(bit)));
110 ecmaRuntimeCallInfo->SetCallArg(1, numericValue.GetTaggedValue());
111
112 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
113 JSTaggedValue result = BuiltinsBigInt::AsIntN(ecmaRuntimeCallInfo);
114 TestHelper::TearDownFrame(thread, prev);
115
116 EXPECT_TRUE(result.IsBigInt());
117 JSHandle<BigInt> bigIntHandle(thread, result);
118 JSHandle<EcmaString> resultStr = BigInt::ToString(thread, bigIntHandle);
119 JSHandle<EcmaString> str = factory->NewFromASCII("9223372036854775807");
120 EXPECT_EQ(EcmaStringAccessor::Compare(*resultStr, *str), 0);
121 }
122
123 // AsIntN(64, (2 ^ 63))
HWTEST_F_L0(BuiltinsBigIntTest,AsIntN_002)124 HWTEST_F_L0(BuiltinsBigIntTest, AsIntN_002)
125 {
126 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
127 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("9223372036854775808"));
128 int bit = 64; // 64-bit
129
130 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
131 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
132 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
133 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(bit)));
134 ecmaRuntimeCallInfo->SetCallArg(1, numericValue.GetTaggedValue());
135
136 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
137 JSTaggedValue result = BuiltinsBigInt::AsIntN(ecmaRuntimeCallInfo);
138 TestHelper::TearDownFrame(thread, prev);
139
140 EXPECT_TRUE(result.IsBigInt());
141 JSHandle<BigInt> bigIntHandle(thread, result);
142 JSHandle<EcmaString> resultStr = BigInt::ToString(thread, bigIntHandle);
143 JSHandle<EcmaString> str = factory->NewFromASCII("-9223372036854775808");
144 EXPECT_EQ(EcmaStringAccessor::Compare(*resultStr, *str), 0);
145 }
146
147 // AsUintN(64, (2 ^ 64 - 1))
HWTEST_F_L0(BuiltinsBigIntTest,AsUintN_001)148 HWTEST_F_L0(BuiltinsBigIntTest, AsUintN_001)
149 {
150 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
151 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("18446744073709551615"));
152 int bit = 64; // 64-bit
153
154 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
155 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
156 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
157 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(bit)));
158 ecmaRuntimeCallInfo->SetCallArg(1, numericValue.GetTaggedValue());
159
160 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
161 JSTaggedValue result = BuiltinsBigInt::AsUintN(ecmaRuntimeCallInfo);
162 TestHelper::TearDownFrame(thread, prev);
163
164 EXPECT_TRUE(result.IsBigInt());
165 JSHandle<BigInt> bigIntHandle(thread, result);
166 JSHandle<EcmaString> resultStr = BigInt::ToString(thread, bigIntHandle);
167 JSHandle<EcmaString> str = factory->NewFromASCII("18446744073709551615");
168 EXPECT_EQ(EcmaStringAccessor::Compare(*resultStr, *str), 0);
169 }
170
171 // AsUintN(64, (2 ^ 64))
HWTEST_F_L0(BuiltinsBigIntTest,AsUintN_002)172 HWTEST_F_L0(BuiltinsBigIntTest, AsUintN_002)
173 {
174 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
175 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("18446744073709551616"));
176 int bit = 64; // 64-bit
177
178 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
179 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
180 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
181 ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(bit)));
182 ecmaRuntimeCallInfo->SetCallArg(1, numericValue.GetTaggedValue());
183
184 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
185 JSTaggedValue result = BuiltinsBigInt::AsUintN(ecmaRuntimeCallInfo);
186 TestHelper::TearDownFrame(thread, prev);
187
188 EXPECT_TRUE(result.IsBigInt());
189 JSHandle<BigInt> bigIntHandle(thread, result);
190 JSHandle<EcmaString> resultStr = BigInt::ToString(thread, bigIntHandle);
191 JSHandle<EcmaString> str = factory->NewFromASCII("0");
192 EXPECT_EQ(EcmaStringAccessor::Compare(*resultStr, *str), 0);
193 }
194
195 // using locale
HWTEST_F_L0(BuiltinsBigIntTest,ToLocaleString_001)196 HWTEST_F_L0(BuiltinsBigIntTest, ToLocaleString_001)
197 {
198 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
199 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("123456789123456789"));
200
201 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
202 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
203 ecmaRuntimeCallInfo1->SetThis(JSTaggedValue::Undefined());
204 ecmaRuntimeCallInfo1->SetCallArg(0, numericValue.GetTaggedValue());
205
206 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
207 JSTaggedValue result1 = BuiltinsBigInt::BigIntConstructor(ecmaRuntimeCallInfo1);
208 TestHelper::TearDownFrame(thread, prev);
209
210 JSHandle<BigInt> bigIntHandle(thread, result1);
211 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("de-DE"));
212
213 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
214 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
215 ecmaRuntimeCallInfo2->SetThis(bigIntHandle.GetTaggedValue());
216 ecmaRuntimeCallInfo2->SetCallArg(0, locale.GetTaggedValue());
217 ecmaRuntimeCallInfo2->SetCallArg(1, JSTaggedValue::Undefined());
218
219 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
220 JSTaggedValue result2 = BuiltinsBigInt::ToLocaleString(ecmaRuntimeCallInfo2);
221 TestHelper::TearDownFrame(thread, prev);
222
223 EXPECT_TRUE(result2.IsString());
224 JSHandle<EcmaString> ecmaStrHandle(thread, result2);
225 JSHandle<EcmaString> resultStr(factory->NewFromASCII("123.456.789.123.456.789"));
226 EXPECT_EQ(EcmaStringAccessor::Compare(*ecmaStrHandle, *resultStr), 0);
227 }
228
229 // using locale and options
HWTEST_F_L0(BuiltinsBigIntTest,ToLocaleString_002)230 HWTEST_F_L0(BuiltinsBigIntTest, ToLocaleString_002)
231 {
232 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
233 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
234 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
235 JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
236 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("123456789123456789"));
237 JSHandle<JSTaggedValue> formatStyle = thread->GlobalConstants()->GetHandledStyleString();
238 JSHandle<JSTaggedValue> styleKey(factory->NewFromASCII("currency"));
239 JSHandle<JSTaggedValue> styleValue(factory->NewFromASCII("EUR"));
240
241 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
242 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
243 ecmaRuntimeCallInfo1->SetThis(JSTaggedValue::Undefined());
244 ecmaRuntimeCallInfo1->SetCallArg(0, numericValue.GetTaggedValue());
245
246 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
247 JSTaggedValue result1 = BuiltinsBigInt::BigIntConstructor(ecmaRuntimeCallInfo1);
248 TestHelper::TearDownFrame(thread, prev);
249
250 JSHandle<BigInt> bigIntHandle(thread, result1);
251 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("de-DE"));
252 JSObject::SetProperty(thread, optionsObj, formatStyle, styleKey);
253 JSObject::SetProperty(thread, optionsObj, styleKey, styleValue);
254
255 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
256 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
257 ecmaRuntimeCallInfo2->SetThis(bigIntHandle.GetTaggedValue());
258 ecmaRuntimeCallInfo2->SetCallArg(0, locale.GetTaggedValue());
259 ecmaRuntimeCallInfo2->SetCallArg(1, optionsObj.GetTaggedValue());
260
261 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
262 JSTaggedValue result2 = BuiltinsBigInt::ToLocaleString(ecmaRuntimeCallInfo2);
263 TestHelper::TearDownFrame(thread, prev);
264
265 EXPECT_TRUE(result2.IsString());
266 JSHandle<EcmaString> ecmaStrHandle(thread, result2);
267 EXPECT_STREQ("123.456.789.123.456.789,00 €", EcmaStringAccessor(ecmaStrHandle).ToCString().c_str());
268 }
269
270 // 17.ToStirng()
HWTEST_F_L0(BuiltinsBigIntTest,ToString_001)271 HWTEST_F_L0(BuiltinsBigIntTest, ToString_001)
272 {
273 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
274 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("17"));
275
276 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
277 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
278 ecmaRuntimeCallInfo1->SetThis(JSTaggedValue::Undefined());
279 ecmaRuntimeCallInfo1->SetCallArg(0, numericValue.GetTaggedValue());
280
281 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
282 JSTaggedValue result1 = BuiltinsBigInt::BigIntConstructor(ecmaRuntimeCallInfo1);
283 TestHelper::TearDownFrame(thread, prev);
284
285 JSHandle<BigInt> bigIntHandle(thread, result1);
286 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
287 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
288 ecmaRuntimeCallInfo2->SetThis(bigIntHandle.GetTaggedValue());
289 ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue::Undefined());
290
291 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
292 JSTaggedValue result2 = BuiltinsBigInt::ToString(ecmaRuntimeCallInfo2);
293 TestHelper::TearDownFrame(thread, prev);
294
295 EXPECT_TRUE(result2.IsString());
296 JSHandle<EcmaString> ecmaStrHandle(thread, result2);
297 EXPECT_STREQ("17", EcmaStringAccessor(ecmaStrHandle).ToCString().c_str());
298 }
299
300 // -0.ToStirng()
HWTEST_F_L0(BuiltinsBigIntTest,ToString_002)301 HWTEST_F_L0(BuiltinsBigIntTest, ToString_002)
302 {
303 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
304 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("-0"));
305
306 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
307 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
308 ecmaRuntimeCallInfo1->SetThis(JSTaggedValue::Undefined());
309 ecmaRuntimeCallInfo1->SetCallArg(0, numericValue.GetTaggedValue());
310
311 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
312 JSTaggedValue result1 = BuiltinsBigInt::BigIntConstructor(ecmaRuntimeCallInfo1);
313 TestHelper::TearDownFrame(thread, prev);
314
315 JSHandle<BigInt> bigIntHandle(thread, result1);
316 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
317 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
318 ecmaRuntimeCallInfo2->SetThis(bigIntHandle.GetTaggedValue());
319 ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue::Undefined());
320
321 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
322 JSTaggedValue result2 = BuiltinsBigInt::ToString(ecmaRuntimeCallInfo2);
323 TestHelper::TearDownFrame(thread, prev);
324
325 EXPECT_TRUE(result2.IsString());
326 JSHandle<EcmaString> ecmaStrHandle(thread, result2);
327 EXPECT_STREQ("0", EcmaStringAccessor(ecmaStrHandle).ToCString().c_str());
328 }
329
330 // -10.ToStirng(2)
HWTEST_F_L0(BuiltinsBigIntTest,ToString_003)331 HWTEST_F_L0(BuiltinsBigIntTest, ToString_003)
332 {
333 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
334 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("-10"));
335
336 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
337 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
338 ecmaRuntimeCallInfo1->SetThis(JSTaggedValue::Undefined());
339 ecmaRuntimeCallInfo1->SetCallArg(0, numericValue.GetTaggedValue());
340
341 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
342 JSTaggedValue result1 = BuiltinsBigInt::BigIntConstructor(ecmaRuntimeCallInfo1);
343 TestHelper::TearDownFrame(thread, prev);
344
345 JSHandle<BigInt> bigIntHandle(thread, result1);
346 JSHandle<JSTaggedValue> radix(thread, JSTaggedValue(2));
347 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
348 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
349 ecmaRuntimeCallInfo2->SetThis(bigIntHandle.GetTaggedValue());
350 ecmaRuntimeCallInfo2->SetCallArg(0, radix.GetTaggedValue());
351
352 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
353 JSTaggedValue result2 = BuiltinsBigInt::ToString(ecmaRuntimeCallInfo2);
354 TestHelper::TearDownFrame(thread, prev);
355
356 EXPECT_TRUE(result2.IsString());
357 JSHandle<EcmaString> ecmaStrHandle(thread, result2);
358 EXPECT_STREQ("-1010", EcmaStringAccessor(ecmaStrHandle).ToCString().c_str());
359 }
360
361 // 254.ToStirng(16)
HWTEST_F_L0(BuiltinsBigIntTest,ToString_004)362 HWTEST_F_L0(BuiltinsBigIntTest, ToString_004)
363 {
364 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
365 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("254"));
366
367 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
368 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
369 ecmaRuntimeCallInfo1->SetThis(JSTaggedValue::Undefined());
370 ecmaRuntimeCallInfo1->SetCallArg(0, numericValue.GetTaggedValue());
371
372 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
373 JSTaggedValue result1 = BuiltinsBigInt::BigIntConstructor(ecmaRuntimeCallInfo1);
374 TestHelper::TearDownFrame(thread, prev);
375
376 JSHandle<BigInt> bigIntHandle(thread, result1);
377 JSHandle<JSTaggedValue> radix(thread, JSTaggedValue(16));
378 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
379 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
380 ecmaRuntimeCallInfo2->SetThis(bigIntHandle.GetTaggedValue());
381 ecmaRuntimeCallInfo2->SetCallArg(0, radix.GetTaggedValue());
382
383 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
384 JSTaggedValue result2 = BuiltinsBigInt::ToString(ecmaRuntimeCallInfo2);
385 TestHelper::TearDownFrame(thread, prev);
386
387 EXPECT_TRUE(result2.IsString());
388 JSHandle<EcmaString> ecmaStrHandle(thread, result2);
389 EXPECT_STREQ("fe", EcmaStringAccessor(ecmaStrHandle).ToCString().c_str());
390 }
391
392 // BigInt.ValueOf
HWTEST_F_L0(BuiltinsBigIntTest,ValueOf_001)393 HWTEST_F_L0(BuiltinsBigIntTest, ValueOf_001)
394 {
395 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
396 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("-65536"));
397
398 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
399 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
400 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
401 ecmaRuntimeCallInfo->SetCallArg(0, numericValue.GetTaggedValue());
402
403 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
404 JSTaggedValue result1 = BuiltinsBigInt::BigIntConstructor(ecmaRuntimeCallInfo);
405 TestHelper::TearDownFrame(thread, prev);
406
407 JSHandle<BigInt> bigIntHandle(thread, result1);
408 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
409 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
410 ecmaRuntimeCallInfo2->SetThis(bigIntHandle.GetTaggedValue());
411
412 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
413 JSTaggedValue result2 = BuiltinsBigInt::ValueOf(ecmaRuntimeCallInfo2);
414 TestHelper::TearDownFrame(thread, prev);
415
416 EXPECT_EQ(BigInt::SameValue(result1, result2), true);
417 }
418
419 // Object.ValueOf
HWTEST_F_L0(BuiltinsBigIntTest,ValueOf_002)420 HWTEST_F_L0(BuiltinsBigIntTest, ValueOf_002)
421 {
422 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
423 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("65535"));
424
425 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
426 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
427 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
428 ecmaRuntimeCallInfo->SetCallArg(0, numericValue.GetTaggedValue());
429
430 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
431 JSTaggedValue result1 = BuiltinsBigInt::BigIntConstructor(ecmaRuntimeCallInfo);
432 TestHelper::TearDownFrame(thread, prev);
433
434 JSHandle<BigInt> bigIntHandle(thread, result1);
435 JSHandle<JSTaggedValue> bigIntObj(bigIntHandle);
436
437 JSHandle<JSPrimitiveRef> jsPrimitiveRef = factory->NewJSPrimitiveRef(PrimitiveType::PRIMITIVE_BIGINT, bigIntObj);
438 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
439 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
440 ecmaRuntimeCallInfo2->SetThis(jsPrimitiveRef.GetTaggedValue());
441
442 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
443 JSTaggedValue result2 = BuiltinsBigInt::ValueOf(ecmaRuntimeCallInfo2);
444 TestHelper::TearDownFrame(thread, prev);
445
446 EXPECT_EQ(BigInt::SameValue(bigIntHandle.GetTaggedValue(), result2), true);
447 }
448
449 // testcases of NumberToBigint()
HWTEST_F_L0(BuiltinsBigIntTest,NumberToBigint)450 HWTEST_F_L0(BuiltinsBigIntTest, NumberToBigint)
451 {
452 JSHandle<JSTaggedValue> number(thread, JSTaggedValue::Undefined());
453 JSHandle<JSTaggedValue> bigint(thread, JSTaggedValue::Undefined());
454
455 number = JSHandle<JSTaggedValue>(thread, JSTaggedValue(base::MAX_VALUE));
456 bigint = JSHandle<JSTaggedValue>(thread, BigInt::NumberToBigInt(thread, number));
457 ASSERT_TRUE(bigint->IsBigInt());
458 bool compareRes = JSTaggedValue::Equal(thread, number, bigint);
459 ASSERT_TRUE(compareRes);
460
461 number = JSHandle<JSTaggedValue>(thread, JSTaggedValue(-base::MAX_VALUE));
462 bigint = JSHandle<JSTaggedValue>(thread, BigInt::NumberToBigInt(thread, number));
463 ASSERT_TRUE(bigint->IsBigInt());
464 compareRes = JSTaggedValue::Equal(thread, number, bigint);
465 ASSERT_TRUE(JSHandle<BigInt>::Cast(bigint)->GetSign());
466 ASSERT_TRUE(compareRes);
467
468 number = JSHandle<JSTaggedValue>(thread, JSTaggedValue(-0xffffffff));
469 bigint = JSHandle<JSTaggedValue>(thread, BigInt::NumberToBigInt(thread, number));
470 ASSERT_TRUE(bigint->IsBigInt());
471 compareRes = JSTaggedValue::Equal(thread, number, bigint);
472 ASSERT_TRUE(compareRes);
473
474 number = JSHandle<JSTaggedValue>(thread, JSTaggedValue(0));
475 bigint = JSHandle<JSTaggedValue>(thread, BigInt::NumberToBigInt(thread, number));
476 ASSERT_TRUE(bigint->IsBigInt());
477 compareRes = JSTaggedValue::Equal(thread, number, bigint);
478 ASSERT_TRUE(compareRes);
479
480 number = JSHandle<JSTaggedValue>(thread, JSTaggedValue(std::numeric_limits<double>::infinity()));
481 bigint = JSHandle<JSTaggedValue>(thread, BigInt::NumberToBigInt(thread, number));
482 ASSERT_TRUE(bigint->IsException());
483 thread->ClearException();
484 }
485
486 // testcases of BigintToNumber()
HWTEST_F_L0(BuiltinsBigIntTest,BigintToNumber)487 HWTEST_F_L0(BuiltinsBigIntTest, BigintToNumber)
488 {
489 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
490 JSHandle<JSTaggedValue> bigint(thread, JSTaggedValue::Undefined());
491 JSTaggedNumber number(0);
492
493 JSHandle<JSTaggedValue> parma(factory->NewFromASCII("0xffff"));
494 bigint = JSHandle<JSTaggedValue>(thread, JSTaggedValue::ToBigInt(thread, parma));
495 ASSERT_TRUE(bigint->IsBigInt());
496 number = BigInt::BigIntToNumber(JSHandle<BigInt>::Cast(bigint));
497 ASSERT_EQ(number.GetNumber(), static_cast<double>(0xffff));
498
499 parma = JSHandle<JSTaggedValue>(
500 factory->NewFromASCII("0xfffffffffffff8000000000000000000000000000000000000000000000000000"
501 "0000000000000000000000000000000000000000000000000000000000000000000"
502 "0000000000000000000000000000000000000000000000000000000000000000000"
503 "000000000000000000000000000000000000000000000000000000000"));
504 bigint = JSHandle<JSTaggedValue>(thread, JSTaggedValue::ToBigInt(thread, parma));
505 ASSERT_TRUE(bigint->IsBigInt());
506 number = BigInt::BigIntToNumber(JSHandle<BigInt>::Cast(bigint));
507 ASSERT_EQ(number.GetNumber(), base::MAX_VALUE);
508
509 parma = JSHandle<JSTaggedValue>(thread, JSTaggedValue::False());
510 bigint = JSHandle<JSTaggedValue>(thread, JSTaggedValue::ToBigInt(thread, parma));
511 ASSERT_TRUE(bigint->IsBigInt());
512 ASSERT_TRUE(JSHandle<BigInt>::Cast(bigint)->IsZero());
513 number = BigInt::BigIntToNumber(JSHandle<BigInt>::Cast(bigint));
514 ASSERT_EQ(number.GetNumber(), 0.0);
515
516 parma = JSHandle<JSTaggedValue>(thread, JSTaggedValue(base::MAX_VALUE));
517 bigint = JSHandle<JSTaggedValue>(thread, BigInt::NumberToBigInt(thread, parma));
518 ASSERT_TRUE(bigint->IsBigInt());
519 number = BigInt::BigIntToNumber(JSHandle<BigInt>::Cast(bigint));
520 ASSERT_EQ(number.GetNumber(), base::MAX_VALUE);
521
522 parma = JSHandle<JSTaggedValue>(thread, JSTaggedValue(-base::MAX_VALUE));
523 bigint = JSHandle<JSTaggedValue>(thread, BigInt::NumberToBigInt(thread, parma));
524 ASSERT_TRUE(bigint->IsBigInt());
525 number = BigInt::BigIntToNumber(JSHandle<BigInt>::Cast(bigint));
526 ASSERT_EQ(number.GetNumber(), -base::MAX_VALUE);
527
528 parma = JSHandle<JSTaggedValue>(thread, JSTaggedValue(-0xffffffff));
529 bigint = JSHandle<JSTaggedValue>(thread, BigInt::NumberToBigInt(thread, parma));
530 ASSERT_TRUE(bigint->IsBigInt());
531 number = BigInt::BigIntToNumber(JSHandle<BigInt>::Cast(bigint));
532 ASSERT_EQ(number.GetNumber(), -0xffffffff);
533 }
534
535 // testcases of StringToBigInt(EcmaString)
HWTEST_F_L0(BuiltinsBigIntTest,StringToBigInt)536 HWTEST_F_L0(BuiltinsBigIntTest, StringToBigInt)
537 {
538 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
539 JSHandle<JSTaggedValue> bigint;
540 JSHandle<EcmaString> str;
541 JSHandle<JSTaggedValue> parma;
542
543 // hex string
544 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("0xffff"));
545 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
546 ASSERT_TRUE(bigint->IsBigInt());
547 str = BigInt::ToString(thread, JSHandle<BigInt>::Cast(bigint), BigInt::HEXADECIMAL);
548 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("ffff"));
549 ASSERT_EQ(EcmaStringAccessor::Compare(*str, reinterpret_cast<EcmaString *>(parma->GetRawData())), 0);
550
551 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("0XFFFF"));
552 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
553 ASSERT_TRUE(bigint->IsBigInt());
554 str = BigInt::ToString(thread, JSHandle<BigInt>::Cast(bigint), BigInt::HEXADECIMAL);
555 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("ffff"));
556 ASSERT_EQ(EcmaStringAccessor::Compare(*str, reinterpret_cast<EcmaString *>(parma->GetRawData())), 0);
557
558 // binary string
559 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("0b11111111"));
560 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
561 ASSERT_TRUE(bigint->IsBigInt());
562 str = BigInt::ToString(thread, JSHandle<BigInt>::Cast(bigint), BigInt::BINARY);
563 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("11111111"));
564 ASSERT_EQ(EcmaStringAccessor::Compare(*str, reinterpret_cast<EcmaString *>(parma->GetRawData())), 0);
565
566 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("0B11111111"));
567 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
568 ASSERT_TRUE(bigint->IsBigInt());
569 str = BigInt::ToString(thread, JSHandle<BigInt>::Cast(bigint), BigInt::BINARY);
570 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("11111111"));
571 ASSERT_EQ(EcmaStringAccessor::Compare(*str, reinterpret_cast<EcmaString *>(parma->GetRawData())), 0);
572
573 // octal string
574 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("0o123456"));
575 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
576 ASSERT_TRUE(bigint->IsBigInt());
577 str = BigInt::ToString(thread, JSHandle<BigInt>::Cast(bigint), BigInt::OCTAL);
578 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("123456"));
579 ASSERT_EQ(EcmaStringAccessor::Compare(*str, reinterpret_cast<EcmaString *>(parma->GetRawData())), 0);
580
581 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("0O123456"));
582 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
583 ASSERT_TRUE(bigint->IsBigInt());
584 str = BigInt::ToString(thread, JSHandle<BigInt>::Cast(bigint), BigInt::OCTAL);
585 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("123456"));
586 ASSERT_EQ(EcmaStringAccessor::Compare(*str, reinterpret_cast<EcmaString *>(parma->GetRawData())), 0);
587
588 // decimal string
589 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("999999999"));
590 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
591 ASSERT_TRUE(bigint->IsBigInt());
592 str = BigInt::ToString(thread, JSHandle<BigInt>::Cast(bigint));
593 ASSERT_EQ(EcmaStringAccessor::Compare(*str, reinterpret_cast<EcmaString *>(parma->GetRawData())), 0);
594
595 // string has space
596 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII(" 123 "));
597 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
598 ASSERT_TRUE(bigint->IsBigInt());
599 JSHandle<JSTaggedValue> number(thread, JSTaggedValue(static_cast<double>(123)));
600 bool compareRes = JSTaggedValue::Equal(thread, bigint, number);
601 ASSERT_TRUE(compareRes);
602
603 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("123 "));
604 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
605 ASSERT_TRUE(bigint->IsBigInt());
606 number = JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<double>(123)));
607 compareRes = JSTaggedValue::Equal(thread, bigint, number);
608 ASSERT_TRUE(compareRes);
609
610 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII(" 123"));
611 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
612 ASSERT_TRUE(bigint->IsBigInt());
613 number = JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<double>(123)));
614 compareRes = JSTaggedValue::Equal(thread, bigint, number);
615 ASSERT_TRUE(compareRes);
616
617 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII(""));
618 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
619 ASSERT_TRUE(bigint->IsBigInt());
620 ASSERT_TRUE(JSHandle<BigInt>::Cast(bigint)->IsZero());
621
622 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII(" "));
623 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
624 ASSERT_TRUE(bigint->IsBigInt());
625 ASSERT_TRUE(JSHandle<BigInt>::Cast(bigint)->IsZero());
626 }
627 } // namespace panda::test
628