1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Const string interpolation

This commit is contained in:
Brian Fiete 2022-02-13 10:41:34 -05:00
parent f38cf6a1fd
commit 8ebd7516d8
10 changed files with 167 additions and 40 deletions

View file

@ -1165,7 +1165,7 @@ namespace System
* @param provider The format provider * @param provider The format provider
* @returns This method can fail if the format string is invalid. * @returns This method can fail if the format string is invalid.
*/ */
public Result<void> AppendF(IFormatProvider provider, StringView format, params Object[] args) public Result<void> AppendF(IFormatProvider provider, StringView format, params Span<Object> args)
{ {
if (format.Ptr == null) if (format.Ptr == null)
{ {
@ -1240,7 +1240,7 @@ namespace System
} }
while (ch >= '0' && ch <= '9' && index < 1000000); while (ch >= '0' && ch <= '9' && index < 1000000);
} }
if (index >= args.Count) return FormatError(); if (index >= args.Length) return FormatError();
while (pos < len && (ch = format[pos]) == ' ') pos++; while (pos < len && (ch = format[pos]) == ' ') pos++;
bool leftJustify = false; bool leftJustify = false;
int width = 0; int width = 0;
@ -1340,7 +1340,7 @@ namespace System
return .Ok; return .Ok;
} }
public Result<void> AppendF(StringView format, params Object[] args) public Result<void> AppendF(StringView format, params Span<Object> args)
{ {
return AppendF((IFormatProvider)null, format, params args); return AppendF((IFormatProvider)null, format, params args);
} }
@ -2475,6 +2475,12 @@ namespace System
} }
} }
[Comptime(ConstEval=true)]
public static String ConstF(String format, params Span<Object> args)
{
return new String()..AppendF(format, params args);
}
public static bool Equals(char8* str1, char8* str2) public static bool Equals(char8* str1, char8* str2)
{ {
for (int i = 0; true; i++) for (int i = 0; true; i++)

View file

@ -377,6 +377,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
mBfObjectTypeDef = NULL; mBfObjectTypeDef = NULL;
mChar32TypeDef = NULL; mChar32TypeDef = NULL;
mFloatTypeDef = NULL;
mDoubleTypeDef = NULL; mDoubleTypeDef = NULL;
mMathTypeDef = NULL; mMathTypeDef = NULL;
mArray1TypeDef = NULL; mArray1TypeDef = NULL;
@ -6773,11 +6774,10 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
_GetRequiredType("System.UInt16"); _GetRequiredType("System.UInt16");
_GetRequiredType("System.UInt32"); _GetRequiredType("System.UInt32");
_GetRequiredType("System.UInt64"); _GetRequiredType("System.UInt64");
_GetRequiredType("System.Float");
_GetRequiredType("System.Double");
_GetRequiredType("System.Char8"); _GetRequiredType("System.Char8");
_GetRequiredType("System.Char16"); _GetRequiredType("System.Char16");
mChar32TypeDef = _GetRequiredType("System.Char32"); mChar32TypeDef = _GetRequiredType("System.Char32");
mFloatTypeDef = _GetRequiredType("System.Float");
mDoubleTypeDef = _GetRequiredType("System.Double"); mDoubleTypeDef = _GetRequiredType("System.Double");
mMathTypeDef = _GetRequiredType("System.Math"); mMathTypeDef = _GetRequiredType("System.Math");

View file

@ -347,6 +347,7 @@ public:
BfTypeDef* mBfObjectTypeDef; BfTypeDef* mBfObjectTypeDef;
BfTypeDef* mChar32TypeDef; BfTypeDef* mChar32TypeDef;
BfTypeDef* mFloatTypeDef;
BfTypeDef* mDoubleTypeDef; BfTypeDef* mDoubleTypeDef;
BfTypeDef* mMathTypeDef; BfTypeDef* mMathTypeDef;

View file

@ -3785,11 +3785,6 @@ void BfExprEvaluator::Visit(BfLiteralExpression* literalExpr)
void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolationExpression) void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolationExpression)
{ {
if (IsConstEval())
{
mModule->Fail("Const evaluation of string interpolation not allowed", stringInterpolationExpression);
}
if ((mBfEvalExprFlags & BfEvalExprFlags_StringInterpolateFormat) != 0) if ((mBfEvalExprFlags & BfEvalExprFlags_StringInterpolateFormat) != 0)
{ {
BfVariant variant; BfVariant variant;
@ -3799,6 +3794,37 @@ void BfExprEvaluator::Visit(BfStringInterpolationExpression* stringInterpolation
return; return;
} }
//
{
SetAndRestoreValue<BfEvalExprFlags> prevEvalExprFlag(mBfEvalExprFlags);
if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mConstEvalAttributeTypeDef)))
{
mModule->mAttributeState->mUsed = true;
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
}
if (IsConstEval())
{
auto stringType = mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef);
if (stringType != NULL)
{
SizedArray<BfExpression*, 2> argExprs;
argExprs.Add(stringInterpolationExpression);
BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
BfResolvedArgs argValues(&sizedArgExprs);
ResolveArgValues(argValues, BfResolveArgsFlag_InsideStringInterpolationAlloc);
auto result = MatchMethod(stringInterpolationExpression, NULL, BfTypedValue(stringType), false, false, "ConstF", argValues, BfMethodGenericArguments());
if (result.mType == stringType)
{
mResult = result;
return;
}
}
mModule->Fail("Const evaluation of string interpolation not allowed", stringInterpolationExpression);
}
}
if (stringInterpolationExpression->mAllocNode != NULL) if (stringInterpolationExpression->mAllocNode != NULL)
{ {
auto stringType = mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef)->ToTypeInstance(); auto stringType = mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef)->ToTypeInstance();
@ -7945,10 +7971,10 @@ BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType
if ((mDeferScopeAlloc != NULL) && (wantType == mModule->mContext->mBfObjectType)) if ((mDeferScopeAlloc != NULL) && (wantType == mModule->mContext->mBfObjectType))
{ {
BfAllocTarget allocTarget(mDeferScopeAlloc); BfAllocTarget allocTarget(mDeferScopeAlloc);
argValue = mModule->BoxValue(expr, argValue, wantType, allocTarget); argValue = mModule->BoxValue(expr, argValue, wantType, allocTarget, ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) ? BfCastFlags_WantsConst : BfCastFlags_None);
} }
else else
argValue = mModule->Cast(expr, argValue, wantType); argValue = mModule->Cast(expr, argValue, wantType, ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) ? BfCastFlags_WantsConst : BfCastFlags_None);
} }
} }
} }

