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 BaseTestWithScope<true> {
29 };
30
31 enum class AlgorithmType {
32 BIGINT_CONSTRUCTOR,
33 BIGINT_ASINTN,
34 BIGINT_ASUINTN,
35 BIGINT_TOLOCALSTR,
36 BIGINT_TOSTR,
37 BIGINT_VALUEOF
38 };
39
BigIntAlgorithm(JSThread *thread, std::vector<JSTaggedValue>& args, int32_t argLen, AlgorithmType type, JSTaggedValue argThis = JSTaggedValue::Undefined())40 static JSTaggedValue BigIntAlgorithm(JSThread *thread, std::vector<JSTaggedValue>& args, int32_t argLen,
41 AlgorithmType type, JSTaggedValue argThis = JSTaggedValue::Undefined())
42 {
43 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), argLen);
44 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
45 ecmaRuntimeCallInfo->SetThis(argThis);
46 for (size_t i = 0; i < args.size(); i++) {
47 ecmaRuntimeCallInfo->SetCallArg(i, args[i]);
48 }
49
50 auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
51 JSTaggedValue result;
52 switch (type) {
53 case AlgorithmType::BIGINT_CONSTRUCTOR:
54 result = BuiltinsBigInt::BigIntConstructor(ecmaRuntimeCallInfo);
55 break;
56 case AlgorithmType::BIGINT_ASINTN:
57 result = BuiltinsBigInt::AsIntN(ecmaRuntimeCallInfo);
58 break;
59 case AlgorithmType::BIGINT_ASUINTN:
60 result = BuiltinsBigInt::AsUintN(ecmaRuntimeCallInfo);
61 break;
62 case AlgorithmType::BIGINT_TOLOCALSTR:
63 result = BuiltinsBigInt::ToLocaleString(ecmaRuntimeCallInfo);
64 break;
65 case AlgorithmType::BIGINT_TOSTR:
66 result = BuiltinsBigInt::ToString(ecmaRuntimeCallInfo);
67 break;
68 case AlgorithmType::BIGINT_VALUEOF:
69 result = BuiltinsBigInt::ValueOf(ecmaRuntimeCallInfo);
70 break;
71 default:
72 break;
73 }
74
75 TestHelper::TearDownFrame(thread, prev);
76 return result;
77 }
78
79 // new BigInt(123)
HWTEST_F_L0(BuiltinsBigIntTest, BigIntConstructor_001)80 HWTEST_F_L0(BuiltinsBigIntTest, BigIntConstructor_001)
81 {
82 JSHandle<JSTaggedValue> numericValue(thread, JSTaggedValue(123));
83 std::vector<JSTaggedValue> vals{numericValue.GetTaggedValue()};
84 auto result = BigIntAlgorithm(thread, vals, 6, AlgorithmType::BIGINT_CONSTRUCTOR);
85
86 EXPECT_TRUE(result.IsBigInt());
87 }
88
89 // new BigInt("456")
HWTEST_F_L0(BuiltinsBigIntTest, BigIntConstructor_002)90 HWTEST_F_L0(BuiltinsBigIntTest, BigIntConstructor_002)
91 {
92 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
93 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("456"));
94
95 std::vector<JSTaggedValue> vals{numericValue.GetTaggedValue()};
96 auto result = BigIntAlgorithm(thread, vals, 6, AlgorithmType::BIGINT_CONSTRUCTOR);
97 EXPECT_TRUE(result.IsBigInt());
98 }
99
100 // AsIntN(64, (2 ^ 63 - 1))
HWTEST_F_L0(BuiltinsBigIntTest, AsIntN_001)101 HWTEST_F_L0(BuiltinsBigIntTest, AsIntN_001)
102 {
103 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
104 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("9223372036854775807"));
105 int bit = 64; // 64-bit
106 std::vector<JSTaggedValue> vals{JSTaggedValue(static_cast<int>(bit)), numericValue.GetTaggedValue()};
107 auto result = BigIntAlgorithm(thread, vals, 8, AlgorithmType::BIGINT_ASINTN);
108 EXPECT_TRUE(result.IsBigInt());
109
110 JSHandle<BigInt> bigIntHandle(thread, result);
111 JSHandle<EcmaString> resultStr = BigInt::ToString(thread, bigIntHandle);
112 JSHandle<EcmaString> str = factory->NewFromASCII("9223372036854775807");
113 EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultStr, str), 0);
114 }
115
116 // AsIntN(64, (2 ^ 63))
HWTEST_F_L0(BuiltinsBigIntTest, AsIntN_002)117 HWTEST_F_L0(BuiltinsBigIntTest, AsIntN_002)
118 {
119 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
120 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("9223372036854775808"));
121 int bit = 64; // 64-bit
122 std::vector<JSTaggedValue> vals{JSTaggedValue(static_cast<int>(bit)), numericValue.GetTaggedValue()};
123 auto result = BigIntAlgorithm(thread, vals, 8, AlgorithmType::BIGINT_ASINTN);
124
125 EXPECT_TRUE(result.IsBigInt());
126 JSHandle<BigInt> bigIntHandle(thread, result);
127 JSHandle<EcmaString> resultStr = BigInt::ToString(thread, bigIntHandle);
128 JSHandle<EcmaString> str = factory->NewFromASCII("-9223372036854775808");
129 EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultStr, str), 0);
130 }
131
132 // AsUintN(64, (2 ^ 64 - 1))
HWTEST_F_L0(BuiltinsBigIntTest, AsUintN_001)133 HWTEST_F_L0(BuiltinsBigIntTest, AsUintN_001)
134 {
135 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
136 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("18446744073709551615"));
137 int bit = 64; // 64-bit
138 std::vector<JSTaggedValue> vals{JSTaggedValue(static_cast<int>(bit)), numericValue.GetTaggedValue()};
139 auto result = BigIntAlgorithm(thread, vals, 8, AlgorithmType::BIGINT_ASUINTN);
140
141 EXPECT_TRUE(result.IsBigInt());
142 JSHandle<BigInt> bigIntHandle(thread, result);
143 JSHandle<EcmaString> resultStr = BigInt::ToString(thread, bigIntHandle);
144 JSHandle<EcmaString> str = factory->NewFromASCII("18446744073709551615");
145 EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultStr, str), 0);
146 }
147
148 // AsUintN(64, (2 ^ 64))
HWTEST_F_L0(BuiltinsBigIntTest, AsUintN_002)149 HWTEST_F_L0(BuiltinsBigIntTest, AsUintN_002)
150 {
151 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
152 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("18446744073709551616"));
153 int bit = 64; // 64-bit
154
155 std::vector<JSTaggedValue> vals{JSTaggedValue(static_cast<int>(bit)), numericValue.GetTaggedValue()};
156 auto result = BigIntAlgorithm(thread, vals, 8, AlgorithmType::BIGINT_ASUINTN);
157
158 EXPECT_TRUE(result.IsBigInt());
159 JSHandle<BigInt> bigIntHandle(thread, result);
160 JSHandle<EcmaString> resultStr = BigInt::ToString(thread, bigIntHandle);
161 JSHandle<EcmaString> str = factory->NewFromASCII("0");
162 EXPECT_EQ(EcmaStringAccessor::Compare(instance, resultStr, str), 0);
163 }
164
165 // using locale
HWTEST_F_L0(BuiltinsBigIntTest, ToLocaleString_001)166 HWTEST_F_L0(BuiltinsBigIntTest, ToLocaleString_001)
167 {
168 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
169 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("123456789123456789"));
170
171 std::vector<JSTaggedValue> vals{numericValue.GetTaggedValue()};
172 auto result1 = BigIntAlgorithm(thread, vals, 6, AlgorithmType::BIGINT_CONSTRUCTOR);
173
174 JSHandle<BigInt> bigIntHandle(thread, result1);
175 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("de-DE"));
176
177 std::vector<JSTaggedValue> vals2{locale.GetTaggedValue(), JSTaggedValue::Undefined()};
178 auto result2 = BigIntAlgorithm(thread, vals2, 8, AlgorithmType::BIGINT_TOLOCALSTR, bigIntHandle.GetTaggedValue());
179
180 EXPECT_TRUE(result2.IsString());
181 JSHandle<EcmaString> ecmaStrHandle(thread, result2);
182 JSHandle<EcmaString> resultStr(factory->NewFromASCII("123.456.789.123.456.789"));
183 EXPECT_EQ(EcmaStringAccessor::Compare(instance, ecmaStrHandle, resultStr), 0);
184 }
185
186 // using locale and options
HWTEST_F_L0(BuiltinsBigIntTest, ToLocaleString_002)187 HWTEST_F_L0(BuiltinsBigIntTest, ToLocaleString_002)
188 {
189 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
190 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
191 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
192 JSHandle<JSObject> optionsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
193 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("123456789123456789"));
194 JSHandle<JSTaggedValue> formatStyle = thread->GlobalConstants()->GetHandledStyleString();
195 JSHandle<JSTaggedValue> styleKey(factory->NewFromASCII("currency"));
196 JSHandle<JSTaggedValue> styleValue(factory->NewFromASCII("EUR"));
197
198 std::vector<JSTaggedValue> vals{numericValue.GetTaggedValue()};
199 auto result1 = BigIntAlgorithm(thread, vals, 6, AlgorithmType::BIGINT_CONSTRUCTOR);
200
201 JSHandle<BigInt> bigIntHandle(thread, result1);
202 JSHandle<JSTaggedValue> locale(factory->NewFromASCII("de-DE"));
203 JSObject::SetProperty(thread, optionsObj, formatStyle, styleKey);
204 JSObject::SetProperty(thread, optionsObj, styleKey, styleValue);
205
206 std::vector<JSTaggedValue> vals2{locale.GetTaggedValue(), optionsObj.GetTaggedValue()};
207 auto result2 = BigIntAlgorithm(thread, vals2, 8, AlgorithmType::BIGINT_TOLOCALSTR, bigIntHandle.GetTaggedValue());
208
209 EXPECT_TRUE(result2.IsString());
210 JSHandle<EcmaString> ecmaStrHandle(thread, result2);
211 EXPECT_STREQ("123.456.789.123.456.789,00 €", EcmaStringAccessor(ecmaStrHandle).ToCString().c_str());
212 }
213
214 // 17.ToStirng()
HWTEST_F_L0(BuiltinsBigIntTest, ToString_001)215 HWTEST_F_L0(BuiltinsBigIntTest, ToString_001)
216 {
217 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
218 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("17"));
219
220 std::vector<JSTaggedValue> vals{numericValue.GetTaggedValue()};
221 auto result1 = BigIntAlgorithm(thread, vals, 6, AlgorithmType::BIGINT_CONSTRUCTOR);
222
223 JSHandle<BigInt> bigIntHandle(thread, result1);
224 std::vector<JSTaggedValue> vals2{JSTaggedValue::Undefined()};
225 auto result2 = BigIntAlgorithm(thread, vals2, 6, AlgorithmType::BIGINT_TOSTR, bigIntHandle.GetTaggedValue());
226
227 EXPECT_TRUE(result2.IsString());
228 JSHandle<EcmaString> ecmaStrHandle(thread, result2);
229 EXPECT_STREQ("17", EcmaStringAccessor(ecmaStrHandle).ToCString().c_str());
230 }
231
232 // -0.ToStirng()
HWTEST_F_L0(BuiltinsBigIntTest, ToString_002)233 HWTEST_F_L0(BuiltinsBigIntTest, ToString_002)
234 {
235 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
236 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("-0"));
237
238 std::vector<JSTaggedValue> vals{numericValue.GetTaggedValue()};
239 auto result1 = BigIntAlgorithm(thread, vals, 6, AlgorithmType::BIGINT_CONSTRUCTOR);
240
241 JSHandle<BigInt> bigIntHandle(thread, result1);
242 std::vector<JSTaggedValue> vals2{JSTaggedValue::Undefined()};
243 auto result2 = BigIntAlgorithm(thread, vals2, 6, AlgorithmType::BIGINT_TOSTR, bigIntHandle.GetTaggedValue());
244
245 EXPECT_TRUE(result2.IsString());
246 JSHandle<EcmaString> ecmaStrHandle(thread, result2);
247 EXPECT_STREQ("0", EcmaStringAccessor(ecmaStrHandle).ToCString().c_str());
248 }
249
250 // -10.ToStirng(2)
HWTEST_F_L0(BuiltinsBigIntTest, ToString_003)251 HWTEST_F_L0(BuiltinsBigIntTest, ToString_003)
252 {
253 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
254 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("-10"));
255
256 std::vector<JSTaggedValue> vals{numericValue.GetTaggedValue()};
257 auto result1 = BigIntAlgorithm(thread, vals, 6, AlgorithmType::BIGINT_CONSTRUCTOR);
258
259 JSHandle<BigInt> bigIntHandle(thread, result1);
260 JSHandle<JSTaggedValue> radix(thread, JSTaggedValue(2));
261 std::vector<JSTaggedValue> vals2{radix.GetTaggedValue()};
262 auto result2 = BigIntAlgorithm(thread, vals2, 6, AlgorithmType::BIGINT_TOSTR, bigIntHandle.GetTaggedValue());
263
264 EXPECT_TRUE(result2.IsString());
265 JSHandle<EcmaString> ecmaStrHandle(thread, result2);
266 EXPECT_STREQ("-1010", EcmaStringAccessor(ecmaStrHandle).ToCString().c_str());
267 }
268
269 // 254.ToStirng(16)
HWTEST_F_L0(BuiltinsBigIntTest, ToString_004)270 HWTEST_F_L0(BuiltinsBigIntTest, ToString_004)
271 {
272 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
273 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("254"));
274
275 std::vector<JSTaggedValue> vals{numericValue.GetTaggedValue()};
276 auto result1 = BigIntAlgorithm(thread, vals, 6, AlgorithmType::BIGINT_CONSTRUCTOR);
277
278 JSHandle<BigInt> bigIntHandle(thread, result1);
279 JSHandle<JSTaggedValue> radix(thread, JSTaggedValue(16));
280 std::vector<JSTaggedValue> vals2{radix.GetTaggedValue()};
281 auto result2 = BigIntAlgorithm(thread, vals2, 6, AlgorithmType::BIGINT_TOSTR, bigIntHandle.GetTaggedValue());
282
283 EXPECT_TRUE(result2.IsString());
284 JSHandle<EcmaString> ecmaStrHandle(thread, result2);
285 EXPECT_STREQ("fe", EcmaStringAccessor(ecmaStrHandle).ToCString().c_str());
286 }
287
288 // BigInt.ValueOf
HWTEST_F_L0(BuiltinsBigIntTest, ValueOf_001)289 HWTEST_F_L0(BuiltinsBigIntTest, ValueOf_001)
290 {
291 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
292 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("-65536"));
293
294 std::vector<JSTaggedValue> vals{numericValue.GetTaggedValue()};
295 auto result1 = BigIntAlgorithm(thread, vals, 6, AlgorithmType::BIGINT_CONSTRUCTOR);
296
297 JSHandle<BigInt> bigIntHandle(thread, result1);
298 std::vector<JSTaggedValue> vals2{};
299 auto result2 = BigIntAlgorithm(thread, vals2, 4, AlgorithmType::BIGINT_VALUEOF, bigIntHandle.GetTaggedValue());
300
301 EXPECT_EQ(BigInt::SameValue(result1, result2), true);
302 }
303
304 // Object.ValueOf
HWTEST_F_L0(BuiltinsBigIntTest, ValueOf_002)305 HWTEST_F_L0(BuiltinsBigIntTest, ValueOf_002)
306 {
307 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
308 JSHandle<JSTaggedValue> numericValue(factory->NewFromASCII("65535"));
309
310 std::vector<JSTaggedValue> vals{numericValue.GetTaggedValue()};
311 auto result1 = BigIntAlgorithm(thread, vals, 6, AlgorithmType::BIGINT_CONSTRUCTOR);
312
313 JSHandle<BigInt> bigIntHandle(thread, result1);
314 JSHandle<JSTaggedValue> bigIntObj(bigIntHandle);
315 std::vector<JSTaggedValue> vals2{};
316
317 JSHandle<JSPrimitiveRef> jsPrimitiveRef = factory->NewJSPrimitiveRef(PrimitiveType::PRIMITIVE_BIGINT, bigIntObj);
318 auto result2 = BigIntAlgorithm(thread, vals2, 4, AlgorithmType::BIGINT_VALUEOF, jsPrimitiveRef.GetTaggedValue());
319
320 EXPECT_EQ(BigInt::SameValue(bigIntHandle.GetTaggedValue(), result2), true);
321 }
322
323 // testcases of NumberToBigint()
HWTEST_F_L0(BuiltinsBigIntTest, NumberToBigint)324 HWTEST_F_L0(BuiltinsBigIntTest, NumberToBigint)
325 {
326 JSHandle<JSTaggedValue> number(thread, JSTaggedValue::Undefined());
327 JSHandle<JSTaggedValue> bigint(thread, JSTaggedValue::Undefined());
328
329 number = JSHandle<JSTaggedValue>(thread, JSTaggedValue(base::MAX_VALUE));
330 bigint = JSHandle<JSTaggedValue>(thread, BigInt::NumberToBigInt(thread, number));
331 ASSERT_TRUE(bigint->IsBigInt());
332 bool compareRes = JSTaggedValue::Equal(thread, number, bigint);
333 ASSERT_TRUE(compareRes);
334
335 number = JSHandle<JSTaggedValue>(thread, JSTaggedValue(-base::MAX_VALUE));
336 bigint = JSHandle<JSTaggedValue>(thread, BigInt::NumberToBigInt(thread, number));
337 ASSERT_TRUE(bigint->IsBigInt());
338 compareRes = JSTaggedValue::Equal(thread, number, bigint);
339 ASSERT_TRUE(JSHandle<BigInt>::Cast(bigint)->GetSign());
340 ASSERT_TRUE(compareRes);
341
342 number = JSHandle<JSTaggedValue>(thread, JSTaggedValue(-0xffffffff));
343 bigint = JSHandle<JSTaggedValue>(thread, BigInt::NumberToBigInt(thread, number));
344 ASSERT_TRUE(bigint->IsBigInt());
345 compareRes = JSTaggedValue::Equal(thread, number, bigint);
346 ASSERT_TRUE(compareRes);
347
348 number = JSHandle<JSTaggedValue>(thread, JSTaggedValue(0));
349 bigint = JSHandle<JSTaggedValue>(thread, BigInt::NumberToBigInt(thread, number));
350 ASSERT_TRUE(bigint->IsBigInt());
351 compareRes = JSTaggedValue::Equal(thread, number, bigint);
352 ASSERT_TRUE(compareRes);
353
354 number = JSHandle<JSTaggedValue>(thread, JSTaggedValue(std::numeric_limits<double>::infinity()));
355 bigint = JSHandle<JSTaggedValue>(thread, BigInt::NumberToBigInt(thread, number));
356 ASSERT_TRUE(bigint->IsException());
357 thread->ClearException();
358 }
359
360 // testcases of BigintToNumber()
HWTEST_F_L0(BuiltinsBigIntTest, BigintToNumber)361 HWTEST_F_L0(BuiltinsBigIntTest, BigintToNumber)
362 {
363 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
364 JSHandle<JSTaggedValue> bigint(thread, JSTaggedValue::Undefined());
365 JSTaggedNumber number(0);
366
367 JSHandle<JSTaggedValue> parma(factory->NewFromASCII("0xffff"));
368 bigint = JSHandle<JSTaggedValue>(thread, JSTaggedValue::ToBigInt(thread, parma));
369 ASSERT_TRUE(bigint->IsBigInt());
370 number = BigInt::BigIntToNumber(JSHandle<BigInt>::Cast(bigint));
371 ASSERT_EQ(number.GetNumber(), static_cast<double>(0xffff));
372
373 parma = JSHandle<JSTaggedValue>(
374 factory->NewFromASCII("0xfffffffffffff8000000000000000000000000000000000000000000000000000"
375 "0000000000000000000000000000000000000000000000000000000000000000000"
376 "0000000000000000000000000000000000000000000000000000000000000000000"
377 "000000000000000000000000000000000000000000000000000000000"));
378 bigint = JSHandle<JSTaggedValue>(thread, JSTaggedValue::ToBigInt(thread, parma));
379 ASSERT_TRUE(bigint->IsBigInt());
380 number = BigInt::BigIntToNumber(JSHandle<BigInt>::Cast(bigint));
381 ASSERT_EQ(number.GetNumber(), base::MAX_VALUE);
382
383 parma = JSHandle<JSTaggedValue>(thread, JSTaggedValue::False());
384 bigint = JSHandle<JSTaggedValue>(thread, JSTaggedValue::ToBigInt(thread, parma));
385 ASSERT_TRUE(bigint->IsBigInt());
386 ASSERT_TRUE(JSHandle<BigInt>::Cast(bigint)->IsZero());
387 number = BigInt::BigIntToNumber(JSHandle<BigInt>::Cast(bigint));
388 ASSERT_EQ(number.GetNumber(), 0.0);
389
390 parma = JSHandle<JSTaggedValue>(thread, JSTaggedValue(base::MAX_VALUE));
391 bigint = JSHandle<JSTaggedValue>(thread, BigInt::NumberToBigInt(thread, parma));
392 ASSERT_TRUE(bigint->IsBigInt());
393 number = BigInt::BigIntToNumber(JSHandle<BigInt>::Cast(bigint));
394 ASSERT_EQ(number.GetNumber(), base::MAX_VALUE);
395
396 parma = JSHandle<JSTaggedValue>(thread, JSTaggedValue(-base::MAX_VALUE));
397 bigint = JSHandle<JSTaggedValue>(thread, BigInt::NumberToBigInt(thread, parma));
398 ASSERT_TRUE(bigint->IsBigInt());
399 number = BigInt::BigIntToNumber(JSHandle<BigInt>::Cast(bigint));
400 ASSERT_EQ(number.GetNumber(), -base::MAX_VALUE);
401
402 parma = JSHandle<JSTaggedValue>(thread, JSTaggedValue(-0xffffffff));
403 bigint = JSHandle<JSTaggedValue>(thread, BigInt::NumberToBigInt(thread, parma));
404 ASSERT_TRUE(bigint->IsBigInt());
405 number = BigInt::BigIntToNumber(JSHandle<BigInt>::Cast(bigint));
406 ASSERT_EQ(number.GetNumber(), -0xffffffff);
407 }
408
409 // testcases of StringToBigInt(EcmaString)
HWTEST_F_L0(BuiltinsBigIntTest, StringToBigInt)410 HWTEST_F_L0(BuiltinsBigIntTest, StringToBigInt)
411 {
412 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
413 JSHandle<JSTaggedValue> bigint;
414 JSHandle<EcmaString> str;
415 JSHandle<JSTaggedValue> parma;
416
417 // hex string
418 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("0xffff"));
419 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
420 ASSERT_TRUE(bigint->IsBigInt());
421 str = BigInt::ToString(thread, JSHandle<BigInt>::Cast(bigint), BigInt::HEXADECIMAL);
422 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("ffff"));
423 ASSERT_EQ(EcmaStringAccessor::Compare(instance, str, JSHandle<EcmaString>(parma)), 0);
424
425 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("0XFFFF"));
426 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
427 ASSERT_TRUE(bigint->IsBigInt());
428 str = BigInt::ToString(thread, JSHandle<BigInt>::Cast(bigint), BigInt::HEXADECIMAL);
429 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("ffff"));
430 ASSERT_EQ(EcmaStringAccessor::Compare(instance, str, JSHandle<EcmaString>(parma)), 0);
431
432 // binary string
433 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("0b11111111"));
434 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
435 ASSERT_TRUE(bigint->IsBigInt());
436 str = BigInt::ToString(thread, JSHandle<BigInt>::Cast(bigint), BigInt::BINARY);
437 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("11111111"));
438 ASSERT_EQ(EcmaStringAccessor::Compare(instance, str, JSHandle<EcmaString>(parma)), 0);
439
440 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("0B11111111"));
441 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
442 ASSERT_TRUE(bigint->IsBigInt());
443 str = BigInt::ToString(thread, JSHandle<BigInt>::Cast(bigint), BigInt::BINARY);
444 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("11111111"));
445 ASSERT_EQ(EcmaStringAccessor::Compare(instance, str, JSHandle<EcmaString>(parma)), 0);
446
447 // octal string
448 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("0o123456"));
449 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
450 ASSERT_TRUE(bigint->IsBigInt());
451 str = BigInt::ToString(thread, JSHandle<BigInt>::Cast(bigint), BigInt::OCTAL);
452 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("123456"));
453 ASSERT_EQ(EcmaStringAccessor::Compare(instance, str, JSHandle<EcmaString>(parma)), 0);
454
455 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("0O123456"));
456 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
457 ASSERT_TRUE(bigint->IsBigInt());
458 str = BigInt::ToString(thread, JSHandle<BigInt>::Cast(bigint), BigInt::OCTAL);
459 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("123456"));
460 ASSERT_EQ(EcmaStringAccessor::Compare(instance, str, JSHandle<EcmaString>(parma)), 0);
461
462 // decimal string
463 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("999999999"));
464 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
465 ASSERT_TRUE(bigint->IsBigInt());
466 str = BigInt::ToString(thread, JSHandle<BigInt>::Cast(bigint));
467 ASSERT_EQ(EcmaStringAccessor::Compare(instance, str, JSHandle<EcmaString>(parma)), 0);
468
469 // string has space
470 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII(" 123 "));
471 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
472 ASSERT_TRUE(bigint->IsBigInt());
473 JSHandle<JSTaggedValue> number(thread, JSTaggedValue(static_cast<double>(123)));
474 bool compareRes = JSTaggedValue::Equal(thread, bigint, number);
475 ASSERT_TRUE(compareRes);
476
477 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII("123 "));
478 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
479 ASSERT_TRUE(bigint->IsBigInt());
480 number = JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<double>(123)));
481 compareRes = JSTaggedValue::Equal(thread, bigint, number);
482 ASSERT_TRUE(compareRes);
483
484 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII(" 123"));
485 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
486 ASSERT_TRUE(bigint->IsBigInt());
487 number = JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<double>(123)));
488 compareRes = JSTaggedValue::Equal(thread, bigint, number);
489 ASSERT_TRUE(compareRes);
490
491 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII(""));
492 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
493 ASSERT_TRUE(bigint->IsBigInt());
494 ASSERT_TRUE(JSHandle<BigInt>::Cast(bigint)->IsZero());
495
496 parma = JSHandle<JSTaggedValue>(factory->NewFromASCII(" "));
497 bigint = JSHandle<JSTaggedValue>(thread, base::NumberHelper::StringToBigInt(thread, parma));
498 ASSERT_TRUE(bigint->IsBigInt());
499 ASSERT_TRUE(JSHandle<BigInt>::Cast(bigint)->IsZero());
500 }
501 } // namespace panda::test
502