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

Side by Side Diff: runtime/lib/double.cc

Issue 11748016: Make ~/, round, ceil, floor, truncate return ints. Remove toInt. (Closed) Base URL: https://dart.googlecode.com/svn/experimental/lib_v2/dart
Patch Set: Checked mode fixes. Created 7 years, 11 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
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"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 } 72 }
73 73
74 74
75 DEFINE_NATIVE_ENTRY(Double_trunc_div, 2) { 75 DEFINE_NATIVE_ENTRY(Double_trunc_div, 2) {
76 double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value(); 76 double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value();
77 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1)); 77 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
78 double right = right_object.value(); 78 double right = right_object.value();
79 if (FLAG_trace_intrinsified_natives) { 79 if (FLAG_trace_intrinsified_natives) {
80 OS::Print("Double_trunc_div %f ~/ %f\n", left, right); 80 OS::Print("Double_trunc_div %f ~/ %f\n", left, right);
81 } 81 }
82 return Double::New(trunc(left / right)); 82 double result = trunc(left / right);
83 if (isinf(result) || isnan(result)) {
floitsch 2013/01/03 18:23:17 From here on same as 'toInt' on the left (except t
84 const Array& args = Array::Handle(Array::New(1));
85 args.SetAt(0, String::Handle(String::New(
86 "Result of truncating division is Infinity or NaN")));
87 Exceptions::ThrowByType(Exceptions::kFormat, args);
Lasse Reichstein Nielsen 2013/01/04 10:29:42 Consider using UnsupportedError instead of FormatE
88 }
89 if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) {
90 return Smi::New(static_cast<intptr_t>(result));
91 } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) {
92 return Mint::New(static_cast<int64_t>(result));
93 } else {
94 return BigintOperations::NewFromDouble(result);
95 }
83 } 96 }
84 97
85 98
86 DEFINE_NATIVE_ENTRY(Double_modulo, 2) { 99 DEFINE_NATIVE_ENTRY(Double_modulo, 2) {
87 double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value(); 100 double left = Double::CheckedHandle(arguments->NativeArgAt(0)).value();
88 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1)); 101 GET_NON_NULL_NATIVE_ARGUMENT(Double, right_object, arguments->NativeArgAt(1));
89 double right = right_object.value(); 102 double right = right_object.value();
90 103
91 double remainder = fmod_ieee(left, right); 104 double remainder = fmod_ieee(left, right);
92 if (remainder == 0.0) { 105 if (remainder == 0.0) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 157
145 DEFINE_NATIVE_ENTRY(Double_equalToInteger, 2) { 158 DEFINE_NATIVE_ENTRY(Double_equalToInteger, 2) {
146 const Double& left = Double::CheckedHandle(arguments->NativeArgAt(0)); 159 const Double& left = Double::CheckedHandle(arguments->NativeArgAt(0));
147 GET_NON_NULL_NATIVE_ARGUMENT(Integer, right, arguments->NativeArgAt(1)); 160 GET_NON_NULL_NATIVE_ARGUMENT(Integer, right, arguments->NativeArgAt(1));
148 return Bool::Get(left.value() == right.AsDoubleValue()); 161 return Bool::Get(left.value() == right.AsDoubleValue());
149 } 162 }
150 163
151 164
152 DEFINE_NATIVE_ENTRY(Double_round, 1) { 165 DEFINE_NATIVE_ENTRY(Double_round, 1) {
153 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); 166 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0));
154 return Double::New(round(arg.value())); 167 if (isinf(arg.value()) || isnan(arg.value())) {
floitsch 2013/01/03 18:23:17 same as "toInt" on the left. Only change: error-me
Lasse Reichstein Nielsen 2013/01/04 10:29:42 Repeated code should be abstracted into a helper m
168 const Array& args = Array::Handle(Array::New(1));
169 args.SetAt(0, String::Handle(String::New("Infinity or NaN round")));
170 Exceptions::ThrowByType(Exceptions::kFormat, args);
171 }
172 double result = round(arg.value());
173 if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) {
174 return Smi::New(static_cast<intptr_t>(result));
175 } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) {
176 return Mint::New(static_cast<int64_t>(result));
177 } else {
178 return BigintOperations::NewFromDouble(result);
179 }
155 } 180 }
156 181
157 DEFINE_NATIVE_ENTRY(Double_floor, 1) { 182 DEFINE_NATIVE_ENTRY(Double_floor, 1) {
158 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); 183 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0));
159 return Double::New(floor(arg.value())); 184 if (isinf(arg.value()) || isnan(arg.value())) {
185 const Array& args = Array::Handle(Array::New(1));
186 args.SetAt(0, String::Handle(String::New("Infinity or NaN floor")));
187 Exceptions::ThrowByType(Exceptions::kFormat, args);
188 }
189 double result = floor(arg.value());
190 if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) {
191 return Smi::New(static_cast<intptr_t>(result));
192 } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) {
193 return Mint::New(static_cast<int64_t>(result));
194 } else {
195 return BigintOperations::NewFromDouble(result);
196 }
160 } 197 }
161 198
162 DEFINE_NATIVE_ENTRY(Double_ceil, 1) { 199 DEFINE_NATIVE_ENTRY(Double_ceil, 1) {
163 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); 200 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0));
164 return Double::New(ceil(arg.value())); 201 if (isinf(arg.value()) || isnan(arg.value())) {
202 const Array& args = Array::Handle(Array::New(1));
203 args.SetAt(0, String::Handle(String::New("Infinity or NaN ceil")));
204 Exceptions::ThrowByType(Exceptions::kFormat, args);
205 }
206 double result = ceil(arg.value());
207 if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) {
208 return Smi::New(static_cast<intptr_t>(result));
209 } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) {
210 return Mint::New(static_cast<int64_t>(result));
211 } else {
212 return BigintOperations::NewFromDouble(result);
213 }
165 } 214 }
166 215
167 216
168 DEFINE_NATIVE_ENTRY(Double_truncate, 1) { 217 DEFINE_NATIVE_ENTRY(Double_truncate, 1) {
169 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); 218 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0));
170 return Double::New(trunc(arg.value())); 219 if (isinf(arg.value()) || isnan(arg.value())) {
220 const Array& args = Array::Handle(Array::New(1));
221 args.SetAt(0, String::Handle(String::New("Infinity or NaN truncate")));
222 Exceptions::ThrowByType(Exceptions::kFormat, args);
223 }
224 double result = trunc(arg.value());
225 if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) {
226 return Smi::New(static_cast<intptr_t>(result));
227 } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) {
228 return Mint::New(static_cast<int64_t>(result));
229 } else {
230 return BigintOperations::NewFromDouble(result);
231 }
171 } 232 }
172 233
173 234
174 DEFINE_NATIVE_ENTRY(Double_pow, 2) { 235 DEFINE_NATIVE_ENTRY(Double_pow, 2) {
175 const double operand = 236 const double operand =
176 Double::CheckedHandle(arguments->NativeArgAt(0)).value(); 237 Double::CheckedHandle(arguments->NativeArgAt(0)).value();
177 GET_NON_NULL_NATIVE_ARGUMENT( 238 GET_NON_NULL_NATIVE_ARGUMENT(
178 Double, exponent_object, arguments->NativeArgAt(1)); 239 Double, exponent_object, arguments->NativeArgAt(1));
179 const double exponent = exponent_object.value(); 240 const double exponent = exponent_object.value();
180 return Double::New(pow(operand, exponent)); 241 return Double::New(pow(operand, exponent));
181 } 242 }
182 243
183 244
184 #if defined(TARGET_OS_MACOS) 245 #if defined(TARGET_OS_MACOS)
185 // MAC OSX math library produces old style cast warning. 246 // MAC OSX math library produces old style cast warning.
186 #pragma GCC diagnostic ignored "-Wold-style-cast" 247 #pragma GCC diagnostic ignored "-Wold-style-cast"
187 #endif 248 #endif
188 249
189 DEFINE_NATIVE_ENTRY(Double_toInt, 1) {
190 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0));
191 if (isinf(arg.value()) || isnan(arg.value())) {
192 const Array& args = Array::Handle(Array::New(1));
193 args.SetAt(0, String::Handle(String::New("Infinity or NaN toInt")));
194 Exceptions::ThrowByType(Exceptions::kFormat, args);
195 }
196 double result = trunc(arg.value());
197 if ((Smi::kMinValue <= result) && (result <= Smi::kMaxValue)) {
198 return Smi::New(static_cast<intptr_t>(result));
199 } else if ((Mint::kMinValue <= result) && (result <= Mint::kMaxValue)) {
200 return Mint::New(static_cast<int64_t>(result));
201 } else {
202 return BigintOperations::NewFromDouble(result);
203 }
204 }
205
206
207 DEFINE_NATIVE_ENTRY(Double_parse, 1) { 250 DEFINE_NATIVE_ENTRY(Double_parse, 1) {
208 GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0)); 251 GET_NON_NULL_NATIVE_ARGUMENT(String, value, arguments->NativeArgAt(0));
209 const String& dummy_key = String::Handle(Symbols::Empty()); 252 const String& dummy_key = String::Handle(Symbols::Empty());
210 Scanner scanner(value, dummy_key); 253 Scanner scanner(value, dummy_key);
211 const Scanner::GrowableTokenStream& tokens = scanner.GetStream(); 254 const Scanner::GrowableTokenStream& tokens = scanner.GetStream();
212 String* number_string; 255 String* number_string;
213 bool is_positive; 256 bool is_positive;
214 if (Scanner::IsValidLiteral(tokens, 257 if (Scanner::IsValidLiteral(tokens,
215 Token::kDOUBLE, 258 Token::kDOUBLE,
216 &is_positive, 259 &is_positive,
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 373
331 DEFINE_NATIVE_ENTRY(Double_getIsNegative, 1) { 374 DEFINE_NATIVE_ENTRY(Double_getIsNegative, 1) {
332 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0)); 375 const Double& arg = Double::CheckedHandle(arguments->NativeArgAt(0));
333 // Include negative zero, infinity. 376 // Include negative zero, infinity.
334 return Bool::Get(signbit(arg.value()) && !isnan(arg.value())); 377 return Bool::Get(signbit(arg.value()) && !isnan(arg.value()));
335 } 378 }
336 379
337 // Add here only functions using/referring to old-style casts. 380 // Add here only functions using/referring to old-style casts.
338 381
339 } // namespace dart 382 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698