-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathCaseNode.h
127 lines (106 loc) · 3.42 KB
/
CaseNode.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#pragma once
using namespace JsUtil;
/*
* CaseNode - represents the case statements (not the case block) in the switch statement
*/
class CaseNode
{
private:
uint32 offset; // offset - indicates the bytecode offset of the case instruction
uint32 targetOffset; // targetOffset - indicates the bytecode offset of the target instruction (case block)
IR::BranchInstr* caseInstr; // caseInstr - stores the case instruction
IR::Opnd* lowerBound; // lowerBound - used for integer cases
int32 GetIntConst(IR::Opnd* opnd)
{
Assert(IsIntConst(opnd));
return opnd->IsIntConstOpnd() ? opnd->AsIntConstOpnd()->AsInt32() : opnd->GetStackSym()->GetIntConstValue();
}
bool IsIntConst(IR::Opnd* opnd)
{
return opnd->IsIntConstOpnd() || opnd->GetStackSym()->IsIntConst();
}
bool IsStrConst(IR::Opnd* opnd)
{
return opnd->GetStackSym()->m_isStrConst;
}
public:
CaseNode(IR::BranchInstr* caseInstr, uint32 offset, uint32 targetOffset, IR::Opnd* lowerBound = nullptr)
: caseInstr(caseInstr),
offset(offset),
targetOffset(targetOffset),
lowerBound(lowerBound)
{
}
int32 GetUpperBoundIntConst()
{
AssertMsg(IsUpperBoundIntConst(), "Source2 operand is not an integer constant");
return GetIntConst(GetUpperBound());
}
JITJavascriptString* GetUpperBoundStringConstLocal()
{
AssertMsg(IsUpperBoundStrConst(), "Upper bound operand is not a string constant");
return JITJavascriptString::FromVar(GetUpperBound()->GetStackSym()->GetConstAddress(true));
}
JITJavascriptString* GetUpperBoundStrConst()
{
AssertMsg(IsUpperBoundStrConst(), "Upper bound operand is not a string constant");
return static_cast<JITJavascriptString*>(GetUpperBound()->GetStackSym()->GetConstAddress(false));
}
bool IsUpperBoundIntConst()
{
return IsIntConst(GetUpperBound());
}
bool IsUpperBoundStrConst()
{
return IsStrConst(GetUpperBound());
}
int32 GetLowerBoundIntConst()
{
AssertMsg(IsLowerBoundIntConst(), "LowerBound is not an integer constant");
return GetIntConst(lowerBound);
}
bool IsLowerBoundIntConst()
{
return IsIntConst(lowerBound);
}
bool IsLowerBoundStrConst()
{
return IsStrConst(lowerBound);
}
uint32 GetOffset()
{
return offset;
}
uint32 GetTargetOffset()
{
return targetOffset;
}
IR::Opnd* GetUpperBound()
{
return caseInstr->GetSrc2();
}
IR::Opnd* GetLowerBound()
{
return lowerBound;
}
void SetLowerBound(IR::Opnd* lowerBound)
{
this->lowerBound = lowerBound;
}
IR::BranchInstr* GetCaseInstr()
{
return caseInstr;
}
};
template <>
struct DefaultComparer<CaseNode *>
{
public:
static int Compare(CaseNode* caseNode1, CaseNode* caseNode2);
static bool Equals(CaseNode* x, CaseNode* y);
static uint GetHashCode(CaseNode * caseNode);
};