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 |