| 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/exceptions.h" | 8 #include "vm/exceptions.h" |
| 9 #include "vm/native_entry.h" | 9 #include "vm/native_entry.h" |
| 10 #include "vm/object.h" | 10 #include "vm/object.h" |
| 11 | 11 |
| 12 namespace dart { | 12 namespace dart { |
| 13 | 13 |
| 14 // ByteArray | 14 // ByteArray |
| 15 | 15 |
| 16 // Checks to see if (index * num_bytes) is in the range | 16 // Checks to see if (index * num_bytes) is in the range |
| 17 // [0..array.ByteLength()). without the risk of integer overflow. If | 17 // [0..array.ByteLength()). without the risk of integer overflow. If |
| 18 // the index is out of range, then a RangeError is thrown. | 18 // the index is out of range, then a RangeError is thrown. |
| 19 static void RangeCheck(const ByteArray& array, | 19 static void RangeCheck(const ByteArray& array, |
| 20 intptr_t index, | 20 intptr_t index, |
| 21 intptr_t num_bytes) { | 21 intptr_t num_bytes) { |
| 22 if (!Utils::RangeCheck(index, num_bytes, array.ByteLength())) { | 22 if (!Utils::RangeCheck(index, num_bytes, array.ByteLength())) { |
| 23 const String& error = String::Handle(String::NewFormatted( | 23 const String& error = String::Handle(String::NewFormatted( |
| 24 "index (%"Pd") must be in the range [0..%"Pd")", | 24 "index (%"Pd") must be in the range [0..%"Pd")", |
| 25 index, (array.ByteLength() / num_bytes))); | 25 (index / num_bytes), (array.ByteLength() / num_bytes))); |
| 26 const Array& args = Array::Handle(Array::New(1)); | 26 const Array& args = Array::Handle(Array::New(1)); |
| 27 args.SetAt(0, error); | 27 args.SetAt(0, error); |
| 28 Exceptions::ThrowByType(Exceptions::kRange, args); | 28 Exceptions::ThrowByType(Exceptions::kRange, args); |
| 29 } | 29 } |
| 30 } | 30 } |
| 31 | 31 |
| 32 | 32 |
| 33 // Checks to see if a length is in the range [0..max]. If the length | 33 // Checks to see if a length is in the range [0..max]. If the length |
| 34 // is out of range, then an ArgumentError is thrown. | 34 // is out of range, then an ArgumentError is thrown. |
| 35 static void LengthCheck(intptr_t len, intptr_t max) { | 35 static void LengthCheck(intptr_t len, intptr_t max) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 | 79 |
| 80 | 80 |
| 81 #define UNALIGNED_SETTER(ArrayT, ObjectT, Getter, ValueT) \ | 81 #define UNALIGNED_SETTER(ArrayT, ObjectT, Getter, ValueT) \ |
| 82 SETTER_ARGUMENTS(ArrayT, ObjectT, ValueT); \ | 82 SETTER_ARGUMENTS(ArrayT, ObjectT, ValueT); \ |
| 83 RangeCheck(array, index.Value(), sizeof(ValueT)); \ | 83 RangeCheck(array, index.Value(), sizeof(ValueT)); \ |
| 84 ValueT src = value_object.Getter(); \ | 84 ValueT src = value_object.Getter(); \ |
| 85 ByteArray::Copy(array, index.Value(), &src, sizeof(ValueT)); \ | 85 ByteArray::Copy(array, index.Value(), &src, sizeof(ValueT)); \ |
| 86 return Integer::New(index.Value() + sizeof(ValueT)); | 86 return Integer::New(index.Value() + sizeof(ValueT)); |
| 87 | 87 |
| 88 | 88 |
| 89 #define SCALED_UNALIGNED_GETTER(ArrayT, ObjectT, ValueT) \ |
| 90 GETTER_ARGUMENTS(ArrayT, ValueT); \ |
| 91 RangeCheck(array, index.Value() * sizeof(ValueT), sizeof(ValueT)); \ |
| 92 ValueT result; \ |
| 93 ByteArray::Copy(&result, array, \ |
| 94 index.Value() * sizeof(ValueT), sizeof(ValueT)); \ |
| 95 return ObjectT::New(result); |
| 96 |
| 97 |
| 98 #define SCALED_UNALIGNED_SETTER(ArrayT, ObjectT, Getter, ValueT) \ |
| 99 SETTER_ARGUMENTS(ArrayT, ObjectT, ValueT); \ |
| 100 RangeCheck(array, index.Value() * sizeof(ValueT), sizeof(ValueT)); \ |
| 101 ValueT src = value_object.Getter(); \ |
| 102 ByteArray::Copy(array, index.Value() * sizeof(ValueT), &src, sizeof(ValueT));\ |
| 103 return Integer::New(index.Value() + sizeof(ValueT)); |
| 104 |
| 105 |
| 89 #define UINT64_TO_INTEGER(value, integer) \ | 106 #define UINT64_TO_INTEGER(value, integer) \ |
| 90 if (value > static_cast<uint64_t>(Mint::kMaxValue)) { \ | 107 if (value > static_cast<uint64_t>(Mint::kMaxValue)) { \ |
| 91 result = BigintOperations::NewFromUint64(value); \ | 108 result = BigintOperations::NewFromUint64(value); \ |
| 92 } else if (value > static_cast<uint64_t>(Smi::kMaxValue)) { \ | 109 } else if (value > static_cast<uint64_t>(Smi::kMaxValue)) { \ |
| 93 result = Mint::New(value); \ | 110 result = Mint::New(value); \ |
| 94 } else { \ | 111 } else { \ |
| 95 result = Smi::New(value); \ | 112 result = Smi::New(value); \ |
| 96 } | 113 } |
| 97 | 114 |
| 98 | 115 |
| (...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 658 | 675 |
| 659 | 676 |
| 660 DEFINE_NATIVE_ENTRY(ExternalInt8Array_setIndexed, 3) { | 677 DEFINE_NATIVE_ENTRY(ExternalInt8Array_setIndexed, 3) { |
| 661 SETTER(ExternalInt8Array, Smi, Value, int8_t); | 678 SETTER(ExternalInt8Array, Smi, Value, int8_t); |
| 662 } | 679 } |
| 663 | 680 |
| 664 | 681 |
| 665 // ExternalUint8Array | 682 // ExternalUint8Array |
| 666 | 683 |
| 667 DEFINE_NATIVE_ENTRY(ExternalUint8Array_getIndexed, 2) { | 684 DEFINE_NATIVE_ENTRY(ExternalUint8Array_getIndexed, 2) { |
| 668 UNALIGNED_GETTER(ExternalUint8Array, Smi, uint8_t); | 685 SCALED_UNALIGNED_GETTER(ExternalUint8Array, Smi, uint8_t); |
| 669 } | 686 } |
| 670 | 687 |
| 671 | 688 |
| 672 DEFINE_NATIVE_ENTRY(ExternalUint8Array_setIndexed, 3) { | 689 DEFINE_NATIVE_ENTRY(ExternalUint8Array_setIndexed, 3) { |
| 673 UNALIGNED_SETTER(ExternalUint8Array, Smi, Value, uint8_t); | 690 SCALED_UNALIGNED_SETTER(ExternalUint8Array, Smi, Value, uint8_t); |
| 674 } | 691 } |
| 675 | 692 |
| 676 | 693 |
| 677 // ExternalUint8ClampedArray | 694 // ExternalUint8ClampedArray |
| 678 | 695 |
| 679 DEFINE_NATIVE_ENTRY(ExternalUint8ClampedArray_getIndexed, 2) { | 696 DEFINE_NATIVE_ENTRY(ExternalUint8ClampedArray_getIndexed, 2) { |
| 680 UNALIGNED_GETTER(ExternalUint8ClampedArray, Smi, uint8_t); | 697 SCALED_UNALIGNED_GETTER(ExternalUint8ClampedArray, Smi, uint8_t); |
| 681 } | 698 } |
| 682 | 699 |
| 683 | 700 |
| 684 DEFINE_NATIVE_ENTRY(ExternalUint8ClampedArray_setIndexed, 3) { | 701 DEFINE_NATIVE_ENTRY(ExternalUint8ClampedArray_setIndexed, 3) { |
| 685 UNALIGNED_SETTER(ExternalUint8ClampedArray, Smi, Value, uint8_t); | 702 SCALED_UNALIGNED_SETTER(ExternalUint8ClampedArray, Smi, Value, uint8_t); |
| 686 } | 703 } |
| 687 | 704 |
| 688 | 705 |
| 689 // ExternalInt16Array | 706 // ExternalInt16Array |
| 690 | 707 |
| 691 DEFINE_NATIVE_ENTRY(ExternalInt16Array_getIndexed, 2) { | 708 DEFINE_NATIVE_ENTRY(ExternalInt16Array_getIndexed, 2) { |
| 692 GETTER(ExternalInt16Array, Smi, int16_t); | 709 GETTER(ExternalInt16Array, Smi, int16_t); |
| 693 } | 710 } |
| 694 | 711 |
| 695 | 712 |
| 696 DEFINE_NATIVE_ENTRY(ExternalInt16Array_setIndexed, 3) { | 713 DEFINE_NATIVE_ENTRY(ExternalInt16Array_setIndexed, 3) { |
| 697 SETTER(ExternalInt16Array, Smi, Value, int16_t); | 714 SETTER(ExternalInt16Array, Smi, Value, int16_t); |
| 698 } | 715 } |
| 699 | 716 |
| 700 | 717 |
| 701 // ExternalUint16Array | 718 // ExternalUint16Array |
| 702 | 719 |
| 703 DEFINE_NATIVE_ENTRY(ExternalUint16Array_getIndexed, 2) { | 720 DEFINE_NATIVE_ENTRY(ExternalUint16Array_getIndexed, 2) { |
| 704 UNALIGNED_GETTER(ExternalUint16Array, Smi, uint16_t); | 721 SCALED_UNALIGNED_GETTER(ExternalUint16Array, Smi, uint16_t); |
| 705 } | 722 } |
| 706 | 723 |
| 707 | 724 |
| 708 DEFINE_NATIVE_ENTRY(ExternalUint16Array_setIndexed, 3) { | 725 DEFINE_NATIVE_ENTRY(ExternalUint16Array_setIndexed, 3) { |
| 709 UNALIGNED_SETTER(ExternalUint16Array, Smi, Value, uint16_t); | 726 SCALED_UNALIGNED_SETTER(ExternalUint16Array, Smi, Value, uint16_t); |
| 710 } | 727 } |
| 711 | 728 |
| 712 | 729 |
| 713 // ExternalInt32Array | 730 // ExternalInt32Array |
| 714 | 731 |
| 715 DEFINE_NATIVE_ENTRY(ExternalInt32Array_getIndexed, 2) { | 732 DEFINE_NATIVE_ENTRY(ExternalInt32Array_getIndexed, 2) { |
| 716 GETTER(ExternalInt32Array, Integer, int32_t); | 733 GETTER(ExternalInt32Array, Integer, int32_t); |
| 717 } | 734 } |
| 718 | 735 |
| 719 | 736 |
| 720 DEFINE_NATIVE_ENTRY(ExternalInt32Array_setIndexed, 3) { | 737 DEFINE_NATIVE_ENTRY(ExternalInt32Array_setIndexed, 3) { |
| 721 SETTER(ExternalInt32Array, Integer, AsInt64Value, int32_t); | 738 SETTER(ExternalInt32Array, Integer, AsInt64Value, int32_t); |
| 722 } | 739 } |
| 723 | 740 |
| 724 | 741 |
| 725 // ExternalUint32Array | 742 // ExternalUint32Array |
| 726 | 743 |
| 727 DEFINE_NATIVE_ENTRY(ExternalUint32Array_getIndexed, 2) { | 744 DEFINE_NATIVE_ENTRY(ExternalUint32Array_getIndexed, 2) { |
| 728 UNALIGNED_GETTER(ExternalUint32Array, Integer, uint32_t); | 745 SCALED_UNALIGNED_GETTER(ExternalUint32Array, Integer, uint32_t); |
| 729 } | 746 } |
| 730 | 747 |
| 731 | 748 |
| 732 DEFINE_NATIVE_ENTRY(ExternalUint32Array_setIndexed, 3) { | 749 DEFINE_NATIVE_ENTRY(ExternalUint32Array_setIndexed, 3) { |
| 733 UNALIGNED_SETTER(ExternalUint32Array, Integer, AsInt64Value, uint32_t); | 750 SCALED_UNALIGNED_SETTER(ExternalUint32Array, Integer, AsInt64Value, uint32_t); |
| 734 } | 751 } |
| 735 | 752 |
| 736 | 753 |
| 737 // ExternalInt64Array | 754 // ExternalInt64Array |
| 738 | 755 |
| 739 DEFINE_NATIVE_ENTRY(ExternalInt64Array_getIndexed, 2) { | 756 DEFINE_NATIVE_ENTRY(ExternalInt64Array_getIndexed, 2) { |
| 740 GETTER(ExternalInt64Array, Integer, int64_t); | 757 GETTER(ExternalInt64Array, Integer, int64_t); |
| 741 } | 758 } |
| 742 | 759 |
| 743 | 760 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 DEFINE_NATIVE_ENTRY(ExternalFloat64Array_getIndexed, 2) { | 792 DEFINE_NATIVE_ENTRY(ExternalFloat64Array_getIndexed, 2) { |
| 776 GETTER(ExternalFloat64Array, Double, double); | 793 GETTER(ExternalFloat64Array, Double, double); |
| 777 } | 794 } |
| 778 | 795 |
| 779 | 796 |
| 780 DEFINE_NATIVE_ENTRY(ExternalFloat64Array_setIndexed, 3) { | 797 DEFINE_NATIVE_ENTRY(ExternalFloat64Array_setIndexed, 3) { |
| 781 SETTER(ExternalFloat64Array, Double, value, double); | 798 SETTER(ExternalFloat64Array, Double, value, double); |
| 782 } | 799 } |
| 783 | 800 |
| 784 } // namespace dart | 801 } // namespace dart |
| OLD | NEW |