| // Copyright 2017 the V8 project authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "src/arguments-inl.h" | |
| #include "src/counters.h" | |
| #include "src/objects-inl.h" | |
| #include "src/objects/bigint.h" | |
| #include "src/runtime/runtime-utils.h" | |
| namespace v8 { | |
| namespace internal { | |
| RUNTIME_FUNCTION(Runtime_BigIntCompareToBigInt) { | |
| SealHandleScope shs(isolate); | |
| DCHECK_EQ(3, args.length()); | |
| CONVERT_ARG_HANDLE_CHECKED(Smi, mode, 0); | |
| CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 1); | |
| CONVERT_ARG_HANDLE_CHECKED(BigInt, rhs, 2); | |
| bool result = ComparisonResultToBool(static_cast<Operation>(mode->value()), | |
| BigInt::CompareToBigInt(lhs, rhs)); | |
| return *isolate->factory()->ToBoolean(result); | |
| } | |
| RUNTIME_FUNCTION(Runtime_BigIntCompareToNumber) { | |
| SealHandleScope shs(isolate); | |
| DCHECK_EQ(3, args.length()); | |
| CONVERT_ARG_HANDLE_CHECKED(Smi, mode, 0); | |
| CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 1); | |
| CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 2); | |
| bool result = ComparisonResultToBool(static_cast<Operation>(mode->value()), | |
| BigInt::CompareToNumber(lhs, rhs)); | |
| return *isolate->factory()->ToBoolean(result); | |
| } | |
| RUNTIME_FUNCTION(Runtime_BigIntCompareToString) { | |
| HandleScope scope(isolate); | |
| DCHECK_EQ(3, args.length()); | |
| CONVERT_ARG_HANDLE_CHECKED(Smi, mode, 0); | |
| CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 1); | |
| CONVERT_ARG_HANDLE_CHECKED(String, rhs, 2); | |
| bool result = | |
| ComparisonResultToBool(static_cast<Operation>(mode->value()), | |
| BigInt::CompareToString(isolate, lhs, rhs)); | |
| return *isolate->factory()->ToBoolean(result); | |
| } | |
| RUNTIME_FUNCTION(Runtime_BigIntEqualToBigInt) { | |
| SealHandleScope shs(isolate); | |
| DCHECK_EQ(2, args.length()); | |
| CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 0); | |
| CONVERT_ARG_HANDLE_CHECKED(BigInt, rhs, 1); | |
| bool result = BigInt::EqualToBigInt(*lhs, *rhs); | |
| return *isolate->factory()->ToBoolean(result); | |
| } | |
| RUNTIME_FUNCTION(Runtime_BigIntEqualToNumber) { | |
| SealHandleScope shs(isolate); | |
| DCHECK_EQ(2, args.length()); | |
| CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 0); | |
| CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); | |
| bool result = BigInt::EqualToNumber(lhs, rhs); | |
| return *isolate->factory()->ToBoolean(result); | |
| } | |
| RUNTIME_FUNCTION(Runtime_BigIntEqualToString) { | |
| HandleScope scope(isolate); | |
| DCHECK_EQ(2, args.length()); | |
| CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 0); | |
| CONVERT_ARG_HANDLE_CHECKED(String, rhs, 1); | |
| bool result = BigInt::EqualToString(isolate, lhs, rhs); | |
| return *isolate->factory()->ToBoolean(result); | |
| } | |
| RUNTIME_FUNCTION(Runtime_BigIntToBoolean) { | |
| SealHandleScope shs(isolate); | |
| DCHECK_EQ(1, args.length()); | |
| CONVERT_ARG_HANDLE_CHECKED(BigInt, bigint, 0); | |
| return *isolate->factory()->ToBoolean(bigint->ToBoolean()); | |
| } | |
| RUNTIME_FUNCTION(Runtime_BigIntToNumber) { | |
| HandleScope scope(isolate); | |
| DCHECK_EQ(1, args.length()); | |
| CONVERT_ARG_HANDLE_CHECKED(BigInt, x, 0); | |
| return *BigInt::ToNumber(isolate, x); | |
| } | |
| RUNTIME_FUNCTION(Runtime_ToBigInt) { | |
| HandleScope scope(isolate); | |
| DCHECK_EQ(1, args.length()); | |
| CONVERT_ARG_HANDLE_CHECKED(Object, x, 0); | |
| RETURN_RESULT_OR_FAILURE(isolate, BigInt::FromObject(isolate, x)); | |
| } | |
| RUNTIME_FUNCTION(Runtime_BigIntBinaryOp) { | |
| HandleScope scope(isolate); | |
| DCHECK_EQ(3, args.length()); | |
| CONVERT_ARG_HANDLE_CHECKED(Object, left_obj, 0); | |
| CONVERT_ARG_HANDLE_CHECKED(Object, right_obj, 1); | |
| CONVERT_SMI_ARG_CHECKED(opcode, 2); | |
| Operation op = static_cast<Operation>(opcode); | |
| if (!left_obj->IsBigInt() || !right_obj->IsBigInt()) { | |
| THROW_NEW_ERROR_RETURN_FAILURE( | |
| isolate, NewTypeError(MessageTemplate::kBigIntMixedTypes)); | |
| } | |
| Handle<BigInt> left(Handle<BigInt>::cast(left_obj)); | |
| Handle<BigInt> right(Handle<BigInt>::cast(right_obj)); | |
| MaybeHandle<BigInt> result; | |
| switch (op) { | |
| case Operation::kAdd: | |
| result = BigInt::Add(isolate, left, right); | |
| break; | |
| case Operation::kSubtract: | |
| result = BigInt::Subtract(isolate, left, right); | |
| break; | |
| case Operation::kMultiply: | |
| result = BigInt::Multiply(isolate, left, right); | |
| break; | |
| case Operation::kDivide: | |
| result = BigInt::Divide(isolate, left, right); | |
| break; | |
| case Operation::kModulus: | |
| result = BigInt::Remainder(isolate, left, right); | |
| break; | |
| case Operation::kExponentiate: | |
| result = BigInt::Exponentiate(isolate, left, right); | |
| break; | |
| case Operation::kBitwiseAnd: | |
| result = BigInt::BitwiseAnd(isolate, left, right); | |
| break; | |
| case Operation::kBitwiseOr: | |
| result = BigInt::BitwiseOr(isolate, left, right); | |
| break; | |
| case Operation::kBitwiseXor: | |
| result = BigInt::BitwiseXor(isolate, left, right); | |
| break; | |
| case Operation::kShiftLeft: | |
| result = BigInt::LeftShift(isolate, left, right); | |
| break; | |
| case Operation::kShiftRight: | |
| result = BigInt::SignedRightShift(isolate, left, right); | |
| break; | |
| case Operation::kShiftRightLogical: | |
| result = BigInt::UnsignedRightShift(isolate, left, right); | |
| break; | |
| default: | |
| UNREACHABLE(); | |
| } | |
| RETURN_RESULT_OR_FAILURE(isolate, result); | |
| } | |
| RUNTIME_FUNCTION(Runtime_BigIntUnaryOp) { | |
| HandleScope scope(isolate); | |
| DCHECK_EQ(2, args.length()); | |
| CONVERT_ARG_HANDLE_CHECKED(BigInt, x, 0); | |
| CONVERT_SMI_ARG_CHECKED(opcode, 1); | |
| Operation op = static_cast<Operation>(opcode); | |
| MaybeHandle<BigInt> result; | |
| switch (op) { | |
| case Operation::kBitwiseNot: | |
| result = BigInt::BitwiseNot(isolate, x); | |
| break; | |
| case Operation::kNegate: | |
| result = BigInt::UnaryMinus(isolate, x); | |
| break; | |
| case Operation::kIncrement: | |
| result = BigInt::Increment(isolate, x); | |
| break; | |
| case Operation::kDecrement: | |
| result = BigInt::Decrement(isolate, x); | |
| break; | |
| default: | |
| UNREACHABLE(); | |
| } | |
| RETURN_RESULT_OR_FAILURE(isolate, result); | |
| } | |
| } // namespace internal | |
| } // namespace v8 |