• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   Maybe<ComparisonResult> maybe_result =
43       BigInt::CompareToString(isolate, lhs, rhs);
44   MAYBE_RETURN(maybe_result, ReadOnlyRoots(isolate).exception());
45   bool result = ComparisonResultToBool(static_cast<Operation>(mode->value()),
46                                        maybe_result.FromJust());
47   return *isolate->factory()->ToBoolean(result);
48 }
49 
RUNTIME_FUNCTION(Runtime_BigIntEqualToBigInt)50 RUNTIME_FUNCTION(Runtime_BigIntEqualToBigInt) {
51   SealHandleScope shs(isolate);
52   DCHECK_EQ(2, args.length());
53   CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 0);
54   CONVERT_ARG_HANDLE_CHECKED(BigInt, rhs, 1);
55   bool result = BigInt::EqualToBigInt(*lhs, *rhs);
56   return *isolate->factory()->ToBoolean(result);
57 }
58 
RUNTIME_FUNCTION(Runtime_BigIntEqualToNumber)59 RUNTIME_FUNCTION(Runtime_BigIntEqualToNumber) {
60   SealHandleScope shs(isolate);
61   DCHECK_EQ(2, args.length());
62   CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 0);
63   CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1);
64   bool result = BigInt::EqualToNumber(lhs, rhs);
65   return *isolate->factory()->ToBoolean(result);
66 }
67 
RUNTIME_FUNCTION(Runtime_BigIntEqualToString)68 RUNTIME_FUNCTION(Runtime_BigIntEqualToString) {
69   HandleScope scope(isolate);
70   DCHECK_EQ(2, args.length());
71   CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 0);
72   CONVERT_ARG_HANDLE_CHECKED(String, rhs, 1);
73   Maybe<bool> maybe_result = BigInt::EqualToString(isolate, lhs, rhs);
74   MAYBE_RETURN(maybe_result, ReadOnlyRoots(isolate).exception());
75   return *isolate->factory()->ToBoolean(maybe_result.FromJust());
76 }
77 
RUNTIME_FUNCTION(Runtime_BigIntToBoolean)78 RUNTIME_FUNCTION(Runtime_BigIntToBoolean) {
79   SealHandleScope shs(isolate);
80   DCHECK_EQ(1, args.length());
81   CONVERT_ARG_HANDLE_CHECKED(BigInt, bigint, 0);
82   return *isolate->factory()->ToBoolean(bigint->ToBoolean());
83 }
84 
RUNTIME_FUNCTION(Runtime_BigIntToNumber)85 RUNTIME_FUNCTION(Runtime_BigIntToNumber) {
86   HandleScope scope(isolate);
87   DCHECK_EQ(1, args.length());
88   CONVERT_ARG_HANDLE_CHECKED(BigInt, x, 0);
89   return *BigInt::ToNumber(isolate, x);
90 }
91 
RUNTIME_FUNCTION(Runtime_ToBigInt)92 RUNTIME_FUNCTION(Runtime_ToBigInt) {
93   HandleScope scope(isolate);
94   DCHECK_EQ(1, args.length());
95   CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
96   RETURN_RESULT_OR_FAILURE(isolate, BigInt::FromObject(isolate, x));
97 }
98 
RUNTIME_FUNCTION(Runtime_BigIntBinaryOp)99 RUNTIME_FUNCTION(Runtime_BigIntBinaryOp) {
100   HandleScope scope(isolate);
101   DCHECK_EQ(3, args.length());
102   CONVERT_ARG_HANDLE_CHECKED(Object, left_obj, 0);
103   CONVERT_ARG_HANDLE_CHECKED(Object, right_obj, 1);
104   CONVERT_SMI_ARG_CHECKED(opcode, 2);
105   Operation op = static_cast<Operation>(opcode);
106 
107   if (!left_obj->IsBigInt() || !right_obj->IsBigInt()) {
108     THROW_NEW_ERROR_RETURN_FAILURE(
109         isolate, NewTypeError(MessageTemplate::kBigIntMixedTypes));
110   }
111   Handle<BigInt> left(Handle<BigInt>::cast(left_obj));
112   Handle<BigInt> right(Handle<BigInt>::cast(right_obj));
113   MaybeHandle<BigInt> result;
114   switch (op) {
115     case Operation::kAdd:
116       result = BigInt::Add(isolate, left, right);
117       break;
118     case Operation::kSubtract:
119       result = BigInt::Subtract(isolate, left, right);
120       break;
121     case Operation::kMultiply:
122       result = BigInt::Multiply(isolate, left, right);
123       break;
124     case Operation::kDivide:
125       result = BigInt::Divide(isolate, left, right);
126       break;
127     case Operation::kModulus:
128       result = BigInt::Remainder(isolate, left, right);
129       break;
130     case Operation::kExponentiate:
131       result = BigInt::Exponentiate(isolate, left, right);
132       break;
133     case Operation::kBitwiseAnd:
134       result = BigInt::BitwiseAnd(isolate, left, right);
135       break;
136     case Operation::kBitwiseOr:
137       result = BigInt::BitwiseOr(isolate, left, right);
138       break;
139     case Operation::kBitwiseXor:
140       result = BigInt::BitwiseXor(isolate, left, right);
141       break;
142     case Operation::kShiftLeft:
143       result = BigInt::LeftShift(isolate, left, right);
144       break;
145     case Operation::kShiftRight:
146       result = BigInt::SignedRightShift(isolate, left, right);
147       break;
148     case Operation::kShiftRightLogical:
149       result = BigInt::UnsignedRightShift(isolate, left, right);
150       break;
151     default:
152       UNREACHABLE();
153   }
154   RETURN_RESULT_OR_FAILURE(isolate, result);
155 }
156 
RUNTIME_FUNCTION(Runtime_BigIntUnaryOp)157 RUNTIME_FUNCTION(Runtime_BigIntUnaryOp) {
158   HandleScope scope(isolate);
159   DCHECK_EQ(2, args.length());
160   CONVERT_ARG_HANDLE_CHECKED(BigInt, x, 0);
161   CONVERT_SMI_ARG_CHECKED(opcode, 1);
162   Operation op = static_cast<Operation>(opcode);
163 
164   MaybeHandle<BigInt> result;
165   switch (op) {
166     case Operation::kBitwiseNot:
167       result = BigInt::BitwiseNot(isolate, x);
168       break;
169     case Operation::kNegate:
170       result = BigInt::UnaryMinus(isolate, x);
171       break;
172     case Operation::kIncrement:
173       result = BigInt::Increment(isolate, x);
174       break;
175     case Operation::kDecrement:
176       result = BigInt::Decrement(isolate, x);
177       break;
178     default:
179       UNREACHABLE();
180   }
181   RETURN_RESULT_OR_FAILURE(isolate, result);
182 }
183 
184 }  // namespace internal
185 }  // namespace v8
186