| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "vm/bootstrap_natives.h" | 5 #include "vm/bootstrap_natives.h" |
| 6 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/exceptions.h" | 9 #include "vm/exceptions.h" |
| 10 #include "vm/native_entry.h" | 10 #include "vm/native_entry.h" |
| 11 #include "vm/object.h" | 11 #include "vm/object.h" |
| 12 #include "vm/symbols.h" | 12 #include "vm/symbols.h" |
| 13 | 13 |
| 14 namespace dart { | 14 namespace dart { |
| 15 | 15 |
| 16 DEFINE_FLAG(bool, throw_on_javascript_int_overflow, false, |
| 17 "Throw an exception when integer arithmetic exceeds 53 bits."); |
| 18 |
| 16 DEFINE_FLAG(bool, trace_intrinsified_natives, false, | 19 DEFINE_FLAG(bool, trace_intrinsified_natives, false, |
| 17 "Report if any of the intrinsified natives are called"); | 20 "Report if any of the intrinsified natives are called"); |
| 18 | 21 |
| 19 // Smi natives. | 22 // Smi natives. |
| 20 | 23 |
| 21 // Returns false if integer is in wrong representation, e.g., as is a Bigint | 24 // Returns false if integer is in wrong representation, e.g., as is a Bigint |
| 22 // when it could have been a Smi. | 25 // when it could have been a Smi. |
| 23 static bool CheckInteger(const Integer& i) { | 26 static bool CheckInteger(const Integer& i) { |
| 24 if (i.IsBigint()) { | 27 if (i.IsBigint()) { |
| 25 const Bigint& bigint = Bigint::Cast(i); | 28 const Bigint& bigint = Bigint::Cast(i); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 38 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 41 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 39 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 42 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
| 40 ASSERT(CheckInteger(right)); | 43 ASSERT(CheckInteger(right)); |
| 41 ASSERT(CheckInteger(left)); | 44 ASSERT(CheckInteger(left)); |
| 42 if (FLAG_trace_intrinsified_natives) { | 45 if (FLAG_trace_intrinsified_natives) { |
| 43 OS::Print("Integer_bitAndFromInteger %s & %s\n", | 46 OS::Print("Integer_bitAndFromInteger %s & %s\n", |
| 44 right.ToCString(), left.ToCString()); | 47 right.ToCString(), left.ToCString()); |
| 45 } | 48 } |
| 46 const Integer& result = | 49 const Integer& result = |
| 47 Integer::Handle(left.BitOp(Token::kBIT_AND, right)); | 50 Integer::Handle(left.BitOp(Token::kBIT_AND, right)); |
| 51 if (FLAG_throw_on_javascript_int_overflow) { |
| 52 Integer::CheckForFiftyThreeBitOverflow(result, "Integer_bitAndFromInteger"); |
| 53 } |
| 48 return result.AsValidInteger(); | 54 return result.AsValidInteger(); |
| 49 } | 55 } |
| 50 | 56 |
| 51 | 57 |
| 52 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { | 58 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { |
| 53 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 59 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 54 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 60 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
| 55 ASSERT(CheckInteger(right)); | 61 ASSERT(CheckInteger(right)); |
| 56 ASSERT(CheckInteger(left)); | 62 ASSERT(CheckInteger(left)); |
| 57 if (FLAG_trace_intrinsified_natives) { | 63 if (FLAG_trace_intrinsified_natives) { |
| 58 OS::Print("Integer_bitOrFromInteger %s | %s\n", | 64 OS::Print("Integer_bitOrFromInteger %s | %s\n", |
| 59 left.ToCString(), right.ToCString()); | 65 left.ToCString(), right.ToCString()); |
| 60 } | 66 } |
| 61 const Integer& result = | 67 const Integer& result = |
| 62 Integer::Handle(left.BitOp(Token::kBIT_OR, right)); | 68 Integer::Handle(left.BitOp(Token::kBIT_OR, right)); |
| 69 if (FLAG_throw_on_javascript_int_overflow) { |
| 70 Integer::CheckForFiftyThreeBitOverflow(result, "Integer_bitOrFromInteger"); |
| 71 } |
| 63 return result.AsValidInteger(); | 72 return result.AsValidInteger(); |
| 64 } | 73 } |
| 65 | 74 |
| 66 | 75 |
| 67 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { | 76 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { |
| 68 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 77 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 69 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 78 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
| 70 ASSERT(CheckInteger(right)); | 79 ASSERT(CheckInteger(right)); |
| 71 ASSERT(CheckInteger(left)); | 80 ASSERT(CheckInteger(left)); |
| 72 if (FLAG_trace_intrinsified_natives) { | 81 if (FLAG_trace_intrinsified_natives) { |
| 73 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", | 82 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", |
| 74 left.ToCString(), right.ToCString()); | 83 left.ToCString(), right.ToCString()); |
| 75 } | 84 } |
| 76 const Integer& result = | 85 const Integer& result = |
| 77 Integer::Handle(left.BitOp(Token::kBIT_XOR, right)); | 86 Integer::Handle(left.BitOp(Token::kBIT_XOR, right)); |
| 87 if (FLAG_throw_on_javascript_int_overflow) { |
| 88 Integer::CheckForFiftyThreeBitOverflow(result, "Integer_bitXorFromInteger"); |
| 89 } |
| 78 return result.AsValidInteger(); | 90 return result.AsValidInteger(); |
| 79 } | 91 } |
| 80 | 92 |
| 81 | 93 |
| 82 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { | 94 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { |
| 83 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 95 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 84 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 96 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 85 ASSERT(CheckInteger(right_int)); | 97 ASSERT(CheckInteger(right_int)); |
| 86 ASSERT(CheckInteger(left_int)); | 98 ASSERT(CheckInteger(left_int)); |
| 87 if (FLAG_trace_intrinsified_natives) { | 99 if (FLAG_trace_intrinsified_natives) { |
| 88 OS::Print("Integer_addFromInteger %s + %s\n", | 100 OS::Print("Integer_addFromInteger %s + %s\n", |
| 89 left_int.ToCString(), right_int.ToCString()); | 101 left_int.ToCString(), right_int.ToCString()); |
| 90 } | 102 } |
| 91 const Integer& result = | 103 const Integer& result = |
| 92 Integer::Handle(left_int.ArithmeticOp(Token::kADD, right_int)); | 104 Integer::Handle(left_int.ArithmeticOp(Token::kADD, right_int)); |
| 105 if (FLAG_throw_on_javascript_int_overflow) { |
| 106 Integer::CheckForFiftyThreeBitOverflow(result, "Integer_addFromInteger"); |
| 107 } |
| 93 return result.AsValidInteger(); | 108 return result.AsValidInteger(); |
| 94 } | 109 } |
| 95 | 110 |
| 96 | 111 |
| 97 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { | 112 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { |
| 98 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 113 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 99 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 114 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 100 ASSERT(CheckInteger(right_int)); | 115 ASSERT(CheckInteger(right_int)); |
| 101 ASSERT(CheckInteger(left_int)); | 116 ASSERT(CheckInteger(left_int)); |
| 102 if (FLAG_trace_intrinsified_natives) { | 117 if (FLAG_trace_intrinsified_natives) { |
| 103 OS::Print("Integer_subFromInteger %s - %s\n", | 118 OS::Print("Integer_subFromInteger %s - %s\n", |
| 104 left_int.ToCString(), right_int.ToCString()); | 119 left_int.ToCString(), right_int.ToCString()); |
| 105 } | 120 } |
| 106 const Integer& result = | 121 const Integer& result = |
| 107 Integer::Handle(left_int.ArithmeticOp(Token::kSUB, right_int)); | 122 Integer::Handle(left_int.ArithmeticOp(Token::kSUB, right_int)); |
| 123 if (FLAG_throw_on_javascript_int_overflow) { |
| 124 Integer::CheckForFiftyThreeBitOverflow(result, "Integer_subFromInteger"); |
| 125 } |
| 108 return result.AsValidInteger(); | 126 return result.AsValidInteger(); |
| 109 } | 127 } |
| 110 | 128 |
| 111 | 129 |
| 112 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { | 130 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { |
| 113 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 131 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 114 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 132 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 115 ASSERT(CheckInteger(right_int)); | 133 ASSERT(CheckInteger(right_int)); |
| 116 ASSERT(CheckInteger(left_int)); | 134 ASSERT(CheckInteger(left_int)); |
| 117 if (FLAG_trace_intrinsified_natives) { | 135 if (FLAG_trace_intrinsified_natives) { |
| 118 OS::Print("Integer_mulFromInteger %s * %s\n", | 136 OS::Print("Integer_mulFromInteger %s * %s\n", |
| 119 left_int.ToCString(), right_int.ToCString()); | 137 left_int.ToCString(), right_int.ToCString()); |
| 120 } | 138 } |
| 121 const Integer& result = | 139 const Integer& result = |
| 122 Integer::Handle(left_int.ArithmeticOp(Token::kMUL, right_int)); | 140 Integer::Handle(left_int.ArithmeticOp(Token::kMUL, right_int)); |
| 141 if (FLAG_throw_on_javascript_int_overflow) { |
| 142 Integer::CheckForFiftyThreeBitOverflow(result, "Integer_mulFromInteger"); |
| 143 } |
| 123 return result.AsValidInteger(); | 144 return result.AsValidInteger(); |
| 124 } | 145 } |
| 125 | 146 |
| 126 | 147 |
| 127 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { | 148 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { |
| 128 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 149 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 129 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 150 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 130 ASSERT(CheckInteger(right_int)); | 151 ASSERT(CheckInteger(right_int)); |
| 131 ASSERT(CheckInteger(left_int)); | 152 ASSERT(CheckInteger(left_int)); |
| 132 ASSERT(!right_int.IsZero()); | 153 ASSERT(!right_int.IsZero()); |
| 133 const Integer& result = | 154 const Integer& result = |
| 134 Integer::Handle(left_int.ArithmeticOp(Token::kTRUNCDIV, right_int)); | 155 Integer::Handle(left_int.ArithmeticOp(Token::kTRUNCDIV, right_int)); |
| 156 if (FLAG_throw_on_javascript_int_overflow) { |
| 157 Integer::CheckForFiftyThreeBitOverflow(result, |
| 158 "Integer_trucDivFromInteger"); |
| 159 } |
| 135 return result.AsValidInteger(); | 160 return result.AsValidInteger(); |
| 136 } | 161 } |
| 137 | 162 |
| 138 | 163 |
| 139 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { | 164 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { |
| 140 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 165 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 141 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 166 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 142 ASSERT(CheckInteger(right_int)); | 167 ASSERT(CheckInteger(right_int)); |
| 143 ASSERT(CheckInteger(right_int)); | 168 ASSERT(CheckInteger(right_int)); |
| 144 if (FLAG_trace_intrinsified_natives) { | 169 if (FLAG_trace_intrinsified_natives) { |
| 145 OS::Print("Integer_moduloFromInteger %s mod %s\n", | 170 OS::Print("Integer_moduloFromInteger %s mod %s\n", |
| 146 left_int.ToCString(), right_int.ToCString()); | 171 left_int.ToCString(), right_int.ToCString()); |
| 147 } | 172 } |
| 148 if (right_int.IsZero()) { | 173 if (right_int.IsZero()) { |
| 149 // Should have been caught before calling into runtime. | 174 // Should have been caught before calling into runtime. |
| 150 UNIMPLEMENTED(); | 175 UNIMPLEMENTED(); |
| 151 } | 176 } |
| 152 const Integer& result = | 177 const Integer& result = |
| 153 Integer::Handle(left_int.ArithmeticOp(Token::kMOD, right_int)); | 178 Integer::Handle(left_int.ArithmeticOp(Token::kMOD, right_int)); |
| 179 if (FLAG_throw_on_javascript_int_overflow) { |
| 180 Integer::CheckForFiftyThreeBitOverflow(result, "Integer_moduloFromInteger"); |
| 181 } |
| 154 return result.AsValidInteger(); | 182 return result.AsValidInteger(); |
| 155 } | 183 } |
| 156 | 184 |
| 157 | 185 |
| 158 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { | 186 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { |
| 159 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 187 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 160 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 188 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
| 161 ASSERT(CheckInteger(right)); | 189 ASSERT(CheckInteger(right)); |
| 162 ASSERT(CheckInteger(left)); | 190 ASSERT(CheckInteger(left)); |
| 163 if (FLAG_trace_intrinsified_natives) { | 191 if (FLAG_trace_intrinsified_natives) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 186 if (value.IsOneByteString()) { | 214 if (value.IsOneByteString()) { |
| 187 // Quick conversion for unpadded integers in strings. | 215 // Quick conversion for unpadded integers in strings. |
| 188 const intptr_t len = value.Length(); | 216 const intptr_t len = value.Length(); |
| 189 if (len > 0) { | 217 if (len > 0) { |
| 190 const char* cstr = value.ToCString(); | 218 const char* cstr = value.ToCString(); |
| 191 ASSERT(cstr != NULL); | 219 ASSERT(cstr != NULL); |
| 192 char* p_end = NULL; | 220 char* p_end = NULL; |
| 193 const int64_t int_value = strtoll(cstr, &p_end, 10); | 221 const int64_t int_value = strtoll(cstr, &p_end, 10); |
| 194 if (p_end == (cstr + len)) { | 222 if (p_end == (cstr + len)) { |
| 195 if ((int_value != LLONG_MIN) && (int_value != LLONG_MAX)) { | 223 if ((int_value != LLONG_MIN) && (int_value != LLONG_MAX)) { |
| 196 return Integer::New(int_value); | 224 const Integer& i = Integer::Handle(Integer::New(int_value)); |
| 225 if (FLAG_throw_on_javascript_int_overflow) { |
| 226 Integer::CheckForFiftyThreeBitOverflow(i, "Integer_parse"); |
| 227 } |
| 228 return i.raw(); |
| 197 } | 229 } |
| 198 } | 230 } |
| 199 } | 231 } |
| 200 } | 232 } |
| 201 | 233 |
| 202 Scanner scanner(value, Symbols::Empty()); | 234 Scanner scanner(value, Symbols::Empty()); |
| 203 const Scanner::GrowableTokenStream& tokens = scanner.GetStream(); | 235 const Scanner::GrowableTokenStream& tokens = scanner.GetStream(); |
| 204 String* int_string; | 236 String* int_string; |
| 205 bool is_positive; | 237 bool is_positive; |
| 206 if (Scanner::IsValidLiteral(tokens, | 238 if (Scanner::IsValidLiteral(tokens, |
| 207 Token::kINTEGER, | 239 Token::kINTEGER, |
| 208 &is_positive, | 240 &is_positive, |
| 209 &int_string)) { | 241 &int_string)) { |
| 210 if (is_positive) { | 242 if (is_positive) { |
| 211 return Integer::New(*int_string); | 243 return Integer::New(*int_string); |
| 212 } | 244 } |
| 213 String& temp = String::Handle(); | 245 String& temp = String::Handle(); |
| 214 temp = String::Concat(Symbols::Dash(), *int_string); | 246 temp = String::Concat(Symbols::Dash(), *int_string); |
| 215 return Integer::New(temp); | 247 const Integer& i = Integer::Handle(Integer::New(temp)); |
| 248 if (FLAG_throw_on_javascript_int_overflow) { |
| 249 Integer::CheckForFiftyThreeBitOverflow(i, "Integer_parse"); |
| 250 } |
| 251 return i.raw(); |
| 216 } | 252 } |
| 217 | 253 |
| 218 const Array& args = Array::Handle(Array::New(1)); | 254 const Array& args = Array::Handle(Array::New(1)); |
| 219 args.SetAt(0, value); | 255 args.SetAt(0, value); |
| 220 Exceptions::ThrowByType(Exceptions::kFormat, args); | 256 Exceptions::ThrowByType(Exceptions::kFormat, args); |
| 221 return Object::null(); | 257 return Object::null(); |
| 222 } | 258 } |
| 223 | 259 |
| 224 | 260 |
| 225 static RawInteger* ShiftOperationHelper(Token::Kind kind, | 261 static RawInteger* ShiftOperationHelper(Token::Kind kind, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 } | 303 } |
| 268 | 304 |
| 269 | 305 |
| 270 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { | 306 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { |
| 271 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); | 307 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
| 272 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); | 308 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); |
| 273 ASSERT(CheckInteger(amount)); | 309 ASSERT(CheckInteger(amount)); |
| 274 ASSERT(CheckInteger(value)); | 310 ASSERT(CheckInteger(value)); |
| 275 const Integer& result = Integer::Handle( | 311 const Integer& result = Integer::Handle( |
| 276 ShiftOperationHelper(Token::kSHR, value, amount)); | 312 ShiftOperationHelper(Token::kSHR, value, amount)); |
| 313 if (FLAG_throw_on_javascript_int_overflow) { |
| 314 Integer::CheckForFiftyThreeBitOverflow(result, "Smi_shrFromInt"); |
| 315 } |
| 277 return result.AsValidInteger(); | 316 return result.AsValidInteger(); |
| 278 } | 317 } |
| 279 | 318 |
| 280 | 319 |
| 281 | 320 |
| 282 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { | 321 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { |
| 283 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); | 322 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
| 284 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); | 323 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); |
| 285 ASSERT(CheckInteger(amount)); | 324 ASSERT(CheckInteger(amount)); |
| 286 ASSERT(CheckInteger(value)); | 325 ASSERT(CheckInteger(value)); |
| 287 if (FLAG_trace_intrinsified_natives) { | 326 if (FLAG_trace_intrinsified_natives) { |
| 288 OS::Print("Smi_shlFromInt: %s << %s\n", | 327 OS::Print("Smi_shlFromInt: %s << %s\n", |
| 289 value.ToCString(), amount.ToCString()); | 328 value.ToCString(), amount.ToCString()); |
| 290 } | 329 } |
| 291 const Integer& result = Integer::Handle( | 330 const Integer& result = Integer::Handle( |
| 292 ShiftOperationHelper(Token::kSHL, value, amount)); | 331 ShiftOperationHelper(Token::kSHL, value, amount)); |
| 332 if (FLAG_throw_on_javascript_int_overflow) { |
| 333 Integer::CheckForFiftyThreeBitOverflow(result, "Smi_shlFromInt"); |
| 334 } |
| 293 return result.AsValidInteger(); | 335 return result.AsValidInteger(); |
| 294 } | 336 } |
| 295 | 337 |
| 296 | 338 |
| 297 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { | 339 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { |
| 298 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0)); | 340 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
| 299 if (FLAG_trace_intrinsified_natives) { | 341 if (FLAG_trace_intrinsified_natives) { |
| 300 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); | 342 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); |
| 301 } | 343 } |
| 302 intptr_t result = ~operand.Value(); | 344 intptr_t result = ~operand.Value(); |
| 303 ASSERT(Smi::IsValid(result)); | 345 ASSERT(Smi::IsValid(result)); |
| 304 return Smi::New(result); | 346 return Smi::New(result); |
| 305 } | 347 } |
| 306 | 348 |
| 307 // Mint natives. | 349 // Mint natives. |
| 308 | 350 |
| 309 DEFINE_NATIVE_ENTRY(Mint_bitNegate, 1) { | 351 DEFINE_NATIVE_ENTRY(Mint_bitNegate, 1) { |
| 310 const Mint& operand = Mint::CheckedHandle(arguments->NativeArgAt(0)); | 352 const Mint& operand = Mint::CheckedHandle(arguments->NativeArgAt(0)); |
| 311 ASSERT(CheckInteger(operand)); | 353 ASSERT(CheckInteger(operand)); |
| 312 if (FLAG_trace_intrinsified_natives) { | 354 if (FLAG_trace_intrinsified_natives) { |
| 313 OS::Print("Mint_bitNegate: %s\n", operand.ToCString()); | 355 OS::Print("Mint_bitNegate: %s\n", operand.ToCString()); |
| 314 } | 356 } |
| 315 int64_t result = ~operand.value(); | 357 int64_t result = ~operand.value(); |
| 316 return Integer::New(result); | 358 const Integer& i = Integer::Handle(Integer::New(result)); |
| 359 if (FLAG_throw_on_javascript_int_overflow) { |
| 360 Integer::CheckForFiftyThreeBitOverflow(i, "Integer_bitAndFromInteger"); |
| 361 } |
| 362 return i.raw(); |
| 317 } | 363 } |
| 318 | 364 |
| 319 // Bigint natives. | 365 // Bigint natives. |
| 320 | 366 |
| 321 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { | 367 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { |
| 322 const Bigint& value = Bigint::CheckedHandle(arguments->NativeArgAt(0)); | 368 const Bigint& value = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| 323 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); | 369 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); |
| 324 ASSERT(CheckInteger(value)); | 370 ASSERT(CheckInteger(value)); |
| 325 ASSERT(CheckInteger(result)); | 371 ASSERT(CheckInteger(result)); |
| 326 return result.AsValidInteger(); | 372 return result.AsValidInteger(); |
| 327 } | 373 } |
| 328 | 374 |
| 329 } // namespace dart | 375 } // namespace dart |
| OLD | NEW |