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/builtins/builtins-utils.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 2511 : BUILTIN(BigIntConstructor) {
15 : HandleScope scope(isolate);
16 : Handle<Object> value = args.atOrUndefined(isolate, 1);
17 :
18 : // TODO(jkummerow): Implement properly.
19 :
20 : // Dummy implementation only takes Smi args.
21 837 : if (!value->IsSmi()) return isolate->heap()->undefined_value();
22 : int num = Smi::ToInt(*value);
23 1674 : return *isolate->factory()->NewBigIntFromInt(num);
24 : }
25 :
26 0 : BUILTIN(BigIntConstructor_ConstructStub) {
27 : HandleScope scope(isolate);
28 : Handle<Object> value = args.atOrUndefined(isolate, 1);
29 0 : Handle<JSFunction> target = args.target();
30 0 : Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
31 : DCHECK(*target == target->native_context()->bigint_function());
32 : Handle<JSObject> result;
33 0 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
34 : JSObject::New(target, new_target));
35 :
36 : // TODO(jkummerow): Implement.
37 : USE(value);
38 : USE(result);
39 :
40 0 : UNIMPLEMENTED();
41 : }
42 :
43 2079 : BUILTIN(BigIntParseInt) {
44 : HandleScope scope(isolate);
45 : Handle<Object> string = args.atOrUndefined(isolate, 1);
46 : Handle<Object> radix = args.atOrUndefined(isolate, 2);
47 :
48 : // Convert {string} to a String and flatten it.
49 : // Fast path: avoid back-and-forth conversion for Smi inputs.
50 693 : if (string->IsSmi() && radix->IsUndefined(isolate)) {
51 : int num = Smi::ToInt(*string);
52 0 : return *isolate->factory()->NewBigIntFromInt(num);
53 : }
54 : Handle<String> subject;
55 1386 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, subject,
56 : Object::ToString(isolate, string));
57 693 : subject = String::Flatten(subject);
58 :
59 : // Convert {radix} to Int32.
60 693 : if (!radix->IsNumber()) {
61 72 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, radix, Object::ToNumber(radix));
62 : }
63 693 : int radix32 = DoubleToInt32(radix->Number());
64 693 : if (radix32 != 0 && (radix32 < 2 || radix32 > 36)) {
65 0 : THROW_NEW_ERROR_RETURN_FAILURE(
66 : isolate, NewSyntaxError(MessageTemplate::kToRadixFormatRange));
67 : }
68 2061 : RETURN_RESULT_OR_FAILURE(isolate, BigIntParseInt(isolate, subject, radix32));
69 : }
70 :
71 0 : BUILTIN(BigIntAsUintN) {
72 : HandleScope scope(isolate);
73 : Handle<Object> bits_obj = args.atOrUndefined(isolate, 1);
74 : Handle<Object> bigint_obj = args.atOrUndefined(isolate, 2);
75 :
76 : // TODO(jkummerow): Implement.
77 : USE(bits_obj);
78 : USE(bigint_obj);
79 :
80 0 : UNIMPLEMENTED();
81 : }
82 :
83 0 : BUILTIN(BigIntAsIntN) {
84 : HandleScope scope(isolate);
85 : Handle<Object> bits_obj = args.atOrUndefined(isolate, 1);
86 : Handle<Object> bigint_obj = args.atOrUndefined(isolate, 2);
87 :
88 : // TODO(jkummerow): Implement.
89 : USE(bits_obj);
90 : USE(bigint_obj);
91 :
92 0 : UNIMPLEMENTED();
93 : }
94 :
95 0 : BUILTIN(BigIntPrototypeToLocaleString) {
96 : HandleScope scope(isolate);
97 :
98 : // TODO(jkummerow): Implement.
99 :
100 0 : UNIMPLEMENTED();
101 : }
102 :
103 : namespace {
104 :
105 1323 : MaybeHandle<BigInt> ThisBigIntValue(Isolate* isolate, Handle<Object> value,
106 : const char* caller) {
107 : // 1. If Type(value) is BigInt, return value.
108 1323 : if (value->IsBigInt()) return Handle<BigInt>::cast(value);
109 : // 2. If Type(value) is Object and value has a [[BigIntData]] internal slot:
110 18 : if (value->IsJSValue()) {
111 : // 2a. Assert: value.[[BigIntData]] is a BigInt value.
112 : // 2b. Return value.[[BigIntData]].
113 : Object* data = JSValue::cast(*value)->value();
114 18 : if (data->IsBigInt()) return handle(BigInt::cast(data), isolate);
115 : }
116 : // 3. Throw a TypeError exception.
117 36 : THROW_NEW_ERROR(
118 : isolate,
119 : NewTypeError(MessageTemplate::kNotGeneric,
120 : isolate->factory()->NewStringFromAsciiChecked(caller),
121 : isolate->factory()->NewStringFromStaticChars("BigInt")),
122 : BigInt);
123 : }
124 :
125 : } // namespace
126 :
127 3915 : BUILTIN(BigIntPrototypeToString) {
128 : HandleScope scope(isolate);
129 : // 1. Let x be ? thisBigIntValue(this value).
130 : Handle<BigInt> x;
131 2610 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
132 : isolate, x,
133 : ThisBigIntValue(isolate, args.receiver(), "BigInt.prototype.toString"));
134 : // 2. If radix is not present, let radixNumber be 10.
135 : // 3. Else if radix is undefined, let radixNumber be 10.
136 : Handle<Object> radix = args.atOrUndefined(isolate, 1);
137 : int radix_number;
138 1305 : if (radix->IsUndefined(isolate)) {
139 : radix_number = 10;
140 : } else {
141 : // 4. Else, let radixNumber be ? ToInteger(radix).
142 1305 : ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, radix,
143 : Object::ToInteger(isolate, radix));
144 1305 : radix_number = static_cast<int>(radix->Number());
145 : }
146 : // 5. If radixNumber < 2 or radixNumber > 36, throw a RangeError exception.
147 1305 : if (radix_number < 2 || radix_number > 36) {
148 0 : THROW_NEW_ERROR_RETURN_FAILURE(
149 : isolate, NewRangeError(MessageTemplate::kToRadixFormatRange));
150 : }
151 : // Return the String representation of this Number value using the radix
152 : // specified by radixNumber.
153 3915 : RETURN_RESULT_OR_FAILURE(isolate, BigInt::ToString(x, radix_number));
154 : }
155 :
156 54 : BUILTIN(BigIntPrototypeValueOf) {
157 : HandleScope scope(isolate);
158 45 : RETURN_RESULT_OR_FAILURE(
159 : isolate,
160 : ThisBigIntValue(isolate, args.receiver(), "BigInt.prototype.valueOf"));
161 : }
162 :
163 : } // namespace internal
164 : } // namespace v8
|