Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
double.cc
Go to the documentation of this file.
1// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "lib/integers.h"
6
8
9#include <math.h> // NOLINT
10
11#include "vm/dart_entry.h"
13#include "vm/double_internals.h"
14#include "vm/exceptions.h"
15#include "vm/native_entry.h"
16#include "vm/object.h"
17#include "vm/runtime_entry.h" // DartModulo.
18#include "vm/symbols.h"
19
20namespace dart {
21
22DEFINE_NATIVE_ENTRY(Double_doubleFromInteger, 0, 2) {
23 ASSERT(
24 TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0)).IsNull());
25 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1));
26 if (FLAG_trace_intrinsified_natives) {
27 OS::PrintErr("Double_doubleFromInteger %s\n", value.ToCString());
28 }
29 return Double::New(value.AsDoubleValue());
30}
31
32DEFINE_NATIVE_ENTRY(Double_add, 0, 2) {
33 double left = Double::CheckedHandle(zone, arguments->NativeArgAt(0)).value();
34 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
35 double right = right_object.value();
36 if (FLAG_trace_intrinsified_natives) {
37 OS::PrintErr("Double_add %f + %f\n", left, right);
38 }
39 return Double::New(left + right);
40}
41
42DEFINE_NATIVE_ENTRY(Double_sub, 0, 2) {
43 double left = Double::CheckedHandle(zone, arguments->NativeArgAt(0)).value();
44 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
45 double right = right_object.value();
46 if (FLAG_trace_intrinsified_natives) {
47 OS::PrintErr("Double_sub %f - %f\n", left, right);
48 }
49 return Double::New(left - right);
50}
51
52DEFINE_NATIVE_ENTRY(Double_mul, 0, 2) {
53 double left = Double::CheckedHandle(zone, arguments->NativeArgAt(0)).value();
54 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
55 double right = right_object.value();
56 if (FLAG_trace_intrinsified_natives) {
57 OS::PrintErr("Double_mul %f * %f\n", left, right);
58 }
59 return Double::New(left * right);
60}
61
62DEFINE_NATIVE_ENTRY(Double_div, 0, 2) {
63 double left = Double::CheckedHandle(zone, arguments->NativeArgAt(0)).value();
64 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
65 double right = right_object.value();
66 if (FLAG_trace_intrinsified_natives) {
67 OS::PrintErr("Double_div %f / %f\n", left, right);
68 }
70}
71
72DEFINE_NATIVE_ENTRY(Double_modulo, 0, 2) {
73 double left = Double::CheckedHandle(zone, arguments->NativeArgAt(0)).value();
74 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
75 double right = right_object.value();
77}
78
79DEFINE_NATIVE_ENTRY(Double_remainder, 0, 2) {
80 double left = Double::CheckedHandle(zone, arguments->NativeArgAt(0)).value();
81 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
82 double right = right_object.value();
84}
85
86DEFINE_NATIVE_ENTRY(Double_greaterThan, 0, 2) {
87 const Double& left = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
88 GET_NON_NULL_NATIVE_ARGUMENT(Double, right, arguments->NativeArgAt(1));
89 bool result = right.IsNull() ? false : (left.value() > right.value());
90 if (FLAG_trace_intrinsified_natives) {
91 OS::PrintErr("Double_greaterThan %s > %s\n", left.ToCString(),
92 right.ToCString());
93 }
94 return Bool::Get(result).ptr();
95}
96
97DEFINE_NATIVE_ENTRY(Double_greaterThanFromInteger, 0, 2) {
98 const Double& right = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
99 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
100 return Bool::Get(left.AsDoubleValue() > right.value()).ptr();
101}
102
103DEFINE_NATIVE_ENTRY(Double_equal, 0, 2) {
104 const Double& left = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
105 GET_NON_NULL_NATIVE_ARGUMENT(Double, right, arguments->NativeArgAt(1));
106 bool result = right.IsNull() ? false : (left.value() == right.value());
107 if (FLAG_trace_intrinsified_natives) {
108 OS::PrintErr("Double_equal %s == %s\n", left.ToCString(),
109 right.ToCString());
110 }
111 return Bool::Get(result).ptr();
112}
113
114DEFINE_NATIVE_ENTRY(Double_equalToInteger, 0, 2) {
115 const Double& left = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
116 GET_NON_NULL_NATIVE_ARGUMENT(Integer, right, arguments->NativeArgAt(1));
117 return Bool::Get(left.value() == right.AsDoubleValue()).ptr();
118}
119
120DEFINE_NATIVE_ENTRY(Double_round, 0, 1) {
121 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
122 return Double::New(round(arg.value()));
123}
124
125DEFINE_NATIVE_ENTRY(Double_floor, 0, 1) {
126 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
127 return Double::New(floor(arg.value()));
128}
129
130DEFINE_NATIVE_ENTRY(Double_ceil, 0, 1) {
131 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
132 return Double::New(ceil(arg.value()));
133}
134
135DEFINE_NATIVE_ENTRY(Double_truncate, 0, 1) {
136 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
137 return Double::New(trunc(arg.value()));
138}
139
140#if defined(DART_HOST_OS_MACOS)
141// MAC OSX math library produces old style cast warning.
142#pragma GCC diagnostic ignored "-Wold-style-cast"
143#endif
144
145DEFINE_NATIVE_ENTRY(Double_toInt, 0, 1) {
146 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
147 return DoubleToInteger(zone, arg.value());
148}
149
150DEFINE_NATIVE_ENTRY(Double_parse, 0, 3) {
151 GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0));
152 GET_NON_NULL_NATIVE_ARGUMENT(Integer, startValue, arguments->NativeArgAt(1));
153 GET_NON_NULL_NATIVE_ARGUMENT(Integer, endValue, arguments->NativeArgAt(2));
154
155 const intptr_t start = startValue.AsTruncatedUint32Value();
156 const intptr_t end = endValue.AsTruncatedUint32Value();
157 const intptr_t len = value.Length();
158
159 // Indices should be inside the string, and 0 <= start < end <= len.
160 if (0 <= start && start < end && end <= len) {
161 double double_value;
162 if (String::ParseDouble(value, start, end, &double_value)) {
163 return Double::New(double_value);
164 }
165 }
166 return Object::null();
167}
168
169DEFINE_NATIVE_ENTRY(Double_toString, 0, 1) {
170 const Number& number = Number::CheckedHandle(zone, arguments->NativeArgAt(0));
171 return number.ToString(Heap::kNew);
172}
173
174DEFINE_NATIVE_ENTRY(Double_toStringAsFixed, 0, 2) {
175 // The boundaries are exclusive.
176 const double kLowerBoundary = -1e21;
177 const double kUpperBoundary = 1e21;
178
179 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
180 GET_NON_NULL_NATIVE_ARGUMENT(Smi, fraction_digits, arguments->NativeArgAt(1));
181 double d = arg.value();
182 intptr_t fraction_digits_value = fraction_digits.Value();
183 if (0 <= fraction_digits_value && fraction_digits_value <= 20 &&
184 kLowerBoundary < d && d < kUpperBoundary) {
185 return DoubleToStringAsFixed(d, static_cast<int>(fraction_digits_value));
186 } else {
188 String::New("Illegal arguments to double.toStringAsFixed")));
189 return Object::null();
190 }
191}
192
193DEFINE_NATIVE_ENTRY(Double_toStringAsExponential, 0, 2) {
194 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
195 GET_NON_NULL_NATIVE_ARGUMENT(Smi, fraction_digits, arguments->NativeArgAt(1));
196 double d = arg.value();
197 intptr_t fraction_digits_value = fraction_digits.Value();
198 if (-1 <= fraction_digits_value && fraction_digits_value <= 20) {
200 static_cast<int>(fraction_digits_value));
201 } else {
203 String::New("Illegal arguments to double.toStringAsExponential")));
204 return Object::null();
205 }
206}
207
208DEFINE_NATIVE_ENTRY(Double_toStringAsPrecision, 0, 2) {
209 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
210 GET_NON_NULL_NATIVE_ARGUMENT(Smi, precision, arguments->NativeArgAt(1));
211 double d = arg.value();
212 intptr_t precision_value = precision.Value();
213 if (1 <= precision_value && precision_value <= 21) {
214 return DoubleToStringAsPrecision(d, static_cast<int>(precision_value));
215 } else {
217 String::New("Illegal arguments to double.toStringAsPrecision")));
218 return Object::null();
219 }
220}
221
222DEFINE_NATIVE_ENTRY(Double_getIsInfinite, 0, 1) {
223 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
224 return Bool::Get(isinf(arg.value())).ptr();
225}
226
227DEFINE_NATIVE_ENTRY(Double_getIsNaN, 0, 1) {
228 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
229 return Bool::Get(isnan(arg.value())).ptr();
230}
231
232DEFINE_NATIVE_ENTRY(Double_getIsNegative, 0, 1) {
233 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
234 // Include negative zero, infinity.
235 double dval = arg.value();
236 return Bool::Get(signbit(dval) && !isnan(dval)).ptr();
237}
238
239DEFINE_NATIVE_ENTRY(Double_flipSignBit, 0, 1) {
240 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
241 const double in_val = arg.value();
242 const int64_t bits = bit_cast<int64_t, double>(in_val) ^ kSignBitDouble;
243 return Double::New(bit_cast<double, int64_t>(bits));
244}
245
246// Add here only functions using/referring to old-style casts.
247
248} // namespace dart
static void round(SkPoint *p)
static bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
static const Bool & Get(bool value)
Definition object.h:10780
static DoublePtr New(double d, Heap::Space space=Heap::kNew)
Definition object.cc:23481
double value() const
Definition object.h:10094
static DART_NORETURN void ThrowArgumentError(const Instance &arg)
@ kNew
Definition heap.h:38
StringPtr ToString(Heap::Space space) const
Definition object.cc:23512
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static ObjectPtr null()
Definition object.h:433
ObjectPtr ptr() const
Definition object.h:332
static Object & Handle()
Definition object.h:407
static bool ParseDouble(const String &str, intptr_t start, intptr_t end, double *result)
Definition object.cc:24286
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition object.cc:23777
static float DivideAllowZero(float a, float b)
Definition utils.h:481
#define ASSERT(E)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition main.cc:19
glong glong end
uint8_t value
GAsyncResult * result
StringPtr DoubleToStringAsPrecision(double d, int precision)
IntegerPtr DoubleToInteger(Zone *zone, double val)
double DartModulo(double left, double right)
StringPtr DoubleToStringAsFixed(double d, int fraction_digits)
StringPtr DoubleToStringAsExponential(double d, int fraction_digits)
constexpr int64_t kSignBitDouble
Definition globals.h:496
#define DEFINE_NATIVE_ENTRY(name, type_argument_count, argument_count)
#define GET_NON_NULL_NATIVE_ARGUMENT(type, name, value)
double fmod_ieee(double x, double y)