Chromium Code Reviews| 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 "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "vm/bigint_operations.h" | |
| 9 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 10 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
| 11 #include "vm/exceptions.h" | 10 #include "vm/exceptions.h" |
| 12 #include "vm/isolate.h" | 11 #include "vm/isolate.h" |
| 13 #include "vm/native_entry.h" | 12 #include "vm/native_entry.h" |
| 14 #include "vm/object.h" | 13 #include "vm/object.h" |
| 15 #include "vm/object_store.h" | 14 #include "vm/object_store.h" |
| 16 #include "vm/symbols.h" | 15 #include "vm/symbols.h" |
| 17 | 16 |
| 18 namespace dart { | 17 namespace dart { |
| 19 | 18 |
| 20 DEFINE_FLAG(bool, trace_intrinsified_natives, false, | 19 DEFINE_FLAG(bool, trace_intrinsified_natives, false, |
| 21 "Report if any of the intrinsified natives are called"); | 20 "Report if any of the intrinsified natives are called"); |
| 22 | 21 |
| 23 // Smi natives. | 22 // Smi natives. |
| 24 | 23 |
| 25 // 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 |
| 26 // when it could have been a Smi. | 25 // when it could have been a Smi. |
| 27 static bool CheckInteger(const Integer& i) { | 26 static bool CheckInteger(const Integer& i) { |
| 28 if (i.IsBigint()) { | 27 if (i.IsBigint()) { |
| 29 const Bigint& bigint = Bigint::Cast(i); | 28 const Bigint& bigint = Bigint::Cast(i); |
| 30 return !BigintOperations::FitsIntoSmi(bigint) && | 29 return !bigint.FitsIntoSmi() && !bigint.FitsIntoInt64(); |
| 31 !BigintOperations::FitsIntoInt64(bigint); | |
| 32 } | 30 } |
| 33 if (i.IsMint()) { | 31 if (i.IsMint()) { |
| 34 const Mint& mint = Mint::Cast(i); | 32 const Mint& mint = Mint::Cast(i); |
| 35 return !Smi::IsValid(mint.value()); | 33 return !Smi::IsValid(mint.value()); |
| 36 } | 34 } |
| 37 return true; | 35 return true; |
| 38 } | 36 } |
| 39 | 37 |
| 40 | 38 |
| 41 static int BitLengthInt64(int64_t value) { | 39 static int BitLengthInt64(int64_t value) { |
| 42 value ^= value >> (8 * sizeof(value) - 1); // flip bits if negative. | 40 value ^= value >> (8 * sizeof(value) - 1); // flip bits if negative. |
| 41 // TODO(regis): Utils::HighestBit handles negative values. Why the above? | |
| 43 return value == 0 ? 0 : Utils::HighestBit(value) + 1; | 42 return value == 0 ? 0 : Utils::HighestBit(value) + 1; |
| 44 } | 43 } |
| 45 | 44 |
| 46 | 45 |
| 47 DEFINE_NATIVE_ENTRY(Integer_bitAndFromInteger, 2) { | 46 DEFINE_NATIVE_ENTRY(Integer_bitAndFromInteger, 2) { |
| 48 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 47 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 49 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 48 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
| 50 ASSERT(CheckInteger(right)); | 49 ASSERT(CheckInteger(right)); |
| 51 ASSERT(CheckInteger(left)); | 50 ASSERT(CheckInteger(left)); |
| 52 if (FLAG_trace_intrinsified_natives) { | 51 if (FLAG_trace_intrinsified_natives) { |
| 53 OS::Print("Integer_bitAndFromInteger %s & %s\n", | 52 OS::Print("Integer_bitAndFromInteger %s & %s\n", |
| 54 right.ToCString(), left.ToCString()); | 53 right.ToCString(), left.ToCString()); |
| 55 } | 54 } |
| 56 const Integer& result = | 55 const Integer& result = |
| 57 Integer::Handle(left.BitOp(Token::kBIT_AND, right)); | 56 Integer::Handle(left.BitOp(Token::kBIT_AND, right)); |
| 57 if (result.IsNull()) { | |
| 58 return result.raw(); // A bigint operation is required. | |
| 59 } | |
| 58 return result.AsValidInteger(); | 60 return result.AsValidInteger(); |
|
srdjan
2014/09/08 19:19:49
maybe: result.IsNull() ? result.raw() : result.AsV
regis
2014/09/09 19:18:14
Done.
| |
| 59 } | 61 } |
| 60 | 62 |
| 61 | 63 |
| 62 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { | 64 DEFINE_NATIVE_ENTRY(Integer_bitOrFromInteger, 2) { |
| 63 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 65 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 64 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 66 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
| 65 ASSERT(CheckInteger(right)); | 67 ASSERT(CheckInteger(right)); |
| 66 ASSERT(CheckInteger(left)); | 68 ASSERT(CheckInteger(left)); |
| 67 if (FLAG_trace_intrinsified_natives) { | 69 if (FLAG_trace_intrinsified_natives) { |
| 68 OS::Print("Integer_bitOrFromInteger %s | %s\n", | 70 OS::Print("Integer_bitOrFromInteger %s | %s\n", |
| 69 left.ToCString(), right.ToCString()); | 71 left.ToCString(), right.ToCString()); |
| 70 } | 72 } |
| 71 const Integer& result = | 73 const Integer& result = |
| 72 Integer::Handle(left.BitOp(Token::kBIT_OR, right)); | 74 Integer::Handle(left.BitOp(Token::kBIT_OR, right)); |
| 75 if (result.IsNull()) { | |
| 76 return result.raw(); // A bigint operation is required. | |
| 77 } | |
| 73 return result.AsValidInteger(); | 78 return result.AsValidInteger(); |
| 74 } | 79 } |
| 75 | 80 |
| 76 | 81 |
| 77 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { | 82 DEFINE_NATIVE_ENTRY(Integer_bitXorFromInteger, 2) { |
| 78 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 83 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 79 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 84 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
| 80 ASSERT(CheckInteger(right)); | 85 ASSERT(CheckInteger(right)); |
| 81 ASSERT(CheckInteger(left)); | 86 ASSERT(CheckInteger(left)); |
| 82 if (FLAG_trace_intrinsified_natives) { | 87 if (FLAG_trace_intrinsified_natives) { |
| 83 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", | 88 OS::Print("Integer_bitXorFromInteger %s ^ %s\n", |
| 84 left.ToCString(), right.ToCString()); | 89 left.ToCString(), right.ToCString()); |
| 85 } | 90 } |
| 86 const Integer& result = | 91 const Integer& result = |
| 87 Integer::Handle(left.BitOp(Token::kBIT_XOR, right)); | 92 Integer::Handle(left.BitOp(Token::kBIT_XOR, right)); |
| 93 if (result.IsNull()) { | |
| 94 return result.raw(); // A bigint operation is required. | |
| 95 } | |
| 88 return result.AsValidInteger(); | 96 return result.AsValidInteger(); |
| 89 } | 97 } |
| 90 | 98 |
| 91 | 99 |
| 92 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { | 100 DEFINE_NATIVE_ENTRY(Integer_addFromInteger, 2) { |
| 93 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 101 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 94 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 102 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 95 ASSERT(CheckInteger(right_int)); | 103 ASSERT(CheckInteger(right_int)); |
| 96 ASSERT(CheckInteger(left_int)); | 104 ASSERT(CheckInteger(left_int)); |
| 97 if (FLAG_trace_intrinsified_natives) { | 105 if (FLAG_trace_intrinsified_natives) { |
| 98 OS::Print("Integer_addFromInteger %s + %s\n", | 106 OS::Print("Integer_addFromInteger %s + %s\n", |
| 99 left_int.ToCString(), right_int.ToCString()); | 107 left_int.ToCString(), right_int.ToCString()); |
| 100 } | 108 } |
| 101 const Integer& result = | 109 const Integer& result = |
| 102 Integer::Handle(left_int.ArithmeticOp(Token::kADD, right_int)); | 110 Integer::Handle(left_int.ArithmeticOp(Token::kADD, right_int)); |
| 111 if (result.IsNull()) { | |
| 112 return result.raw(); // A bigint operation is required. | |
| 113 } | |
| 103 return result.AsValidInteger(); | 114 return result.AsValidInteger(); |
| 104 } | 115 } |
| 105 | 116 |
| 106 | 117 |
| 107 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { | 118 DEFINE_NATIVE_ENTRY(Integer_subFromInteger, 2) { |
| 108 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 119 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 109 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 120 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 110 ASSERT(CheckInteger(right_int)); | 121 ASSERT(CheckInteger(right_int)); |
| 111 ASSERT(CheckInteger(left_int)); | 122 ASSERT(CheckInteger(left_int)); |
| 112 if (FLAG_trace_intrinsified_natives) { | 123 if (FLAG_trace_intrinsified_natives) { |
| 113 OS::Print("Integer_subFromInteger %s - %s\n", | 124 OS::Print("Integer_subFromInteger %s - %s\n", |
| 114 left_int.ToCString(), right_int.ToCString()); | 125 left_int.ToCString(), right_int.ToCString()); |
| 115 } | 126 } |
| 116 const Integer& result = | 127 const Integer& result = |
| 117 Integer::Handle(left_int.ArithmeticOp(Token::kSUB, right_int)); | 128 Integer::Handle(left_int.ArithmeticOp(Token::kSUB, right_int)); |
| 129 if (result.IsNull()) { | |
| 130 return result.raw(); // A bigint operation is required. | |
| 131 } | |
| 118 return result.AsValidInteger(); | 132 return result.AsValidInteger(); |
| 119 } | 133 } |
| 120 | 134 |
| 121 | 135 |
| 122 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { | 136 DEFINE_NATIVE_ENTRY(Integer_mulFromInteger, 2) { |
| 123 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 137 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 124 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 138 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 125 ASSERT(CheckInteger(right_int)); | 139 ASSERT(CheckInteger(right_int)); |
| 126 ASSERT(CheckInteger(left_int)); | 140 ASSERT(CheckInteger(left_int)); |
| 127 if (FLAG_trace_intrinsified_natives) { | 141 if (FLAG_trace_intrinsified_natives) { |
| 128 OS::Print("Integer_mulFromInteger %s * %s\n", | 142 OS::Print("Integer_mulFromInteger %s * %s\n", |
| 129 left_int.ToCString(), right_int.ToCString()); | 143 left_int.ToCString(), right_int.ToCString()); |
| 130 } | 144 } |
| 131 const Integer& result = | 145 const Integer& result = |
| 132 Integer::Handle(left_int.ArithmeticOp(Token::kMUL, right_int)); | 146 Integer::Handle(left_int.ArithmeticOp(Token::kMUL, right_int)); |
| 147 if (result.IsNull()) { | |
| 148 return result.raw(); // A bigint operation is required. | |
| 149 } | |
| 133 return result.AsValidInteger(); | 150 return result.AsValidInteger(); |
| 134 } | 151 } |
| 135 | 152 |
| 136 | 153 |
| 137 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { | 154 DEFINE_NATIVE_ENTRY(Integer_truncDivFromInteger, 2) { |
| 138 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 155 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 139 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 156 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 140 ASSERT(CheckInteger(right_int)); | 157 ASSERT(CheckInteger(right_int)); |
| 141 ASSERT(CheckInteger(left_int)); | 158 ASSERT(CheckInteger(left_int)); |
| 142 ASSERT(!right_int.IsZero()); | 159 ASSERT(!right_int.IsZero()); |
| 143 const Integer& result = | 160 const Integer& result = |
| 144 Integer::Handle(left_int.ArithmeticOp(Token::kTRUNCDIV, right_int)); | 161 Integer::Handle(left_int.ArithmeticOp(Token::kTRUNCDIV, right_int)); |
| 162 if (result.IsNull()) { | |
| 163 return result.raw(); // A bigint operation is required. | |
| 164 } | |
| 145 return result.AsValidInteger(); | 165 return result.AsValidInteger(); |
| 146 } | 166 } |
| 147 | 167 |
| 148 | 168 |
| 149 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { | 169 DEFINE_NATIVE_ENTRY(Integer_moduloFromInteger, 2) { |
| 150 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 170 const Integer& right_int = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 151 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); | 171 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left_int, arguments->NativeArgAt(1)); |
| 152 ASSERT(CheckInteger(right_int)); | 172 ASSERT(CheckInteger(right_int)); |
| 153 ASSERT(CheckInteger(right_int)); | 173 ASSERT(CheckInteger(right_int)); |
| 154 if (FLAG_trace_intrinsified_natives) { | 174 if (FLAG_trace_intrinsified_natives) { |
| 155 OS::Print("Integer_moduloFromInteger %s mod %s\n", | 175 OS::Print("Integer_moduloFromInteger %s mod %s\n", |
| 156 left_int.ToCString(), right_int.ToCString()); | 176 left_int.ToCString(), right_int.ToCString()); |
| 157 } | 177 } |
| 158 if (right_int.IsZero()) { | 178 if (right_int.IsZero()) { |
| 159 // Should have been caught before calling into runtime. | 179 // Should have been caught before calling into runtime. |
| 160 UNIMPLEMENTED(); | 180 UNIMPLEMENTED(); |
| 161 } | 181 } |
| 162 const Integer& result = | 182 const Integer& result = |
| 163 Integer::Handle(left_int.ArithmeticOp(Token::kMOD, right_int)); | 183 Integer::Handle(left_int.ArithmeticOp(Token::kMOD, right_int)); |
| 184 if (result.IsNull()) { | |
| 185 return result.raw(); // A bigint operation is required. | |
| 186 } | |
| 164 return result.AsValidInteger(); | 187 return result.AsValidInteger(); |
| 165 } | 188 } |
| 166 | 189 |
| 167 | 190 |
| 168 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { | 191 DEFINE_NATIVE_ENTRY(Integer_greaterThanFromInteger, 2) { |
| 169 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 192 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 170 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 193 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
| 171 ASSERT(CheckInteger(right)); | 194 ASSERT(CheckInteger(right)); |
| 172 ASSERT(CheckInteger(left)); | 195 ASSERT(CheckInteger(left)); |
| 173 if (FLAG_trace_intrinsified_natives) { | 196 if (FLAG_trace_intrinsified_natives) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 271 const Integer& value, | 294 const Integer& value, |
| 272 const Smi& amount, | 295 const Smi& amount, |
| 273 const bool silent = false) { | 296 const bool silent = false) { |
| 274 if (amount.Value() < 0) { | 297 if (amount.Value() < 0) { |
| 275 Exceptions::ThrowArgumentError(amount); | 298 Exceptions::ThrowArgumentError(amount); |
| 276 } | 299 } |
| 277 if (value.IsSmi()) { | 300 if (value.IsSmi()) { |
| 278 const Smi& smi_value = Smi::Cast(value); | 301 const Smi& smi_value = Smi::Cast(value); |
| 279 return smi_value.ShiftOp(kind, amount, silent); | 302 return smi_value.ShiftOp(kind, amount, silent); |
| 280 } | 303 } |
| 281 Bigint& big_value = Bigint::Handle(); | |
| 282 if (value.IsMint()) { | 304 if (value.IsMint()) { |
| 283 const int64_t mint_value = value.AsInt64Value(); | 305 const int64_t mint_value = value.AsInt64Value(); |
| 284 const int count = Utils::HighestBit(mint_value); | 306 const int count = Utils::HighestBit(mint_value); |
| 285 intptr_t shift_count = amount.Value(); | 307 intptr_t shift_count = amount.Value(); |
| 286 if (kind == Token::kSHR) { | 308 if (kind == Token::kSHR) { |
| 287 shift_count = -shift_count; | 309 shift_count = -shift_count; |
| 288 } | 310 } |
| 289 if ((count + shift_count) < Mint::kBits) { | 311 if ((count + shift_count) < Mint::kBits) { |
| 290 switch (kind) { | 312 switch (kind) { |
| 291 case Token::kSHL: | 313 case Token::kSHL: |
| 292 return Integer::New(mint_value << shift_count, Heap::kNew, silent); | 314 return Integer::New(mint_value << shift_count, Heap::kNew, silent); |
| 293 case Token::kSHR: | 315 case Token::kSHR: |
| 294 return Integer::New(mint_value >> -shift_count, Heap::kNew, silent); | 316 return Integer::New(mint_value >> -shift_count, Heap::kNew, silent); |
| 295 default: | 317 default: |
| 296 UNIMPLEMENTED(); | 318 UNIMPLEMENTED(); |
| 297 } | 319 } |
| 298 } else { | 320 } else { |
| 299 // Overflow in shift, use Bigints | 321 // Overflow in shift, use Bigints |
| 300 big_value = BigintOperations::NewFromInt64(mint_value); | 322 return Integer::null(); |
| 301 } | 323 } |
| 302 } else { | 324 } else { |
| 303 ASSERT(value.IsBigint()); | 325 ASSERT(value.IsBigint()); |
| 304 big_value = Bigint::Cast(value).raw(); | |
| 305 } | |
| 306 switch (kind) { | |
| 307 case Token::kSHL: | |
| 308 return BigintOperations::ShiftLeft(big_value, amount.Value()); | |
| 309 case Token::kSHR: | |
| 310 return BigintOperations::ShiftRight(big_value, amount.Value()); | |
| 311 default: | |
| 312 UNIMPLEMENTED(); | |
| 313 } | 326 } |
| 314 return Integer::null(); | 327 return Integer::null(); |
| 315 } | 328 } |
| 316 | 329 |
| 317 | 330 |
| 318 DEFINE_NATIVE_ENTRY(Integer_leftShiftWithMask32, 3) { | 331 DEFINE_NATIVE_ENTRY(Integer_leftShiftWithMask32, 3) { |
| 319 const Integer& value = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 332 const Integer& value = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
| 320 GET_NON_NULL_NATIVE_ARGUMENT(Integer, shift_count, arguments->NativeArgAt(1)); | 333 GET_NON_NULL_NATIVE_ARGUMENT(Integer, shift_count, arguments->NativeArgAt(1)); |
| 321 GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(2)); | 334 GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(2)); |
| 322 ASSERT(CheckInteger(value)); | 335 ASSERT(CheckInteger(value)); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 337 } | 350 } |
| 338 | 351 |
| 339 | 352 |
| 340 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { | 353 DEFINE_NATIVE_ENTRY(Smi_shrFromInt, 2) { |
| 341 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); | 354 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
| 342 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); | 355 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); |
| 343 ASSERT(CheckInteger(amount)); | 356 ASSERT(CheckInteger(amount)); |
| 344 ASSERT(CheckInteger(value)); | 357 ASSERT(CheckInteger(value)); |
| 345 const Integer& result = Integer::Handle( | 358 const Integer& result = Integer::Handle( |
| 346 ShiftOperationHelper(Token::kSHR, value, amount)); | 359 ShiftOperationHelper(Token::kSHR, value, amount)); |
| 360 if (result.IsNull()) { | |
| 361 return result.raw(); // A bigint operation is required. | |
| 362 } | |
| 347 return result.AsValidInteger(); | 363 return result.AsValidInteger(); |
| 348 } | 364 } |
| 349 | 365 |
| 350 | 366 |
| 351 | 367 |
| 352 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { | 368 DEFINE_NATIVE_ENTRY(Smi_shlFromInt, 2) { |
| 353 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); | 369 const Smi& amount = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
| 354 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); | 370 GET_NON_NULL_NATIVE_ARGUMENT(Integer, value, arguments->NativeArgAt(1)); |
| 355 ASSERT(CheckInteger(amount)); | 371 ASSERT(CheckInteger(amount)); |
| 356 ASSERT(CheckInteger(value)); | 372 ASSERT(CheckInteger(value)); |
| 357 if (FLAG_trace_intrinsified_natives) { | 373 if (FLAG_trace_intrinsified_natives) { |
| 358 OS::Print("Smi_shlFromInt: %s << %s\n", | 374 OS::Print("Smi_shlFromInt: %s << %s\n", |
| 359 value.ToCString(), amount.ToCString()); | 375 value.ToCString(), amount.ToCString()); |
| 360 } | 376 } |
| 361 const Integer& result = Integer::Handle( | 377 const Integer& result = Integer::Handle( |
| 362 ShiftOperationHelper(Token::kSHL, value, amount)); | 378 ShiftOperationHelper(Token::kSHL, value, amount)); |
| 379 if (result.IsNull()) { | |
| 380 return result.raw(); // A bigint operation is required. | |
| 381 } | |
| 363 return result.AsValidInteger(); | 382 return result.AsValidInteger(); |
| 364 } | 383 } |
| 365 | 384 |
| 366 | 385 |
| 367 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { | 386 DEFINE_NATIVE_ENTRY(Smi_bitNegate, 1) { |
| 368 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0)); | 387 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
| 369 if (FLAG_trace_intrinsified_natives) { | 388 if (FLAG_trace_intrinsified_natives) { |
| 370 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); | 389 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); |
| 371 } | 390 } |
| 372 intptr_t result = ~operand.Value(); | 391 intptr_t result = ~operand.Value(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 416 DEFINE_NATIVE_ENTRY(Mint_shlFromInt, 2) { | 435 DEFINE_NATIVE_ENTRY(Mint_shlFromInt, 2) { |
| 417 // Use the preallocated out of memory exception to avoid calling | 436 // Use the preallocated out of memory exception to avoid calling |
| 418 // into dart code or allocating any code. | 437 // into dart code or allocating any code. |
| 419 const Instance& exception = | 438 const Instance& exception = |
| 420 Instance::Handle(isolate->object_store()->out_of_memory()); | 439 Instance::Handle(isolate->object_store()->out_of_memory()); |
| 421 Exceptions::Throw(isolate, exception); | 440 Exceptions::Throw(isolate, exception); |
| 422 UNREACHABLE(); | 441 UNREACHABLE(); |
| 423 return 0; | 442 return 0; |
| 424 } | 443 } |
| 425 | 444 |
| 426 | |
| 427 // Bigint natives. | 445 // Bigint natives. |
| 428 | 446 |
| 429 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { | 447 DEFINE_NATIVE_ENTRY(Bigint_getNeg, 1) { |
| 430 const Bigint& value = Bigint::CheckedHandle(arguments->NativeArgAt(0)); | 448 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| 431 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); | 449 return bigint.neg(); |
| 432 ASSERT(CheckInteger(value)); | |
| 433 ASSERT(CheckInteger(result)); | |
| 434 return result.AsValidInteger(); | |
| 435 } | 450 } |
| 436 | 451 |
| 437 | 452 |
| 438 DEFINE_NATIVE_ENTRY(Bigint_bitLength, 1) { | 453 DEFINE_NATIVE_ENTRY(Bigint_setNeg, 2) { |
| 439 const Bigint& value = Bigint::CheckedHandle(arguments->NativeArgAt(0)); | 454 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| 440 return Integer::New(BigintOperations::BitLength(value)); | 455 const Bool& neg = Bool::CheckedHandle(arguments->NativeArgAt(1)); |
| 456 bigint.set_neg(neg); | |
| 457 return Object::null(); | |
| 441 } | 458 } |
| 442 | 459 |
| 443 | 460 |
| 444 DEFINE_NATIVE_ENTRY(Bigint_shlFromInt, 2) { | 461 DEFINE_NATIVE_ENTRY(Bigint_getUsed, 1) { |
| 445 // Use the preallocated out of memory exception to avoid calling | 462 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| 446 // into dart code or allocating any code. | 463 return bigint.used(); |
| 447 const Instance& exception = | 464 } |
| 448 Instance::Handle(isolate->object_store()->out_of_memory()); | 465 |
| 449 Exceptions::Throw(isolate, exception); | 466 |
| 450 UNREACHABLE(); | 467 DEFINE_NATIVE_ENTRY(Bigint_setUsed, 2) { |
| 451 return 0; | 468 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| 469 const Smi& used = Smi::CheckedHandle(arguments->NativeArgAt(1)); | |
| 470 bigint.set_used(used); | |
| 471 return Object::null(); | |
| 472 } | |
| 473 | |
| 474 | |
| 475 DEFINE_NATIVE_ENTRY(Bigint_getDigits, 1) { | |
| 476 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); | |
| 477 return bigint.digits(); | |
| 478 } | |
| 479 | |
| 480 | |
| 481 DEFINE_NATIVE_ENTRY(Bigint_setDigits, 2) { | |
| 482 const Bigint& bigint = Bigint::CheckedHandle(arguments->NativeArgAt(0)); | |
| 483 const TypedData& digits = TypedData::CheckedHandle(arguments->NativeArgAt(1)); | |
| 484 bigint.set_digits(digits); | |
| 485 return Object::null(); | |
| 486 } | |
| 487 | |
| 488 | |
| 489 DEFINE_NATIVE_ENTRY(Bigint_allocate, 1) { | |
|
srdjan
2014/09/08 19:19:49
Why one argument? type?
regis
2014/09/09 19:18:14
This is the null type arguments, since class Bigin
| |
| 490 return Bigint::New(); | |
| 452 } | 491 } |
| 453 | 492 |
| 454 } // namespace dart | 493 } // namespace dart |
| OLD | NEW |