CaseNode.h 3.4 KB

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