|
Lines 47-54
Link Here
|
| 47 |
# include <iostream> |
47 |
# include <iostream> |
| 48 |
#endif |
48 |
#endif |
| 49 |
|
49 |
|
|
|
50 |
#include "JavaDef.h" |
| 50 |
#include "CommonDef.h" |
51 |
#include "CommonDef.h" |
|
|
52 |
|
| 51 |
#include "JClassFile.h" |
53 |
#include "JClassFile.h" |
|
|
54 |
#include "JMemStream.h" |
| 52 |
|
55 |
|
| 53 |
USE_NAMESPACE(std); |
56 |
USE_NAMESPACE(std); |
| 54 |
|
57 |
|
|
Lines 259-266
CCPUtf8Info::~CCPUtf8Info()
Link Here
|
| 259 |
void |
262 |
void |
| 260 |
CCPUtf8Info::Read(CJStream& i_jstream) |
263 |
CCPUtf8Info::Read(CJStream& i_jstream) |
| 261 |
{ |
264 |
{ |
| 262 |
i_jstream >> m_u2Length; |
265 |
i_jstream >> m_u2Length; |
| 263 |
m_pu1Bytes = new u1[m_u2Length]; |
266 |
m_pu1Bytes = new u1[m_u2Length + 1]; |
|
|
267 |
m_pu1Bytes[m_u2Length] = 0; /*Helps standard string functions find end of the string*/ |
| 264 |
i_jstream.ReadUtf8((void*)m_pu1Bytes, m_u2Length); |
268 |
i_jstream.ReadUtf8((void*)m_pu1Bytes, m_u2Length); |
| 265 |
} |
269 |
} |
| 266 |
|
270 |
|
|
Lines 1738-1743
CJAttribs::Read(CJStream& i_jstream)
Link Here
|
| 1738 |
{ |
1742 |
{ |
| 1739 |
pCurrent = new CLocalVariableTypeTableAttribute(m_pClassFile); |
1743 |
pCurrent = new CLocalVariableTypeTableAttribute(m_pClassFile); |
| 1740 |
} |
1744 |
} |
|
|
1745 |
else if(*pcpUtf8 == "StackMapTable") |
| 1746 |
{ |
| 1747 |
pCurrent = new CStackMapTableAttribute(m_pClassFile); |
| 1748 |
} |
| 1741 |
else if(*pcpUtf8 == "Exceptions") |
1749 |
else if(*pcpUtf8 == "Exceptions") |
| 1742 |
{ |
1750 |
{ |
| 1743 |
pCurrent = new CExceptionsAttribute(m_pClassFile); |
1751 |
pCurrent = new CExceptionsAttribute(m_pClassFile); |
|
Lines 2119-2124
CCodeAttribute::GetLocalVariableTypes()
Link Here
|
| 2119 |
return NULL; |
2127 |
return NULL; |
| 2120 |
} |
2128 |
} |
| 2121 |
|
2129 |
|
|
|
2130 |
//------------------------------------------------------------------------------ |
| 2131 |
CStackMapTableAttribute* |
| 2132 |
CCodeAttribute::GetStackMaps() |
| 2133 |
{ |
| 2134 |
for(CJAttribs::iterator iter = m_Attribs.begin(); iter < m_Attribs.end(); iter++) |
| 2135 |
{ |
| 2136 |
if(*(*iter)->GetName() == "StackMapTable") |
| 2137 |
return (CStackMapTableAttribute*)*iter; |
| 2138 |
} |
| 2139 |
return NULL; |
| 2140 |
} |
| 2141 |
|
| 2142 |
//------------------------------------------------------------------------------ |
| 2143 |
CStackMapTableAttribute* |
| 2144 |
CCodeAttribute::GetOrCreateStackMaps() |
| 2145 |
{ |
| 2146 |
// Return the StackMapTable attribute of this Code attribute, creating a new one |
| 2147 |
// if such an attribute does not exist |
| 2148 |
|
| 2149 |
CStackMapTableAttribute* result = NULL; |
| 2150 |
for(CJAttribs::iterator iter = m_Attribs.begin(); iter < m_Attribs.end(); iter++) |
| 2151 |
{ |
| 2152 |
if(*(*iter)->GetName() == "StackMapTable") |
| 2153 |
{ |
| 2154 |
result = (CStackMapTableAttribute*)*iter; |
| 2155 |
} |
| 2156 |
} |
| 2157 |
|
| 2158 |
if (result == NULL) |
| 2159 |
{ |
| 2160 |
result = new CStackMapTableAttribute(m_pClassFile); |
| 2161 |
m_Attribs.push_back(result); |
| 2162 |
} |
| 2163 |
return result; |
| 2164 |
} |
| 2122 |
|
2165 |
|
| 2123 |
//============================================================================== |
2166 |
//============================================================================== |
| 2124 |
// CExceptionsAttribute implementation |
2167 |
// CExceptionsAttribute implementation |
|
Lines 2500-2505
CSourceDirAttribute::CSourceDirAttribute
Link Here
|
| 2500 |
{} |
2543 |
{} |
| 2501 |
|
2544 |
|
| 2502 |
//============================================================================== |
2545 |
//============================================================================== |
|
|
2546 |
// CStackMapTableAttribute implementation |
| 2547 |
// |
| 2548 |
CVerificationTypeInfo::CVerificationTypeInfo(u1 i_u1Tag) |
| 2549 |
: m_u1Tag(i_u1Tag) |
| 2550 |
{ |
| 2551 |
} |
| 2552 |
|
| 2553 |
CVerificationTypeInfo::~CVerificationTypeInfo() |
| 2554 |
{ |
| 2555 |
} |
| 2556 |
|
| 2557 |
void |
| 2558 |
CVerificationTypeInfo::Read(CJStream& i_jstream) |
| 2559 |
{ |
| 2560 |
// m_u1Tag is read by the CVerificationTypes container. |
| 2561 |
} |
| 2562 |
|
| 2563 |
u2 |
| 2564 |
CVerificationTypeInfo::Read(u1 *i_tbl) |
| 2565 |
{ |
| 2566 |
// m_u1Tag is read by the CVerificationTypes container. |
| 2567 |
return 0; |
| 2568 |
} |
| 2569 |
|
| 2570 |
void |
| 2571 |
CVerificationTypeInfo::Write(CJStream& i_jstream) const |
| 2572 |
{ |
| 2573 |
i_jstream << m_u1Tag; |
| 2574 |
} |
| 2575 |
|
| 2576 |
u4 |
| 2577 |
CVerificationTypeInfo::GetSize() const |
| 2578 |
{ |
| 2579 |
return sizeof(m_u1Tag); |
| 2580 |
} |
| 2581 |
|
| 2582 |
//------------------------------------------------------------------------------ |
| 2583 |
CVerificationTypes::~CVerificationTypes() |
| 2584 |
{ |
| 2585 |
for (iterator iter = begin(); iter != end(); iter++) |
| 2586 |
{ |
| 2587 |
delete *iter; |
| 2588 |
} |
| 2589 |
} |
| 2590 |
|
| 2591 |
CVerificationTypes::CVerificationTypes(const CVerificationTypes &i_VerTypes) |
| 2592 |
{ |
| 2593 |
*this = i_VerTypes; |
| 2594 |
} |
| 2595 |
|
| 2596 |
CVerificationTypes& |
| 2597 |
CVerificationTypes::operator =(const CVerificationTypes &i_VerTypes) |
| 2598 |
{ |
| 2599 |
for(iterator iter = begin(); iter != end(); iter++) |
| 2600 |
{ |
| 2601 |
delete *iter; |
| 2602 |
} |
| 2603 |
if(!i_VerTypes.empty()) |
| 2604 |
{ |
| 2605 |
const_iterator iterIn; |
| 2606 |
clear(); |
| 2607 |
for(iterIn = i_VerTypes.begin(); iterIn != i_VerTypes.end(); iterIn++) |
| 2608 |
{ |
| 2609 |
push_back((*iterIn)->Clone()); |
| 2610 |
} |
| 2611 |
} |
| 2612 |
return *this; |
| 2613 |
} |
| 2614 |
|
| 2615 |
void |
| 2616 |
CVerificationTypes::Read(CJStream& i_jstream, u2 i_u2EntriesToRead) |
| 2617 |
{ |
| 2618 |
CVerificationTypeInfo* pCurrent; |
| 2619 |
|
| 2620 |
resize(i_u2EntriesToRead); |
| 2621 |
for(u2 u2Ind = 0; u2Ind < i_u2EntriesToRead; u2Ind++) |
| 2622 |
{ |
| 2623 |
u1 u1Tag; |
| 2624 |
i_jstream >> u1Tag; |
| 2625 |
switch (u1Tag) |
| 2626 |
{ |
| 2627 |
case ITEM_Top: |
| 2628 |
case ITEM_Integer: |
| 2629 |
case ITEM_Float: |
| 2630 |
case ITEM_Double: |
| 2631 |
case ITEM_Long: |
| 2632 |
case ITEM_Null: |
| 2633 |
case ITEM_UninitializedThis: |
| 2634 |
pCurrent = new CVerificationTypeInfo(u1Tag); |
| 2635 |
break; |
| 2636 |
case ITEM_Object: |
| 2637 |
pCurrent = new CVerificationTypeObjectInfo(u1Tag); |
| 2638 |
break; |
| 2639 |
case ITEM_Uninitialized: |
| 2640 |
pCurrent = new CVerificationTypeUninitializedVariableInfo(u1Tag); |
| 2641 |
break; |
| 2642 |
default: |
| 2643 |
throw CJClassFileException(CJClassFileException::X_INTERNAL_ERROR); |
| 2644 |
} |
| 2645 |
|
| 2646 |
pCurrent->Read(i_jstream); |
| 2647 |
(*this)[u2Ind] = pCurrent; |
| 2648 |
} |
| 2649 |
} |
| 2650 |
|
| 2651 |
void |
| 2652 |
CVerificationTypes::Write(CJStream& i_jstream) const |
| 2653 |
{ |
| 2654 |
for (u2 u2Ind = 0; u2Ind < size(); u2Ind++) |
| 2655 |
{ |
| 2656 |
(*this)[u2Ind]->Write(i_jstream); |
| 2657 |
} |
| 2658 |
} |
| 2659 |
|
| 2660 |
u4 |
| 2661 |
CVerificationTypes::GetSize() const |
| 2662 |
{ |
| 2663 |
u4 u4Size = 0; |
| 2664 |
for (const_iterator iter = begin(); iter != end(); iter++) |
| 2665 |
{ |
| 2666 |
u4Size += (*iter)->GetSize(); |
| 2667 |
} |
| 2668 |
return u4Size; |
| 2669 |
} |
| 2670 |
|
| 2671 |
//------------------------------------------------------------------------------ |
| 2672 |
CVerificationTypeObjectInfo::CVerificationTypeObjectInfo(u1 i_u1Tag) |
| 2673 |
: CVerificationTypeInfo(i_u1Tag) |
| 2674 |
{ |
| 2675 |
} |
| 2676 |
|
| 2677 |
CVerificationTypeObjectInfo::~CVerificationTypeObjectInfo() |
| 2678 |
{ |
| 2679 |
} |
| 2680 |
|
| 2681 |
void |
| 2682 |
CVerificationTypeObjectInfo::Read(CJStream& i_jstream) |
| 2683 |
{ |
| 2684 |
CVerificationTypeInfo::Read(i_jstream); |
| 2685 |
i_jstream >> m_u2CpoolIndex; |
| 2686 |
} |
| 2687 |
|
| 2688 |
void |
| 2689 |
CVerificationTypeObjectInfo::Write(CJStream& i_jstream) const |
| 2690 |
{ |
| 2691 |
CVerificationTypeInfo::Write(i_jstream); |
| 2692 |
i_jstream << m_u2CpoolIndex; |
| 2693 |
} |
| 2694 |
|
| 2695 |
u4 |
| 2696 |
CVerificationTypeObjectInfo::GetSize() const |
| 2697 |
{ |
| 2698 |
u4 u4Size = CVerificationTypeInfo::GetSize() |
| 2699 |
+ sizeof(m_u2CpoolIndex); |
| 2700 |
return u4Size; |
| 2701 |
} |
| 2702 |
|
| 2703 |
//------------------------------------------------------------------------------ |
| 2704 |
CVerificationTypeUninitializedVariableInfo::CVerificationTypeUninitializedVariableInfo(u1 i_u1Tag) |
| 2705 |
: CVerificationTypeInfo(i_u1Tag) |
| 2706 |
{ |
| 2707 |
} |
| 2708 |
|
| 2709 |
CVerificationTypeUninitializedVariableInfo::~CVerificationTypeUninitializedVariableInfo() |
| 2710 |
{ |
| 2711 |
} |
| 2712 |
|
| 2713 |
void |
| 2714 |
CVerificationTypeUninitializedVariableInfo::Read(CJStream& i_jstream) |
| 2715 |
{ |
| 2716 |
CVerificationTypeInfo::Read(i_jstream); |
| 2717 |
i_jstream >> m_u2Offset; |
| 2718 |
} |
| 2719 |
|
| 2720 |
void |
| 2721 |
CVerificationTypeUninitializedVariableInfo::Write(CJStream& i_jstream) const |
| 2722 |
{ |
| 2723 |
CVerificationTypeInfo::Write(i_jstream); |
| 2724 |
i_jstream << m_u2Offset; |
| 2725 |
} |
| 2726 |
|
| 2727 |
u4 |
| 2728 |
CVerificationTypeUninitializedVariableInfo::GetSize() const |
| 2729 |
{ |
| 2730 |
u4 u4Size = CVerificationTypeInfo::GetSize() |
| 2731 |
+ sizeof(m_u2Offset); |
| 2732 |
return u4Size; |
| 2733 |
} |
| 2734 |
|
| 2735 |
//------------------------------------------------------------------------------ |
| 2736 |
CStackMapFrameInfo::CStackMapFrameInfo(u1 i_u1FrameType) |
| 2737 |
: m_u1FrameType(i_u1FrameType) |
| 2738 |
{ |
| 2739 |
m_u2ByteCodeOffset = 0; |
| 2740 |
m_u2OffsetDelta = 0; |
| 2741 |
} |
| 2742 |
|
| 2743 |
CStackMapFrameInfo::~CStackMapFrameInfo() |
| 2744 |
{ |
| 2745 |
} |
| 2746 |
|
| 2747 |
void |
| 2748 |
CStackMapFrameInfo::Read(CJStream& i_jstream) |
| 2749 |
{ |
| 2750 |
// m_u1FrameType is read by the CStackMapTable container |
| 2751 |
} |
| 2752 |
|
| 2753 |
void |
| 2754 |
CStackMapFrameInfo::Write(CJStream& i_jstream) const |
| 2755 |
{ |
| 2756 |
i_jstream << m_u1FrameType; |
| 2757 |
} |
| 2758 |
|
| 2759 |
u4 |
| 2760 |
CStackMapFrameInfo::GetSize() const |
| 2761 |
{ |
| 2762 |
return sizeof(m_u1FrameType); |
| 2763 |
} |
| 2764 |
|
| 2765 |
void |
| 2766 |
CStackMapFrameInfo::SetByteCodeOffset(u2 i_u2Offset) |
| 2767 |
{ |
| 2768 |
m_u2ByteCodeOffset = i_u2Offset; |
| 2769 |
} |
| 2770 |
|
| 2771 |
void |
| 2772 |
CStackMapFrameInfo::AdjustOffsetDelta(int i_s2PrevFrameOffset) |
| 2773 |
{ |
| 2774 |
int newOffsetDelta = m_u2ByteCodeOffset - 1 - i_s2PrevFrameOffset; |
| 2775 |
if (newOffsetDelta < 0) |
| 2776 |
{ |
| 2777 |
// Frame order was changed. This is not supported |
| 2778 |
throw CJClassFileException(CJClassFileException::X_INTERNAL_ERROR); |
| 2779 |
} |
| 2780 |
m_u2OffsetDelta = (u2)newOffsetDelta; // this is a safe cast since newDelta >= 1 |
| 2781 |
} |
| 2782 |
|
| 2783 |
CStackMapFrameInfo::CStackMapFrameInfo(const CStackMapFrameInfo &i_Other) |
| 2784 |
: m_u2ByteCodeOffset(i_Other.m_u2ByteCodeOffset), m_u2OffsetDelta(i_Other.m_u2OffsetDelta), |
| 2785 |
m_u1FrameType(i_Other.m_u1FrameType) |
| 2786 |
{ |
| 2787 |
} |
| 2788 |
|
| 2789 |
//------------------------------------------------------------------------------ |
| 2790 |
CStackMapSameFrameInfo::CStackMapSameFrameInfo(u1 i_u1FrameType, bool i_IsExtended) |
| 2791 |
: CStackMapFrameInfo(i_u1FrameType), m_IsExtended(i_IsExtended) |
| 2792 |
{ |
| 2793 |
} |
| 2794 |
|
| 2795 |
CStackMapSameFrameInfo::~CStackMapSameFrameInfo() |
| 2796 |
{ |
| 2797 |
} |
| 2798 |
|
| 2799 |
void |
| 2800 |
CStackMapSameFrameInfo::Read(CJStream& i_jstream) |
| 2801 |
{ |
| 2802 |
CStackMapFrameInfo::Read(i_jstream); |
| 2803 |
if (m_IsExtended) |
| 2804 |
{ |
| 2805 |
// SAME_FRAME_EXTENDED type |
| 2806 |
i_jstream >> m_u2OffsetDelta; |
| 2807 |
} |
| 2808 |
else |
| 2809 |
{ |
| 2810 |
// SAME frame type. offset_delta is stored in the tag |
| 2811 |
m_u2OffsetDelta = GetFrameType(); |
| 2812 |
} |
| 2813 |
} |
| 2814 |
|
| 2815 |
void |
| 2816 |
CStackMapSameFrameInfo::Write(CJStream& i_jstream) const |
| 2817 |
{ |
| 2818 |
CStackMapFrameInfo::Write(i_jstream); |
| 2819 |
if (m_IsExtended) |
| 2820 |
{ |
| 2821 |
// SAME_FRAME_EXTENDED type |
| 2822 |
i_jstream << m_u2OffsetDelta; |
| 2823 |
} |
| 2824 |
} |
| 2825 |
|
| 2826 |
u4 |
| 2827 |
CStackMapSameFrameInfo::GetSize() const |
| 2828 |
{ |
| 2829 |
u4 u4Size = CStackMapFrameInfo::GetSize(); |
| 2830 |
if (m_IsExtended) |
| 2831 |
{ |
| 2832 |
u4Size += sizeof(m_u2OffsetDelta); |
| 2833 |
} |
| 2834 |
return u4Size; |
| 2835 |
} |
| 2836 |
|
| 2837 |
void |
| 2838 |
CStackMapSameFrameInfo::AdjustOffsetDelta(int i_s2PrevFrameOffset) |
| 2839 |
{ |
| 2840 |
CStackMapFrameInfo::AdjustOffsetDelta(i_s2PrevFrameOffset); |
| 2841 |
if (m_u2OffsetDelta > 63) |
| 2842 |
{ |
| 2843 |
// Frame type is SAME_FRAME_EXTENDED |
| 2844 |
m_u1FrameType = SAME_FRAME_EXTENDED; |
| 2845 |
m_IsExtended = true; |
| 2846 |
} |
| 2847 |
else |
| 2848 |
{ |
| 2849 |
// Frame type is SAME_FRAME. offset_delta is stored in the tag |
| 2850 |
m_u1FrameType = (u1)m_u2OffsetDelta; // this is safe since m_u2OffsetDelta <= 63 |
| 2851 |
m_IsExtended = false; |
| 2852 |
} |
| 2853 |
} |
| 2854 |
|
| 2855 |
CStackMapFrameInfo* |
| 2856 |
CStackMapSameFrameInfo::Clone() const |
| 2857 |
{ |
| 2858 |
return new CStackMapSameFrameInfo(*this); |
| 2859 |
} |
| 2860 |
|
| 2861 |
//------------------------------------------------------------------------------ |
| 2862 |
CStackMapChopFrameInfo::CStackMapChopFrameInfo(u1 i_u1FrameType) |
| 2863 |
: CStackMapFrameInfo(i_u1FrameType) |
| 2864 |
{ |
| 2865 |
} |
| 2866 |
|
| 2867 |
CStackMapChopFrameInfo::~CStackMapChopFrameInfo() |
| 2868 |
{ |
| 2869 |
} |
| 2870 |
|
| 2871 |
void |
| 2872 |
CStackMapChopFrameInfo::Read(CJStream& i_jstream) |
| 2873 |
{ |
| 2874 |
CStackMapFrameInfo::Read(i_jstream); |
| 2875 |
i_jstream >> m_u2OffsetDelta; |
| 2876 |
} |
| 2877 |
|
| 2878 |
void |
| 2879 |
CStackMapChopFrameInfo::Write(CJStream& i_jstream) const |
| 2880 |
{ |
| 2881 |
CStackMapFrameInfo::Write(i_jstream); |
| 2882 |
i_jstream << m_u2OffsetDelta; |
| 2883 |
} |
| 2884 |
|
| 2885 |
u4 |
| 2886 |
CStackMapChopFrameInfo::GetSize() const |
| 2887 |
{ |
| 2888 |
u4 u4Size = CStackMapFrameInfo::GetSize() |
| 2889 |
+ sizeof(m_u2OffsetDelta); |
| 2890 |
return u4Size; |
| 2891 |
} |
| 2892 |
|
| 2893 |
CStackMapFrameInfo* |
| 2894 |
CStackMapChopFrameInfo::Clone() const |
| 2895 |
{ |
| 2896 |
return new CStackMapChopFrameInfo(*this); |
| 2897 |
} |
| 2898 |
|
| 2899 |
//------------------------------------------------------------------------------ |
| 2900 |
CStackMapSameLocals1StackItemFrameInfo::CStackMapSameLocals1StackItemFrameInfo(u1 i_u1FrameType, |
| 2901 |
bool i_IsExtended) |
| 2902 |
: CStackMapFrameInfo(i_u1FrameType), m_IsExtended(i_IsExtended) |
| 2903 |
{ |
| 2904 |
} |
| 2905 |
|
| 2906 |
CStackMapSameLocals1StackItemFrameInfo::~CStackMapSameLocals1StackItemFrameInfo() |
| 2907 |
{ |
| 2908 |
} |
| 2909 |
|
| 2910 |
void |
| 2911 |
CStackMapSameLocals1StackItemFrameInfo::Read(CJStream& i_jstream) |
| 2912 |
{ |
| 2913 |
CStackMapFrameInfo::Read(i_jstream); |
| 2914 |
if (m_IsExtended) |
| 2915 |
{ |
| 2916 |
// SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED type |
| 2917 |
i_jstream >> m_u2OffsetDelta; |
| 2918 |
} |
| 2919 |
else |
| 2920 |
{ |
| 2921 |
// SAME_LOCALS_1_STACK_ITEM_FRAME frame type |
| 2922 |
m_u2OffsetDelta = GetFrameType() - 64; |
| 2923 |
} |
| 2924 |
m_Stack.Read(i_jstream, 1); // must hold exactly one stack item |
| 2925 |
} |
| 2926 |
|
| 2927 |
void |
| 2928 |
CStackMapSameLocals1StackItemFrameInfo::Write(CJStream& i_jstream) const |
| 2929 |
{ |
| 2930 |
CStackMapFrameInfo::Write(i_jstream); |
| 2931 |
if (m_IsExtended) |
| 2932 |
{ |
| 2933 |
// SAME_FRAME_EXTENDED type |
| 2934 |
i_jstream << m_u2OffsetDelta; |
| 2935 |
} |
| 2936 |
m_Stack.Write(i_jstream); |
| 2937 |
} |
| 2938 |
|
| 2939 |
u4 |
| 2940 |
CStackMapSameLocals1StackItemFrameInfo::GetSize() const |
| 2941 |
{ |
| 2942 |
u4 u4Size = CStackMapFrameInfo::GetSize(); |
| 2943 |
if (m_IsExtended) |
| 2944 |
{ |
| 2945 |
u4Size += sizeof(m_u2OffsetDelta); |
| 2946 |
} |
| 2947 |
u4Size += m_Stack.GetSize(); |
| 2948 |
return u4Size; |
| 2949 |
} |
| 2950 |
|
| 2951 |
void |
| 2952 |
CStackMapSameLocals1StackItemFrameInfo::AdjustOffsetDelta(int i_s2PrevFrameOffset) |
| 2953 |
{ |
| 2954 |
CStackMapFrameInfo::AdjustOffsetDelta(i_s2PrevFrameOffset); |
| 2955 |
if (m_u2OffsetDelta + 64 > 127) |
| 2956 |
{ |
| 2957 |
// Frame type is SAME_LOCALS_1_STACK_FRAME_EXTENDED |
| 2958 |
m_u1FrameType = SAME_LOCALS_1_STACK_ITEM_EXTENDED; |
| 2959 |
m_IsExtended = true; |
| 2960 |
} |
| 2961 |
else |
| 2962 |
{ |
| 2963 |
// Frame type is SAME_LOCALS_1_STACK_FRAME. offset_delta is stored in the tag |
| 2964 |
m_u1FrameType = (u1)(m_u2OffsetDelta + 64); // this is safe since m_u2OffsetDelta <= 63 |
| 2965 |
m_IsExtended = false; |
| 2966 |
} |
| 2967 |
} |
| 2968 |
|
| 2969 |
CStackMapFrameInfo* |
| 2970 |
CStackMapSameLocals1StackItemFrameInfo::Clone() const |
| 2971 |
{ |
| 2972 |
return new CStackMapSameLocals1StackItemFrameInfo(*this); |
| 2973 |
} |
| 2974 |
|
| 2975 |
CStackMapSameLocals1StackItemFrameInfo::CStackMapSameLocals1StackItemFrameInfo(const CStackMapSameLocals1StackItemFrameInfo &i_Other) |
| 2976 |
: CStackMapFrameInfo(i_Other), m_Stack(i_Other.m_Stack), m_IsExtended(i_Other.m_IsExtended) |
| 2977 |
{ |
| 2978 |
} |
| 2979 |
|
| 2980 |
//------------------------------------------------------------------------------ |
| 2981 |
CStackMapAppendFrameInfo::CStackMapAppendFrameInfo(u1 i_u1FrameType) |
| 2982 |
: CStackMapFrameInfo(i_u1FrameType) |
| 2983 |
{ |
| 2984 |
} |
| 2985 |
|
| 2986 |
CStackMapAppendFrameInfo::~CStackMapAppendFrameInfo() |
| 2987 |
{ |
| 2988 |
} |
| 2989 |
|
| 2990 |
void |
| 2991 |
CStackMapAppendFrameInfo::Read(CJStream& i_jstream) |
| 2992 |
{ |
| 2993 |
CStackMapFrameInfo::Read(i_jstream); |
| 2994 |
i_jstream >> m_u2OffsetDelta; |
| 2995 |
m_Locals.Read(i_jstream, GetFrameType() - 251); |
| 2996 |
} |
| 2997 |
|
| 2998 |
void |
| 2999 |
CStackMapAppendFrameInfo::Write(CJStream& i_jstream) const |
| 3000 |
{ |
| 3001 |
CStackMapFrameInfo::Write(i_jstream); |
| 3002 |
i_jstream << m_u2OffsetDelta; |
| 3003 |
m_Locals.Write(i_jstream); |
| 3004 |
} |
| 3005 |
|
| 3006 |
u4 |
| 3007 |
CStackMapAppendFrameInfo::GetSize() const |
| 3008 |
{ |
| 3009 |
u4 u4Size = CStackMapFrameInfo::GetSize() |
| 3010 |
+ sizeof(m_u2OffsetDelta) |
| 3011 |
+ m_Locals.GetSize(); |
| 3012 |
return u4Size; |
| 3013 |
} |
| 3014 |
|
| 3015 |
CStackMapFrameInfo* |
| 3016 |
CStackMapAppendFrameInfo::Clone() const |
| 3017 |
{ |
| 3018 |
return new CStackMapAppendFrameInfo(*this); |
| 3019 |
} |
| 3020 |
|
| 3021 |
CStackMapAppendFrameInfo::CStackMapAppendFrameInfo(const CStackMapAppendFrameInfo &i_Other) |
| 3022 |
: CStackMapFrameInfo(i_Other), m_Locals(i_Other.m_Locals) |
| 3023 |
{ |
| 3024 |
} |
| 3025 |
|
| 3026 |
//------------------------------------------------------------------------------ |
| 3027 |
CStackMapFullFrameInfo::CStackMapFullFrameInfo(u1 i_u1FrameType) |
| 3028 |
: CStackMapFrameInfo(i_u1FrameType), m_u2NumberOfLocals(0), m_u2NumberOfStackItems(0) |
| 3029 |
{ |
| 3030 |
} |
| 3031 |
|
| 3032 |
CStackMapFullFrameInfo::~CStackMapFullFrameInfo() |
| 3033 |
{ |
| 3034 |
} |
| 3035 |
|
| 3036 |
void |
| 3037 |
CStackMapFullFrameInfo::Read(CJStream& i_jstream) |
| 3038 |
{ |
| 3039 |
CStackMapFrameInfo::Read(i_jstream); |
| 3040 |
i_jstream >> m_u2OffsetDelta |
| 3041 |
>> m_u2NumberOfLocals; |
| 3042 |
m_Locals.Read(i_jstream, m_u2NumberOfLocals); |
| 3043 |
i_jstream >> m_u2NumberOfStackItems; |
| 3044 |
m_Stack.Read(i_jstream, m_u2NumberOfStackItems); |
| 3045 |
} |
| 3046 |
|
| 3047 |
void |
| 3048 |
CStackMapFullFrameInfo::Write(CJStream& i_jstream) const |
| 3049 |
{ |
| 3050 |
CStackMapFrameInfo::Write(i_jstream); |
| 3051 |
i_jstream << m_u2OffsetDelta |
| 3052 |
<< m_u2NumberOfLocals; |
| 3053 |
m_Locals.Write(i_jstream); |
| 3054 |
i_jstream << m_u2NumberOfStackItems; |
| 3055 |
m_Stack.Write(i_jstream); |
| 3056 |
} |
| 3057 |
|
| 3058 |
u4 |
| 3059 |
CStackMapFullFrameInfo::GetSize() const |
| 3060 |
{ |
| 3061 |
u4 u4Size = CStackMapFrameInfo::GetSize() |
| 3062 |
+ sizeof(m_u2OffsetDelta) |
| 3063 |
+ sizeof(m_u2NumberOfLocals) |
| 3064 |
+ m_Locals.GetSize() |
| 3065 |
+ sizeof(m_u2NumberOfStackItems) |
| 3066 |
+ m_Stack.GetSize(); |
| 3067 |
return u4Size; |
| 3068 |
} |
| 3069 |
|
| 3070 |
CStackMapFrameInfo* |
| 3071 |
CStackMapFullFrameInfo::Clone() const |
| 3072 |
{ |
| 3073 |
return new CStackMapFullFrameInfo(*this); |
| 3074 |
} |
| 3075 |
|
| 3076 |
CStackMapFullFrameInfo::CStackMapFullFrameInfo(const CStackMapFullFrameInfo &i_Other) |
| 3077 |
: CStackMapFrameInfo(i_Other), m_Locals(i_Other.m_Locals), m_Stack(i_Other.m_Stack), |
| 3078 |
m_u2NumberOfLocals(i_Other.m_u2NumberOfLocals), |
| 3079 |
m_u2NumberOfStackItems(i_Other.m_u2NumberOfStackItems) |
| 3080 |
{ |
| 3081 |
} |
| 3082 |
|
| 3083 |
//------------------------------------------------------------------------------ |
| 3084 |
CStackMapTable::~CStackMapTable() |
| 3085 |
{ |
| 3086 |
for (iterator iter = begin(); iter != end(); iter++) |
| 3087 |
{ |
| 3088 |
delete *iter; |
| 3089 |
} |
| 3090 |
} |
| 3091 |
|
| 3092 |
void |
| 3093 |
CStackMapTable::Read(CJStream& i_jstream) |
| 3094 |
{ |
| 3095 |
u2 u2Size; |
| 3096 |
CStackMapFrameInfo* pCurrent; |
| 3097 |
int s2PrevFrameOffset = -1; |
| 3098 |
|
| 3099 |
i_jstream >> u2Size; |
| 3100 |
resize(u2Size); |
| 3101 |
for(u2 u2Ind = 0; u2Ind < u2Size; u2Ind++) |
| 3102 |
{ |
| 3103 |
u1 u1FrameType; |
| 3104 |
i_jstream >> u1FrameType; |
| 3105 |
if (u1FrameType >= 0 && u1FrameType <= 63) |
| 3106 |
{ |
| 3107 |
pCurrent = new CStackMapSameFrameInfo(u1FrameType, false); |
| 3108 |
} |
| 3109 |
else if (u1FrameType >= 64 && u1FrameType <= 127) |
| 3110 |
{ |
| 3111 |
pCurrent = new CStackMapSameLocals1StackItemFrameInfo(u1FrameType, false); |
| 3112 |
} |
| 3113 |
else if (u1FrameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED) |
| 3114 |
{ |
| 3115 |
pCurrent = new CStackMapSameLocals1StackItemFrameInfo(u1FrameType, true); |
| 3116 |
} |
| 3117 |
else if (u1FrameType >= 248 && u1FrameType <= 250) |
| 3118 |
{ |
| 3119 |
pCurrent = new CStackMapChopFrameInfo(u1FrameType); |
| 3120 |
} |
| 3121 |
else if (u1FrameType == SAME_FRAME_EXTENDED) |
| 3122 |
{ |
| 3123 |
pCurrent = new CStackMapSameFrameInfo(u1FrameType, true); |
| 3124 |
} |
| 3125 |
else if (u1FrameType >= 252 && u1FrameType <= 254) |
| 3126 |
{ |
| 3127 |
pCurrent = new CStackMapAppendFrameInfo(u1FrameType); |
| 3128 |
} |
| 3129 |
else if (u1FrameType == FULL_FRAME) |
| 3130 |
{ |
| 3131 |
pCurrent = new CStackMapFullFrameInfo(u1FrameType); |
| 3132 |
} |
| 3133 |
else |
| 3134 |
{ |
| 3135 |
// Unknown frame type |
| 3136 |
throw CJClassFileException(CJClassFileException::X_INTERNAL_ERROR); |
| 3137 |
} |
| 3138 |
|
| 3139 |
pCurrent->Read(i_jstream); |
| 3140 |
pCurrent->SetByteCodeOffset(s2PrevFrameOffset + 1 + pCurrent->m_u2OffsetDelta); |
| 3141 |
(*this)[u2Ind] = pCurrent; |
| 3142 |
s2PrevFrameOffset = pCurrent->GetByteCodeOffset(); |
| 3143 |
} |
| 3144 |
} |
| 3145 |
|
| 3146 |
void |
| 3147 |
CStackMapTable::AdjustOffsetDeltas() |
| 3148 |
{ |
| 3149 |
// Recalculate offset deltas for all frames. This function must be called before |
| 3150 |
// writing the Stack Map Table to the class file or calculating its size |
| 3151 |
CStackMapFrameInfo* pCurrent; |
| 3152 |
int s2PrevFrameOffset = -1; |
| 3153 |
|
| 3154 |
for (u2 u2Ind = 0; u2Ind < size(); u2Ind++) |
| 3155 |
{ |
| 3156 |
pCurrent = (*this)[u2Ind]; |
| 3157 |
pCurrent->AdjustOffsetDelta(s2PrevFrameOffset); |
| 3158 |
s2PrevFrameOffset = pCurrent->GetByteCodeOffset(); |
| 3159 |
} |
| 3160 |
} |
| 3161 |
|
| 3162 |
CStackMapFrameInfo* |
| 3163 |
CStackMapTable::GetFrameAtOffset(u2 i_u2Offset) |
| 3164 |
{ |
| 3165 |
bool found = false; |
| 3166 |
iterator it = begin(); |
| 3167 |
for (; it != end(); ++it) |
| 3168 |
{ |
| 3169 |
if ((*it)->GetByteCodeOffset() == i_u2Offset) |
| 3170 |
{ |
| 3171 |
found = true; |
| 3172 |
break; |
| 3173 |
} |
| 3174 |
} |
| 3175 |
|
| 3176 |
if (found) |
| 3177 |
{ |
| 3178 |
return (*it); |
| 3179 |
} |
| 3180 |
else |
| 3181 |
{ |
| 3182 |
return NULL; |
| 3183 |
} |
| 3184 |
} |
| 3185 |
|
| 3186 |
void |
| 3187 |
CStackMapTable::Write(CJStream& i_jstream) const |
| 3188 |
{ |
| 3189 |
i_jstream << (u2)size(); // the number_of_entries field |
| 3190 |
|
| 3191 |
CStackMapFrameInfo* pCurrent; |
| 3192 |
int s2PrevFrameOffset = -1; |
| 3193 |
|
| 3194 |
for (u2 u2Ind = 0; u2Ind < size(); u2Ind++) |
| 3195 |
{ |
| 3196 |
pCurrent = (*this)[u2Ind]; |
| 3197 |
pCurrent->Write(i_jstream); |
| 3198 |
s2PrevFrameOffset = pCurrent->GetByteCodeOffset(); |
| 3199 |
} |
| 3200 |
} |
| 3201 |
|
| 3202 |
u4 |
| 3203 |
CStackMapTable::GetSize() const |
| 3204 |
{ |
| 3205 |
u4 u4Size = sizeof(u2); // the number_of_entries field |
| 3206 |
for (const_iterator iter = begin(); iter != end(); iter++) |
| 3207 |
{ |
| 3208 |
u4Size += (*iter)->GetSize(); |
| 3209 |
} |
| 3210 |
return u4Size; |
| 3211 |
} |
| 3212 |
|
| 3213 |
CStackMapTable& |
| 3214 |
CStackMapTable::operator = (const CStackMapTable& i_StackMaps) |
| 3215 |
{ |
| 3216 |
for(iterator iter = begin(); iter != end(); iter++) |
| 3217 |
{ |
| 3218 |
delete *iter; |
| 3219 |
} |
| 3220 |
if(!i_StackMaps.empty()) |
| 3221 |
{ |
| 3222 |
const_iterator iterIn; |
| 3223 |
clear(); |
| 3224 |
for(iterIn = i_StackMaps.begin(); iterIn != i_StackMaps.end(); iterIn++) |
| 3225 |
{ |
| 3226 |
push_back((*iterIn)->Clone()); |
| 3227 |
} |
| 3228 |
} |
| 3229 |
return *this; |
| 3230 |
} |
| 3231 |
|
| 3232 |
//------------------------------------------------------------------------------ |
| 3233 |
CStackMapTableAttribute::CStackMapTableAttribute(CJClassFile* i_pClassFile) |
| 3234 |
: CAttributeInfo(i_pClassFile) |
| 3235 |
{ |
| 3236 |
u2 u2NameInd = i_pClassFile->GetConstPool()->Add(new CCPUtf8Info("StackMapTable")); |
| 3237 |
m_u2NameInd = u2NameInd; |
| 3238 |
m_StackMapTable.clear(); |
| 3239 |
} |
| 3240 |
|
| 3241 |
CStackMapTableAttribute::~CStackMapTableAttribute() |
| 3242 |
{ |
| 3243 |
} |
| 3244 |
|
| 3245 |
void |
| 3246 |
CStackMapTableAttribute::Read(CJStream& i_jstream) |
| 3247 |
{ |
| 3248 |
CAttributeInfo::Read(i_jstream); |
| 3249 |
m_StackMapTable.Read(i_jstream); |
| 3250 |
} |
| 3251 |
|
| 3252 |
void |
| 3253 |
CStackMapTableAttribute::Write(CJStream& i_jstream) const |
| 3254 |
{ |
| 3255 |
const u4 u4Length = GetLength() - CAttributeInfo::SizeOf(); |
| 3256 |
i_jstream << m_u2NameInd |
| 3257 |
<< u4Length; |
| 3258 |
m_StackMapTable.Write(i_jstream); |
| 3259 |
} |
| 3260 |
|
| 3261 |
u4 |
| 3262 |
CStackMapTableAttribute::GetSize() const |
| 3263 |
{ |
| 3264 |
return GetLength(); |
| 3265 |
} |
| 3266 |
|
| 3267 |
u4 |
| 3268 |
CStackMapTableAttribute::GetLength() const |
| 3269 |
{ |
| 3270 |
u4 u4Length = CAttributeInfo::SizeOf() |
| 3271 |
+ m_StackMapTable.GetSize(); |
| 3272 |
return u4Length; |
| 3273 |
} |
| 3274 |
|
| 3275 |
void |
| 3276 |
CStackMapTableAttribute::RereadFromBuffer(u1 *i_u1Tbl) |
| 3277 |
{ |
| 3278 |
u2 u2skip = 0; |
| 3279 |
u4 u4attributeLenght = 0; |
| 3280 |
|
| 3281 |
if (i_u1Tbl == NULL) return; |
| 3282 |
|
| 3283 |
u2skip = i_u1Tbl[0]; |
| 3284 |
u2skip <<= 8; |
| 3285 |
u2skip |= i_u1Tbl[1]; |
| 3286 |
|
| 3287 |
u4attributeLenght = i_u1Tbl[2]; |
| 3288 |
u4attributeLenght <<= 8; |
| 3289 |
u4attributeLenght |= i_u1Tbl[3]; |
| 3290 |
u4attributeLenght <<= 8; |
| 3291 |
u4attributeLenght |= i_u1Tbl[4]; |
| 3292 |
u4attributeLenght <<= 8; |
| 3293 |
u4attributeLenght |= i_u1Tbl[5]; |
| 3294 |
m_u4Length = u4attributeLenght; |
| 3295 |
CJMemStream memstream; |
| 3296 |
memstream.Open(&i_u1Tbl[2], u4attributeLenght |
| 3297 |
+ sizeof(u2) /*part of attribute header (its length)*/ |
| 3298 |
+ 2 /*workaround for end buffer checking*/); |
| 3299 |
CJStream mem_jstream(&memstream); |
| 3300 |
//GetStackMapTable().RereadFromBuffer(&i_u1Tbl[6]); |
| 3301 |
this->Read(mem_jstream); |
| 3302 |
} |
| 3303 |
//============================================================================== |
| 2503 |
// CJClassFile implementation |
3304 |
// CJClassFile implementation |
| 2504 |
// |
3305 |
// |
| 2505 |
|
3306 |
|
|
Lines 2544-2555
CJClassFile::Read(CJStream& i_jstream)
Link Here
|
| 2544 |
{ |
3345 |
{ |
| 2545 |
throw CJClassFileException(CJClassFileException::X_BAD_MAGIC); |
3346 |
throw CJClassFileException(CJClassFileException::X_BAD_MAGIC); |
| 2546 |
} |
3347 |
} |
| 2547 |
i_jstream >> m_u2MajorVersion; |
|
|
| 2548 |
if(CJClassFile::MajorVersion < m_u2MajorVersion) |
| 2549 |
{ |
| 2550 |
throw CJClassFileException(CJClassFileException::X_BAD_VERSION); |
| 2551 |
} |
| 2552 |
i_jstream >> m_u2MinorVersion; |
3348 |
i_jstream >> m_u2MinorVersion; |
|
|
3349 |
i_jstream >> m_u2MajorVersion; |
| 2553 |
m_pConstPool->Read(i_jstream); |
3350 |
m_pConstPool->Read(i_jstream); |
| 2554 |
i_jstream >> m_u2AccessFlags |
3351 |
i_jstream >> m_u2AccessFlags |
| 2555 |
>> m_u2ThisClass |
3352 |
>> m_u2ThisClass |
|
Lines 2565-2572
void
Link Here
|
| 2565 |
CJClassFile::Write(CJStream& i_jstream) const |
3362 |
CJClassFile::Write(CJStream& i_jstream) const |
| 2566 |
{ |
3363 |
{ |
| 2567 |
i_jstream << m_u4Magic |
3364 |
i_jstream << m_u4Magic |
| 2568 |
<< m_u2MajorVersion |
3365 |
<< m_u2MinorVersion |
| 2569 |
<< m_u2MinorVersion; |
3366 |
<< m_u2MajorVersion; |
| 2570 |
m_pConstPool->Write(i_jstream); |
3367 |
m_pConstPool->Write(i_jstream); |
| 2571 |
i_jstream << m_u2AccessFlags |
3368 |
i_jstream << m_u2AccessFlags |
| 2572 |
<< m_u2ThisClass |
3369 |
<< m_u2ThisClass |