From 15c3ad98de2bb92763e38acf7ea6064f95c6c0e1 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sat, 4 Apr 2020 12:14:52 -0700 Subject: [PATCH] Changed array to Ordered instead of CRepr --- BeefLibs/corlib/src/Array.bf | 11 ++--- IDE/mintest/minlib/src/System/Array.bf | 58 +++++++++++++++++++++++- IDEHelper/Compiler/BfExprEvaluator.cpp | 36 +++++++++++---- IDEHelper/Compiler/BfModule.cpp | 31 ++++--------- IDEHelper/Compiler/BfModule.h | 7 +-- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 22 ++++++++- 6 files changed, 121 insertions(+), 44 deletions(-) diff --git a/BeefLibs/corlib/src/Array.bf b/BeefLibs/corlib/src/Array.bf index 30abf405..9a8dc34c 100644 --- a/BeefLibs/corlib/src/Array.bf +++ b/BeefLibs/corlib/src/Array.bf @@ -12,8 +12,7 @@ namespace System #else typealias int_arsize = int32; #endif - - [CRepr] + class Array { protected int_arsize mLength; @@ -184,7 +183,7 @@ namespace System } } - [CRepr] + [Ordered] class Array1 : Array { T mFirstElement; @@ -278,7 +277,7 @@ namespace System } } - [CRepr] + [Ordered] class Array2 : Array { int_arsize mLength1; @@ -389,7 +388,7 @@ namespace System } } - [CRepr] + [Ordered] class Array3 : Array { int_arsize mLength1; @@ -505,7 +504,7 @@ namespace System } } - [CRepr] + [Ordered] class Array4 : Array { int_arsize mLength1; diff --git a/IDE/mintest/minlib/src/System/Array.bf b/IDE/mintest/minlib/src/System/Array.bf index 66ff0013..fb705cd7 100644 --- a/IDE/mintest/minlib/src/System/Array.bf +++ b/IDE/mintest/minlib/src/System/Array.bf @@ -7,7 +7,11 @@ using System.Diagnostics; namespace System { - typealias int_arsize = int; +#if BF_LARGE_COLLECTIONS + typealias int_arsize = int64; +#else + typealias int_arsize = int32; +#endif class Array { @@ -20,7 +24,7 @@ namespace System { // We only allow reducing the length - consider using System.Collections.Generic.List when dynamic sizing is required Runtime.Assert(value <= mLength); - mLength = value; + mLength = (.)value; } [Inline] @@ -112,8 +116,58 @@ namespace System var sorter = Sorter(&array.[Friend]mFirstElement, null, array.[Friend]mLength, comp); sorter.Sort(index, count); } + + // Reverses the elements in a range of an array. Following a call to this + // method, an element in the range given by index and count + // which was previously located at index i will now be located at + // index index + (index + count - i - 1). + // Reliability note: This may fail because it may have to box objects. + [DisableChecks] + public static void Reverse(T[] arr, int index, int length) + { + Debug.Assert(arr != null); + Debug.Assert(index >= 0); + Debug.Assert(length >= 0); + Debug.Assert(length >= arr.Count - index); + + int i = index; + int j = index + length - 1; + while (i < j) + { + let temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + i++; + j--; + } + } + + // Reverses the elements in a range of an array. Following a call to this + // method, an element in the range given by index and count + // which was previously located at index i will now be located at + // index index + (index + count - i - 1). + // Reliability note: This may fail because it may have to box objects. + public static void SlowReverse(T[] arr, int index, int length) + { + Debug.Assert(arr != null); + Debug.Assert(index >= 0); + Debug.Assert(length >= 0); + Debug.Assert(length >= arr.Count - index); + + int i = index; + int j = index + length - 1; + while (i < j) + { + let temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + i++; + j--; + } + } } + [Ordered] class Array1 : Array { T mFirstElement; diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 5e3e2693..ce658378 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -5515,10 +5515,14 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu } else { - argValue = mModule->LoadValue(argValue); - auto firstAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamsArray.mValue, 0, 1); - auto indexedAddr = mModule->CreateIndexedValue(argValue.mType, firstAddr, extendedParamIdx); - auto storeInst = mModule->mBfIRBuilder->CreateAlignedStore(argValue.mValue, indexedAddr, argValue.mType->mAlign); + auto firstElem = mModule->GetFieldByName(expandedParamsArray.mType->ToTypeInstance(), "mFirstElement"); + if (firstElem != NULL) + { + argValue = mModule->LoadValue(argValue); + auto firstAddr = mModule->mBfIRBuilder->CreateInBoundsGEP(expandedParamsArray.mValue, 0, firstElem->mDataIdx); + auto indexedAddr = mModule->CreateIndexedValue(argValue.mType, firstAddr, extendedParamIdx); + auto storeInst = mModule->mBfIRBuilder->CreateAlignedStore(argValue.mValue, indexedAddr, argValue.mType->mAlign); + } } } extendedParamIdx++; @@ -11511,7 +11515,17 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr) mModule->Fail("INTERNAL ERROR: Unable to find array 'length' field", objCreateExpr); return; } - auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayBits, 0, 1/*, "length"*/); + + mResult = arrayValue; + + auto lengthFieldInstance = mModule->GetFieldByName(arrayType->mBaseType->ToTypeInstance(), "mLength"); + if (lengthFieldInstance == NULL) + return; + auto firstElementFieldInstance = mModule->GetFieldByName(arrayType->ToTypeInstance(), "mFirstElement"); + if (firstElementFieldInstance == NULL) + return; + + auto addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayBits, 0, lengthFieldInstance->mDataIdx); if (arrayLengthBitCount == 64) mModule->mBfIRBuilder->CreateAlignedStore(arraySize, addr, 8); @@ -11523,7 +11537,12 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr) for (int lowerDim = 1; lowerDim < (int)dimLengthVals.size(); lowerDim++) { - addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayValue.mValue, 0, lowerDim/*, "dimLength"*/); // mDimLengthX + auto length1FieldInstance = mModule->GetFieldByName(arrayType->ToTypeInstance(), "mLength1"); + if (length1FieldInstance == NULL) + return; + + addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayValue.mValue, 0, length1FieldInstance->mDataIdx + lowerDim - 1); + auto lowerDimVal = mModule->mBfIRBuilder->CreateNumericCast(dimLengthVals[lowerDim], true, (arrayLengthBitCount == 64) ? BfTypeCode_Int64 : BfTypeCode_Int32); mModule->mBfIRBuilder->CreateStore(lowerDimVal, addr); } @@ -11531,10 +11550,9 @@ void BfExprEvaluator::Visit(BfObjectCreateExpression* objCreateExpr) if (resultType->IsValuelessType()) addr = mModule->mBfIRBuilder->GetFakeVal(); else - addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayValue.mValue, 0, (int)dimLengthVals.size()/*, "elem"*/); // mFirstElement + addr = mModule->mBfIRBuilder->CreateInBoundsGEP(arrayValue.mValue, 0, firstElementFieldInstance->mDataIdx); _HandleInitExprs(addr, 0, objCreateExpr->mArguments); - - mResult = arrayValue; + return; } else diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index b0a21739..b14d0493 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -2622,6 +2622,14 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers return bfError; } +BfError* BfModule::FailInternal(const StringImpl& error, BfAstNode* refNode) +{ + if (mHadBuildError) + return NULL; + + return Fail(error, refNode); +} + BfError* BfModule::FailAfter(const StringImpl& error, BfAstNode* refNode) { if (mIgnoreErrors) @@ -9059,29 +9067,6 @@ bool BfModule::HasMixin(BfTypeInstance* typeInstance, const StringImpl& methodNa return BfModuleMethodInstance(); } -BfFieldInstance* BfModule::GetFieldByName(BfTypeInstance* typeInstance, const StringImpl& fieldName) -{ - PopulateType(typeInstance, BfPopulateType_DataAndMethods); - - typeInstance->mTypeDef->PopulateMemberSets(); - BfMemberSetEntry* entry = NULL; - BfFieldDef* fieldDef = NULL; - if (typeInstance->mTypeDef->mFieldSet.TryGetWith(fieldName, &entry)) - { - fieldDef = (BfFieldDef*)entry->mMemberDef; - return &typeInstance->mFieldInstances[fieldDef->mIdx]; - } - -// for (auto& fieldInst : typeInstance->mFieldInstances) -// { -// auto fieldDef = fieldInst.GetFieldDef(); -// if ((fieldDef != NULL) && (fieldDef->mName == fieldName)) -// return &fieldInst; -// } - - return NULL; -} - String BfModule::MethodToString(BfMethodInstance* methodInst, BfMethodNameFlags methodNameFlags, BfTypeVector* methodGenericArgs) { auto methodDef = methodInst->mMethodDef; diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 3fee8df5..f69772da 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1410,6 +1410,7 @@ public: bool CheckProtection(BfProtectionCheckFlags& flags, BfTypeInstance* memberOwner, BfProject* memberProject, BfProtection memberProtection, BfTypeInstance* lookupStartType); void SetElementType(BfAstNode* astNode, BfSourceElementType elementType); BfError* Fail(const StringImpl& error, BfAstNode* refNode = NULL, bool isPersistent = false); + BfError* FailInternal(const StringImpl& error, BfAstNode* refNode = NULL); BfError* FailAfter(const StringImpl& error, BfAstNode* refNode); BfError* Warn(int warningNum, const StringImpl& warning, BfAstNode* refNode = NULL, bool isPersistent = false); void CheckRangeError(BfType* type, BfAstNode* refNode); @@ -1516,8 +1517,7 @@ public: void EmitEnsureInstructionAt(); void EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* targetType, BfIRBlock trueBlock, BfIRBlock falseBlock, bool nullSucceeds = false); void EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool allowNull); - void CheckStaticAccess(BfTypeInstance* typeInstance); - BfFieldInstance* GetFieldByName(BfTypeInstance* typeInstance, const StringImpl& fieldName); + void CheckStaticAccess(BfTypeInstance* typeInstance); BfTypedValue RemoveRef(BfTypedValue typedValue); BfTypedValue LoadOrAggregateValue(BfTypedValue typedValue); BfTypedValue LoadValue(BfTypedValue typedValue, BfAstNode* refNode = NULL, bool isVolatile = false); @@ -1608,6 +1608,7 @@ public: static BfModule* GetModuleFor(BfType* type); void DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance); void RebuildMethods(BfTypeInstance* typeInstance); + BfFieldInstance* GetFieldByName(BfTypeInstance* typeInstance, const StringImpl& fieldName, bool isRequired = true, BfAstNode* refNode = NULL); void CreateStaticField(BfFieldInstance* fieldInstance, bool isThreadLocal = false); void ResolveConstField(BfTypeInstance* typeInst, BfFieldInstance* fieldInstance, BfFieldDef* field, bool forceResolve = false); BfTypedValue GetFieldInitializerValue(BfFieldInstance* fieldInstance, BfExpression* initializer = NULL, BfFieldDef* fieldDef = NULL, BfType* fieldType = NULL); @@ -1759,7 +1760,7 @@ public: BfMethodInstance* GetRawMethodInstanceAtIdx(BfTypeInstance* typeInstance, int methodIdx, const char* assertName = NULL); BfMethodInstance* GetRawMethodInstance(BfTypeInstance* typeInstance, BfMethodDef* methodDef); BfMethodInstance* GetRawMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, int paramCount = -1, bool checkBase = false, bool allowMixin = false); - BfMethodInstance* GetUnspecializedMethodInstance(BfMethodInstance* methodInstance); // Unspecialized owner type and unspecialized method type + BfMethodInstance* GetUnspecializedMethodInstance(BfMethodInstance* methodInstance); // Unspecialized owner type and unspecialized method type int GetGenericParamAndReturnCount(BfMethodInstance* methodInstance); BfModule* GetSpecializedMethodModule(const SizedArrayImpl& projectList); BfModuleMethodInstance GetMethodInstanceAtIdx(BfTypeInstance* typeInstance, int methodIdx, const char* assertName = NULL); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 13aed904..5e918181 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -509,6 +509,26 @@ void BfModule::AddFieldDependency(BfTypeInstance* typeInstance, BfFieldInstance* } } +BfFieldInstance* BfModule::GetFieldByName(BfTypeInstance* typeInstance, const StringImpl& fieldName, bool isRequired, BfAstNode* refNode) +{ + PopulateType(typeInstance); + typeInstance->mTypeDef->PopulateMemberSets(); + BfMemberSetEntry* entry = NULL; + BfFieldDef* fieldDef = NULL; + if (typeInstance->mTypeDef->mFieldSet.TryGetWith(fieldName, &entry)) + { + fieldDef = (BfFieldDef*)entry->mMemberDef; + return &typeInstance->mFieldInstances[fieldDef->mIdx]; + } + + if (isRequired) + { + FailInternal(StrFormat("Field '%s' not found in '%s'", fieldName.c_str(), TypeToString(typeInstance).c_str()), refNode); + } + + return NULL; +} + void BfModule::CheckMemberNames(BfTypeInstance* typeInst) { struct MemberRef @@ -4268,7 +4288,7 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance) if (!mIsModuleMutable) PrepareForIRWriting(methodInstance->GetOwner()); - BfIRValue func = CreateFunctionFrom(methodInstance, false, methodInstance->mAlwaysInline); + BfIRValue func = CreateFunctionFrom(methodInstance, false, methodInstance->mAlwaysInline); methodInstance->mIRFunction = func; mFuncReferences[methodInstance] = func; }