| OLD | NEW |
| 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 |
| OLD | NEW |