blob: 5bc3152c49b597739953a1037f600e3ae1fce446 [file] [log] [blame]
//-------------------------------------------------------------------------------------------------------
// 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);
};