Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: lib/double.cc

Issue 10874072: Use the return value of vm native methods to set the return value, (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/date.cc ('k') | lib/error.cc » ('j') | vm/bootstrap_natives.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include <math.h> 5 #include <math.h>
6 6
7 #include "vm/bootstrap_natives.h" 7 #include "vm/bootstrap_natives.h"
8 8
9 #include "vm/bigint_operations.h" 9 #include "vm/bigint_operations.h"
10 #include "vm/double_conversion.h" 10 #include "vm/double_conversion.h"
11 #include "vm/exceptions.h" 11 #include "vm/exceptions.h"
12 #include "vm/native_entry.h" 12 #include "vm/native_entry.h"
13 #include "vm/object.h" 13 #include "vm/object.h"
14 14
15 namespace dart { 15 namespace dart {
16 16
17 DEFINE_NATIVE_ENTRY(Double_doubleFromInteger, 2) { 17 DEFINE_NATIVE_ENTRY(Double_doubleFromInteger, 2) {
18 ASSERT(AbstractTypeArguments::CheckedHandle(arguments->At(0)).IsNull()); 18 ASSERT(AbstractTypeArguments::CheckedHandle(arguments->At(0)).IsNull());
19 const Integer& value = Integer::CheckedHandle(arguments->At(1)); 19 const Integer& value = Integer::CheckedHandle(arguments->At(1));
20 const Double& result = Double::Handle(Double::New(value.AsDoubleValue())); 20 return Double::New(value.AsDoubleValue());
21 arguments->SetReturn(result);
22 } 21 }
23 22
24 23
25 DEFINE_NATIVE_ENTRY(Double_add, 2) { 24 DEFINE_NATIVE_ENTRY(Double_add, 2) {
26 double left = Double::CheckedHandle(arguments->At(0)).value(); 25 double left = Double::CheckedHandle(arguments->At(0)).value();
27 GET_NATIVE_ARGUMENT(Double, right_object, arguments->At(1)); 26 GET_NATIVE_ARGUMENT(Double, right_object, arguments->At(1));
28 double right = right_object.value(); 27 double right = right_object.value();
29 const Double& result = Double::Handle(Double::New(left + right)); 28 return Double::New(left + right);
30 arguments->SetReturn(result);
31 } 29 }
32 30
33 31
34 DEFINE_NATIVE_ENTRY(Double_sub, 2) { 32 DEFINE_NATIVE_ENTRY(Double_sub, 2) {
35 double left = Double::CheckedHandle(arguments->At(0)).value(); 33 double left = Double::CheckedHandle(arguments->At(0)).value();
36 GET_NATIVE_ARGUMENT(Double, right_object, arguments->At(1)); 34 GET_NATIVE_ARGUMENT(Double, right_object, arguments->At(1));
37 double right = right_object.value(); 35 double right = right_object.value();
38 const Double& result = Double::Handle(Double::New(left - right)); 36 return Double::New(left - right);
39 arguments->SetReturn(result);
40 } 37 }
41 38
42 39
43 DEFINE_NATIVE_ENTRY(Double_mul, 2) { 40 DEFINE_NATIVE_ENTRY(Double_mul, 2) {
44 double left = Double::CheckedHandle(arguments->At(0)).value(); 41 double left = Double::CheckedHandle(arguments->At(0)).value();
45 GET_NATIVE_ARGUMENT(Double, right_object, arguments->At(1)); 42 GET_NATIVE_ARGUMENT(Double, right_object, arguments->At(1));
46 double right = right_object.value(); 43 double right = right_object.value();
47 const Double& result = Double::Handle(Double::New(left * right)); 44 return Double::New(left * right);
48 arguments->SetReturn(result);
49 } 45 }
50 46
51 47
52 DEFINE_NATIVE_ENTRY(Double_div, 2) { 48 DEFINE_NATIVE_ENTRY(Double_div, 2) {
53 double left = Double::CheckedHandle(arguments->At(0)).value(); 49 double left = Double::CheckedHandle(arguments->At(0)).value();
54 GET_NATIVE_ARGUMENT(Double, right_object, arguments->At(1)); 50 GET_NATIVE_ARGUMENT(Double, right_object, arguments->At(1));
55 double right = right_object.value(); 51 double right = right_object.value();
56 const Double& result = Double::Handle(Double::New(left / right)); 52 return Double::New(left / right);
57 arguments->SetReturn(result);
58 } 53 }
59 54
60 55
61 DEFINE_NATIVE_ENTRY(Double_trunc_div, 2) { 56 DEFINE_NATIVE_ENTRY(Double_trunc_div, 2) {
62 double left = Double::CheckedHandle(arguments->At(0)).value(); 57 double left = Double::CheckedHandle(arguments->At(0)).value();
63 GET_NATIVE_ARGUMENT(Double, right_object, arguments->At(1)); 58 GET_NATIVE_ARGUMENT(Double, right_object, arguments->At(1));
64 double right = right_object.value(); 59 double right = right_object.value();
65 const Double& result = Double::Handle(Double::New(trunc(left / right))); 60 return Double::New(trunc(left / right));
66 arguments->SetReturn(result);
67 } 61 }
68 62
69 63
70 DEFINE_NATIVE_ENTRY(Double_modulo, 2) { 64 DEFINE_NATIVE_ENTRY(Double_modulo, 2) {
71 double left = Double::CheckedHandle(arguments->At(0)).value(); 65 double left = Double::CheckedHandle(arguments->At(0)).value();
72 GET_NATIVE_ARGUMENT(Double, right_object, arguments->At(1)); 66 GET_NATIVE_ARGUMENT(Double, right_object, arguments->At(1));
73 double right = right_object.value(); 67 double right = right_object.value();
74 double remainder = fmod(left, right); 68 double remainder = fmod(left, right);
75 if (remainder == 0.0) { 69 if (remainder == 0.0) {
76 // We explicitely switch to the positive 0.0 (just in case it was negative). 70 // We explicitely switch to the positive 0.0 (just in case it was negative).
77 remainder = +0.0; 71 remainder = +0.0;
78 } else if (remainder < 0) { 72 } else if (remainder < 0) {
79 if (right < 0) { 73 if (right < 0) {
80 remainder -= right; 74 remainder -= right;
81 } else { 75 } else {
82 remainder += right; 76 remainder += right;
83 } 77 }
84 } 78 }
85 const Double& result = Double::Handle(Double::New(remainder)); 79 return Double::New(remainder);
86 arguments->SetReturn(result);
87 } 80 }
88 81
89 82
90 DEFINE_NATIVE_ENTRY(Double_remainder, 2) { 83 DEFINE_NATIVE_ENTRY(Double_remainder, 2) {
91 double left = Double::CheckedHandle(arguments->At(0)).value(); 84 double left = Double::CheckedHandle(arguments->At(0)).value();
92 GET_NATIVE_ARGUMENT(Double, right_object, arguments->At(1)); 85 GET_NATIVE_ARGUMENT(Double, right_object, arguments->At(1));
93 double right = right_object.value(); 86 double right = right_object.value();
94 const Double& result = Double::Handle(Double::New(fmod(left, right))); 87 return Double::New(fmod(left, right));
95 arguments->SetReturn(result);
96 } 88 }
97 89
98 90
99 DEFINE_NATIVE_ENTRY(Double_greaterThan, 2) { 91 DEFINE_NATIVE_ENTRY(Double_greaterThan, 2) {
100 const Double& left = Double::CheckedHandle(arguments->At(0)); 92 const Double& left = Double::CheckedHandle(arguments->At(0));
101 GET_NATIVE_ARGUMENT(Double, right, arguments->At(1)); 93 GET_NATIVE_ARGUMENT(Double, right, arguments->At(1));
102 bool result = right.IsNull() ? false : (left.value() > right.value()); 94 bool result = right.IsNull() ? false : (left.value() > right.value());
103 arguments->SetReturn(Bool::Handle(Bool::Get(result))); 95 return Bool::Get(result);
104 } 96 }
105 97
106 98
107 DEFINE_NATIVE_ENTRY(Double_greaterThanFromInteger, 2) { 99 DEFINE_NATIVE_ENTRY(Double_greaterThanFromInteger, 2) {
108 const Double& right = Double::CheckedHandle(arguments->At(0)); 100 const Double& right = Double::CheckedHandle(arguments->At(0));
109 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); 101 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1));
110 const Bool& result = Bool::Handle(Bool::Get( 102 return Bool::Get(left.AsDoubleValue() > right.value());
111 left.AsDoubleValue() > right.value()));
112 arguments->SetReturn(result);
113 } 103 }
114 104
115 105
116 DEFINE_NATIVE_ENTRY(Double_equal, 2) { 106 DEFINE_NATIVE_ENTRY(Double_equal, 2) {
117 const Double& left = Double::CheckedHandle(arguments->At(0)); 107 const Double& left = Double::CheckedHandle(arguments->At(0));
118 GET_NATIVE_ARGUMENT(Double, right, arguments->At(1)); 108 GET_NATIVE_ARGUMENT(Double, right, arguments->At(1));
119 bool result = right.IsNull() ? false : (left.value() == right.value()); 109 bool result = right.IsNull() ? false : (left.value() == right.value());
120 arguments->SetReturn(Bool::Handle(Bool::Get(result))); 110 return Bool::Get(result);
121 } 111 }
122 112
123 113
124 DEFINE_NATIVE_ENTRY(Double_equalToInteger, 2) { 114 DEFINE_NATIVE_ENTRY(Double_equalToInteger, 2) {
125 const Double& left = Double::CheckedHandle(arguments->At(0)); 115 const Double& left = Double::CheckedHandle(arguments->At(0));
126 GET_NATIVE_ARGUMENT(Integer, right, arguments->At(1)); 116 GET_NATIVE_ARGUMENT(Integer, right, arguments->At(1));
127 const Bool& result = 117 return Bool::Get(left.value() == right.AsDoubleValue());
128 Bool::Handle(Bool::Get(left.value() == right.AsDoubleValue()));
129 arguments->SetReturn(result);
130 } 118 }
131 119
132 120
133 DEFINE_NATIVE_ENTRY(Double_round, 1) { 121 DEFINE_NATIVE_ENTRY(Double_round, 1) {
134 const Double& arg = Double::CheckedHandle(arguments->At(0)); 122 const Double& arg = Double::CheckedHandle(arguments->At(0));
135 arguments->SetReturn(Double::Handle(Double::New(round(arg.value())))); 123 return Double::New(round(arg.value()));
136 } 124 }
137 125
138 DEFINE_NATIVE_ENTRY(Double_floor, 1) { 126 DEFINE_NATIVE_ENTRY(Double_floor, 1) {
139 const Double& arg = Double::CheckedHandle(arguments->At(0)); 127 const Double& arg = Double::CheckedHandle(arguments->At(0));
140 arguments->SetReturn(Double::Handle(Double::New(floor(arg.value())))); 128 return Double::New(floor(arg.value()));
141 } 129 }
142 130
143 DEFINE_NATIVE_ENTRY(Double_ceil, 1) { 131 DEFINE_NATIVE_ENTRY(Double_ceil, 1) {
144 const Double& arg = Double::CheckedHandle(arguments->At(0)); 132 const Double& arg = Double::CheckedHandle(arguments->At(0));
145 arguments->SetReturn(Double::Handle(Double::New(ceil(arg.value())))); 133 return Double::New(ceil(arg.value()));
146 } 134 }
147 135
148 136
149 DEFINE_NATIVE_ENTRY(Double_truncate, 1) { 137 DEFINE_NATIVE_ENTRY(Double_truncate, 1) {
150 const Double& arg = Double::CheckedHandle(arguments->At(0)); 138 const Double& arg = Double::CheckedHandle(arguments->At(0));
151 arguments->SetReturn(Double::Handle(Double::New(trunc(arg.value())))); 139 return Double::New(trunc(arg.value()));
152 } 140 }
153 141
154 142
155 DEFINE_NATIVE_ENTRY(Double_pow, 2) { 143 DEFINE_NATIVE_ENTRY(Double_pow, 2) {
156 const double operand = Double::CheckedHandle(arguments->At(0)).value(); 144 const double operand = Double::CheckedHandle(arguments->At(0)).value();
157 GET_NATIVE_ARGUMENT(Double, exponent_object, arguments->At(1)); 145 GET_NATIVE_ARGUMENT(Double, exponent_object, arguments->At(1));
158 const double exponent = exponent_object.value(); 146 const double exponent = exponent_object.value();
159 arguments->SetReturn(Double::Handle(Double::New(pow(operand, exponent)))); 147 return Double::New(pow(operand, exponent));
160 } 148 }
161 149
162 150
163 #if defined(TARGET_OS_MACOS) 151 #if defined(TARGET_OS_MACOS)
164 // MAC OSX math library produces old style cast warning. 152 // MAC OSX math library produces old style cast warning.
165 #pragma GCC diagnostic ignored "-Wold-style-cast" 153 #pragma GCC diagnostic ignored "-Wold-style-cast"
166 #endif 154 #endif
167 155
168 DEFINE_NATIVE_ENTRY(Double_toInt, 1) { 156 DEFINE_NATIVE_ENTRY(Double_toInt, 1) {
169 const Double& arg = Double::CheckedHandle(arguments->At(0)); 157 const Double& arg = Double::CheckedHandle(arguments->At(0));
170 if (isinf(arg.value()) || isnan(arg.value())) { 158 if (isinf(arg.value()) || isnan(arg.value())) {
171 GrowableArray<const Object*> args; 159 GrowableArray<const Object*> args;
172 args.Add(&String::ZoneHandle(String::New( 160 args.Add(&String::ZoneHandle(String::New(
173 "Infinity or NaN toInt"))); 161 "Infinity or NaN toInt")));
174 Exceptions::ThrowByType(Exceptions::kFormat, args); 162 Exceptions::ThrowByType(Exceptions::kFormat, args);
175 } 163 }
176 double result = trunc(arg.value()); 164 double result = trunc(arg.value());
177 if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) { 165 if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) {
178 arguments->SetReturn(Smi::Handle(Smi::New(static_cast<intptr_t>(result)))); 166 return Smi::New(static_cast<intptr_t>(result));
179 } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) { 167 } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) {
180 arguments->SetReturn(Mint::Handle(Mint::New(static_cast<int64_t>(result)))); 168 return Mint::New(static_cast<int64_t>(result));
181 } else { 169 } else {
182 arguments->SetReturn( 170 return BigintOperations::NewFromDouble(result);
183 Bigint::Handle(BigintOperations::NewFromDouble(result)));
184 } 171 }
185 } 172 }
186 173
187 174
188 DEFINE_NATIVE_ENTRY(Double_toStringAsFixed, 2) { 175 DEFINE_NATIVE_ENTRY(Double_toStringAsFixed, 2) {
189 // The boundaries are exclusive. 176 // The boundaries are exclusive.
190 static const double kLowerBoundary = -1e21; 177 static const double kLowerBoundary = -1e21;
191 static const double kUpperBoundary = 1e21; 178 static const double kUpperBoundary = 1e21;
192 179
193 const Double& arg = Double::CheckedHandle(arguments->At(0)); 180 const Double& arg = Double::CheckedHandle(arguments->At(0));
194 GET_NATIVE_ARGUMENT(Smi, fraction_digits, arguments->At(1)); 181 GET_NATIVE_ARGUMENT(Smi, fraction_digits, arguments->At(1));
195 double d = arg.value(); 182 double d = arg.value();
196 intptr_t fraction_digits_value = fraction_digits.Value(); 183 intptr_t fraction_digits_value = fraction_digits.Value();
197 if (0 <= fraction_digits_value && fraction_digits_value <= 20 184 if (0 <= fraction_digits_value && fraction_digits_value <= 20
198 && kLowerBoundary < d && d < kUpperBoundary) { 185 && kLowerBoundary < d && d < kUpperBoundary) {
199 String& result = String::Handle(); 186 return DoubleToStringAsFixed(d, static_cast<int>(fraction_digits_value));
200 result = DoubleToStringAsFixed(d, static_cast<int>(fraction_digits_value));
201 arguments->SetReturn(result);
202 } else { 187 } else {
203 GrowableArray<const Object*> args; 188 GrowableArray<const Object*> args;
204 args.Add(&String::ZoneHandle(String::New( 189 args.Add(&String::ZoneHandle(String::New(
205 "Illegal arguments to double.toStringAsFixed"))); 190 "Illegal arguments to double.toStringAsFixed")));
206 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args); 191 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
192 return Object::null();
207 } 193 }
208 } 194 }
209 195
210 196
211 DEFINE_NATIVE_ENTRY(Double_toStringAsExponential, 2) { 197 DEFINE_NATIVE_ENTRY(Double_toStringAsExponential, 2) {
212 const Double& arg = Double::CheckedHandle(arguments->At(0)); 198 const Double& arg = Double::CheckedHandle(arguments->At(0));
213 GET_NATIVE_ARGUMENT(Smi, fraction_digits, arguments->At(1)); 199 GET_NATIVE_ARGUMENT(Smi, fraction_digits, arguments->At(1));
214 double d = arg.value(); 200 double d = arg.value();
215 intptr_t fraction_digits_value = fraction_digits.Value(); 201 intptr_t fraction_digits_value = fraction_digits.Value();
216 if (-1 <= fraction_digits_value && fraction_digits_value <= 20) { 202 if (-1 <= fraction_digits_value && fraction_digits_value <= 20) {
217 String& result = String::Handle(); 203 return DoubleToStringAsExponential(
218 result = DoubleToStringAsExponential(
219 d, static_cast<int>(fraction_digits_value)); 204 d, static_cast<int>(fraction_digits_value));
220 arguments->SetReturn(result);
221 } else { 205 } else {
222 GrowableArray<const Object*> args; 206 GrowableArray<const Object*> args;
223 args.Add(&String::ZoneHandle(String::New( 207 args.Add(&String::ZoneHandle(String::New(
224 "Illegal arguments to double.toStringAsExponential"))); 208 "Illegal arguments to double.toStringAsExponential")));
225 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args); 209 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
210 return Object::null();
226 } 211 }
227 } 212 }
228 213
229 214
230 DEFINE_NATIVE_ENTRY(Double_toStringAsPrecision, 2) { 215 DEFINE_NATIVE_ENTRY(Double_toStringAsPrecision, 2) {
231 const Double& arg = Double::CheckedHandle(arguments->At(0)); 216 const Double& arg = Double::CheckedHandle(arguments->At(0));
232 GET_NATIVE_ARGUMENT(Smi, precision, arguments->At(1)); 217 GET_NATIVE_ARGUMENT(Smi, precision, arguments->At(1));
233 double d = arg.value(); 218 double d = arg.value();
234 intptr_t precision_value = precision.Value(); 219 intptr_t precision_value = precision.Value();
235 if (1 <= precision_value && precision_value <= 21) { 220 if (1 <= precision_value && precision_value <= 21) {
236 String& result = String::Handle(); 221 return DoubleToStringAsPrecision(d, static_cast<int>(precision_value));
237 result = DoubleToStringAsPrecision(d, static_cast<int>(precision_value));
238 arguments->SetReturn(result);
239 } else { 222 } else {
240 GrowableArray<const Object*> args; 223 GrowableArray<const Object*> args;
241 args.Add(&String::ZoneHandle(String::New( 224 args.Add(&String::ZoneHandle(String::New(
242 "Illegal arguments to double.toStringAsPrecision"))); 225 "Illegal arguments to double.toStringAsPrecision")));
243 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args); 226 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
227 return Object::null();
244 } 228 }
245 } 229 }
246 230
247 231
248 DEFINE_NATIVE_ENTRY(Double_isInfinite, 1) { 232 DEFINE_NATIVE_ENTRY(Double_isInfinite, 1) {
249 const Double& arg = Double::CheckedHandle(arguments->At(0)); 233 const Double& arg = Double::CheckedHandle(arguments->At(0));
250 if (isinf(arg.value())) { 234 return Bool::Get(isinf(arg.value()));
251 arguments->SetReturn(Bool::Handle(Bool::True()));
252 } else {
253 arguments->SetReturn(Bool::Handle(Bool::False()));
254 }
255 } 235 }
256 236
257 237
258 DEFINE_NATIVE_ENTRY(Double_isNaN, 1) { 238 DEFINE_NATIVE_ENTRY(Double_isNaN, 1) {
259 const Double& arg = Double::CheckedHandle(arguments->At(0)); 239 const Double& arg = Double::CheckedHandle(arguments->At(0));
260 if (isnan(arg.value())) { 240 return Bool::Get(isnan(arg.value()));
261 arguments->SetReturn(Bool::Handle(Bool::True()));
262 } else {
263 arguments->SetReturn(Bool::Handle(Bool::False()));
264 }
265 } 241 }
266 242
267 243
268 DEFINE_NATIVE_ENTRY(Double_isNegative, 1) { 244 DEFINE_NATIVE_ENTRY(Double_isNegative, 1) {
269 const Double& arg = Double::CheckedHandle(arguments->At(0)); 245 const Double& arg = Double::CheckedHandle(arguments->At(0));
270 // Include negative zero, infinity. 246 // Include negative zero, infinity.
271 if (signbit(arg.value()) && !isnan(arg.value())) { 247 return Bool::Get(signbit(arg.value()) && !isnan(arg.value()));
272 arguments->SetReturn(Bool::Handle(Bool::True()));
273 } else {
274 arguments->SetReturn(Bool::Handle(Bool::False()));
275 }
276 } 248 }
277 249
278 // Add here only functions using/referring to old-style casts. 250 // Add here only functions using/referring to old-style casts.
279 251
280 } // namespace dart 252 } // namespace dart
OLDNEW
« no previous file with comments | « lib/date.cc ('k') | lib/error.cc » ('j') | vm/bootstrap_natives.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698