Line data Source code
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/runtime/runtime-utils.h"
6 :
7 : #include "src/arguments.h"
8 : #include "src/counters.h"
9 : #include "src/objects-inl.h"
10 : #include "src/objects/bigint.h"
11 : #include "src/parsing/token.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 :
16 1332 : RUNTIME_FUNCTION(Runtime_BigIntEqual) {
17 : SealHandleScope shs(isolate);
18 : DCHECK_EQ(2, args.length());
19 666 : CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0);
20 666 : CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1);
21 1980 : bool result = lhs->IsBigInt() && rhs->IsBigInt() &&
22 648 : BigInt::EqualToBigInt(BigInt::cast(*lhs), BigInt::cast(*rhs));
23 1332 : return *isolate->factory()->ToBoolean(result);
24 : // TODO(neis): Remove IsBigInt checks?
25 : }
26 :
27 1080 : RUNTIME_FUNCTION(Runtime_BigIntEqualToNumber) {
28 : SealHandleScope shs(isolate);
29 : DCHECK_EQ(2, args.length());
30 1080 : CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 0);
31 540 : CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1);
32 540 : bool result = BigInt::EqualToNumber(lhs, rhs);
33 1080 : return *isolate->factory()->ToBoolean(result);
34 : }
35 :
36 180 : RUNTIME_FUNCTION(Runtime_BigIntEqualToString) {
37 90 : HandleScope scope(isolate);
38 : DCHECK_EQ(2, args.length());
39 180 : CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 0);
40 180 : CONVERT_ARG_HANDLE_CHECKED(String, rhs, 1);
41 90 : bool result = BigInt::EqualToString(lhs, rhs);
42 180 : return *isolate->factory()->ToBoolean(result);
43 : }
44 :
45 108 : RUNTIME_FUNCTION(Runtime_BigIntToBoolean) {
46 : SealHandleScope shs(isolate);
47 : DCHECK_EQ(1, args.length());
48 108 : CONVERT_ARG_HANDLE_CHECKED(BigInt, bigint, 0);
49 108 : return *isolate->factory()->ToBoolean(bigint->ToBoolean());
50 : }
51 :
52 1098 : RUNTIME_FUNCTION(Runtime_BigIntBinaryOp) {
53 549 : HandleScope scope(isolate);
54 : DCHECK_EQ(3, args.length());
55 549 : CONVERT_ARG_HANDLE_CHECKED(Object, left_obj, 0);
56 549 : CONVERT_ARG_HANDLE_CHECKED(Object, right_obj, 1);
57 1098 : CONVERT_SMI_ARG_CHECKED(opcode, 2);
58 :
59 918 : if (!left_obj->IsBigInt() || !right_obj->IsBigInt()) {
60 738 : THROW_NEW_ERROR_RETURN_FAILURE(
61 : isolate, NewTypeError(MessageTemplate::kBigIntMixedTypes));
62 : }
63 180 : Handle<BigInt> left(Handle<BigInt>::cast(left_obj));
64 180 : Handle<BigInt> right(Handle<BigInt>::cast(right_obj));
65 : MaybeHandle<BigInt> result;
66 180 : switch (opcode) {
67 : case Token::ADD:
68 27 : result = BigInt::Add(left, right);
69 : break;
70 : case Token::SUB:
71 9 : result = BigInt::Subtract(left, right);
72 : break;
73 : case Token::MUL:
74 27 : result = BigInt::Multiply(left, right);
75 : break;
76 : case Token::DIV:
77 18 : result = BigInt::Divide(left, right);
78 : break;
79 : case Token::MOD:
80 18 : result = BigInt::Remainder(left, right);
81 : break;
82 : case Token::BIT_AND:
83 36 : result = BigInt::BitwiseAnd(left, right);
84 : break;
85 : case Token::BIT_OR:
86 9 : result = BigInt::BitwiseOr(left, right);
87 : break;
88 : case Token::BIT_XOR:
89 9 : result = BigInt::BitwiseXor(left, right);
90 : break;
91 : case Token::SHL:
92 9 : result = BigInt::LeftShift(left, right);
93 : break;
94 : case Token::SAR:
95 9 : result = BigInt::SignedRightShift(left, right);
96 : break;
97 : case Token::SHR:
98 9 : result = BigInt::UnsignedRightShift(left, right);
99 : break;
100 : default:
101 0 : UNREACHABLE();
102 : }
103 729 : RETURN_RESULT_OR_FAILURE(isolate, result);
104 : }
105 :
106 324 : RUNTIME_FUNCTION(Runtime_BigIntUnaryOp) {
107 162 : HandleScope scope(isolate);
108 : DCHECK_EQ(2, args.length());
109 324 : CONVERT_ARG_HANDLE_CHECKED(BigInt, x, 0);
110 324 : CONVERT_SMI_ARG_CHECKED(opcode, 1);
111 :
112 : MaybeHandle<BigInt> result;
113 162 : switch (opcode) {
114 : case Token::BIT_NOT:
115 36 : result = BigInt::BitwiseNot(x);
116 : break;
117 : case Token::SUB:
118 36 : result = BigInt::UnaryMinus(x);
119 : break;
120 : case Token::INC:
121 45 : result = BigInt::Increment(x);
122 : break;
123 : case Token::DEC:
124 45 : result = BigInt::Decrement(x);
125 : break;
126 : default:
127 0 : UNREACHABLE();
128 : }
129 324 : RETURN_RESULT_OR_FAILURE(isolate, result);
130 : }
131 :
132 : } // namespace internal
133 : } // namespace v8
|