Flutter Engine
The Flutter Engine
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 }
69 return Double::New(Utils::DivideAllowZero(left, right));
70}
71
72DEFINE_NATIVE_ENTRY(Double_greaterThan, 0, 2) {
73 const Double& left = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
74 GET_NON_NULL_NATIVE_ARGUMENT(Double, right, arguments->NativeArgAt(1));
75 bool result = right.IsNull() ? false : (left.value() > right.value());
76 if (FLAG_trace_intrinsified_natives) {
77 OS::PrintErr("Double_greaterThan %s > %s\n", left.ToCString(),
78 right.ToCString());
79 }
80 return Bool::Get(result).ptr();
81}
82
83DEFINE_NATIVE_ENTRY(Double_greaterThanFromInteger, 0, 2) {
84 const Double& right = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
85 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1));
86 return Bool::Get(left.AsDoubleValue() > right.value()).ptr();
87}
88
89DEFINE_NATIVE_ENTRY(Double_equal, 0, 2) {
90 const Double& left = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
91 GET_NON_NULL_NATIVE_ARGUMENT(Double, right, arguments->NativeArgAt(1));
92 bool result = right.IsNull() ? false : (left.value() == right.value());
93 if (FLAG_trace_intrinsified_natives) {
94 OS::PrintErr("Double_equal %s == %s\n", left.ToCString(),
95 right.ToCString());
96 }
97 return Bool::Get(result).ptr();
98}
99
100DEFINE_NATIVE_ENTRY(Double_equalToInteger, 0, 2) {
101 const Double& left = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
102 GET_NON_NULL_NATIVE_ARGUMENT(Integer, right, arguments->NativeArgAt(1));
103 return Bool::Get(left.value() == right.AsDoubleValue()).ptr();
104}
105
106#if defined(DART_HOST_OS_MACOS)
107// MAC OSX math library produces old style cast warning.
108#pragma GCC diagnostic ignored "-Wold-style-cast"
109#endif
110
111DEFINE_NATIVE_ENTRY(Double_parse, 0, 3) {
112 GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0));
113 GET_NON_NULL_NATIVE_ARGUMENT(Integer, startValue, arguments->NativeArgAt(1));
114 GET_NON_NULL_NATIVE_ARGUMENT(Integer, endValue, arguments->NativeArgAt(2));
115
116 const intptr_t start = startValue.AsTruncatedUint32Value();
117 const intptr_t end = endValue.AsTruncatedUint32Value();
118 const intptr_t len = value.Length();
119
120 // Indices should be inside the string, and 0 <= start < end <= len.
121 if (0 <= start && start < end && end <= len) {
122 double double_value;
123 if (String::ParseDouble(value, start, end, &double_value)) {
124 return Double::New(double_value);
125 }
126 }
127 return Object::null();
128}
129
130DEFINE_NATIVE_ENTRY(Double_toString, 0, 1) {
131 const Number& number = Number::CheckedHandle(zone, arguments->NativeArgAt(0));
132 return number.ToString(Heap::kNew);
133}
134
135DEFINE_NATIVE_ENTRY(Double_toStringAsFixed, 0, 2) {
136 // The boundaries are exclusive.
137 const double kLowerBoundary = -1e21;
138 const double kUpperBoundary = 1e21;
139
140 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
141 GET_NON_NULL_NATIVE_ARGUMENT(Smi, fraction_digits, arguments->NativeArgAt(1));
142 double d = arg.value();
143 intptr_t fraction_digits_value = fraction_digits.Value();
144 if (0 <= fraction_digits_value && fraction_digits_value <= 20 &&
145 kLowerBoundary < d && d < kUpperBoundary) {
146 return DoubleToStringAsFixed(d, static_cast<int>(fraction_digits_value));
147 } else {
149 String::New("Illegal arguments to double.toStringAsFixed")));
150 return Object::null();
151 }
152}
153
154DEFINE_NATIVE_ENTRY(Double_toStringAsExponential, 0, 2) {
155 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
156 GET_NON_NULL_NATIVE_ARGUMENT(Smi, fraction_digits, arguments->NativeArgAt(1));
157 double d = arg.value();
158 intptr_t fraction_digits_value = fraction_digits.Value();
159 if (-1 <= fraction_digits_value && fraction_digits_value <= 20) {
161 static_cast<int>(fraction_digits_value));
162 } else {
164 String::New("Illegal arguments to double.toStringAsExponential")));
165 return Object::null();
166 }
167}
168
169DEFINE_NATIVE_ENTRY(Double_toStringAsPrecision, 0, 2) {
170 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
171 GET_NON_NULL_NATIVE_ARGUMENT(Smi, precision, arguments->NativeArgAt(1));
172 double d = arg.value();
173 intptr_t precision_value = precision.Value();
174 if (1 <= precision_value && precision_value <= 21) {
175 return DoubleToStringAsPrecision(d, static_cast<int>(precision_value));
176 } else {
178 String::New("Illegal arguments to double.toStringAsPrecision")));
179 return Object::null();
180 }
181}
182
183DEFINE_NATIVE_ENTRY(Double_getIsInfinite, 0, 1) {
184 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
185 return Bool::Get(isinf(arg.value())).ptr();
186}
187
188DEFINE_NATIVE_ENTRY(Double_getIsNaN, 0, 1) {
189 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
190 return Bool::Get(isnan(arg.value())).ptr();
191}
192
193DEFINE_NATIVE_ENTRY(Double_getIsNegative, 0, 1) {
194 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
195 // Include negative zero, infinity.
196 double dval = arg.value();
197 return Bool::Get(signbit(dval) && !isnan(dval)).ptr();
198}
199
200DEFINE_NATIVE_ENTRY(Double_flipSignBit, 0, 1) {
201 const Double& arg = Double::CheckedHandle(zone, arguments->NativeArgAt(0));
202 const double in_val = arg.value();
203 const int64_t bits = bit_cast<int64_t, double>(in_val) ^ kSignBitDouble;
204 return Double::New(bit_cast<double, int64_t>(bits));
205}
206
207// Add here only functions using/referring to old-style casts.
208
209} // namespace dart
static const Bool & Get(bool value)
Definition: object.h:10801
static DoublePtr New(double d, Heap::Space space=Heap::kNew)
Definition: object.cc:23402
double value() const
Definition: object.h:10115
static DART_NORETURN void ThrowArgumentError(const Instance &arg)
Definition: exceptions.cc:1082
@ kNew
Definition: heap.h:38
StringPtr ToString(Heap::Space space) const
Definition: object.cc:23433
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:24207
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition: object.cc:23698
static float DivideAllowZero(float a, float b)
Definition: utils.h:496
#define ASSERT(E)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
glong glong end
uint8_t value
GAsyncResult * result
Definition: dart_vm.cc:33
StringPtr DoubleToStringAsPrecision(double d, int precision)
StringPtr DoubleToStringAsFixed(double d, int fraction_digits)
StringPtr DoubleToStringAsExponential(double d, int fraction_digits)
DEFINE_NATIVE_ENTRY(List_allocate, 0, 2)
Definition: array.cc:13
constexpr int64_t kSignBitDouble
Definition: globals.h:496
#define GET_NON_NULL_NATIVE_ARGUMENT(type, name, value)
Definition: native_entry.h:74