v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
builtins-number.cc
Go to the documentation of this file.
1// Copyright 2016 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
11#ifdef V8_INTL_SUPPORT
13#endif
14
15namespace v8 {
16namespace internal {
17
18// -----------------------------------------------------------------------------
19// ES6 section 20.1 Number Objects
20
21// ES6 section 20.1.3.2 Number.prototype.toExponential ( fractionDigits )
22BUILTIN(NumberPrototypeToExponential) {
23 HandleScope scope(isolate);
24 DirectHandle<Object> value = args.at(0);
25 Handle<Object> fraction_digits = args.atOrUndefined(isolate, 1);
26
27 // Unwrap the receiver {value}.
28 if (IsJSPrimitiveWrapper(*value)) {
29 value = direct_handle(Cast<JSPrimitiveWrapper>(value)->value(), isolate);
30 }
31 if (!IsNumber(*value)) {
33 isolate, NewTypeError(MessageTemplate::kNotGeneric,
34 isolate->factory()->NewStringFromAsciiChecked(
35 "Number.prototype.toExponential"),
36 isolate->factory()->Number_string()));
37 }
38 double const value_number = Object::NumberValue(*value);
39
40 // Convert the {fraction_digits} to an integer first.
41 double fraction_digits_number;
43 isolate, fraction_digits_number,
44 Object::IntegerValue(isolate, fraction_digits));
45
46 if (std::isnan(value_number)) return ReadOnlyRoots(isolate).NaN_string();
47 if (std::isinf(value_number)) {
48 return (value_number < 0.0) ? ReadOnlyRoots(isolate).minus_Infinity_string()
49 : ReadOnlyRoots(isolate).Infinity_string();
50 }
51 if (fraction_digits_number < 0.0 ||
52 fraction_digits_number > kMaxFractionDigits) {
54 isolate, NewRangeError(MessageTemplate::kNumberFormatRange,
55 isolate->factory()->NewStringFromAsciiChecked(
56 "toExponential()")));
57 }
58 int const f = IsUndefined(*args.atOrUndefined(isolate, 1), isolate)
59 ? -1
60 : static_cast<int>(fraction_digits_number);
63 std::string_view str = DoubleToExponentialStringView(value_number, f, buffer);
65 isolate->factory()->NewStringFromAsciiChecked(str);
66 return *result;
67}
68
69// ES6 section 20.1.3.3 Number.prototype.toFixed ( fractionDigits )
70BUILTIN(NumberPrototypeToFixed) {
71 HandleScope scope(isolate);
72 DirectHandle<Object> value = args.at(0);
73 Handle<Object> fraction_digits = args.atOrUndefined(isolate, 1);
74
75 // Unwrap the receiver {value}.
76 if (IsJSPrimitiveWrapper(*value)) {
77 value = direct_handle(Cast<JSPrimitiveWrapper>(value)->value(), isolate);
78 }
79 if (!IsNumber(*value)) {
81 isolate, NewTypeError(MessageTemplate::kNotGeneric,
82 isolate->factory()->NewStringFromAsciiChecked(
83 "Number.prototype.toFixed"),
84 isolate->factory()->Number_string()));
85 }
86 double const value_number = Object::NumberValue(*value);
87
88 // Convert the {fraction_digits} to an integer first.
89 double fraction_digits_number;
91 isolate, fraction_digits_number,
92 Object::IntegerValue(isolate, fraction_digits));
93
94 // Check if the {fraction_digits} are in the supported range.
95 if (fraction_digits_number < 0.0 ||
96 fraction_digits_number > kMaxFractionDigits) {
98 isolate, NewRangeError(MessageTemplate::kNumberFormatRange,
99 isolate->factory()->NewStringFromAsciiChecked(
100 "toFixed() digits")));
101 }
102
103 if (std::isnan(value_number)) return ReadOnlyRoots(isolate).NaN_string();
104 if (std::isinf(value_number)) {
105 return (value_number < 0.0) ? ReadOnlyRoots(isolate).minus_Infinity_string()
106 : ReadOnlyRoots(isolate).Infinity_string();
107 }
108 char chars[kDoubleToFixedMaxChars];
110 std::string_view str = DoubleToFixedStringView(
111 value_number, static_cast<int>(fraction_digits_number), buffer);
113 isolate->factory()->NewStringFromAsciiChecked(str);
114 return *result;
115}
116
117// ES6 section 20.1.3.4 Number.prototype.toLocaleString ( [ r1 [ , r2 ] ] )
118BUILTIN(NumberPrototypeToLocaleString) {
119 HandleScope scope(isolate);
120 const char* method_name = "Number.prototype.toLocaleString";
121
123
124 Handle<Object> value = args.at(0);
125
126 // Unwrap the receiver {value}.
127 if (IsJSPrimitiveWrapper(*value)) {
128 value = handle(Cast<JSPrimitiveWrapper>(value)->value(), isolate);
129 }
130 // 1. Let x be ? thisNumberValue(this value)
131 if (!IsNumber(*value)) {
133 isolate,
134 NewTypeError(MessageTemplate::kNotGeneric,
135 isolate->factory()->NewStringFromAsciiChecked(method_name),
136 isolate->factory()->Number_string()));
137 }
138
139#ifdef V8_INTL_SUPPORT
141 isolate,
142 Intl::NumberToLocaleString(isolate, value, args.atOrUndefined(isolate, 1),
143 args.atOrUndefined(isolate, 2), method_name));
144#else
145 // Turn the {value} into a String.
146 return *isolate->factory()->NumberToString(value);
147#endif // V8_INTL_SUPPORT
148}
149
150// ES6 section 20.1.3.5 Number.prototype.toPrecision ( precision )
151BUILTIN(NumberPrototypeToPrecision) {
152 HandleScope scope(isolate);
153 DirectHandle<Object> value = args.at(0);
154 Handle<Object> precision = args.atOrUndefined(isolate, 1);
155
156 // Unwrap the receiver {value}.
157 if (IsJSPrimitiveWrapper(*value)) {
158 value = direct_handle(Cast<JSPrimitiveWrapper>(value)->value(), isolate);
159 }
160 if (!IsNumber(*value)) {
162 isolate, NewTypeError(MessageTemplate::kNotGeneric,
163 isolate->factory()->NewStringFromAsciiChecked(
164 "Number.prototype.toPrecision"),
165 isolate->factory()->Number_string()));
166 }
167 double const value_number = Object::NumberValue(*value);
168
169 // If no {precision} was specified, just return ToString of {value}.
170 if (IsUndefined(*precision, isolate)) {
171 return *isolate->factory()->NumberToString(value);
172 }
173
174 // Convert the {precision} to an integer first.
175 double precision_number;
177 isolate, precision_number, Object::IntegerValue(isolate, precision));
178
179 if (std::isnan(value_number)) return ReadOnlyRoots(isolate).NaN_string();
180 if (std::isinf(value_number)) {
181 return (value_number < 0.0) ? ReadOnlyRoots(isolate).minus_Infinity_string()
182 : ReadOnlyRoots(isolate).Infinity_string();
183 }
184 if (precision_number < 1.0 || precision_number > kMaxFractionDigits) {
186 isolate, NewRangeError(MessageTemplate::kToPrecisionFormatRange));
187 }
188 char chars[kDoubleToPrecisionMaxChars];
190 std::string_view str = DoubleToPrecisionStringView(
191 value_number, static_cast<int>(precision_number), buffer);
193 isolate->factory()->NewStringFromAsciiChecked(str);
194 return *result;
195}
196
197} // namespace internal
198} // namespace v8
#define BUILTIN(name)
@ kNumberToLocaleString
Definition v8-isolate.h:534
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > NumberToLocaleString(Isolate *isolate, Handle< Object > num, DirectHandle< Object > locales, DirectHandle< Object > options, const char *method_name)
static double NumberValue(Tagged< Number > obj)
static V8_WARN_UNUSED_RESULT Maybe< double > IntegerValue(Isolate *isolate, HandleType< T > input)
#define THROW_NEW_ERROR_RETURN_FAILURE(isolate, call)
Definition isolate.h:294
#define RETURN_RESULT_OR_FAILURE(isolate, call)
Definition isolate.h:264
#define MAYBE_ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, dst, call)
Definition isolate.h:448
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
Precision precision
ZoneVector< RpoNumber > & result
constexpr Vector< T > ArrayVector(T(&arr)[N])
Definition vector.h:354
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
constexpr int kDoubleToPrecisionMaxChars
Definition conversions.h:77
bool IsNumber(Tagged< Object > obj)
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
std::string_view DoubleToExponentialStringView(double value, int f, base::Vector< char > buffer)
constexpr int kDoubleToFixedMaxChars
Definition conversions.h:73
return value
Definition map-inl.h:893
constexpr int kDoubleToExponentialMaxChars
Definition conversions.h:81
std::string_view DoubleToFixedStringView(double value, int f, base::Vector< char > buffer)
std::string_view DoubleToPrecisionStringView(double value, int p, base::Vector< char > buffer)
constexpr int kMaxFractionDigits
Definition conversions.h:70
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150