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