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
23using namespace panda::ecmascript;
24using namespace panda::ecmascript::builtins;
25
26namespace panda::test {
27using BigInt = ecmascript::BigInt;
28class BuiltinsBigIntTest : public BaseTestWithScope<true> {
29};
30
31enum class AlgorithmType {
32    BIGINT_CONSTRUCTOR,
33    BIGINT_ASINTN,
34    BIGINT_ASUINTN,
35    BIGINT_TOLOCALSTR,
36    BIGINT_TOSTR,
37    BIGINT_VALUEOF
38};
39
40static 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)
80HWTEST_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")
90HWTEST_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))
101HWTEST_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))
117HWTEST_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))
133HWTEST_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))
149HWTEST_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
166HWTEST_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
187HWTEST_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()
215HWTEST_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()
233HWTEST_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)
251HWTEST_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)
270HWTEST_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
289HWTEST_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
305HWTEST_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()
324HWTEST_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()
361HWTEST_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)
410HWTEST_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