View file

@ -892,6 +892,24 @@ BfIRValue BfIRConstHolder::CreateConstBitCast(BfIRValue val, BfIRType type)
return castedVal; return castedVal;
} }
BfIRValue BfIRConstHolder::CreateConstBox(BfIRValue val, BfIRType type)
{
auto constVal = GetConstant(val);
auto box = mTempAlloc.Alloc<BfConstantBox>();
box->mConstType = BfConstType_Box;
BF_ASSERT(val.mId != -1);
box->mTarget = val.mId;
box->mToType = type;
BfIRValue castedVal(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(box));
#ifdef CHECK_CONSTHOLDER
castedVal.mHolder = this;
#endif
BF_ASSERT((void*)GetConstant(castedVal) == (void*)box);
return castedVal;
}
BfIRValue BfIRConstHolder::CreateTypeOf(BfType* type) BfIRValue BfIRConstHolder::CreateTypeOf(BfType* type)
{ {
BfTypeOf_Const* typeOf = mTempAlloc.Alloc<BfTypeOf_Const>(); BfTypeOf_Const* typeOf = mTempAlloc.Alloc<BfTypeOf_Const>();
@ -1635,6 +1653,12 @@ String BfIRBuilder::ToString(BfIRValue irValue)
BfIRValue targetConst(BfIRValueFlags_Const, bitcast->mTarget); BfIRValue targetConst(BfIRValueFlags_Const, bitcast->mTarget);
return ToString(targetConst) + " BitCast to " + ToString(bitcast->mToType); return ToString(targetConst) + " BitCast to " + ToString(bitcast->mToType);
} }
else if (constant->mConstType == BfConstType_Box)
{
auto box = (BfConstantBox*)constant;
BfIRValue targetConst(BfIRValueFlags_Const, box->mTarget);
return ToString(targetConst) + " box to " + ToString(box->mToType);
}
else if (constant->mConstType == BfConstType_GEP32_2) else if (constant->mConstType == BfConstType_GEP32_2)
{ {
auto gepConst = (BfConstantGEP32_2*)constant; auto gepConst = (BfConstantGEP32_2*)constant;
@ -1825,6 +1849,11 @@ String BfIRBuilder::ToString(BfIRType irType)
{ {
return StrFormat("TypeInstPtr#%d:%s", irType.mId, mModule->TypeToString(mModule->mContext->mTypes[irType.mId]).c_str()); return StrFormat("TypeInstPtr#%d:%s", irType.mId, mModule->TypeToString(mModule->mContext->mTypes[irType.mId]).c_str());
} }
else if (irType.mKind == BfIRTypeData::TypeKind_SizedArray)
{
auto sizedArrayType = (BfConstantSizedArrayType*)GetConstantById(irType.mId);
return StrFormat("%s[%d]", ToString(sizedArrayType->mType).c_str(), (int)sizedArrayType->mLength);
}
else else
{ {
return "Type ???"; return "Type ???";

View file

@ -138,7 +138,8 @@ enum BfConstType
BfConstType_ArrayZero, BfConstType_ArrayZero,
BfConstType_ArrayZero8, BfConstType_ArrayZero8,
BfConstType_Undef, BfConstType_Undef,
BfConstType_SizedArrayType BfConstType_SizedArrayType,
BfConstType_Box
}; };
enum BfIRValueFlags : uint8 enum BfIRValueFlags : uint8
@ -856,6 +857,13 @@ struct BfConstantBitCast
BfIRType mToType; BfIRType mToType;
}; };
struct BfConstantBox
{
BfConstType mConstType;
int mTarget;
BfIRType mToType;
};
struct BfConstantPtrToInt struct BfConstantPtrToInt
{ {
BfConstType mConstType; BfConstType mConstType;
@ -946,6 +954,7 @@ public:
BfIRValue CreateConstArrayZero(BfIRType type, int count); BfIRValue CreateConstArrayZero(BfIRType type, int count);
BfIRValue CreateConstArrayZero(int count); BfIRValue CreateConstArrayZero(int count);
BfIRValue CreateConstBitCast(BfIRValue val, BfIRType type); BfIRValue CreateConstBitCast(BfIRValue val, BfIRType type);
BfIRValue CreateConstBox(BfIRValue val, BfIRType type);
BfIRValue CreateTypeOf(BfType* type); BfIRValue CreateTypeOf(BfType* type);
BfIRValue CreateTypeOf(BfType* type, BfIRValue typeData); BfIRValue CreateTypeOf(BfType* type, BfIRValue typeData);
BfIRValue GetUndefConstValue(BfIRType type); BfIRValue GetUndefConstValue(BfIRType type);

View file

@ -240,13 +240,6 @@ void BfMethodState::LocalDefined(BfLocalVariable* localVar, int fieldIdx, BfLoca
{ {
return; return;
} }
//BF_ASSERT(localVarMethodState == this);
// if (assignKind == BfLocalVarAssignKind_None)
// assignKind = ((localVarMethodState->mLeftBlockCond) && ((mDeferredLocalAssignData != NULL) || isFromDeferredAssignData)) ? BfLocalVarAssignKind_Conditional : BfLocalVarAssignKind_Unconditional;
//
// //assignKind = BfLocalVarAssignKind_Unconditional;
if (localVar->mAssignedKind == BfLocalVarAssignKind_None) if (localVar->mAssignedKind == BfLocalVarAssignKind_None)
{ {
@ -10108,8 +10101,9 @@ void BfModule::EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool al
BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfType* toType, const BfAllocTarget& allocTarget, BfCastFlags castFlags) BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfType* toType, const BfAllocTarget& allocTarget, BfCastFlags castFlags)
{ {
bool callDtor = (castFlags & BfCastFlags_NoBoxDtor) == 0; bool callDtor = (castFlags & BfCastFlags_NoBoxDtor) == 0;
bool wantConst = ((castFlags & BfCastFlags_WantsConst) != 0) && (typedVal.mValue.IsConst());
if (mBfIRBuilder->mIgnoreWrites) if ((mBfIRBuilder->mIgnoreWrites) && (!wantConst))
{ {
if (toType == mContext->mBfObjectType) if (toType == mContext->mBfObjectType)
return BfTypedValue(mBfIRBuilder->GetFakeVal(), toType); return BfTypedValue(mBfIRBuilder->GetFakeVal(), toType);
@ -10241,12 +10235,15 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
if ((toType == NULL) || (toType == mContext->mBfObjectType) || (isBoxedType) || (alreadyCheckedCast) || (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance))) if ((toType == NULL) || (toType == mContext->mBfObjectType) || (isBoxedType) || (alreadyCheckedCast) || (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance)))
{ {
if (mBfIRBuilder->mIgnoreWrites) if ((mBfIRBuilder->mIgnoreWrites) && (!wantConst))
return BfTypedValue(mBfIRBuilder->GetFakeVal(), (toType != NULL) ? toType : CreateBoxedType(typedVal.mType)); return BfTypedValue(mBfIRBuilder->GetFakeVal(), (toType != NULL) ? toType : CreateBoxedType(typedVal.mType));
auto boxedType = CreateBoxedType(typedVal.mType); auto boxedType = CreateBoxedType(typedVal.mType);
mBfIRBuilder->PopulateType(boxedType); mBfIRBuilder->PopulateType(boxedType);
if (wantConst)
return BfTypedValue(mBfIRBuilder->CreateConstBox(typedVal.mValue, mBfIRBuilder->MapType(boxedType)), boxedType);
AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields); AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
auto allocaInst = AllocFromType(boxedType, allocTarget, BfIRValue(), BfIRValue(), 0, callDtor ? BfAllocFlags_None : BfAllocFlags_NoDtorCall); auto allocaInst = AllocFromType(boxedType, allocTarget, BfIRValue(), BfIRValue(), 0, callDtor ? BfAllocFlags_None : BfAllocFlags_NoDtorCall);

View file

@ -5680,6 +5680,7 @@ BfStatement* BfReducer::CreateAttributedStatement(BfTokenNode* tokenNode)
if ((checkNode->IsA<BfObjectCreateExpression>()) || if ((checkNode->IsA<BfObjectCreateExpression>()) ||
(checkNode->IsA<BfInvocationExpression>()) || (checkNode->IsA<BfInvocationExpression>()) ||
(checkNode->IsA<BfVariableDeclaration>()) || (checkNode->IsA<BfVariableDeclaration>()) ||
(checkNode->IsA<BfStringInterpolationExpression>()) ||
(checkNode->IsA<BfBlock>())) (checkNode->IsA<BfBlock>()))
{ {
BfAttributedStatement* attribStmt = mAlloc->Alloc<BfAttributedStatement>(); BfAttributedStatement* attribStmt = mAlloc->Alloc<BfAttributedStatement>();
@ -5723,6 +5724,7 @@ BfExpression* BfReducer::CreateAttributedExpression(BfTokenNode* tokenNode, bool
if ((expr->IsA<BfObjectCreateExpression>()) || if ((expr->IsA<BfObjectCreateExpression>()) ||
(expr->IsA<BfInvocationExpression>()) || (expr->IsA<BfInvocationExpression>()) ||
(expr->IsA<BfVariableDeclaration>()) || (expr->IsA<BfVariableDeclaration>()) ||
(expr->IsA<BfStringInterpolationExpression>()) ||
(expr->IsA<BfBlock>())) (expr->IsA<BfBlock>()))
{ {
BfAttributedExpression* attribExpr = mAlloc->Alloc<BfAttributedExpression>(); BfAttributedExpression* attribExpr = mAlloc->Alloc<BfAttributedExpression>();

View file

@ -3340,6 +3340,13 @@ BfType* CeContext::GetBfType(int typeId)
return NULL; return NULL;
} }
BfType* CeContext::GetBfType(BfIRType irType)
{
if (irType.mKind == BfIRTypeData::TypeKind_TypeId)
return GetBfType(irType.mId);
return NULL;
}
void CeContext::PrepareConstStructEntry(CeConstStructData& constEntry) void CeContext::PrepareConstStructEntry(CeConstStructData& constEntry)
{ {
if (constEntry.mHash.IsZero()) if (constEntry.mHash.IsZero())
@ -3479,6 +3486,8 @@ bool CeContext::GetCustomAttribute(BfCustomAttributes* customAttributes, int att
bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* constant, BfType* type, bool isParams) bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* constant, BfType* type, bool isParams)
{ {
int ptrSize = mCeMachine->mCeModule->mSystem->mPtrSize;
switch (constant->mTypeCode) switch (constant->mTypeCode)
{ {
case BfTypeCode_Int8: case BfTypeCode_Int8:
@ -3502,7 +3511,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
CE_GETC(int64) = constant->mInt64; CE_GETC(int64) = constant->mInt64;
return true; return true;
case BfTypeCode_NullPtr: case BfTypeCode_NullPtr:
if (mCeMachine->mCeModule->mSystem->mPtrSize == 4) if (ptrSize == 4)
CE_GETC(int32) = 0; CE_GETC(int32) = 0;
else else
CE_GETC(int64) = 0; CE_GETC(int64) = 0;
@ -3522,7 +3531,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
auto elementType = type->GetUnderlyingType(); auto elementType = type->GetUnderlyingType();
auto toPtr = CeMalloc(elementType->mSize); auto toPtr = CeMalloc(elementType->mSize);
addr_ce toAddr = (addr_ce)(toPtr - mMemory.mVals); addr_ce toAddr = (addr_ce)(toPtr - mMemory.mVals);
if (mCeMachine->mCeModule->mSystem->mPtrSize == 4) if (ptrSize == 4)
CE_GETC(int32) = (int32)toAddr; CE_GETC(int32) = (int32)toAddr;
else else
CE_GETC(int64) = (int64)toAddr; CE_GETC(int64) = (int64)toAddr;
@ -3560,7 +3569,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
return false; return false;
} }
if (mCeMachine->mCeModule->mSystem->mPtrSize == 4) if (ptrSize == 4)
CE_GETC(int32) = arrayAddr; CE_GETC(int32) = arrayAddr;
else else
CE_GETC(int64) = arrayAddr; CE_GETC(int64) = arrayAddr;
@ -3581,7 +3590,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
return false; return false;
} }
if (mCeMachine->mCeModule->mSystem->mPtrSize == 4) if (ptrSize == 4)
{ {
CE_GETC(int32) = elemsAddr; CE_GETC(int32) = elemsAddr;
addr += 4; addr += 4;
@ -3662,7 +3671,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
if (type->IsPointer()) if (type->IsPointer())
{ {
if (mCeMachine->mCeModule->mSystem->mPtrSize == 4) if (ptrSize == 4)
CE_GETC(int32) = constAggData->mCEAddr; CE_GETC(int32) = constAggData->mCEAddr;
else else
CE_GETC(int64) = constAggData->mCEAddr; CE_GETC(int64) = constAggData->mCEAddr;
@ -3678,11 +3687,38 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
if (constant->mConstType == BfConstType_BitCast) if (constant->mConstType == BfConstType_BitCast)
{ {
auto constBitCast = (BfConstantBitCast*)constant; auto constBitCast = (BfConstantBitCast*)constant;
auto constTarget = module->mBfIRBuilder->GetConstantById(constBitCast->mTarget); auto constTarget = module->mBfIRBuilder->GetConstantById(constBitCast->mTarget);
return WriteConstant(module, addr, constTarget, type); return WriteConstant(module, addr, constTarget, type);
} }
if (constant->mConstType == BfConstType_Box)
{
auto constBox = (BfConstantBox*)constant;
auto boxedType = GetBfType(constBox->mToType);
if (boxedType == NULL)
return false;
auto boxedTypeInst = boxedType->ToTypeInstance();
if (boxedTypeInst == NULL)
return false;
module->PopulateType(boxedTypeInst);
if (boxedTypeInst->mFieldInstances.IsEmpty())
return false;
auto& fieldInstance = boxedTypeInst->mFieldInstances.back();
auto boxedMem = CeMalloc(boxedTypeInst->mInstSize);
memset(boxedMem, 0, ptrSize*2);
*(int32*)boxedMem = boxedTypeInst->mTypeId;
auto constTarget = module->mBfIRBuilder->GetConstantById(constBox->mTarget);
WriteConstant(module, boxedMem - mMemory.mVals + fieldInstance.mDataOffset, constTarget, fieldInstance.mResolvedType);
if (ptrSize == 4)
CE_GETC(int32) = (int32)(boxedMem - mMemory.mVals);
else
CE_GETC(int64) = (int64)(boxedMem - mMemory.mVals);
return true;
}
if (constant->mConstType == BfConstType_PtrToInt) if (constant->mConstType == BfConstType_PtrToInt)
{ {
auto ptrToIntConst = (BfConstantPtrToInt*)constant; auto ptrToIntConst = (BfConstantPtrToInt*)constant;
@ -3711,7 +3747,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
int stringId = atoi(globalVar->mName + 11); int stringId = atoi(globalVar->mName + 11);
addr_ce strAddr = GetString(stringId) + stringTypeInst->mInstSize; addr_ce strAddr = GetString(stringId) + stringTypeInst->mInstSize;
if (mCeMachine->mCeModule->mSystem->mPtrSize == 4) if (ptrSize == 4)
CE_GETC(int32) = strAddr; CE_GETC(int32) = strAddr;
else else
CE_GETC(int64) = strAddr; CE_GETC(int64) = strAddr;
@ -3727,7 +3763,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
{ {
int stringId = atoi(globalVar->mName + 10); int stringId = atoi(globalVar->mName + 10);
addr_ce strAddr = GetString(stringId); addr_ce strAddr = GetString(stringId);
if (mCeMachine->mCeModule->mSystem->mPtrSize == 4) if (ptrSize == 4)
CE_GETC(int32) = strAddr; CE_GETC(int32) = strAddr;
else else
CE_GETC(int64) = strAddr; CE_GETC(int64) = strAddr;
@ -3745,7 +3781,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
strAddr += stringTypeInst->mInstSize; strAddr += stringTypeInst->mInstSize;
} }
if (mCeMachine->mCeModule->mSystem->mPtrSize == 4) if (ptrSize == 4)
CE_GETC(int32) = strAddr; CE_GETC(int32) = strAddr;
else else
CE_GETC(int64) = strAddr; CE_GETC(int64) = strAddr;
@ -3756,7 +3792,7 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
{ {
auto constTypeOf = (BfTypeOf_Const*)constant; auto constTypeOf = (BfTypeOf_Const*)constant;
addr_ce typeAddr = GetReflectType(constTypeOf->mType->mTypeId); addr_ce typeAddr = GetReflectType(constTypeOf->mType->mTypeId);
if (mCeMachine->mCeModule->mSystem->mPtrSize == 4) if (ptrSize == 4)
CE_GETC(int32) = typeAddr; CE_GETC(int32) = typeAddr;
else else
CE_GETC(int64) = typeAddr; CE_GETC(int64) = typeAddr;
@ -5397,6 +5433,18 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
memcpy(memStart + strAddr, str, count + 1); memcpy(memStart + strAddr, str, count + 1);
result = count; result = count;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Float_ToString)
{
int32& result = *(int32*)((uint8*)stackPtr + 0);
float val = *(float*)((uint8*)stackPtr + 4);
addr_ce strAddr = *(addr_ce*)((uint8*)stackPtr + 4 + 4);
char str[256];
int count = FloatToString(val, str);
CE_CHECKADDR(strAddr, count + 1);
memcpy(memStart + strAddr, str, count + 1);
result = count;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_Create) else if (checkFunction->mFunctionKind == CeFunctionKind_BfpDirectory_Create)
{ {
addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0); addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 0);
@ -8176,6 +8224,13 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
if (methodDef->mName == "ToString") if (methodDef->mName == "ToString")
ceFunction->mFunctionKind = CeFunctionKind_Double_ToString; ceFunction->mFunctionKind = CeFunctionKind_Double_ToString;
} }
else if (owner->IsInstanceOf(mCeModule->mCompiler->mFloatTypeDef))
{
if (methodDef->mName == "ftoa")
ceFunction->mFunctionKind = CeFunctionKind_Double_Ftoa;
if (methodDef->mName == "ToString")
ceFunction->mFunctionKind = CeFunctionKind_Float_ToString;
}
else if (owner->IsInstanceOf(mCeModule->mCompiler->mMathTypeDef)) else if (owner->IsInstanceOf(mCeModule->mCompiler->mMathTypeDef))
{ {
if (methodDef->mName == "Abs") if (methodDef->mName == "Abs")

View file

@ -398,6 +398,7 @@ enum CeFunctionKind
CeFunctionKind_Double_Strtod, CeFunctionKind_Double_Strtod,
CeFunctionKind_Double_Ftoa, CeFunctionKind_Double_Ftoa,
CeFunctionKind_Double_ToString, CeFunctionKind_Double_ToString,
CeFunctionKind_Float_ToString,
CeFunctionKind_Math_Abs, CeFunctionKind_Math_Abs,
CeFunctionKind_Math_Acos, CeFunctionKind_Math_Acos,
@ -900,6 +901,7 @@ public:
addr_ce GetString(const StringImpl& str); addr_ce GetString(const StringImpl& str);
addr_ce GetConstantData(BeConstant* constant); addr_ce GetConstantData(BeConstant* constant);
BfType* GetBfType(int typeId); BfType* GetBfType(int typeId);
BfType* GetBfType(BfIRType irType);
void PrepareConstStructEntry(CeConstStructData& constStructData); void PrepareConstStructEntry(CeConstStructData& constStructData);
bool CheckMemory(addr_ce addr, int32 size); bool CheckMemory(addr_ce addr, int32 size);
bool GetStringFromAddr(addr_ce strInstAddr, StringImpl& str); bool GetStringFromAddr(addr_ce strInstAddr, StringImpl& str);