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" |
(...skipping 17 matching lines...) Expand all Loading... |
28 !BigintOperations::FitsIntoInt64(bigint); | 28 !BigintOperations::FitsIntoInt64(bigint); |
29 } | 29 } |
30 if (i.IsMint()) { | 30 if (i.IsMint()) { |
31 const Mint& mint = Mint::Cast(i); | 31 const Mint& mint = Mint::Cast(i); |
32 return !Smi::IsValid64(mint.value()); | 32 return !Smi::IsValid64(mint.value()); |
33 } | 33 } |
34 return true; | 34 return true; |
35 } | 35 } |
36 | 36 |
37 | 37 |
| 38 static int BitLengthInt64(int64_t value) { |
| 39 value ^= value >> (8 * sizeof(value) - 1); // flip bits if negative. |
| 40 return value == 0 ? 0 : Utils::HighestBit(value) + 1; |
| 41 } |
| 42 |
| 43 |
38 DEFINE_NATIVE_ENTRY(Integer_bitAndFromInteger, 2) { | 44 DEFINE_NATIVE_ENTRY(Integer_bitAndFromInteger, 2) { |
39 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); | 45 const Integer& right = Integer::CheckedHandle(arguments->NativeArgAt(0)); |
40 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); | 46 GET_NON_NULL_NATIVE_ARGUMENT(Integer, left, arguments->NativeArgAt(1)); |
41 ASSERT(CheckInteger(right)); | 47 ASSERT(CheckInteger(right)); |
42 ASSERT(CheckInteger(left)); | 48 ASSERT(CheckInteger(left)); |
43 if (FLAG_trace_intrinsified_natives) { | 49 if (FLAG_trace_intrinsified_natives) { |
44 OS::Print("Integer_bitAndFromInteger %s & %s\n", | 50 OS::Print("Integer_bitAndFromInteger %s & %s\n", |
45 right.ToCString(), left.ToCString()); | 51 right.ToCString(), left.ToCString()); |
46 } | 52 } |
47 const Integer& result = | 53 const Integer& result = |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0)); | 326 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
321 if (FLAG_trace_intrinsified_natives) { | 327 if (FLAG_trace_intrinsified_natives) { |
322 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); | 328 OS::Print("Smi_bitNegate: %s\n", operand.ToCString()); |
323 } | 329 } |
324 intptr_t result = ~operand.Value(); | 330 intptr_t result = ~operand.Value(); |
325 ASSERT(Smi::IsValid(result)); | 331 ASSERT(Smi::IsValid(result)); |
326 return Smi::New(result); | 332 return Smi::New(result); |
327 } | 333 } |
328 | 334 |
329 | 335 |
| 336 DEFINE_NATIVE_ENTRY(Smi_bitLength, 1) { |
| 337 const Smi& operand = Smi::CheckedHandle(arguments->NativeArgAt(0)); |
| 338 if (FLAG_trace_intrinsified_natives) { |
| 339 OS::Print("Smi_bitLength: %s\n", operand.ToCString()); |
| 340 } |
| 341 int64_t value = operand.AsInt64Value(); |
| 342 intptr_t result = BitLengthInt64(value); |
| 343 ASSERT(Smi::IsValid(result)); |
| 344 return Smi::New(result); |
| 345 } |
| 346 |
| 347 |
330 // Mint natives. | 348 // Mint natives. |
331 | 349 |
332 DEFINE_NATIVE_ENTRY(Mint_bitNegate, 1) { | 350 DEFINE_NATIVE_ENTRY(Mint_bitNegate, 1) { |
333 const Mint& operand = Mint::CheckedHandle(arguments->NativeArgAt(0)); | 351 const Mint& operand = Mint::CheckedHandle(arguments->NativeArgAt(0)); |
334 ASSERT(CheckInteger(operand)); | 352 ASSERT(CheckInteger(operand)); |
335 if (FLAG_trace_intrinsified_natives) { | 353 if (FLAG_trace_intrinsified_natives) { |
336 OS::Print("Mint_bitNegate: %s\n", operand.ToCString()); | 354 OS::Print("Mint_bitNegate: %s\n", operand.ToCString()); |
337 } | 355 } |
338 int64_t result = ~operand.value(); | 356 int64_t result = ~operand.value(); |
339 return Integer::New(result); | 357 return Integer::New(result); |
340 } | 358 } |
341 | 359 |
342 | 360 |
| 361 DEFINE_NATIVE_ENTRY(Mint_bitLength, 1) { |
| 362 const Mint& operand = Mint::CheckedHandle(arguments->NativeArgAt(0)); |
| 363 ASSERT(CheckInteger(operand)); |
| 364 if (FLAG_trace_intrinsified_natives) { |
| 365 OS::Print("Mint_bitLength: %s\n", operand.ToCString()); |
| 366 } |
| 367 int64_t value = operand.AsInt64Value(); |
| 368 intptr_t result = BitLengthInt64(value); |
| 369 ASSERT(Smi::IsValid(result)); |
| 370 return Smi::New(result); |
| 371 } |
| 372 |
| 373 |
343 DEFINE_NATIVE_ENTRY(Mint_shlFromInt, 2) { | 374 DEFINE_NATIVE_ENTRY(Mint_shlFromInt, 2) { |
344 // Use the preallocated out of memory exception to avoid calling | 375 // Use the preallocated out of memory exception to avoid calling |
345 // into dart code or allocating any code. | 376 // into dart code or allocating any code. |
346 const Instance& exception = | 377 const Instance& exception = |
347 Instance::Handle(isolate->object_store()->out_of_memory()); | 378 Instance::Handle(isolate->object_store()->out_of_memory()); |
348 Exceptions::Throw(exception); | 379 Exceptions::Throw(exception); |
349 UNREACHABLE(); | 380 UNREACHABLE(); |
350 return 0; | 381 return 0; |
351 } | 382 } |
352 | 383 |
353 | 384 |
354 // Bigint natives. | 385 // Bigint natives. |
355 | 386 |
356 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { | 387 DEFINE_NATIVE_ENTRY(Bigint_bitNegate, 1) { |
357 const Bigint& value = Bigint::CheckedHandle(arguments->NativeArgAt(0)); | 388 const Bigint& value = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
358 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); | 389 const Bigint& result = Bigint::Handle(BigintOperations::BitNot(value)); |
359 ASSERT(CheckInteger(value)); | 390 ASSERT(CheckInteger(value)); |
360 ASSERT(CheckInteger(result)); | 391 ASSERT(CheckInteger(result)); |
361 return result.AsValidInteger(); | 392 return result.AsValidInteger(); |
362 } | 393 } |
363 | 394 |
364 | 395 |
| 396 DEFINE_NATIVE_ENTRY(Bigint_bitLength, 1) { |
| 397 const Bigint& value = Bigint::CheckedHandle(arguments->NativeArgAt(0)); |
| 398 return Integer::New(BigintOperations::BitLength(value)); |
| 399 } |
| 400 |
| 401 |
365 DEFINE_NATIVE_ENTRY(Bigint_shlFromInt, 2) { | 402 DEFINE_NATIVE_ENTRY(Bigint_shlFromInt, 2) { |
366 // Use the preallocated out of memory exception to avoid calling | 403 // Use the preallocated out of memory exception to avoid calling |
367 // into dart code or allocating any code. | 404 // into dart code or allocating any code. |
368 const Instance& exception = | 405 const Instance& exception = |
369 Instance::Handle(isolate->object_store()->out_of_memory()); | 406 Instance::Handle(isolate->object_store()->out_of_memory()); |
370 Exceptions::Throw(exception); | 407 Exceptions::Throw(exception); |
371 UNREACHABLE(); | 408 UNREACHABLE(); |
372 return 0; | 409 return 0; |
373 } | 410 } |
374 | 411 |
375 } // namespace dart | 412 } // namespace dart |
OLD | NEW |