| 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 | 12 |
| 13 namespace dart { | 13 namespace dart { |
| 14 | 14 |
| 15 DEFINE_FLAG(bool, trace_intrinsified_natives, false, | 15 DEFINE_FLAG(bool, trace_intrinsified_natives, false, |
| 16 "Report if any of the intrinsified natives are called"); | 16 "Report if any of the intrinsified natives are called"); |
| 17 | 17 |
| 18 // Smi natives. | 18 // Smi natives. |
| 19 | 19 |
| 20 // Return the most compact presentation of an integer. | |
| 21 static RawInteger* AsInteger(const Integer& value) { | |
| 22 if (value.IsSmi()) return value.raw(); | |
| 23 if (value.IsMint()) { | |
| 24 Mint& mint = Mint::Handle(); | |
| 25 mint ^= value.raw(); | |
| 26 if (Smi::IsValid64(mint.value())) { | |
| 27 return Smi::New(mint.value()); | |
| 28 } else { | |
| 29 return value.raw(); | |
| 30 } | |
| 31 } | |
| 32 ASSERT(value.IsBigint()); | |
| 33 Bigint& big_value = Bigint::Handle(); | |
| 34 big_value ^= value.raw(); | |
| 35 if (BigintOperations::FitsIntoSmi(big_value)) { | |
| 36 return BigintOperations::ToSmi(big_value); | |
| 37 } else if (BigintOperations::FitsIntoMint(big_value)) { | |
| 38 return Mint::New(BigintOperations::ToMint(big_value)); | |
| 39 } else { | |
| 40 return big_value.raw(); | |
| 41 } | |
| 42 } | |
| 43 | |
| 44 | |
| 45 // Returns value in form of a RawBigint. | |
| 46 static RawBigint* AsBigint(const Integer& value) { | |
| 47 ASSERT(!value.IsNull()); | |
| 48 if (value.IsSmi()) { | |
| 49 Smi& smi = Smi::Handle(); | |
| 50 smi ^= value.raw(); | |
| 51 return BigintOperations::NewFromSmi(smi); | |
| 52 } else if (value.IsMint()) { | |
| 53 Mint& mint = Mint::Handle(); | |
| 54 mint ^= value.raw(); | |
| 55 return BigintOperations::NewFromInt64(mint.value()); | |
| 56 } else { | |
| 57 ASSERT(value.IsBigint()); | |
| 58 Bigint& big = Bigint::Handle(); | |
| 59 big ^= value.raw(); | |
| 60 ASSERT(!BigintOperations::FitsIntoSmi(big)); | |
| 61 return big.raw(); | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 | |
| 66 static bool Are64bitOperands(const Integer& op1, const Integer& op2) { | 20 static bool Are64bitOperands(const Integer& op1, const Integer& op2) { |
| 67 return !op1.IsBigint() && !op2.IsBigint(); | 21 return !op1.IsBigint() && !op2.IsBigint(); |
| 68 } | 22 } |
| 69 | 23 |
| 70 | 24 |
| 71 static RawInteger* IntegerBitOperation(Token::Kind kind, | 25 static RawInteger* IntegerBitOperation(Token::Kind kind, |
| 72 const Integer& op1_int, | 26 const Integer& op1_int, |
| 73 const Integer& op2_int) { | 27 const Integer& op2_int) { |
| 74 if (op1_int.IsSmi() && op2_int.IsSmi()) { | 28 if (op1_int.IsSmi() && op2_int.IsSmi()) { |
| 75 Smi& op1 = Smi::Handle(); | 29 Smi& op1 = Smi::Handle(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 99 case Token::kBIT_AND: | 53 case Token::kBIT_AND: |
| 100 return Integer::New(a & b); | 54 return Integer::New(a & b); |
| 101 case Token::kBIT_OR: | 55 case Token::kBIT_OR: |
| 102 return Integer::New(a | b); | 56 return Integer::New(a | b); |
| 103 case Token::kBIT_XOR: | 57 case Token::kBIT_XOR: |
| 104 return Integer::New(a ^ b); | 58 return Integer::New(a ^ b); |
| 105 default: | 59 default: |
| 106 UNIMPLEMENTED(); | 60 UNIMPLEMENTED(); |
| 107 } | 61 } |
| 108 } else { | 62 } else { |
| 109 Bigint& op1 = Bigint::Handle(AsBigint(op1_int)); | 63 Bigint& op1 = Bigint::Handle(Bigint::AsBigint(op1_int)); |
| 110 Bigint& op2 = Bigint::Handle(AsBigint(op2_int)); | 64 Bigint& op2 = Bigint::Handle(Bigint::AsBigint(op2_int)); |
| 111 switch (kind) { | 65 switch (kind) { |
| 112 case Token::kBIT_AND: | 66 case Token::kBIT_AND: |
| 113 return BigintOperations::BitAnd(op1, op2); | 67 return BigintOperations::BitAnd(op1, op2); |
| 114 case Token::kBIT_OR: | 68 case Token::kBIT_OR: |
| 115 return BigintOperations::BitOr(op1, op2); | 69 return BigintOperations::BitOr(op1, op2); |
| 116 case Token::kBIT_XOR: | 70 case Token::kBIT_XOR: |
| 117 return BigintOperations::BitXor(op1, op2); | 71 return BigintOperations::BitXor(op1, op2); |
| 118 default: | 72 default: |
| 119 UNIMPLEMENTED(); | 73 UNIMPLEMENTED(); |
| 120 } | 74 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 145 const Integer& right = Integer::CheckedHandle(arguments->At(0)); | 99 const Integer& right = Integer::CheckedHandle(arguments->At(0)); |
| 146 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); | 100 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); |
| 147 ASSERT(CheckInteger(right)); | 101 ASSERT(CheckInteger(right)); |
| 148 ASSERT(CheckInteger(left)); | 102 ASSERT(CheckInteger(left)); |
| 149 if (FLAG_trace_intrinsified_natives) { | 103 if (FLAG_trace_intrinsified_natives) { |
| 150 OS::Print("Integer_bitAndFromInteger %s & %s\n", | 104 OS::Print("Integer_bitAndFromInteger %s & %s\n", |
| 151 right.ToCString(), left.ToCString()); | 105 right.ToCString(), left.ToCString()); |
| 152 } | 106 } |
| 153 Integer& result = Integer::Handle( | 107 Integer& result = Integer::Handle( |
| 154 IntegerBitOperation(Token::kBIT_AND, left, right)); | 108 IntegerBitOperation(Token::kBIT_AND, left, right)); |
| 155 return AsInteger(result); | 109 return Integer::AsInteger(result); |
| 156 } | 110 } |
| 157 | 111 |
| 158 | 112 |
| 159 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { | 113 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { |
| 160 const Integer& right = Integer::CheckedHandle(arguments->At(0)); | 114 const Integer& right = Integer::CheckedHandle(arguments->At(0)); |
| 161 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); | 115 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); |
| 162 ASSERT(CheckInteger(right)); | 116 ASSERT(CheckInteger(right)); |
| 163 ASSERT(CheckInteger(left)); | 117 ASSERT(CheckInteger(left)); |
| 164 if (FLAG_trace_intrinsified_natives) { | 118 if (FLAG_trace_intrinsified_natives) { |
| 165 OS::Print("Integer_bitOrFromInteger %s | %s\n", | 119 OS::Print("Integer_bitOrFromInteger %s | %s\n", |
| 166 left.ToCString(), right.ToCString()); | 120 left.ToCString(), right.ToCString()); |
| 167 } | 121 } |
| 168 Integer& result = Integer::Handle( | 122 Integer& result = Integer::Handle( |
| 169 IntegerBitOperation(Token::kBIT_OR, left, right)); | 123 IntegerBitOperation(Token::kBIT_OR, left, right)); |
| 170 return AsInteger(result); | 124 return Integer::AsInteger(result); |
| 171 } | 125 } |
| 172 | 126 |
| 173 | 127 |
| 174 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { | 128 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { |
| 175 const Integer& right = Integer::CheckedHandle(arguments->At(0)); | 129 const Integer& right = Integer::CheckedHandle(arguments->At(0)); |
| 176 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); | 130 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); |
| 177 ASSERT(CheckInteger(right)); | 131 ASSERT(CheckInteger(right)); |
| 178 ASSERT(CheckInteger(left)); | 132 ASSERT(CheckInteger(left)); |
| 179 if (FLAG_trace_intrinsified_natives) { | 133 if (FLAG_trace_intrinsified_natives) { |
| 180 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", | 134 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", |
| 181 left.ToCString(), right.ToCString()); | 135 left.ToCString(), right.ToCString()); |
| 182 } | 136 } |
| 183 Integer& result = Integer::Handle( | 137 Integer& result = Integer::Handle( |
| 184 IntegerBitOperation(Token::kBIT_XOR, left, right)); | 138 IntegerBitOperation(Token::kBIT_XOR, left, right)); |
| 185 return AsInteger(result); | 139 return Integer::AsInteger(result); |
| 186 } | 140 } |
| 187 | 141 |
| 188 | 142 |
| 189 static RawBigint* BinaryOpWithTwoBigints(Token::Kind operation, | |
| 190 const Bigint& left, | |
| 191 const Bigint& right) { | |
| 192 switch (operation) { | |
| 193 case Token::kADD: | |
| 194 return BigintOperations::Add(left, right); | |
| 195 case Token::kSUB: | |
| 196 return BigintOperations::Subtract(left, right); | |
| 197 case Token::kMUL: | |
| 198 return BigintOperations::Multiply(left, right); | |
| 199 case Token::kTRUNCDIV: | |
| 200 return BigintOperations::Divide(left, right); | |
| 201 case Token::kMOD: | |
| 202 return BigintOperations::Modulo(left, right); | |
| 203 default: | |
| 204 UNIMPLEMENTED(); | |
| 205 return Bigint::null(); | |
| 206 } | |
| 207 } | |
| 208 | |
| 209 | |
| 210 static RawInteger* IntegerBinopHelper(Token::Kind operation, | |
| 211 const Integer& left_int, | |
| 212 const Integer& right_int) { | |
| 213 // In 32-bit mode, the result of any operation between two Smis will fit in a | |
| 214 // 32-bit signed result, except the product of two Smis, which will be 64-bit. | |
| 215 // In 64-bit mode, the result of any operation between two Smis will fit in a | |
| 216 // 64-bit signed result, except the product of two Smis (unless the Smis are | |
| 217 // 32-bit or less). | |
| 218 if (left_int.IsSmi() && right_int.IsSmi()) { | |
| 219 Smi& left_smi = Smi::Handle(); | |
| 220 Smi& right_smi = Smi::Handle(); | |
| 221 left_smi ^= left_int.raw(); | |
| 222 right_smi ^= right_int.raw(); | |
| 223 const intptr_t left_value = left_smi.Value(); | |
| 224 const intptr_t right_value = right_smi.Value(); | |
| 225 switch (operation) { | |
| 226 case Token::kADD: | |
| 227 return Integer::New(left_value + right_value); | |
| 228 case Token::kSUB: | |
| 229 return Integer::New(left_value - right_value); | |
| 230 case Token::kMUL: { | |
| 231 if (Smi::kBits < 32) { | |
| 232 // In 32-bit mode, the product of two Smis fits in a 64-bit result. | |
| 233 return Integer::New(static_cast<int64_t>(left_value) * | |
| 234 static_cast<int64_t>(right_value)); | |
| 235 } else { | |
| 236 // In 64-bit mode, the product of two 32-bit signed integers fits in a | |
| 237 // 64-bit result. | |
| 238 ASSERT(sizeof(intptr_t) == sizeof(int64_t)); | |
| 239 if (Utils::IsInt(32, left_value) && Utils::IsInt(32, right_value)) { | |
| 240 return Integer::New(left_value * right_value); | |
| 241 } | |
| 242 } | |
| 243 // Perform a Bigint multiplication below. | |
| 244 break; | |
| 245 } | |
| 246 case Token::kTRUNCDIV: | |
| 247 return Integer::New(left_value / right_value); | |
| 248 case Token::kMOD: { | |
| 249 const intptr_t remainder = left_value % right_value; | |
| 250 if (remainder < 0) { | |
| 251 if (right_value < 0) { | |
| 252 return Integer::New(remainder - right_value); | |
| 253 } else { | |
| 254 return Integer::New(remainder + right_value); | |
| 255 } | |
| 256 } | |
| 257 return Integer::New(remainder); | |
| 258 } | |
| 259 default: | |
| 260 UNIMPLEMENTED(); | |
| 261 } | |
| 262 } | |
| 263 // In 32-bit mode, the result of any operation between two 63-bit signed | |
| 264 // integers (or 32-bit for multiplication) will fit in a 64-bit signed result. | |
| 265 // In 64-bit mode, 63-bit signed integers are Smis, already processed above. | |
| 266 if ((Smi::kBits < 32) && !left_int.IsBigint() && !right_int.IsBigint()) { | |
| 267 const int64_t left_value = left_int.AsInt64Value(); | |
| 268 if (Utils::IsInt(63, left_value)) { | |
| 269 const int64_t right_value = right_int.AsInt64Value(); | |
| 270 if (Utils::IsInt(63, right_value)) { | |
| 271 switch (operation) { | |
| 272 case Token::kADD: | |
| 273 return Integer::New(left_value + right_value); | |
| 274 case Token::kSUB: | |
| 275 return Integer::New(left_value - right_value); | |
| 276 case Token::kMUL: { | |
| 277 if (Utils::IsInt(32, left_value) && Utils::IsInt(32, right_value)) { | |
| 278 return Integer::New(left_value * right_value); | |
| 279 } | |
| 280 // Perform a Bigint multiplication below. | |
| 281 break; | |
| 282 } | |
| 283 case Token::kTRUNCDIV: | |
| 284 return Integer::New(left_value / right_value); | |
| 285 case Token::kMOD: { | |
| 286 const int64_t remainder = left_value % right_value; | |
| 287 if (remainder < 0) { | |
| 288 if (right_value < 0) { | |
| 289 return Integer::New(remainder - right_value); | |
| 290 } else { | |
| 291 return Integer::New(remainder + right_value); | |
| 292 } | |
| 293 } | |
| 294 return Integer::New(remainder); | |
| 295 } | |
| 296 default: | |
| 297 UNIMPLEMENTED(); | |
| 298 } | |
| 299 } | |
| 300 } | |
| 301 } | |
| 302 const Bigint& left_big = Bigint::Handle(AsBigint(left_int)); | |
| 303 const Bigint& right_big = Bigint::Handle(AsBigint(right_int)); | |
| 304 const Bigint& result = | |
| 305 Bigint::Handle(BinaryOpWithTwoBigints(operation, left_big, right_big)); | |
| 306 return Integer::Handle(AsInteger(result)).raw(); | |
| 307 } | |
| 308 | |
| 309 | |
| 310 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { | 143 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { |
| 311 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 144 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); |
| 312 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 145 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); |
| 313 ASSERT(CheckInteger(right_int)); | 146 ASSERT(CheckInteger(right_int)); |
| 314 ASSERT(CheckInteger(left_int)); | 147 ASSERT(CheckInteger(left_int)); |
| 315 if (FLAG_trace_intrinsified_natives) { | 148 if (FLAG_trace_intrinsified_natives) { |
| 316 OS::Print("Integer_addFromInteger %s + %s\n", | 149 OS::Print("Integer_addFromInteger %s + %s\n", |
| 317 left_int.ToCString(), right_int.ToCString()); | 150 left_int.ToCString(), right_int.ToCString()); |
| 318 } | 151 } |
| 319 return IntegerBinopHelper(Token::kADD, left_int, right_int); | 152 return Integer::BinaryOp(Token::kADD, left_int, right_int); |
| 320 } | 153 } |
| 321 | 154 |
| 322 | 155 |
| 323 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { | 156 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { |
| 324 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 157 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); |
| 325 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 158 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); |
| 326 ASSERT(CheckInteger(right_int)); | 159 ASSERT(CheckInteger(right_int)); |
| 327 ASSERT(CheckInteger(left_int)); | 160 ASSERT(CheckInteger(left_int)); |
| 328 if (FLAG_trace_intrinsified_natives) { | 161 if (FLAG_trace_intrinsified_natives) { |
| 329 OS::Print("Integer_subFromInteger %s - %s\n", | 162 OS::Print("Integer_subFromInteger %s - %s\n", |
| 330 left_int.ToCString(), right_int.ToCString()); | 163 left_int.ToCString(), right_int.ToCString()); |
| 331 } | 164 } |
| 332 return IntegerBinopHelper(Token::kSUB, left_int, right_int); | 165 return Integer::BinaryOp(Token::kSUB, left_int, right_int); |
| 333 } | 166 } |
| 334 | 167 |
| 335 | 168 |
| 336 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { | 169 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { |
| 337 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 170 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); |
| 338 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 171 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); |
| 339 ASSERT(CheckInteger(right_int)); | 172 ASSERT(CheckInteger(right_int)); |
| 340 ASSERT(CheckInteger(left_int)); | 173 ASSERT(CheckInteger(left_int)); |
| 341 if (FLAG_trace_intrinsified_natives) { | 174 if (FLAG_trace_intrinsified_natives) { |
| 342 OS::Print("Integer_mulFromInteger %s * %s\n", | 175 OS::Print("Integer_mulFromInteger %s * %s\n", |
| 343 left_int.ToCString(), right_int.ToCString()); | 176 left_int.ToCString(), right_int.ToCString()); |
| 344 } | 177 } |
| 345 return IntegerBinopHelper(Token::kMUL, left_int, right_int); | 178 return Integer::BinaryOp(Token::kMUL, left_int, right_int); |
| 346 } | 179 } |
| 347 | 180 |
| 348 | 181 |
| 349 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { | 182 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { |
| 350 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 183 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); |
| 351 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 184 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); |
| 352 ASSERT(CheckInteger(right_int)); | 185 ASSERT(CheckInteger(right_int)); |
| 353 ASSERT(CheckInteger(left_int)); | 186 ASSERT(CheckInteger(left_int)); |
| 354 ASSERT(!right_int.IsZero()); | 187 ASSERT(!right_int.IsZero()); |
| 355 return IntegerBinopHelper(Token::kTRUNCDIV, left_int, right_int); | 188 return Integer::BinaryOp(Token::kTRUNCDIV, left_int, right_int); |
| 356 } | 189 } |
| 357 | 190 |
| 358 | 191 |
| 359 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { | 192 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { |
| 360 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); | 193 const Integer& right_int = Integer::CheckedHandle(arguments->At(0)); |
| 361 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); | 194 GET_NATIVE_ARGUMENT(Integer, left_int, arguments->At(1)); |
| 362 ASSERT(CheckInteger(right_int)); | 195 ASSERT(CheckInteger(right_int)); |
| 363 ASSERT(CheckInteger(right_int)); | 196 ASSERT(CheckInteger(right_int)); |
| 364 if (FLAG_trace_intrinsified_natives) { | 197 if (FLAG_trace_intrinsified_natives) { |
| 365 OS::Print("Integer_moduloFromInteger %s mod %s\n", | 198 OS::Print("Integer_moduloFromInteger %s mod %s\n", |
| 366 left_int.ToCString(), right_int.ToCString()); | 199 left_int.ToCString(), right_int.ToCString()); |
| 367 } | 200 } |
| 368 if (right_int.IsZero()) { | 201 if (right_int.IsZero()) { |
| 369 // Should have been caught before calling into runtime. | 202 // Should have been caught before calling into runtime. |
| 370 UNIMPLEMENTED(); | 203 UNIMPLEMENTED(); |
| 371 } | 204 } |
| 372 return IntegerBinopHelper(Token::kMOD, left_int, right_int); | 205 return Integer::BinaryOp(Token::kMOD, left_int, right_int); |
| 373 } | 206 } |
| 374 | 207 |
| 375 | 208 |
| 376 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { | 209 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { |
| 377 const Integer& right = Integer::CheckedHandle(arguments->At(0)); | 210 const Integer& right = Integer::CheckedHandle(arguments->At(0)); |
| 378 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); | 211 GET_NATIVE_ARGUMENT(Integer, left, arguments->At(1)); |
| 379 ASSERT(CheckInteger(right)); | 212 ASSERT(CheckInteger(right)); |
| 380 ASSERT(CheckInteger(left)); | 213 ASSERT(CheckInteger(left)); |
| 381 if (FLAG_trace_intrinsified_natives) { | 214 if (FLAG_trace_intrinsified_natives) { |
| 382 OS::Print("Integer_greaterThanFromInteger %s > %s\n", | 215 OS::Print("Integer_greaterThanFromInteger %s > %s\n", |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 switch (kind) { | 253 switch (kind) { |
| 421 case Token::kSHL: { | 254 case Token::kSHL: { |
| 422 if ((left_value == 0) || (right_value == 0)) { | 255 if ((left_value == 0) || (right_value == 0)) { |
| 423 return left.raw(); | 256 return left.raw(); |
| 424 } | 257 } |
| 425 { // Check for overflow. | 258 { // Check for overflow. |
| 426 int cnt = HighestBit(left_value); | 259 int cnt = HighestBit(left_value); |
| 427 if ((cnt + right_value) >= Smi::kBits) { | 260 if ((cnt + right_value) >= Smi::kBits) { |
| 428 if ((cnt + right_value) >= Mint::kBits) { | 261 if ((cnt + right_value) >= Mint::kBits) { |
| 429 return BigintOperations::ShiftLeft( | 262 return BigintOperations::ShiftLeft( |
| 430 Bigint::Handle(AsBigint(left)), right_value); | 263 Bigint::Handle(Bigint::AsBigint(left)), right_value); |
| 431 } else { | 264 } else { |
| 432 int64_t left_64 = left_value; | 265 int64_t left_64 = left_value; |
| 433 return Integer::New(left_64 << right_value); | 266 return Integer::New(left_64 << right_value); |
| 434 } | 267 } |
| 435 } | 268 } |
| 436 } | 269 } |
| 437 result = left_value << right_value; | 270 result = left_value << right_value; |
| 438 break; | 271 break; |
| 439 } | 272 } |
| 440 case Token::kSHR: { | 273 case Token::kSHR: { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 } | 330 } |
| 498 | 331 |
| 499 | 332 |
| 500 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { | 333 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { |
| 501 const Smi& amount = Smi::CheckedHandle(arguments->At(0)); | 334 const Smi& amount = Smi::CheckedHandle(arguments->At(0)); |
| 502 GET_NATIVE_ARGUMENT(Integer, value, arguments->At(1)); | 335 GET_NATIVE_ARGUMENT(Integer, value, arguments->At(1)); |
| 503 ASSERT(CheckInteger(amount)); | 336 ASSERT(CheckInteger(amount)); |
| 504 ASSERT(CheckInteger(value)); | 337 ASSERT(CheckInteger(value)); |
| 505 Integer& result = Integer::Handle( | 338 Integer& result = Integer::Handle( |
| 506 ShiftOperationHelper(Token::kSHR, value, amount)); | 339 ShiftOperationHelper(Token::kSHR, value, amount)); |
| 507 return AsInteger(result); | 340 return Integer::AsInteger(result); |
| 508 } | 341 } |
| 509 | 342 |
| 510 | 343 |
| 511 | 344 |
| 512 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { | 345 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { |
| 513 const Smi& amount = Smi::CheckedHandle(arguments->At(0)); | 346 const Smi& amount = Smi::CheckedHandle(arguments->At(0)); |
| 514 GET_NATIVE_ARGUMENT(Integer, value, arguments->At(1)); | 347 GET_NATIVE_ARGUMENT(Integer, value, arguments->At(1)); |
| 515 ASSERT(CheckInteger(amount)); | 348 ASSERT(CheckInteger(amount)); |
| 516 ASSERT(CheckInteger(value)); | 349 ASSERT(CheckInteger(value)); |
| 517 if (FLAG_trace_intrinsified_natives) { | 350 if (FLAG_trace_intrinsified_natives) { |
| 518 OS::Print("Smi_shlFromInt: %s << %s\n", | 351 OS::Print("Smi_shlFromInt: %s << %s\n", |
| 519 value.ToCString(), amount.ToCString()); | 352 value.ToCString(), amount.ToCString()); |
| 520 } | 353 } |
| 521 Integer& result = Integer::Handle( | 354 Integer& result = Integer::Handle( |
| 522 ShiftOperationHelper(Token::kSHL, value, amount)); | 355 ShiftOperationHelper(Token::kSHL, value, amount)); |
| 523 return AsInteger(result); | 356 return Integer::AsInteger(result); |
| 524 } | 357 } |
| 525 | 358 |
| 526 | 359 |
| 527 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { | 360 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { |
| 528 const Smi& operand = Smi::CheckedHandle(arguments->At(0)); | 361 const Smi& operand = Smi::CheckedHandle(arguments->At(0)); |
| 529 if (FLAG_trace_intrinsified_natives) { | 362 if (FLAG_trace_intrinsified_natives) { |
| 530 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); | 363 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); |
| 531 } | 364 } |
| 532 intptr_t result = ~operand.Value(); | 365 intptr_t result = ~operand.Value(); |
| 533 ASSERT(Smi::IsValid(result)); | 366 ASSERT(Smi::IsValid(result)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 546 return Integer::New(result); | 379 return Integer::New(result); |
| 547 } | 380 } |
| 548 | 381 |
| 549 // Bigint natives. | 382 // Bigint natives. |
| 550 | 383 |
| 551 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { | 384 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { |
| 552 const Bigint& value = Bigint::CheckedHandle(arguments->At(0)); | 385 const Bigint& value = Bigint::CheckedHandle(arguments->At(0)); |
| 553 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); | 386 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); |
| 554 ASSERT(CheckInteger(value)); | 387 ASSERT(CheckInteger(value)); |
| 555 ASSERT(CheckInteger(result)); | 388 ASSERT(CheckInteger(result)); |
| 556 return AsInteger(result); | 389 return Integer::AsInteger(result); |
| 557 } | 390 } |
| 558 | 391 |
| 559 } // namespace dart | 392 } // namespace dart |
| OLD | NEW |