1 // Copyright 2017 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/execution/arguments-inl.h"
6 #include "src/logging/counters.h"
7 #include "src/objects/bigint.h"
8 #include "src/objects/objects-inl.h"
9 #include "src/runtime/runtime-utils.h"
10 
11 namespace v8 {
12 namespace internal {
13 
RUNTIME_FUNCTION(Runtime_BigIntCompareToBigInt)14 RUNTIME_FUNCTION(Runtime_BigIntCompareToBigInt) {
15   SealHandleScope shs(isolate);
16   DCHECK_EQ(3, args.length());
17   CONVERT_ARG_HANDLE_CHECKED(Smi, mode, 0);
18   CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 1);
19   CONVERT_ARG_HANDLE_CHECKED(BigInt, rhs, 2);
20   bool result = ComparisonResultToBool(static_cast<Operation>(mode->value()),
21                                        BigInt::CompareToBigInt(lhs, rhs));
22   return *isolate->factory()->ToBoolean(result);
23 }
24 
RUNTIME_FUNCTION(Runtime_BigIntCompareToNumber)25 RUNTIME_FUNCTION(Runtime_BigIntCompareToNumber) {
26   SealHandleScope shs(isolate);
27   DCHECK_EQ(3, args.length());
28   CONVERT_ARG_HANDLE_CHECKED(Smi, mode, 0);
29   CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 1);
30   CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 2);
31   bool result = ComparisonResultToBool(static_cast<Operation>(mode->value()),
32                                        BigInt::CompareToNumber(lhs, rhs));
33   return *isolate->factory()->ToBoolean(result);
34 }
35 
RUNTIME_FUNCTION(Runtime_BigIntCompareToString)36 RUNTIME_FUNCTION(Runtime_BigIntCompareToString) {
37   HandleScope scope(isolate);
38   DCHECK_EQ(3, args.length());
39   CONVERT_ARG_HANDLE_CHECKED(Smi, mode, 0);
40   CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 1);
41   CONVERT_ARG_HANDLE_CHECKED(String, rhs, 2);
42   bool result =
43       ComparisonResultToBool(static_cast<Operation>(mode->value()),
44                              BigInt::CompareToString(isolate, lhs, rhs));
45   return *isolate->factory()->ToBoolean(result);
46 }
47 
RUNTIME_FUNCTION(Runtime_BigIntEqualToBigInt)48 RUNTIME_FUNCTION(Runtime_BigIntEqualToBigInt) {
49   SealHandleScope shs(isolate);
50   DCHECK_EQ(2, args.length());
51   CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 0);
52   CONVERT_ARG_HANDLE_CHECKED(BigInt, rhs, 1);
53   bool result = BigInt::EqualToBigInt(*lhs, *rhs);
54   return *isolate->factory()->ToBoolean(result);
55 }
56 
RUNTIME_FUNCTION(Runtime_BigIntEqualToNumber)57 RUNTIME_FUNCTION(Runtime_BigIntEqualToNumber) {
58   SealHandleScope shs(isolate);
59   DCHECK_EQ(2, args.length());
60   CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 0);
61   CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1);
62   bool result = BigInt::EqualToNumber(lhs, rhs);
63   return *isolate->factory()->ToBoolean(result);
64 }
65 
RUNTIME_FUNCTION(Runtime_BigIntEqualToString)66 RUNTIME_FUNCTION(Runtime_BigIntEqualToString) {
67   HandleScope scope(isolate);
68   DCHECK_EQ(2, args.length());
69   CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 0);
70   CONVERT_ARG_HANDLE_CHECKED(String, rhs, 1);
71   bool result = BigInt::EqualToString(isolate, lhs, rhs);
72   return *isolate->factory()->ToBoolean(result);
73 }
74 
RUNTIME_FUNCTION(Runtime_BigIntToBoolean)75 RUNTIME_FUNCTION(Runtime_BigIntToBoolean) {
76   SealHandleScope shs(isolate);
77   DCHECK_EQ(1, args.length());
78   CONVERT_ARG_HANDLE_CHECKED(BigInt, bigint, 0);
79   return *isolate->factory()->ToBoolean(bigint->ToBoolean());
80 }
81 
RUNTIME_FUNCTION(Runtime_BigIntToNumber)82 RUNTIME_FUNCTION(Runtime_BigIntToNumber) {
83   HandleScope scope(isolate);
84   DCHECK_EQ(1, args.length());
85   CONVERT_ARG_HANDLE_CHECKED(BigInt, x, 0);
86   return *BigInt::ToNumber(isolate, x);
87 }
88 
RUNTIME_FUNCTION(Runtime_ToBigInt)89 RUNTIME_FUNCTION(Runtime_ToBigInt) {
90   HandleScope scope(isolate);
91   DCHECK_EQ(1, args.length());
92   CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
93   RETURN_RESULT_OR_FAILURE(isolate, BigInt::FromObject(isolate, x));
94 }
95 
RUNTIME_FUNCTION(Runtime_BigIntBinaryOp)96 RUNTIME_FUNCTION(Runtime_BigIntBinaryOp) {
97   HandleScope scope(isolate);
98   DCHECK_EQ(3, args.length());
99   CONVERT_ARG_HANDLE_CHECKED(Object, left_obj, 0);
100   CONVERT_ARG_HANDLE_CHECKED(Object, right_obj, 1);
101   CONVERT_SMI_ARG_CHECKED(opcode, 2);
102   Operation op = static_cast<Operation>(opcode);
103 
104   if (!left_obj->IsBigInt() || !right_obj->IsBigInt()) {
105     THROW_NEW_ERROR_RETURN_FAILURE(
106         isolate, NewTypeError(MessageTemplate::kBigIntMixedTypes));
107   }
108   Handle<BigInt> left(Handle<BigInt>::cast(left_obj));
109   Handle<BigInt> right(Handle<BigInt>::cast(right_obj));
110   MaybeHandle<BigInt> result;
111   switch (op) {
112     case Operation::kAdd:
113       result = BigInt::Add(isolate, left, right);
114       break;
115     case Operation::kSubtract:
116       result = BigInt::Subtract(isolate, left, right);
117       break;
118     case Operation::kMultiply:
119       result = BigInt::Multiply(isolate, left, right);
120       break;
121     case Operation::kDivide:
122       result = BigInt::Divide(isolate, left, right);
123       break;
124     case Operation::kModulus:
125       result = BigInt::Remainder(isolate, left, right);
126       break;
127     case Operation::kExponentiate:
128       result = BigInt::Exponentiate(isolate, left, right);
129       break;
130     case Operation::kBitwiseAnd:
131       result = BigInt::BitwiseAnd(isolate, left, right);
132       break;
133     case Operation::kBitwiseOr:
134       result = BigInt::BitwiseOr(isolate, left, right);
135       break;
136     case Operation::kBitwiseXor:
137       result = BigInt::BitwiseXor(isolate, left, right);
138       break;
139     case Operation::kShiftLeft:
140       result = BigInt::LeftShift(isolate, left, right);
141       break;
142     case Operation::kShiftRight:
143       result = BigInt::SignedRightShift(isolate, left, right);
144       break;
145     case Operation::kShiftRightLogical:
146       result = BigInt::UnsignedRightShift(isolate, left, right);
147       break;
148     default:
149       UNREACHABLE();
150   }
151   RETURN_RESULT_OR_FAILURE(isolate, result);
152 }
153 
RUNTIME_FUNCTION(Runtime_BigIntUnaryOp)154 RUNTIME_FUNCTION(Runtime_BigIntUnaryOp) {
155   HandleScope scope(isolate);
156   DCHECK_EQ(2, args.length());
157   CONVERT_ARG_HANDLE_CHECKED(BigInt, x, 0);
158   CONVERT_SMI_ARG_CHECKED(opcode, 1);
159   Operation op = static_cast<Operation>(opcode);
160 
161   MaybeHandle<BigInt> result;
162   switch (op) {
163     case Operation::kBitwiseNot:
164       result = BigInt::BitwiseNot(isolate, x);
165       break;
166     case Operation::kNegate:
167       result = BigInt::UnaryMinus(isolate, x);
168       break;
169     case Operation::kIncrement:
170       result = BigInt::Increment(isolate, x);
171       break;
172     case Operation::kDecrement:
173       result = BigInt::Decrement(isolate, x);
174       break;
175     default:
176       UNREACHABLE();
177   }
178   RETURN_RESULT_OR_FAILURE(isolate, result);
179 }
180 
181 }  // namespace internal
182 }  // namespace v8
183