diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 84427248..597e8d37 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -6109,7 +6109,13 @@ void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveAr if ((resolvedArg.mArgFlags & BfArgFlag_StringInterpolateFormat) != 0) exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_StringInterpolateFormat); + int lastLocalVarIdx = mModule->mCurMethodState->mLocals.mSize; exprEvaluator.Evaluate(argExpr, false, false, true); + if ((deferParamValues) && (mModule->mCurMethodState->mLocals.mSize > lastLocalVarIdx)) + { + // Remove any ignored locals + mModule->RestoreScoreState_LocalVariables(lastLocalVarIdx); + } } if ((mModule->mCurMethodState != NULL) && (exprEvaluator.mResultLocalVar != NULL) && (exprEvaluator.mResultLocalVarRefNode != NULL)) @@ -6175,6 +6181,18 @@ void BfExprEvaluator::PerformCallChecks(BfMethodInstance* methodInstance, BfAstN mModule->CheckErrorAttributes(methodInstance->GetOwner(), methodInstance, NULL, customAttributes, targetSrc); } +void BfExprEvaluator::CheckSkipCall(BfAstNode* targetSrc, SizedArrayImpl& argValues) +{ + for (auto& argValue : argValues) + { + if (!argValue.IsDeferredValue()) + { + mModule->Fail("Illegal SkipCall invocation", targetSrc); + return; + } + } +} + BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl& irArgs, BfTypedValue* sret, BfCreateCallFlags callFlags, BfType* origTargetType) { // static int sCallIdx = 0; @@ -7372,7 +7390,6 @@ void BfExprEvaluator::AddCallDependencies(BfMethodInstance* methodInstance) } } -//TODO: delete argumentsZ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValue& inTarget, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance moduleMethodInstance, BfCreateCallFlags callFlags, SizedArrayImpl& argValues, BfTypedValue* argCascade) { SetAndRestoreValue prevEvalExprFlag(mBfEvalExprFlags); @@ -7433,7 +7450,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu { returnType = methodInstance->GetOwner(); BF_ASSERT(returnType->IsInterface()); - }*/ + }*/ Array argCascades; BfTypedValue target = inTarget; @@ -7543,6 +7560,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu if (isSkipCall) { + CheckSkipCall(targetSrc, argValues); FinishDeferredEvals(argValues); mModule->EmitEnsureInstructionAt(); return mModule->GetDefaultTypedValue(returnType); @@ -8749,7 +8767,7 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou } methodMatcher.mArguments.Insert(0, resolvedArg); } - } + } if (isFailurePass) mModule->Fail(StrFormat("'%s' is inaccessible due to its protection level", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc); @@ -18643,30 +18661,38 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m int methodCount = 0; bool mayBeSkipCall = false; bool mayBeComptimeCall = false; + + BfTypeInstance* checkTypeInst = NULL; + if (thisValue.mType != NULL) { if (thisValue.mType->IsAllocType()) thisValue.mType = thisValue.mType->GetUnderlyingType(); - auto checkTypeInst = thisValue.mType->ToTypeInstance(); - while (checkTypeInst != NULL) + checkTypeInst = thisValue.mType->ToTypeInstance(); + } + else if (allowImplicitThis) + { + checkTypeInst = mModule->mCurTypeInstance; + } + + while (checkTypeInst != NULL) + { + checkTypeInst->mTypeDef->PopulateMemberSets(); + BfMemberSetEntry* memberSetEntry; + if (checkTypeInst->mTypeDef->mMethodSet.TryGetWith(targetFunctionName, &memberSetEntry)) { - checkTypeInst->mTypeDef->PopulateMemberSets(); - BfMemberSetEntry* memberSetEntry; - if (checkTypeInst->mTypeDef->mMethodSet.TryGetWith(targetFunctionName, &memberSetEntry)) + BfMethodDef* methodDef = (BfMethodDef*)memberSetEntry->mMemberDef; + while (methodDef != NULL) { - BfMethodDef* methodDef = (BfMethodDef*)memberSetEntry->mMemberDef; - while (methodDef != NULL) - { - if (methodDef->mIsSkipCall) - mayBeSkipCall = true; - if (methodDef->mHasComptime) - mayBeComptimeCall = true; - methodDef = methodDef->mNextWithSameName; - } + if (methodDef->mIsSkipCall) + mayBeSkipCall = true; + if (methodDef->mHasComptime) + mayBeComptimeCall = true; + methodDef = methodDef->mNextWithSameName; } - checkTypeInst = checkTypeInst->mBaseType; } + checkTypeInst = checkTypeInst->mBaseType; } SizedArray copiedArgs; diff --git a/IDEHelper/Compiler/BfExprEvaluator.h b/IDEHelper/Compiler/BfExprEvaluator.h index 630ab57e..cf013954 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.h +++ b/IDEHelper/Compiler/BfExprEvaluator.h @@ -83,6 +83,11 @@ public: { return (mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_UntypedDefault | BfArgFlag_DeferredEval)) != 0; } + + bool IsDeferredValue() + { + return (mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_UntypedDefault | BfArgFlag_DeferredEval | BfArgFlag_DeferredValue)) != 0; + } }; struct BfResolvedArgs @@ -481,6 +486,7 @@ public: BfTypedValue LookupIdentifier(BfIdentifierNode* identifierNode, bool ignoreInitialError = false, bool* hadError = NULL); void AddCallDependencies(BfMethodInstance* methodInstance); void PerformCallChecks(BfMethodInstance* methodInstance, BfAstNode* targetSrc); + void CheckSkipCall(BfAstNode* targetSrc, SizedArrayImpl& argValues); BfTypedValue CreateCall(BfAstNode* targetSrc, BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl& irArgs, BfTypedValue* sret = NULL, BfCreateCallFlags callFlags = BfCreateCallFlags_None, BfType* origTargetType = NULL); BfTypedValue CreateCall(BfAstNode* targetSrc, const BfTypedValue& target, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance methodInstance, BfCreateCallFlags callFlags, SizedArrayImpl& argValues, BfTypedValue* argCascade = NULL); BfTypedValue CreateCall(BfMethodMatcher* methodMatcher, BfTypedValue target); diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 68b83286..15120d27 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -1963,9 +1963,9 @@ void BfModule::NewScopeState(bool createLexicalBlock, bool flushValueScope) mCurMethodState->mCurScope->mMixinState = mCurMethodState->mMixinState; } -void BfModule::RestoreScoreState_LocalVariables() +void BfModule::RestoreScoreState_LocalVariables(int localVarStart) { - while (mCurMethodState->mCurScope->mLocalVarStart < (int)mCurMethodState->mLocals.size()) + while (localVarStart < (int)mCurMethodState->mLocals.size()) { auto localVar = mCurMethodState->mLocals.back(); LocalVariableDone(localVar, false); @@ -2022,7 +2022,7 @@ void BfModule::RestoreScopeState() EmitDeferredCallProcessorInstances(mCurMethodState->mCurScope); - RestoreScoreState_LocalVariables(); + RestoreScoreState_LocalVariables(mCurMethodState->mCurScope->mLocalVarStart); if (mCurMethodState->mCurScope->mValueScopeStart) mBfIRBuilder->CreateValueScopeHardEnd(mCurMethodState->mCurScope->mValueScopeStart); @@ -15498,6 +15498,11 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, bool addDebugInfo, bool doAliasValue, BfIRValue declareBefore, BfIRInitType initType) { + if (localVarDef->mName == "newSuccIndex") + { + NOP; + } + if ((localVarDef->mValue) && (!localVarDef->mAddr) && (IsTargetingBeefBackend()) && (!localVarDef->mResolvedType->IsValuelessType())) { if ((!localVarDef->mValue.IsConst()) && diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 5234ce41..c67f453c 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -1678,7 +1678,7 @@ public: BfIRValue CreateAlloca(BfType* type, bool addLifetime = true, const char* name = NULL, BfIRValue arraySize = BfIRValue()); BfIRValue CreateAllocaInst(BfTypeInstance* typeInst, bool addLifetime = true, const char* name = NULL); BfDeferredCallEntry* AddStackAlloc(BfTypedValue val, BfIRValue arraySize, BfAstNode* refNode, BfScopeData* scope, bool condAlloca = false, bool mayEscape = false, BfIRBlock valBlock = BfIRBlock()); - void RestoreScoreState_LocalVariables(); + void RestoreScoreState_LocalVariables(int localVarStart); void RestoreScopeState(); void MarkDynStack(BfScopeData* scope); void SaveStackState(BfScopeData* scope); diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index 5e5f4970..28ef11cd 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -3893,7 +3893,7 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i // We restore the scopeData before the False block because we don't want variables created in the if condition to // be visible in the false section //RestoreScopeState(); - RestoreScoreState_LocalVariables(); + RestoreScoreState_LocalVariables(mCurMethodState->mCurScope->mLocalVarStart); if ((!mCurMethodState->mLeftBlockUncond) && (!ignoredLastBlock)) mBfIRBuilder->CreateBr_NoCollapse(contBB);