V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
builtins-bigint.cc
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/builtins/builtins-utils-inl.h"
6 #include "src/builtins/builtins.h"
7 #include "src/conversions.h"
8 #include "src/counters.h"
9 #include "src/objects-inl.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 BUILTIN(BigIntConstructor) {
15  HandleScope scope(isolate);
16  if (!args.new_target()->IsUndefined(isolate)) { // [[Construct]]
17  THROW_NEW_ERROR_RETURN_FAILURE(
18  isolate, NewTypeError(MessageTemplate::kNotConstructor,
19  isolate->factory()->BigInt_string()));
20  }
21  // [[Call]]
22  Handle<Object> value = args.atOrUndefined(isolate, 1);
23 
24  if (value->IsJSReceiver()) {
25  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
26  isolate, value,
27  JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(value),
28  ToPrimitiveHint::kNumber));
29  }
30 
31  if (value->IsNumber()) {
32  RETURN_RESULT_OR_FAILURE(isolate, BigInt::FromNumber(isolate, value));
33  } else {
34  RETURN_RESULT_OR_FAILURE(isolate, BigInt::FromObject(isolate, value));
35  }
36 }
37 
38 BUILTIN(BigIntAsUintN) {
39  HandleScope scope(isolate);
40  Handle<Object> bits_obj = args.atOrUndefined(isolate, 1);
41  Handle<Object> bigint_obj = args.atOrUndefined(isolate, 2);
42 
43  Handle<Object> bits;
44  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
45  isolate, bits,
46  Object::ToIndex(isolate, bits_obj, MessageTemplate::kInvalidIndex));
47 
48  Handle<BigInt> bigint;
49  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, bigint,
50  BigInt::FromObject(isolate, bigint_obj));
51 
52  RETURN_RESULT_OR_FAILURE(isolate,
53  BigInt::AsUintN(isolate, bits->Number(), bigint));
54 }
55 
56 BUILTIN(BigIntAsIntN) {
57  HandleScope scope(isolate);
58  Handle<Object> bits_obj = args.atOrUndefined(isolate, 1);
59  Handle<Object> bigint_obj = args.atOrUndefined(isolate, 2);
60 
61  Handle<Object> bits;
62  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
63  isolate, bits,
64  Object::ToIndex(isolate, bits_obj, MessageTemplate::kInvalidIndex));
65 
66  Handle<BigInt> bigint;
67  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, bigint,
68  BigInt::FromObject(isolate, bigint_obj));
69 
70  return *BigInt::AsIntN(isolate, bits->Number(), bigint);
71 }
72 
73 namespace {
74 
75 MaybeHandle<BigInt> ThisBigIntValue(Isolate* isolate, Handle<Object> value,
76  const char* caller) {
77  // 1. If Type(value) is BigInt, return value.
78  if (value->IsBigInt()) return Handle<BigInt>::cast(value);
79  // 2. If Type(value) is Object and value has a [[BigIntData]] internal slot:
80  if (value->IsJSValue()) {
81  // 2a. Assert: value.[[BigIntData]] is a BigInt value.
82  // 2b. Return value.[[BigIntData]].
83  Object* data = JSValue::cast(*value)->value();
84  if (data->IsBigInt()) return handle(BigInt::cast(data), isolate);
85  }
86  // 3. Throw a TypeError exception.
87  THROW_NEW_ERROR(
88  isolate,
89  NewTypeError(MessageTemplate::kNotGeneric,
90  isolate->factory()->NewStringFromAsciiChecked(caller),
91  isolate->factory()->NewStringFromStaticChars("BigInt")),
92  BigInt);
93 }
94 
95 Object* BigIntToStringImpl(Handle<Object> receiver, Handle<Object> radix,
96  Isolate* isolate, const char* builtin_name) {
97  // 1. Let x be ? thisBigIntValue(this value).
98  Handle<BigInt> x;
99  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
100  isolate, x, ThisBigIntValue(isolate, receiver, builtin_name));
101  // 2. If radix is not present, let radixNumber be 10.
102  // 3. Else if radix is undefined, let radixNumber be 10.
103  int radix_number;
104  if (radix->IsUndefined(isolate)) {
105  radix_number = 10;
106  } else {
107  // 4. Else, let radixNumber be ? ToInteger(radix).
108  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, radix,
109  Object::ToInteger(isolate, radix));
110  radix_number = static_cast<int>(radix->Number());
111  }
112  // 5. If radixNumber < 2 or radixNumber > 36, throw a RangeError exception.
113  if (radix_number < 2 || radix_number > 36) {
114  THROW_NEW_ERROR_RETURN_FAILURE(
115  isolate, NewRangeError(MessageTemplate::kToRadixFormatRange));
116  }
117  // Return the String representation of this Number value using the radix
118  // specified by radixNumber.
119  RETURN_RESULT_OR_FAILURE(isolate, BigInt::ToString(isolate, x, radix_number));
120 }
121 
122 } // namespace
123 
124 BUILTIN(BigIntPrototypeToLocaleString) {
125  HandleScope scope(isolate);
126  Handle<Object> radix = isolate->factory()->undefined_value();
127  return BigIntToStringImpl(args.receiver(), radix, isolate,
128  "BigInt.prototype.toLocaleString");
129 }
130 
131 BUILTIN(BigIntPrototypeToString) {
132  HandleScope scope(isolate);
133  Handle<Object> radix = args.atOrUndefined(isolate, 1);
134  return BigIntToStringImpl(args.receiver(), radix, isolate,
135  "BigInt.prototype.toString");
136 }
137 
138 BUILTIN(BigIntPrototypeValueOf) {
139  HandleScope scope(isolate);
140  RETURN_RESULT_OR_FAILURE(
141  isolate,
142  ThisBigIntValue(isolate, args.receiver(), "BigInt.prototype.valueOf"));
143 }
144 
145 } // namespace internal
146 } // namespace v8
Definition: libplatform.h:13