BeContext.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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. case BeTypeCode_M128:
  54. primType->mSize = primType->mAlign = 16;
  55. break;
  56. case BeTypeCode_M256:
  57. primType->mSize = primType->mAlign = 32;
  58. break;
  59. case BeTypeCode_M512:
  60. primType->mSize = primType->mAlign = 64;
  61. break;
  62. }
  63. mPrimitiveTypes[(int)typeCode] = primType;
  64. return primType;
  65. }
  66. BeType* BeContext::GetVoidPtrType()
  67. {
  68. return GetPointerTo(GetPrimitiveType(BeTypeCode_None));
  69. }
  70. BeStructType* BeContext::CreateStruct(const StringImpl& name)
  71. {
  72. BeStructType* structType = mTypes.Alloc<BeStructType>();
  73. structType->mContext = this;
  74. structType->mTypeCode = BeTypeCode_Struct;
  75. structType->mName = name;
  76. structType->mIsOpaque = true;
  77. return structType;
  78. }
  79. BeStructType* BeContext::CreateStruct(const SizedArrayImpl<BeType*>& types)
  80. {
  81. BeStructType** valuePtr = NULL;
  82. if (mAnonymousStructMap.TryGetValueWith(types, &valuePtr))
  83. return *valuePtr;
  84. Array<BeType*> key;
  85. for (auto type : types)
  86. key.Add(type);
  87. BeStructType* structType = CreateStruct("");
  88. SetStructBody(structType, types, false);
  89. mAnonymousStructMap.TryAdd(key, structType);
  90. return structType;
  91. }
  92. BePointerType* BeContext::GetPointerTo(BeType* beType)
  93. {
  94. if (beType->mPointerType == NULL)
  95. {
  96. BePointerType* pointerType = mTypes.Alloc<BePointerType>();
  97. pointerType->mTypeCode = BeTypeCode_Pointer;
  98. pointerType->mElementType = beType;
  99. pointerType->mSize = mPointerSize;
  100. pointerType->mAlign = mPointerSize;
  101. beType->mPointerType = pointerType;
  102. /*if (beType->IsSizedArray())
  103. {
  104. auto sizedArrayType = (BeSizedArrayType*)beType;
  105. pointerType->mElementType = sizedArrayType->mElementType;
  106. }*/
  107. }
  108. return beType->mPointerType;
  109. }
  110. void BeContext::SetStructBody(BeStructType* structType, const SizedArrayImpl<BeType*>& types, bool packed)
  111. {
  112. BF_ASSERT(structType->mMembers.IsEmpty());
  113. int dataPos = 0;
  114. for (auto& beType : types)
  115. {
  116. if (!packed)
  117. {
  118. int alignSize = beType->mAlign;
  119. dataPos = (dataPos + (alignSize - 1)) & ~(alignSize - 1);
  120. }
  121. BF_ASSERT(beType->mSize >= 0);
  122. BeStructMember member;
  123. member.mType = beType;
  124. member.mByteOffset = dataPos;
  125. dataPos += beType->mSize;
  126. if (packed)
  127. structType->mAlign = 1;
  128. else
  129. structType->mAlign = std::max(structType->mAlign, beType->mAlign);
  130. structType->mMembers.push_back(member);
  131. }
  132. if (!packed)
  133. {
  134. int alignSize = structType->mAlign;
  135. dataPos = (dataPos + (alignSize - 1)) & ~(alignSize - 1);
  136. }
  137. structType->mSize = dataPos;
  138. structType->mIsPacked = packed;
  139. structType->mIsOpaque = false;
  140. }
  141. BeSizedArrayType* BeContext::CreateSizedArrayType(BeType* type, int length)
  142. {
  143. auto arrayType = mTypes.Alloc<BeSizedArrayType>();
  144. arrayType->mContext = this;
  145. arrayType->mTypeCode = BeTypeCode_SizedArray;
  146. arrayType->mElementType = type;
  147. arrayType->mLength = length;
  148. arrayType->mSize = type->GetStride() * length;
  149. arrayType->mAlign = type->mAlign;
  150. return arrayType;
  151. }
  152. BeVectorType* BeContext::CreateVectorType(BeType* type, int length)
  153. {
  154. auto arrayType = mTypes.Alloc<BeVectorType>();
  155. arrayType->mContext = this;
  156. arrayType->mTypeCode = BeTypeCode_Vector;
  157. arrayType->mElementType = type;
  158. arrayType->mLength = length;
  159. arrayType->mSize = type->GetStride() * length;
  160. arrayType->mAlign = type->mAlign;
  161. return arrayType;
  162. }
  163. BeFunctionType* BeContext::CreateFunctionType(BeType* returnType, const SizedArrayImpl<BeType*>& paramTypes, bool isVarArg)
  164. {
  165. auto funcType = mTypes.Alloc<BeFunctionType>();
  166. funcType->mTypeCode = BeTypeCode_Function;
  167. funcType->mReturnType = returnType;
  168. for (auto& paramType : paramTypes)
  169. {
  170. BeFunctionTypeParam funcParam;
  171. funcParam.mType = paramType;
  172. funcType->mParams.push_back(funcParam);
  173. }
  174. funcType->mIsVarArg = isVarArg;
  175. return funcType;
  176. }
  177. bool BeContext::AreTypesEqual(BeType* lhs, BeType* rhs)
  178. {
  179. if (lhs == rhs)
  180. return true;
  181. if (lhs->mTypeCode != rhs->mTypeCode)
  182. return false;
  183. switch (lhs->mTypeCode)
  184. {
  185. case BeTypeCode_None:
  186. case BeTypeCode_NullPtr:
  187. case BeTypeCode_Boolean:
  188. case BeTypeCode_Int8:
  189. case BeTypeCode_Int16:
  190. case BeTypeCode_Int32:
  191. case BeTypeCode_Int64:
  192. case BeTypeCode_Float:
  193. case BeTypeCode_Double:
  194. return true;
  195. case BeTypeCode_Pointer:
  196. return AreTypesEqual(((BePointerType*)lhs)->mElementType, ((BePointerType*)rhs)->mElementType);
  197. case BeTypeCode_SizedArray:
  198. {
  199. auto lhsSizedArray = (BeSizedArrayType*)lhs;
  200. auto rhsSizedArray = (BeSizedArrayType*)rhs;
  201. if (lhsSizedArray->mLength != rhsSizedArray->mLength)
  202. return false;
  203. return AreTypesEqual(lhsSizedArray->mElementType, rhsSizedArray->mElementType);
  204. }
  205. case BeTypeCode_Vector:
  206. {
  207. auto lhsSizedArray = (BeVectorType*)lhs;
  208. auto rhsSizedArray = (BeVectorType*)rhs;
  209. if (lhsSizedArray->mLength != rhsSizedArray->mLength)
  210. return false;
  211. return AreTypesEqual(lhsSizedArray->mElementType, rhsSizedArray->mElementType);
  212. }
  213. }
  214. return false;
  215. }