OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_UTILS_H_ | 5 #ifndef V8_UTILS_H_ |
6 #define V8_UTILS_H_ | 6 #define V8_UTILS_H_ |
7 | 7 |
8 #include <limits.h> | 8 #include <limits.h> |
9 #include <stdlib.h> | 9 #include <stdlib.h> |
10 #include <string.h> | 10 #include <string.h> |
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 // Calculate 10^exponent. | 734 // Calculate 10^exponent. |
735 inline int TenToThe(int exponent) { | 735 inline int TenToThe(int exponent) { |
736 DCHECK(exponent <= 9); | 736 DCHECK(exponent <= 9); |
737 DCHECK(exponent >= 1); | 737 DCHECK(exponent >= 1); |
738 int answer = 10; | 738 int answer = 10; |
739 for (int i = 1; i < exponent; i++) answer *= 10; | 739 for (int i = 1; i < exponent; i++) answer *= 10; |
740 return answer; | 740 return answer; |
741 } | 741 } |
742 | 742 |
743 | 743 |
744 // The type-based aliasing rule allows the compiler to assume that pointers of | |
745 // different types (for some definition of different) never alias each other. | |
746 // Thus the following code does not work: | |
747 // | |
748 // float f = foo(); | |
749 // int fbits = *(int*)(&f); | |
750 // | |
751 // The compiler 'knows' that the int pointer can't refer to f since the types | |
752 // don't match, so the compiler may cache f in a register, leaving random data | |
753 // in fbits. Using C++ style casts makes no difference, however a pointer to | |
754 // char data is assumed to alias any other pointer. This is the 'memcpy | |
755 // exception'. | |
756 // | |
757 // Bit_cast uses the memcpy exception to move the bits from a variable of one | |
758 // type of a variable of another type. Of course the end result is likely to | |
759 // be implementation dependent. Most compilers (gcc-4.2 and MSVC 2005) | |
760 // will completely optimize BitCast away. | |
761 // | |
762 // There is an additional use for BitCast. | |
763 // Recent gccs will warn when they see casts that may result in breakage due to | |
764 // the type-based aliasing rule. If you have checked that there is no breakage | |
765 // you can use BitCast to cast one pointer type to another. This confuses gcc | |
766 // enough that it can no longer see that you have cast one pointer type to | |
767 // another thus avoiding the warning. | |
768 | |
769 // We need different implementations of BitCast for pointer and non-pointer | |
770 // values. We use partial specialization of auxiliary struct to work around | |
771 // issues with template functions overloading. | |
772 template <class Dest, class Source> | |
773 struct BitCastHelper { | |
774 STATIC_ASSERT(sizeof(Dest) == sizeof(Source)); | |
775 | |
776 INLINE(static Dest cast(const Source& source)) { | |
777 Dest dest; | |
778 memcpy(&dest, &source, sizeof(dest)); | |
779 return dest; | |
780 } | |
781 }; | |
782 | |
783 template <class Dest, class Source> | |
784 struct BitCastHelper<Dest, Source*> { | |
785 INLINE(static Dest cast(Source* source)) { | |
786 return BitCastHelper<Dest, uintptr_t>:: | |
787 cast(reinterpret_cast<uintptr_t>(source)); | |
788 } | |
789 }; | |
790 | |
791 template <class Dest, class Source> | |
792 INLINE(Dest BitCast(const Source& source)); | |
793 | |
794 template <class Dest, class Source> | |
795 inline Dest BitCast(const Source& source) { | |
796 return BitCastHelper<Dest, Source>::cast(source); | |
797 } | |
798 | |
799 | |
800 template<typename ElementType, int NumElements> | 744 template<typename ElementType, int NumElements> |
801 class EmbeddedContainer { | 745 class EmbeddedContainer { |
802 public: | 746 public: |
803 EmbeddedContainer() : elems_() { } | 747 EmbeddedContainer() : elems_() { } |
804 | 748 |
805 int length() const { return NumElements; } | 749 int length() const { return NumElements; } |
806 const ElementType& operator[](int i) const { | 750 const ElementType& operator[](int i) const { |
807 DCHECK(i < length()); | 751 DCHECK(i < length()); |
808 return elems_[i]; | 752 return elems_[i]; |
809 } | 753 } |
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 // Takes the address of the limit variable in order to find out where | 1492 // Takes the address of the limit variable in order to find out where |
1549 // the top of stack is right now. | 1493 // the top of stack is right now. |
1550 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit); | 1494 uintptr_t limit = reinterpret_cast<uintptr_t>(&limit); |
1551 return limit; | 1495 return limit; |
1552 } | 1496 } |
1553 | 1497 |
1554 } // namespace internal | 1498 } // namespace internal |
1555 } // namespace v8 | 1499 } // namespace v8 |
1556 | 1500 |
1557 #endif // V8_UTILS_H_ | 1501 #endif // V8_UTILS_H_ |
OLD | NEW |