BeContext.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #include "BeContext.h"
  2. USING_NS_BF;
  3. BeContext::BeContext()
  4. {
  5. mPointerSize = 8;
  6. for (int primIdx = 0; primIdx < (int)BeTypeCode_COUNT; primIdx++)
  7. mPrimitiveTypes[primIdx] = NULL;
  8. }
  9. void BeContext::NotImpl()
  10. {
  11. BF_FATAL("Not implemented");
  12. }
  13. BeType* BeContext::GetPrimitiveType(BeTypeCode typeCode)
  14. {
  15. if (typeCode == BeTypeCode_NullPtr)
  16. {
  17. return GetPointerTo(GetPrimitiveType(BeTypeCode_None));
  18. }
  19. if (mPrimitiveTypes[(int)typeCode] != NULL)
  20. return mPrimitiveTypes[(int)typeCode];
  21. BeType* primType = mTypes.Alloc<BeType>();
  22. primType->mTypeCode = typeCode;
  23. switch (typeCode)
  24. {
  25. case BeTypeCode_None:
  26. primType->mSize = 0;
  27. primType->mAlign = 0;
  28. break;
  29. case BeTypeCode_NullPtr:
  30. primType->mSize = primType->mAlign = mPointerSize;
  31. break;
  32. case BeTypeCode_Boolean:
  33. primType->mSize = primType->mAlign = 1;
  34. break;
  35. case BeTypeCode_Int8:
  36. primType->mSize = primType->mAlign = 1;
  37. break;
  38. case BeTypeCode_Int16:
  39. primType->mSize = primType->mAlign = 2;
  40. break;
  41. case BeTypeCode_Int32:
  42. primType->mSize = primType->mAlign = 4;
  43. break;
  44. case BeTypeCode_Int64:
  45. primType->mSize = primType->mAlign = 8;
  46. break;
  47. case BeTypeCode_Float:
  48. primType->mSize = primType->mAlign = 4;
  49. break;
  50. case BeTypeCode_Double:
  51. primType->mSize = primType->mAlign = 8;
  52. break;
  53. }
  54. mPrimitiveTypes[(int)typeCode] = primType;
  55. return primType;
  56. }
  57. BeStructType* BeContext::CreateStruct(const StringImpl& name)
  58. {
  59. BeStructType* structType = mTypes.Alloc<BeStructType>();
  60. structType->mContext = this;
  61. structType->mTypeCode = BeTypeCode_Struct;
  62. structType->mName = name;
  63. structType->mIsOpaque = true;
  64. return structType;
  65. }
  66. BePointerType* BeContext::GetPointerTo(BeType* beType)
  67. {
  68. if (beType->mPointerType == NULL)
  69. {
  70. BePointerType* pointerType = mTypes.Alloc<BePointerType>();
  71. pointerType->mTypeCode = BeTypeCode_Pointer;
  72. pointerType->mElementType = beType;
  73. pointerType->mSize = mPointerSize;
  74. pointerType->mAlign = mPointerSize;
  75. beType->mPointerType = pointerType;
  76. /*if (beType->IsSizedArray())
  77. {
  78. auto sizedArrayType = (BeSizedArrayType*)beType;
  79. pointerType->mElementType = sizedArrayType->mElementType;
  80. }*/
  81. }
  82. return beType->mPointerType;
  83. }
  84. void BeContext::SetStructBody(BeStructType* structType, const SizedArrayImpl<BeType*>& types, bool packed)
  85. {
  86. BF_ASSERT(structType->mMembers.IsEmpty());
  87. int dataPos = 0;
  88. for (auto& beType : types)
  89. {
  90. if (!packed)
  91. {
  92. int alignSize = beType->mAlign;
  93. dataPos = (dataPos + (alignSize - 1)) & ~(alignSize - 1);
  94. }
  95. BF_ASSERT(beType->mSize >= 0);
  96. BeStructMember member;
  97. member.mType = beType;
  98. member.mByteOffset = dataPos;
  99. dataPos += beType->mSize;
  100. structType->mAlign = std::max(structType->mAlign, beType->mAlign);
  101. structType->mMembers.push_back(member);
  102. }
  103. if (!packed)
  104. {
  105. int alignSize = structType->mAlign;
  106. dataPos = (dataPos + (alignSize - 1)) & ~(alignSize - 1);
  107. }
  108. structType->mSize = dataPos;
  109. structType->mIsPacked = packed;
  110. structType->mIsOpaque = false;
  111. }
  112. BeSizedArrayType* BeContext::CreateSizedArrayType(BeType* type, int length)
  113. {
  114. auto arrayType = mTypes.Alloc<BeSizedArrayType>();
  115. arrayType->mContext = this;
  116. arrayType->mTypeCode = BeTypeCode_SizedArray;
  117. arrayType->mElementType = type;
  118. arrayType->mLength = length;
  119. arrayType->mSize = type->mSize * length;
  120. arrayType->mAlign = type->mAlign;
  121. return arrayType;
  122. }
  123. BeFunctionType* BeContext::CreateFunctionType(BeType* returnType, const SizedArrayImpl<BeType*>& paramTypes, bool isVarArg)
  124. {
  125. auto funcType = mTypes.Alloc<BeFunctionType>();
  126. funcType->mTypeCode = BeTypeCode_Function;
  127. funcType->mReturnType = returnType;
  128. for (auto& paramType : paramTypes)
  129. {
  130. BeFunctionTypeParam funcParam;
  131. funcParam.mType = paramType;
  132. funcType->mParams.push_back(funcParam);
  133. }
  134. funcType->mIsVarArg = isVarArg;
  135. return funcType;
  136. }
  137. bool BeContext::AreTypesEqual(BeType* lhs, BeType* rhs)
  138. {
  139. if (lhs == rhs)
  140. return true;
  141. if (lhs->mTypeCode != rhs->mTypeCode)
  142. return false;
  143. switch (lhs->mTypeCode)
  144. {
  145. case BeTypeCode_None:
  146. case BeTypeCode_NullPtr:
  147. case BeTypeCode_Boolean:
  148. case BeTypeCode_Int8:
  149. case BeTypeCode_Int16:
  150. case BeTypeCode_Int32:
  151. case BeTypeCode_Int64:
  152. case BeTypeCode_Float:
  153. case BeTypeCode_Double:
  154. return true;
  155. case BeTypeCode_Pointer:
  156. return AreTypesEqual(((BePointerType*)lhs)->mElementType, ((BePointerType*)rhs)->mElementType);
  157. }
  158. return false;
  159. }