Brian Fiete 4 éve
szülő
commit
6d058ba59c

+ 1 - 1
IDEHelper/Compiler/BfCompiler.cpp

@@ -1009,7 +1009,7 @@ void BfCompiler::EmitTestMethod(BfVDataModule* bfModule, Array<TestMethod>& test
 		}
 		}
 
 
 		BfExprEvaluator exprEvaluator(bfModule);
 		BfExprEvaluator exprEvaluator(bfModule);
-		exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs);
+		exprEvaluator.CreateCall(NULL, moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs);
 
 
 		bfModule->mBfIRBuilder->CreateBr(testHeadBlock);
 		bfModule->mBfIRBuilder->CreateBr(testHeadBlock);
 	}
 	}

+ 1 - 0
IDEHelper/Compiler/BfContext.cpp

@@ -645,6 +645,7 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods)
 			dupMethodInstance.mMethodProcessRequest = NULL;
 			dupMethodInstance.mMethodProcessRequest = NULL;
 			dupMethodInstance.mIsReified = true;			
 			dupMethodInstance.mIsReified = true;			
 			dupMethodInstance.mHotMethod = NULL;
 			dupMethodInstance.mHotMethod = NULL;
+			dupMethodInstance.mInCEMachine = false; // Only have the original one
 			BF_ASSERT(module->mIsReified); // We should only bother inlining in reified modules
 			BF_ASSERT(module->mIsReified); // We should only bother inlining in reified modules
 
 
 			{
 			{

+ 12 - 12
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -4801,7 +4801,7 @@ void BfExprEvaluator::PerformCallChecks(BfMethodInstance* methodInstance, BfAstN
 		mModule->CheckErrorAttributes(methodInstance->GetOwner(), methodInstance, customAttributes, targetSrc);	
 		mModule->CheckErrorAttributes(methodInstance->GetOwner(), methodInstance, customAttributes, targetSrc);	
 }
 }
 
 
-BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl<BfIRValue>& irArgs, BfTypedValue* sret, bool isTailCall)
+BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl<BfIRValue>& irArgs, BfTypedValue* sret, bool isTailCall)
 {
 {
 // 	static int sCallIdx = 0;
 // 	static int sCallIdx = 0;
 // 	if (!mModule->mCompiler->mIsResolveOnly)
 // 	if (!mModule->mCompiler->mIsResolveOnly)
@@ -4990,7 +4990,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
 		}
 		}
 		else if ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0)
 		else if ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0)
 		{
 		{
-			auto constRet = mModule->mCompiler->mCEMachine->Call(mModule, methodInstance, irArgs, CeEvalFlags_None);
+			auto constRet = mModule->mCompiler->mCEMachine->Call(targetSrc, mModule, methodInstance, irArgs, CeEvalFlags_None);
 			if (constRet)
 			if (constRet)
 				return constRet;
 				return constRet;
 		}
 		}
@@ -6632,7 +6632,7 @@ SplatArgs(lookupVal, irArgs);
 	}
 	}
 
 
 	auto func = moduleMethodInstance.mFunc;	
 	auto func = moduleMethodInstance.mFunc;	
-	BfTypedValue result = CreateCall(methodInstance, func, bypassVirtual, irArgs);	
+	BfTypedValue result = CreateCall(targetSrc, methodInstance, func, bypassVirtual, irArgs);	
 	if ((result.mType != NULL) && (result.mType->IsVar()) && (mModule->mCompiler->mIsResolveOnly))		
 	if ((result.mType != NULL) && (result.mType->IsVar()) && (mModule->mCompiler->mIsResolveOnly))		
 		mModule->Fail("Method return type reference failed to resolve", targetSrc);
 		mModule->Fail("Method return type reference failed to resolve", targetSrc);
 	return result;
 	return result;
@@ -9144,7 +9144,7 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
 				exprEvaluator.MatchMethod(elementExpr, NULL, initValue, false, false, "Add", argValues, NULL);
 				exprEvaluator.MatchMethod(elementExpr, NULL, initValue, false, false, "Add", argValues, NULL);
 
 
 				if (addFunctionBindResult.mMethodInstance != NULL)
 				if (addFunctionBindResult.mMethodInstance != NULL)
-					CreateCall(addFunctionBindResult.mMethodInstance, addFunctionBindResult.mFunc, true, addFunctionBindResult.mIRArgs);
+					CreateCall(initExpr, addFunctionBindResult.mMethodInstance, addFunctionBindResult.mFunc, true, addFunctionBindResult.mIRArgs);
 
 
 				isFirstAdd = false;
 				isFirstAdd = false;
 			}
 			}
@@ -9162,7 +9162,7 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
 					PushArg(argValue, irArgs);
 					PushArg(argValue, irArgs);
 					for (int argIdx = (int)irArgs.size(); argIdx < (int)addFunctionBindResult.mIRArgs.size(); argIdx++)
 					for (int argIdx = (int)irArgs.size(); argIdx < (int)addFunctionBindResult.mIRArgs.size(); argIdx++)
 						irArgs.Add(addFunctionBindResult.mIRArgs[argIdx]);
 						irArgs.Add(addFunctionBindResult.mIRArgs[argIdx]);
-					CreateCall(addFunctionBindResult.mMethodInstance, addFunctionBindResult.mFunc, true, irArgs);
+					CreateCall(initExpr, addFunctionBindResult.mMethodInstance, addFunctionBindResult.mFunc, true, irArgs);
 				}
 				}
 			}
 			}
 
 
@@ -13100,7 +13100,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
 			{
 			{
 				BF_ASSERT(calcAppendMethodModule.mFunc);
 				BF_ASSERT(calcAppendMethodModule.mFunc);
 								
 								
-				appendSizeTypedValue = CreateCall(calcAppendMethodModule.mMethodInstance, calcAppendMethodModule.mFunc, false, irArgs);
+				appendSizeTypedValue = CreateCall(objCreateExpr, calcAppendMethodModule.mMethodInstance, calcAppendMethodModule.mFunc, false, irArgs);
 				BF_ASSERT(appendSizeTypedValue.mType == mModule->GetPrimitiveType(BfTypeCode_IntPtr));
 				BF_ASSERT(appendSizeTypedValue.mType == mModule->GetPrimitiveType(BfTypeCode_IntPtr));
 			}
 			}
 			appendSizeValue = appendSizeTypedValue.mValue;
 			appendSizeValue = appendSizeTypedValue.mValue;
@@ -13187,7 +13187,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
 					{
 					{
 						SizedArray<BfIRValue, 1> irArgs;
 						SizedArray<BfIRValue, 1> irArgs;
 						irArgs.push_back(mResult.mValue);
 						irArgs.push_back(mResult.mValue);
-						CreateCall(ctorClear.mMethodInstance, ctorClear.mFunc, false, irArgs);
+						CreateCall(objCreateExpr, ctorClear.mMethodInstance, ctorClear.mFunc, false, irArgs);
 					}
 					}
 				}
 				}
 
 
@@ -13255,7 +13255,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
 			}
 			}
 			if (!typeInstance->IsValuelessType())
 			if (!typeInstance->IsValuelessType())
 				bindResult.mIRArgs.Insert(0, mResult.mValue);
 				bindResult.mIRArgs.Insert(0, mResult.mValue);
-			CreateCall(bindResult.mMethodInstance, bindResult.mFunc, false, bindResult.mIRArgs);
+			CreateCall(objCreateExpr, bindResult.mMethodInstance, bindResult.mFunc, false, bindResult.mIRArgs);
 		}
 		}
 	}
 	}
 }
 }
@@ -15870,7 +15870,7 @@ BfTypedValue BfExprEvaluator::GetResult(bool clearResult, bool resolveGenericTyp
 					}
 					}
 				}
 				}
 				else
 				else
-					mResult = CreateCall(methodInstance.mMethodInstance, methodInstance.mFunc, mPropDefBypassVirtual, args);
+					mResult = CreateCall(mPropSrc, methodInstance.mMethodInstance, methodInstance.mFunc, mPropDefBypassVirtual, args);
 				if (mResult.mType != NULL)
 				if (mResult.mType != NULL)
 				{
 				{
 					if ((mResult.mType->IsVar()) && (mModule->mCompiler->mIsResolveOnly))
 					if ((mResult.mType->IsVar()) && (mModule->mCompiler->mIsResolveOnly))
@@ -16794,7 +16794,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool
 			PushArg(convVal, args);
 			PushArg(convVal, args);
 
 
 			if (methodInstance)
 			if (methodInstance)
-				CreateCall(methodInstance.mMethodInstance, methodInstance.mFunc, mPropDefBypassVirtual, args);
+				CreateCall(assignExpr, methodInstance.mMethodInstance, methodInstance.mFunc, mPropDefBypassVirtual, args);
 	
 	
 			mPropDef = NULL;
 			mPropDef = NULL;
 			mResult = convVal;
 			mResult = convVal;
@@ -16868,7 +16868,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool
 					SizedArray<BfIRValue, 1> args;
 					SizedArray<BfIRValue, 1> args;
 					exprEvaluator.PushThis(assignExpr->mLeft, leftValue, moduleMethodInstance.mMethodInstance, args);
 					exprEvaluator.PushThis(assignExpr->mLeft, leftValue, moduleMethodInstance.mMethodInstance, args);
 					exprEvaluator.PushArg(rightValue, args);
 					exprEvaluator.PushArg(rightValue, args);
-					exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, args);
+					exprEvaluator.CreateCall(assignExpr, moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, args);
 					convVal = leftValue;
 					convVal = leftValue;
 					handled = true;
 					handled = true;
 					break;
 					break;
@@ -19068,7 +19068,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr,
 		}
 		}
 
 
 		PushArg(writeToProp, args);
 		PushArg(writeToProp, args);
-		CreateCall(methodInstance.mMethodInstance, methodInstance.mFunc, false, args);
+		CreateCall(opToken, methodInstance.mMethodInstance, methodInstance.mFunc, false, args);
 	}
 	}
 }
 }
 
 

+ 1 - 1
IDEHelper/Compiler/BfExprEvaluator.h

@@ -420,7 +420,7 @@ public:
 	BfTypedValue LookupIdentifier(BfIdentifierNode* identifierNode, bool ignoreInitialError = false, bool* hadError = NULL);
 	BfTypedValue LookupIdentifier(BfIdentifierNode* identifierNode, bool ignoreInitialError = false, bool* hadError = NULL);
 	void AddCallDependencies(BfMethodInstance* methodInstance);
 	void AddCallDependencies(BfMethodInstance* methodInstance);
 	void PerformCallChecks(BfMethodInstance* methodInstance, BfAstNode* targetSrc);
 	void PerformCallChecks(BfMethodInstance* methodInstance, BfAstNode* targetSrc);
-	BfTypedValue CreateCall(BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl<BfIRValue>& irArgs, BfTypedValue* sret = NULL, bool isTailCall = false);
+	BfTypedValue CreateCall(BfAstNode* targetSrc, BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl<BfIRValue>& irArgs, BfTypedValue* sret = NULL, bool isTailCall = false);
 	BfTypedValue CreateCall(BfAstNode* targetSrc, const BfTypedValue& target, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance methodInstance, bool bypassVirtual, SizedArrayImpl<BfResolvedArg>& argValues, bool skipThis = false);
 	BfTypedValue CreateCall(BfAstNode* targetSrc, const BfTypedValue& target, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance methodInstance, bool bypassVirtual, SizedArrayImpl<BfResolvedArg>& argValues, bool skipThis = false);
 	BfTypedValue CreateCall(BfMethodMatcher* methodMatcher, BfTypedValue target);
 	BfTypedValue CreateCall(BfMethodMatcher* methodMatcher, BfTypedValue target);
 	void MakeBaseConcrete(BfTypedValue& typedValue);
 	void MakeBaseConcrete(BfTypedValue& typedValue);

+ 99 - 97
IDEHelper/Compiler/BfModule.cpp

@@ -694,7 +694,7 @@ public:
 							{
 							{
 								BF_ASSERT(calcAppendMethodModule.mFunc);
 								BF_ASSERT(calcAppendMethodModule.mFunc);
 
 
-								subDependSize = exprEvaluator.CreateCall(calcAppendMethodModule.mMethodInstance, calcAppendMethodModule.mFunc, false, calcAppendArgs);
+								subDependSize = exprEvaluator.CreateCall(objCreateExpr, calcAppendMethodModule.mMethodInstance, calcAppendMethodModule.mFunc, false, calcAppendArgs);
 								BF_ASSERT(subDependSize.mType == mModule->GetPrimitiveType(BfTypeCode_IntPtr));
 								BF_ASSERT(subDependSize.mType == mModule->GetPrimitiveType(BfTypeCode_IntPtr));
 							}
 							}
 							if (subDependSize)
 							if (subDependSize)
@@ -9211,7 +9211,7 @@ void BfModule::EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* tar
 		SizedArray<BfIRValue, 4> irArgs;
 		SizedArray<BfIRValue, 4> irArgs;
 		irArgs.push_back(objectParam);
 		irArgs.push_back(objectParam);
 		irArgs.push_back(GetConstValue32(targetType->mTypeId));
 		irArgs.push_back(GetConstValue32(targetType->mTypeId));
-		auto callResult = exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs);
+		auto callResult = exprEvaluator.CreateCall(NULL, moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs);
 		auto resultType = ResolveTypeDef(mSystem->mTypeBool);
 		auto resultType = ResolveTypeDef(mSystem->mTypeBool);
 		auto cmpResult = mBfIRBuilder->CreateCmpNE(callResult.mValue, GetDefaultValue(callResult.mType));
 		auto cmpResult = mBfIRBuilder->CreateCmpNE(callResult.mValue, GetDefaultValue(callResult.mType));
 		irb->CreateCondBr(cmpResult, trueBlock, falseBlock);
 		irb->CreateCondBr(cmpResult, trueBlock, falseBlock);
@@ -14788,7 +14788,7 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly)
 		calcAppendArgs = bindResult.mIRArgs;
 		calcAppendArgs = bindResult.mIRArgs;
 	}	
 	}	
 	BF_ASSERT(calcAppendMethodModule.mFunc);
 	BF_ASSERT(calcAppendMethodModule.mFunc);
-	appendSizeTypedValue = exprEvaluator.CreateCall(calcAppendMethodModule.mMethodInstance, calcAppendMethodModule.mFunc, false, calcAppendArgs);
+	appendSizeTypedValue = exprEvaluator.CreateCall(NULL, calcAppendMethodModule.mMethodInstance, calcAppendMethodModule.mFunc, false, calcAppendArgs);
 
 
 	
 	
 	BF_ASSERT(appendSizeTypedValue.mType == GetPrimitiveType(BfTypeCode_IntPtr));
 	BF_ASSERT(appendSizeTypedValue.mType == GetPrimitiveType(BfTypeCode_IntPtr));
@@ -15648,7 +15648,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
 
 
 				SizedArray<BfIRValue, 1> irArgs;
 				SizedArray<BfIRValue, 1> irArgs;
 				exprEvaluator.PushThis(NULL, GetThis(), moduleMethodInstance.mMethodInstance, irArgs);
 				exprEvaluator.PushThis(NULL, GetThis(), moduleMethodInstance.mMethodInstance, irArgs);
-				exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs);
+				exprEvaluator.CreateCall(NULL, moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs);
 
 
 				calledCtorNoBody = true;
 				calledCtorNoBody = true;
 			}
 			}
@@ -16131,7 +16131,7 @@ void BfModule::EmitEnumToStringBody()
 			SizedArray<BfIRValue, 2> args;
 			SizedArray<BfIRValue, 2> args;
 			args.Add(stringDestVal.mValue);
 			args.Add(stringDestVal.mValue);
 			args.Add(caseStr);
 			args.Add(caseStr);
-			exprEvaluator.CreateCall(appendModuleMethodInstance.mMethodInstance, appendModuleMethodInstance.mFunc, false, args);
+			exprEvaluator.CreateCall(NULL, appendModuleMethodInstance.mMethodInstance, appendModuleMethodInstance.mFunc, false, args);
 						
 						
 			auto payloadType = fieldInstance.mResolvedType->ToTypeInstance();
 			auto payloadType = fieldInstance.mResolvedType->ToTypeInstance();
 			BF_ASSERT(payloadType->IsTuple());
 			BF_ASSERT(payloadType->IsTuple());
@@ -16150,7 +16150,7 @@ void BfModule::EmitEnumToStringBody()
 				exprEvaluator.PushThis(NULL, payload, toStringMethod.mMethodInstance, irArgs);
 				exprEvaluator.PushThis(NULL, payload, toStringMethod.mMethodInstance, irArgs);
 				stringDestVal = LoadValue(stringDestAddr);
 				stringDestVal = LoadValue(stringDestAddr);
 				irArgs.Add(stringDestVal.mValue);
 				irArgs.Add(stringDestVal.mValue);
-				exprEvaluator.CreateCall(toStringMethod.mMethodInstance, toStringMethod.mFunc, true, irArgs);
+				exprEvaluator.CreateCall(NULL, toStringMethod.mMethodInstance, toStringMethod.mFunc, true, irArgs);
 			}
 			}
 
 
 			mBfIRBuilder->CreateBr(endBlock);
 			mBfIRBuilder->CreateBr(endBlock);
@@ -16186,7 +16186,7 @@ void BfModule::EmitEnumToStringBody()
 	auto stringDestVal = LoadValue(stringDestAddr);
 	auto stringDestVal = LoadValue(stringDestAddr);
 	args.Add(stringDestVal.mValue);
 	args.Add(stringDestVal.mValue);
 	args.Add(mBfIRBuilder->CreateLoad(strVal));
 	args.Add(mBfIRBuilder->CreateLoad(strVal));
-	exprEvaluator.CreateCall(appendModuleMethodInstance.mMethodInstance, appendModuleMethodInstance.mFunc, false, args);
+	exprEvaluator.CreateCall(NULL, appendModuleMethodInstance.mMethodInstance, appendModuleMethodInstance.mFunc, false, args);
 	mBfIRBuilder->CreateBr(endBlock);
 	mBfIRBuilder->CreateBr(endBlock);
 
 
 	mBfIRBuilder->AddBlock(noMatchBlock);
 	mBfIRBuilder->AddBlock(noMatchBlock);
@@ -16197,7 +16197,7 @@ void BfModule::EmitEnumToStringBody()
 	args.Add(int64Val);
 	args.Add(int64Val);
 	stringDestVal = LoadValue(stringDestAddr);
 	stringDestVal = LoadValue(stringDestAddr);
 	args.Add(stringDestVal.mValue);
 	args.Add(stringDestVal.mValue);
-	exprEvaluator.CreateCall(toStringModuleMethodInstance.mMethodInstance, toStringModuleMethodInstance.mFunc, false, args);
+	exprEvaluator.CreateCall(NULL, toStringModuleMethodInstance.mMethodInstance, toStringModuleMethodInstance.mFunc, false, args);
 	mBfIRBuilder->CreateBr(endBlock);
 	mBfIRBuilder->CreateBr(endBlock);
 
 
 	mBfIRBuilder->AddBlock(endBlock);
 	mBfIRBuilder->AddBlock(endBlock);
@@ -16226,7 +16226,7 @@ void BfModule::EmitTupleToStringBody()
 		auto stringDestVal = LoadValue(stringDestRef);
 		auto stringDestVal = LoadValue(stringDestRef);
 		args.Add(stringDestVal.mValue);
 		args.Add(stringDestVal.mValue);
 		args.Add(mBfIRBuilder->CreateConst(BfTypeCode_Char8, (int)c));
 		args.Add(mBfIRBuilder->CreateConst(BfTypeCode_Char8, (int)c));
-		exprEvaluator.CreateCall(appendCharModuleMethodInstance.mMethodInstance, appendCharModuleMethodInstance.mFunc, false, args);
+		exprEvaluator.CreateCall(NULL, appendCharModuleMethodInstance.mMethodInstance, appendCharModuleMethodInstance.mFunc, false, args);
 	};
 	};
 
 
 	int fieldIdx = 0;
 	int fieldIdx = 0;
@@ -16254,7 +16254,7 @@ void BfModule::EmitTupleToStringBody()
 			auto stringDestVal = LoadValue(stringDestRef);
 			auto stringDestVal = LoadValue(stringDestRef);
 			args.Add(stringDestVal.mValue);
 			args.Add(stringDestVal.mValue);
 			args.Add(commaStr);
 			args.Add(commaStr);
-			exprEvaluator.CreateCall(appendModuleMethodInstance.mMethodInstance, appendModuleMethodInstance.mFunc, false, args);
+			exprEvaluator.CreateCall(NULL, appendModuleMethodInstance.mMethodInstance, appendModuleMethodInstance.mFunc, false, args);
 		}
 		}
 		fieldIdx++;
 		fieldIdx++;
 
 
@@ -16300,7 +16300,7 @@ void BfModule::EmitTupleToStringBody()
 			auto stringDestVal = exprEvaluator.LoadLocal(mCurMethodState->mLocals[1]);
 			auto stringDestVal = exprEvaluator.LoadLocal(mCurMethodState->mLocals[1]);
 			stringDestVal = LoadValue(stringDestVal);
 			stringDestVal = LoadValue(stringDestVal);
 			args.Add(stringDestVal.mValue);			
 			args.Add(stringDestVal.mValue);			
-			exprEvaluator.CreateCall(toStringSafeModuleMethodInstance.mMethodInstance, toStringSafeModuleMethodInstance.mFunc, false, args);
+			exprEvaluator.CreateCall(NULL, toStringSafeModuleMethodInstance.mMethodInstance, toStringSafeModuleMethodInstance.mFunc, false, args);
 			continue;
 			continue;
 		}
 		}
 
 
@@ -16324,7 +16324,7 @@ void BfModule::EmitTupleToStringBody()
 			auto stringDestVal = LoadValue(stringDestRef);
 			auto stringDestVal = LoadValue(stringDestRef);
 			args.Add(stringDestVal.mValue);
 			args.Add(stringDestVal.mValue);
 			args.Add(strVal);
 			args.Add(strVal);
-			exprEvaluator.CreateCall(appendModuleMethodInstance.mMethodInstance, appendModuleMethodInstance.mFunc, false, args);
+			exprEvaluator.CreateCall(NULL, appendModuleMethodInstance.mMethodInstance, appendModuleMethodInstance.mFunc, false, args);
 			continue;
 			continue;
 		}
 		}
 
 
@@ -16389,7 +16389,7 @@ void BfModule::EmitGCMarkValue(BfTypedValue markVal, BfModuleMethodInstance mark
 		val = mBfIRBuilder->CreateBitCast(val, mBfIRBuilder->MapType(mContext->mBfObjectType));
 		val = mBfIRBuilder->CreateBitCast(val, mBfIRBuilder->MapType(mContext->mBfObjectType));
 		SizedArray<BfIRValue, 1> args;
 		SizedArray<BfIRValue, 1> args;
 		args.push_back(val);
 		args.push_back(val);
-		exprEvaluator.CreateCall(markFromGCThreadMethodInstance.mMethodInstance, markFromGCThreadMethodInstance.mFunc, false, args);
+		exprEvaluator.CreateCall(NULL, markFromGCThreadMethodInstance.mMethodInstance, markFromGCThreadMethodInstance.mFunc, false, args);
 	}
 	}
 	else if ((fieldTypeInst->IsComposite()) && (!fieldTypeInst->IsTypedPrimitive()))
 	else if ((fieldTypeInst->IsComposite()) && (!fieldTypeInst->IsTypedPrimitive()))
 	{
 	{
@@ -16403,7 +16403,7 @@ void BfModule::EmitGCMarkValue(BfTypedValue markVal, BfModuleMethodInstance mark
 				markVal = Cast(NULL, markVal, methodOwner);
 				markVal = Cast(NULL, markVal, methodOwner);
 
 
 			exprEvaluator.PushThis(NULL, markVal, markMemberMethodInstance.mMethodInstance, args);
 			exprEvaluator.PushThis(NULL, markVal, markMemberMethodInstance.mMethodInstance, args);
-			exprEvaluator.CreateCall(markMemberMethodInstance.mMethodInstance, markMemberMethodInstance.mFunc, false, args);
+			exprEvaluator.CreateCall(NULL, markMemberMethodInstance.mMethodInstance, markMemberMethodInstance.mFunc, false, args);
 		}
 		}
 	}
 	}
 }
 }
@@ -16452,7 +16452,7 @@ void BfModule::CallChainedMethods(BfMethodInstance* methodInstance, bool reverse
 		BfExprEvaluator exprEvaluator(this);
 		BfExprEvaluator exprEvaluator(this);
 		SizedArray<BfIRValue, 1> args;
 		SizedArray<BfIRValue, 1> args;
 		exprEvaluator.PushThis(chainedMethodInst->mMethodDef->GetRefNode(), GetThis(), chainedMethodInst, args);
 		exprEvaluator.PushThis(chainedMethodInst->mMethodDef->GetRefNode(), GetThis(), chainedMethodInst, args);
-		exprEvaluator.CreateCall(moduleMethodInst.mMethodInstance, moduleMethodInst.mFunc, true, args);
+		exprEvaluator.CreateCall(NULL, moduleMethodInst.mMethodInstance, moduleMethodInst.mFunc, true, args);
 	}
 	}
 }
 }
 
 
@@ -18617,14 +18617,14 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
 					mBfIRBuilder->PopulateType(methodInstance->mReturnType);
 					mBfIRBuilder->PopulateType(methodInstance->mReturnType);
 					auto returnType = BfTypedValue(mBfIRBuilder->GetArgument(methodInstance->GetStructRetIdx()), methodInstance->mReturnType, true);
 					auto returnType = BfTypedValue(mBfIRBuilder->GetArgument(methodInstance->GetStructRetIdx()), methodInstance->mReturnType, true);
 					exprEvaluator.mReceivingValue = &returnType;
 					exprEvaluator.mReceivingValue = &returnType;
-					auto retVal = exprEvaluator.CreateCall(innerMethodInstance.mMethodInstance, innerMethodInstance.mFunc, true, innerParams, NULL, true);					
+					auto retVal = exprEvaluator.CreateCall(NULL, innerMethodInstance.mMethodInstance, innerMethodInstance.mFunc, true, innerParams, NULL, true);
 					BF_ASSERT(exprEvaluator.mReceivingValue == NULL); // Ensure it was actually used
 					BF_ASSERT(exprEvaluator.mReceivingValue == NULL); // Ensure it was actually used
 					mBfIRBuilder->CreateRetVoid();
 					mBfIRBuilder->CreateRetVoid();
 				}
 				}
 				else
 				else
 				{
 				{
 					mBfIRBuilder->PopulateType(methodInstance->mReturnType);
 					mBfIRBuilder->PopulateType(methodInstance->mReturnType);
-					auto retVal = exprEvaluator.CreateCall(innerMethodInstance.mMethodInstance, innerMethodInstance.mFunc, true, innerParams, NULL, true);
+					auto retVal = exprEvaluator.CreateCall(NULL, innerMethodInstance.mMethodInstance, innerMethodInstance.mFunc, true, innerParams, NULL, true);
 					if (mCurMethodInstance->mReturnType->IsValueType())
 					if (mCurMethodInstance->mReturnType->IsValueType())
 						retVal = LoadValue(retVal);
 						retVal = LoadValue(retVal);
 					CreateReturn(retVal.mValue);
 					CreateReturn(retVal.mValue);
@@ -21680,107 +21680,109 @@ genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var);
 				auto checkMethod = nextMethod;
 				auto checkMethod = nextMethod;
 				nextMethod = nextMethod->mNextWithSameName;
 				nextMethod = nextMethod->mNextWithSameName;
 
 
-				if ((checkMethod != methodDef) && (typeInstance->mMethodInstanceGroups[checkMethod->mIdx].mDefault != NULL))
-				{					
-					auto checkMethodInstance = typeInstance->mMethodInstanceGroups[checkMethod->mIdx].mDefault;
+				if (checkMethod == methodDef)
+					continue;
 
 
-					if (((checkMethodInstance->mChainType == BfMethodChainType_None) || (checkMethodInstance->mChainType == BfMethodChainType_ChainHead)) &&						
-						(checkMethodInstance->GetExplicitInterface() == methodInstance->GetExplicitInterface()) &&
-						(checkMethod->mIsMutating == methodDef->mIsMutating) &&
-						(CompareMethodSignatures(checkMethodInstance, mCurMethodInstance)))
-					{							
-						bool canChain = false;
+				auto checkMethodInstance = typeInstance->mMethodInstanceGroups[checkMethod->mIdx].mDefault;				
+				if (checkMethodInstance == NULL)
+					continue;
 
 
-						if ((methodDef->mParams.empty()) &&
-							(checkMethodInstance->mMethodDef->mIsStatic == methodInstance->mMethodDef->mIsStatic))
+				if (((checkMethodInstance->mChainType == BfMethodChainType_None) || (checkMethodInstance->mChainType == BfMethodChainType_ChainHead)) &&
+					(checkMethodInstance->GetExplicitInterface() == methodInstance->GetExplicitInterface()) &&
+					(checkMethod->mIsMutating == methodDef->mIsMutating) &&
+					(CompareMethodSignatures(checkMethodInstance, mCurMethodInstance)))
+				{
+					bool canChain = false;
+
+					if ((methodDef->mParams.empty()) &&
+						(checkMethodInstance->mMethodDef->mIsStatic == methodInstance->mMethodDef->mIsStatic))
+					{
+						if ((methodDef->mMethodType == BfMethodType_CtorNoBody) || (methodDef->mMethodType == BfMethodType_Dtor))
+							canChain = true;
+						else if (methodDef->mMethodType == BfMethodType_Normal)
 						{
 						{
-							if ((methodDef->mMethodType == BfMethodType_CtorNoBody) || (methodDef->mMethodType == BfMethodType_Dtor))
+							if ((methodDef->mName == BF_METHODNAME_MARKMEMBERS) ||
+								(methodDef->mName == BF_METHODNAME_MARKMEMBERS_STATIC) ||
+								(methodDef->mName == BF_METHODNAME_FIND_TLS_MEMBERS))
 								canChain = true;
 								canChain = true;
-							else if (methodDef->mMethodType == BfMethodType_Normal)
-							{
-								if ((methodDef->mName == BF_METHODNAME_MARKMEMBERS) ||
-									(methodDef->mName == BF_METHODNAME_MARKMEMBERS_STATIC) ||
-									(methodDef->mName == BF_METHODNAME_FIND_TLS_MEMBERS))
-									canChain = true;
-							}
 						}
 						}
-						
-						if (canChain)
+					}
+
+					if (canChain)
+					{
+						bool isBetter;
+						bool isWorse;
+						CompareDeclTypes(checkMethodInstance->mMethodDef->mDeclaringType, methodInstance->mMethodDef->mDeclaringType, isBetter, isWorse);
+						if (isBetter && !isWorse)
+						{
+							methodInstance->mChainType = BfMethodChainType_ChainHead;
+							checkMethodInstance->mChainType = BfMethodChainType_ChainMember;
+						}
+						else
 						{
 						{
-							bool isBetter;
-							bool isWorse;
-							CompareDeclTypes(checkMethodInstance->mMethodDef->mDeclaringType, methodInstance->mMethodDef->mDeclaringType, isBetter, isWorse);
-							if (isBetter && !isWorse)
+							checkMethodInstance->mChainType = BfMethodChainType_ChainHead;
+							methodInstance->mChainType = BfMethodChainType_ChainMember;
+						}
+					}
+					else
+					{
+						if (!typeInstance->IsTypeMemberAccessible(checkMethod->mDeclaringType, methodDef->mDeclaringType))
+							continue;
+
+						bool silentlyAllow = false;
+						bool extensionWarn = false;
+						if (checkMethod->mDeclaringType != methodDef->mDeclaringType)
+						{
+							if (typeInstance->IsInterface())
 							{
 							{
-								methodInstance->mChainType = BfMethodChainType_ChainHead;
-								checkMethodInstance->mChainType = BfMethodChainType_ChainMember;								
+								if (methodDef->mIsOverride)
+									silentlyAllow = true;
 							}
 							}
 							else
 							else
 							{
 							{
-								checkMethodInstance->mChainType = BfMethodChainType_ChainHead;
-								methodInstance->mChainType = BfMethodChainType_ChainMember;
-							}
-						}
-						else
-						{
-							if (!typeInstance->IsTypeMemberAccessible(checkMethod->mDeclaringType, methodDef->mDeclaringType))
-								continue;
-														
-							bool silentlyAllow = false;
-							bool extensionWarn = false;
-							if (checkMethod->mDeclaringType != methodDef->mDeclaringType)
-							{								
-								if (typeInstance->IsInterface())
-								{									
-									if (methodDef->mIsOverride)
-										silentlyAllow = true;
+								if ((methodDef->mIsOverride) && (checkMethod->mIsExtern))
+								{
+									silentlyAllow = true;
+									methodInstance->mIsInnerOverride = true;
+									CheckOverridenMethod(methodInstance, checkMethodInstance);
 								}
 								}
-								else
+								else if ((methodDef->mDeclaringType->mProject != checkMethod->mDeclaringType->mProject) &&
+									(!checkMethod->mDeclaringType->IsExtension()))
 								{
 								{
-									if ((methodDef->mIsOverride) && (checkMethod->mIsExtern))
-									{
+									foundHiddenMethod = true;
+									if ((methodDef->mMethodType == BfMethodType_Ctor) && (methodDef->mIsStatic))
 										silentlyAllow = true;
 										silentlyAllow = true;
-										methodInstance->mIsInnerOverride = true;
-										CheckOverridenMethod(methodInstance, checkMethodInstance);
-									}
-									else if ((methodDef->mDeclaringType->mProject != checkMethod->mDeclaringType->mProject) &&
-										(!checkMethod->mDeclaringType->IsExtension()))
-									{
-										foundHiddenMethod = true;
-										if ((methodDef->mMethodType == BfMethodType_Ctor) && (methodDef->mIsStatic))
-											silentlyAllow = true;
-										else if (methodDef->mIsNew)
-											silentlyAllow = true;
-										else
-											extensionWarn = true;
-									}
-									else
+									else if (methodDef->mIsNew)
 										silentlyAllow = true;
 										silentlyAllow = true;
+									else
+										extensionWarn = true;
 								}
 								}
+								else
+									silentlyAllow = true;
 							}
 							}
+						}
 
 
-							if ((checkMethod->mCommutableKind == BfCommutableKind_Reverse) || (methodDef->mCommutableKind == BfCommutableKind_Reverse))
-								silentlyAllow = true;
-							
-							if (!silentlyAllow)
+						if ((checkMethod->mCommutableKind == BfCommutableKind_Reverse) || (methodDef->mCommutableKind == BfCommutableKind_Reverse))
+							silentlyAllow = true;
+
+						if (!silentlyAllow)
+						{
+							if ((!methodDef->mName.IsEmpty()) || (checkMethodInstance->mMethodDef->mIsOperator))
 							{
 							{
-								if ((!methodDef->mName.IsEmpty()) || (checkMethodInstance->mMethodDef->mIsOperator))
-								{
-									auto refNode = methodDef->GetRefNode();
-									BfError* bfError;
-									if (extensionWarn)
-										bfError = Warn(BfWarning_CS0114_MethodHidesInherited, 
-											StrFormat("This method hides a method in the root type definition. Use the 'new' keyword if the hiding was intentional. Note that this method is not callable from project '%s'.", 
-												checkMethod->mDeclaringType->mProject->mName.c_str()), refNode);
-									else
-										bfError = Fail("Method already declared with the same parameter types", refNode, true);
-									if (bfError != NULL)
-										mCompiler->mPassInstance->MoreInfo("First declaration", checkMethod->GetRefNode());
-								}
+								auto refNode = methodDef->GetRefNode();
+								BfError* bfError;
+								if (extensionWarn)
+									bfError = Warn(BfWarning_CS0114_MethodHidesInherited,
+										StrFormat("This method hides a method in the root type definition. Use the 'new' keyword if the hiding was intentional. Note that this method is not callable from project '%s'.",
+											checkMethod->mDeclaringType->mProject->mName.c_str()), refNode);
+								else
+									bfError = Fail("Method already declared with the same parameter types", refNode, true);
+								if (bfError != NULL)
+									mCompiler->mPassInstance->MoreInfo("First declaration", checkMethod->GetRefNode());
 							}
 							}
 						}
 						}
 					}
 					}
-				}
+				}				
 			}
 			}
 		}
 		}
 
 

+ 83 - 77
IDEHelper/Compiler/BfModuleTypeUtils.cpp

@@ -4370,103 +4370,109 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
 
 
 	BfLogSysM("Starting DoTypeInstanceMethodProcessing %p GetMethodInstance pass.  OnDemandMethods: %d\n", typeInstance, mOnDemandMethodCount);
 	BfLogSysM("Starting DoTypeInstanceMethodProcessing %p GetMethodInstance pass.  OnDemandMethods: %d\n", typeInstance, mOnDemandMethodCount);
 
 
-	// Pass 2
-	for (auto methodDef : typeDef->mMethods)
+	// Def passes. First non-overrides then overrides (for in-place overrides in methods)
+	for (int pass = 0; pass < 2; pass++)	
 	{
 	{
-		auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodDef->mIdx];
+		for (auto methodDef : typeDef->mMethods)
+		{			
+			if ((pass == 1) != (methodDef->mIsOverride))
+				continue;
 
 
-		if ((methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_AlwaysInclude) &&
-			(methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Decl_AwaitingDecl))
-		{
-			BfLogSysM("Skipping GetMethodInstance on MethodDef: %p OnDemandKind: %d\n", methodDef, methodInstanceGroup->mOnDemandKind);
-			continue;
-		}
+			auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodDef->mIdx];
 
 
-		if (methodDef->mMethodType == BfMethodType_Init)
-			continue;
+			if ((methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_AlwaysInclude) &&
+				(methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Decl_AwaitingDecl))
+			{
+				BfLogSysM("Skipping GetMethodInstance on MethodDef: %p OnDemandKind: %d\n", methodDef, methodInstanceGroup->mOnDemandKind);
+				continue;
+			}
 
 
-		int prevWorklistSize = (int)mContext->mMethodWorkList.size();
-		auto moduleMethodInstance = GetMethodInstance(typeInstance, methodDef, BfTypeVector(), ((methodDef->mGenericParams.size() != 0) || (typeInstance->IsUnspecializedType())) ? BfGetMethodInstanceFlag_UnspecializedPass : BfGetMethodInstanceFlag_None);
-				
-		auto methodInstance = moduleMethodInstance.mMethodInstance;
-		if (methodInstance == NULL)
-		{
-			BF_ASSERT(typeInstance->IsGenericTypeInstance() && (typeInstance->mTypeDef->mIsCombinedPartial));
-			continue;
-		}
+			if (methodDef->mMethodType == BfMethodType_Init)
+				continue;
 
 
-		if ((!mCompiler->mIsResolveOnly) &&
-			((methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference) || (!typeInstance->IsReified())))
-		{
-			bool forceMethodImpl = false;
+			int prevWorklistSize = (int)mContext->mMethodWorkList.size();
+			auto moduleMethodInstance = GetMethodInstance(typeInstance, methodDef, BfTypeVector(), ((methodDef->mGenericParams.size() != 0) || (typeInstance->IsUnspecializedType())) ? BfGetMethodInstanceFlag_UnspecializedPass : BfGetMethodInstanceFlag_None);
 
 
-			BfCustomAttributes* customAttributes = methodInstance->GetCustomAttributes();
-			if ((customAttributes != NULL) && (typeInstance->IsReified()))
+			auto methodInstance = moduleMethodInstance.mMethodInstance;
+			if (methodInstance == NULL)
 			{
 			{
-				for (auto& attr : customAttributes->mAttributes)
-				{
-					auto attrTypeInst = attr.mType->ToTypeInstance();
-					auto attrCustomAttributes = attrTypeInst->mCustomAttributes;
-					if (attrCustomAttributes == NULL)
-						continue;
+				BF_ASSERT(typeInstance->IsGenericTypeInstance() && (typeInstance->mTypeDef->mIsCombinedPartial));
+				continue;
+			}
+
+			if ((!mCompiler->mIsResolveOnly) &&
+				((methodInstanceGroup->mOnDemandKind == BfMethodOnDemandKind_Decl_AwaitingReference) || (!typeInstance->IsReified())))
+			{
+				bool forceMethodImpl = false;
 
 
-					for (auto& attrAttr : attrCustomAttributes->mAttributes)
+				BfCustomAttributes* customAttributes = methodInstance->GetCustomAttributes();
+				if ((customAttributes != NULL) && (typeInstance->IsReified()))
+				{
+					for (auto& attr : customAttributes->mAttributes)
 					{
 					{
-						if (attrAttr.mType->ToTypeInstance()->mTypeDef == mCompiler->mAttributeUsageAttributeTypeDef)
+						auto attrTypeInst = attr.mType->ToTypeInstance();
+						auto attrCustomAttributes = attrTypeInst->mCustomAttributes;
+						if (attrCustomAttributes == NULL)
+							continue;
+
+						for (auto& attrAttr : attrCustomAttributes->mAttributes)
 						{
 						{
-							// Check for Flags arg
-							if (attrAttr.mCtorArgs.size() < 2)
-								continue;														
-							auto constant = attrTypeInst->mConstHolder->GetConstant(attrAttr.mCtorArgs[1]);								
-							if (constant == NULL)
-								continue;
-							if (constant->mTypeCode == BfTypeCode_Boolean)
-								continue;
-							if ((constant->mInt8 & BfCustomAttributeFlags_AlwaysIncludeTarget) != 0)
-								forceMethodImpl = true;
+							if (attrAttr.mType->ToTypeInstance()->mTypeDef == mCompiler->mAttributeUsageAttributeTypeDef)
+							{
+								// Check for Flags arg
+								if (attrAttr.mCtorArgs.size() < 2)
+									continue;
+								auto constant = attrTypeInst->mConstHolder->GetConstant(attrAttr.mCtorArgs[1]);
+								if (constant == NULL)
+									continue;
+								if (constant->mTypeCode == BfTypeCode_Boolean)
+									continue;
+								if ((constant->mInt8 & BfCustomAttributeFlags_AlwaysIncludeTarget) != 0)
+									forceMethodImpl = true;
+							}
 						}
 						}
 					}
 					}
 				}
 				}
-			}
 
 
-			if (typeInstance->mTypeDef->mProject->mTargetType == BfTargetType_BeefTest)
-			{
-				if ((customAttributes != NULL) && (customAttributes->Contains(mCompiler->mTestAttributeTypeDef)))
+				if (typeInstance->mTypeDef->mProject->mTargetType == BfTargetType_BeefTest)
 				{
 				{
-					forceMethodImpl = true;					
+					if ((customAttributes != NULL) && (customAttributes->Contains(mCompiler->mTestAttributeTypeDef)))
+					{
+						forceMethodImpl = true;
+					}
 				}
 				}
-			}
 
 
-			if (forceMethodImpl)
-			{
-				if (!typeInstance->IsReified())
-					mContext->mScratchModule->PopulateType(typeInstance, BfPopulateType_Data);
-				// Reify method
-				mContext->mScratchModule->GetMethodInstance(typeInstance, methodDef, BfTypeVector());
-				BF_ASSERT(methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Decl_AwaitingReference);
+				if (forceMethodImpl)
+				{
+					if (!typeInstance->IsReified())
+						mContext->mScratchModule->PopulateType(typeInstance, BfPopulateType_Data);
+					// Reify method
+					mContext->mScratchModule->GetMethodInstance(typeInstance, methodDef, BfTypeVector());
+					BF_ASSERT(methodInstanceGroup->mOnDemandKind != BfMethodOnDemandKind_Decl_AwaitingReference);
+				}
 			}
 			}
-		}
 
 
 
 
-		bool methodUsedVirtually = false;
-		if (typeInstance->IsInterface())
-		{
-			if ((!methodDef->mIsConcrete) && (!methodDef->mIsStatic) && (!methodInstance->HasSelf()))
-				SlotInterfaceMethod(methodInstance);
-		}
-		else if (!methodDef->IsEmptyPartial())
-		{
-			methodUsedVirtually = SlotVirtualMethod(methodInstance, &ambiguityContext);
-		}
+			bool methodUsedVirtually = false;
+			if (typeInstance->IsInterface())
+			{
+				if ((!methodDef->mIsConcrete) && (!methodDef->mIsStatic) && (!methodInstance->HasSelf()))
+					SlotInterfaceMethod(methodInstance);
+			}
+			else if (!methodDef->IsEmptyPartial())
+			{
+				methodUsedVirtually = SlotVirtualMethod(methodInstance, &ambiguityContext);
+			}
 
 
-		// This is important for reducing latency of autocomplete popup, but it's important we don't allow the autocomplete
-		//  thread to cause any reentry issues by re-populating a type at an "inopportune time".  We do allow certain 
-		//  reentries in PopulateType, but not when we're resolving fields (for example)
-		if ((mContext->mFieldResolveReentrys.size() == 0) && (!mContext->mResolvingVarField))
-		{
-			disableYield.Release();
-			mSystem->CheckLockYield();
-			disableYield.Acquire();
+			// This is important for reducing latency of autocomplete popup, but it's important we don't allow the autocomplete
+			//  thread to cause any reentry issues by re-populating a type at an "inopportune time".  We do allow certain 
+			//  reentries in PopulateType, but not when we're resolving fields (for example)
+			if ((mContext->mFieldResolveReentrys.size() == 0) && (!mContext->mResolvingVarField))
+			{
+				disableYield.Release();
+				mSystem->CheckLockYield();
+				disableYield.Acquire();
+			}
 		}
 		}
 	}
 	}
 
 
@@ -11031,7 +11037,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
 
 
 						SizedArray<BfIRValue, 1> args;
 						SizedArray<BfIRValue, 1> args;
 						exprEvaluator.PushArg(castedFromValue, args);
 						exprEvaluator.PushArg(castedFromValue, args);
-						operatorOut = exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, IsSkippingExtraResolveChecks() ? BfIRValue() : moduleMethodInstance.mFunc, false, args);
+						operatorOut = exprEvaluator.CreateCall(NULL, moduleMethodInstance.mMethodInstance, IsSkippingExtraResolveChecks() ? BfIRValue() : moduleMethodInstance.mFunc, false, args);
 						if ((operatorOut.mType != NULL) && (operatorOut.mType->IsSelf()))
 						if ((operatorOut.mType != NULL) && (operatorOut.mType->IsSelf()))
 						{
 						{
 							BF_ASSERT(IsInGeneric());
 							BF_ASSERT(IsInGeneric());

+ 3 - 3
IDEHelper/Compiler/BfStmtEvaluator.cpp

@@ -760,7 +760,7 @@ void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, Siz
 	}	
 	}	
 
 
 	BfExprEvaluator expressionEvaluator(this);
 	BfExprEvaluator expressionEvaluator(this);
-	expressionEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, ((flags & BfDeferredBlockFlag_BypassVirtual) != 0), llvmArgs);
+	expressionEvaluator.CreateCall(NULL, moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, ((flags & BfDeferredBlockFlag_BypassVirtual) != 0), llvmArgs);
 
 
 	if ((flags & BfDeferredBlockFlag_DoNullChecks) != 0)
 	if ((flags & BfDeferredBlockFlag_DoNullChecks) != 0)
 	{
 	{
@@ -3956,7 +3956,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
 			BF_ASSERT(methodInstance->mMethodDef->mName == "~this");
 			BF_ASSERT(methodInstance->mMethodDef->mName == "~this");
 			SizedArray<BfIRValue, 4> llvmArgs;
 			SizedArray<BfIRValue, 4> llvmArgs;
 			llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(objectType)));
 			llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(objectType)));
-			expressionEvaluator.CreateCall(methodInstance, methodInstance->mIRFunction, false, llvmArgs);
+			expressionEvaluator.CreateCall(deleteStmt->mDeleteToken, methodInstance, methodInstance->mIRFunction, false, llvmArgs);
 		}
 		}
 
 
 		if ((deleteStmt->mTargetTypeToken != NULL) && (!isAppendDelete))
 		if ((deleteStmt->mTargetTypeToken != NULL) && (!isAppendDelete))
@@ -5998,7 +5998,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
 				SizedArray<BfIRValue, 1> args;
 				SizedArray<BfIRValue, 1> args;
 				auto castedTarget = Cast(forEachStmt->mCollectionExpression, target, getEnumeratorMethod.mMethodInstance->GetOwner());
 				auto castedTarget = Cast(forEachStmt->mCollectionExpression, target, getEnumeratorMethod.mMethodInstance->GetOwner());
 				exprEvaluator.PushThis(forEachStmt->mCollectionExpression, castedTarget, getEnumeratorMethod.mMethodInstance, args);
 				exprEvaluator.PushThis(forEachStmt->mCollectionExpression, castedTarget, getEnumeratorMethod.mMethodInstance, args);
-				itr = exprEvaluator.CreateCall(getEnumeratorMethod.mMethodInstance, IsSkippingExtraResolveChecks() ? BfIRValue() : getEnumeratorMethod.mFunc, false, args);
+				itr = exprEvaluator.CreateCall(forEachStmt->mCollectionExpression, getEnumeratorMethod.mMethodInstance, IsSkippingExtraResolveChecks() ? BfIRValue() : getEnumeratorMethod.mFunc, false, args);
 			}
 			}
 		}
 		}
 
 

+ 420 - 56
IDEHelper/Compiler/CeMachine.cpp

@@ -16,6 +16,13 @@ struct CeOpInfo
 	CeOperandInfoKind mOperandC;
 	CeOperandInfoKind mOperandC;
 };
 };
 
 
+#define CEOPINFO_SIZED_1(OPNAME, OPINFOA) \
+	{OPNAME##"_8", OPINFOA}, \
+	{OPNAME##"_16", OPINFOA}, \
+	{OPNAME##"_32", OPINFOA}, \
+	{OPNAME##"_64", OPINFOA}, \
+	{OPNAME##"_X", OPINFOA, CEOI_IMM32}
+
 #define CEOPINFO_SIZED_2(OPNAME, OPINFOA, OPINFOB) \
 #define CEOPINFO_SIZED_2(OPNAME, OPINFOA, OPINFOB) \
 	{OPNAME##"_8", OPINFOA, OPINFOB}, \
 	{OPNAME##"_8", OPINFOA, OPINFOB}, \
 	{OPNAME##"_16", OPINFOA, OPINFOB}, \
 	{OPNAME##"_16", OPINFOA, OPINFOB}, \
@@ -43,6 +50,11 @@ struct CeOpInfo
 	{OPNAME##"_I64", OPINFOA, OPINFOB}, \
 	{OPNAME##"_I64", OPINFOA, OPINFOB}, \
 	{OPNAME##"_F32", OPINFOA, OPINFOB}, \
 	{OPNAME##"_F32", OPINFOA, OPINFOB}, \
 	{OPNAME##"_F64", OPINFOA, OPINFOB}
 	{OPNAME##"_F64", OPINFOA, OPINFOB}
+#define CEOPINFO_SIZED_NUMERIC_3(OPNAME, OPINFOA, OPINFOB, OPINFOC) \
+	{OPNAME##"_I8", OPINFOA, OPINFOB, OPINFOC}, \
+	{OPNAME##"_I16", OPINFOA, OPINFOB, OPINFOC}, \
+	{OPNAME##"_I32", OPINFOA, OPINFOB, OPINFOC}, \
+	{OPNAME##"_I64", OPINFOA, OPINFOB, OPINFOC}
 #define CEOPINFO_SIZED_NUMERIC_PLUSF_3(OPNAME, OPINFOA, OPINFOB, OPINFOC) \
 #define CEOPINFO_SIZED_NUMERIC_PLUSF_3(OPNAME, OPINFOA, OPINFOB, OPINFOC) \
 	{OPNAME##"_I8", OPINFOA, OPINFOB, OPINFOC}, \
 	{OPNAME##"_I8", OPINFOA, OPINFOB, OPINFOC}, \
 	{OPNAME##"_I16", OPINFOA, OPINFOB, OPINFOC}, \
 	{OPNAME##"_I16", OPINFOA, OPINFOB, OPINFOC}, \
@@ -60,6 +72,7 @@ static CeOpInfo gOpInfo[] =
 	{"JmpIfNot", CEOI_None, CEOI_JMPREL, CEOI_FrameRef},
 	{"JmpIfNot", CEOI_None, CEOI_JMPREL, CEOI_FrameRef},
 	{"FrameAddr32", CEOI_FrameRef, CEOI_FrameRef},
 	{"FrameAddr32", CEOI_FrameRef, CEOI_FrameRef},
 	{"FrameAddr64", CEOI_FrameRef, CEOI_FrameRef},
 	{"FrameAddr64", CEOI_FrameRef, CEOI_FrameRef},
+	{"Zero",  CEOI_FrameRef, CEOI_IMM32},
 		
 		
 	{"Const_8", CEOI_FrameRef, CEOI_IMM8},
 	{"Const_8", CEOI_FrameRef, CEOI_IMM8},
 	{"Const_16", CEOI_FrameRef, CEOI_IMM16},
 	{"Const_16", CEOI_FrameRef, CEOI_IMM16},
@@ -71,15 +84,33 @@ static CeOpInfo gOpInfo[] =
 	CEOPINFO_SIZED_3("Store", CEOI_None, CEOI_FrameRef, CEOI_FrameRef),
 	CEOPINFO_SIZED_3("Store", CEOI_None, CEOI_FrameRef, CEOI_FrameRef),
 	CEOPINFO_SIZED_3("Move", CEOI_None, CEOI_FrameRef, CEOI_FrameRef),
 	CEOPINFO_SIZED_3("Move", CEOI_None, CEOI_FrameRef, CEOI_FrameRef),
 	CEOPINFO_SIZED_2("Push", CEOI_None, CEOI_FrameRef),
 	CEOPINFO_SIZED_2("Push", CEOI_None, CEOI_FrameRef),
+	CEOPINFO_SIZED_1("Pop", CEOI_FrameRef),
 
 
 	{"AdjustSP", CEOI_None, CEOI_FrameRef},
 	{"AdjustSP", CEOI_None, CEOI_FrameRef},
 	{"Call", CEOI_None, CEOI_IMM32},
 	{"Call", CEOI_None, CEOI_IMM32},
 
 
 	{"Conv_I32_I64", CEOI_FrameRef, CEOI_FrameRef},
 	{"Conv_I32_I64", CEOI_FrameRef, CEOI_FrameRef},
 
 
+	{"AddConst_I8", CEOI_FrameRef, CEOI_IMM8},
+	{"AddConst_I16", CEOI_FrameRef, CEOI_IMM16},
+	{"AddConst_I32", CEOI_FrameRef, CEOI_IMM32},
+	{"AddConst_I64", CEOI_FrameRef, CEOI_IMM64},
+	{"AddConst_F32", CEOI_FrameRef, CEOI_IMMF32},
+	{"AddConst_F64", CEOI_FrameRef, CEOI_IMMF64},
+
 	CEOPINFO_SIZED_NUMERIC_PLUSF_3("Add", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
 	CEOPINFO_SIZED_NUMERIC_PLUSF_3("Add", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
+	CEOPINFO_SIZED_NUMERIC_PLUSF_3("Sub", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
+	CEOPINFO_SIZED_NUMERIC_PLUSF_3("Mul", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
+	CEOPINFO_SIZED_NUMERIC_PLUSF_3("SDiv", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
+	CEOPINFO_SIZED_NUMERIC_3("UDiv", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
+	CEOPINFO_SIZED_NUMERIC_PLUSF_3("SMod", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
+	CEOPINFO_SIZED_NUMERIC_3("UMod", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
+
 	CEOPINFO_SIZED_NUMERIC_PLUSF_3("Cmp_EQ", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
 	CEOPINFO_SIZED_NUMERIC_PLUSF_3("Cmp_EQ", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
 	CEOPINFO_SIZED_NUMERIC_PLUSF_3("Cmp_SLT", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
 	CEOPINFO_SIZED_NUMERIC_PLUSF_3("Cmp_SLT", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
+	CEOPINFO_SIZED_NUMERIC_3("Cmp_ULT", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
+	CEOPINFO_SIZED_NUMERIC_PLUSF_3("Cmp_SLE", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
+	CEOPINFO_SIZED_NUMERIC_3("Cmp_ULE", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
 	//{"Cmp_SLT_I32", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef},
 	//{"Cmp_SLT_I32", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef},
 
 
 	CEOPINFO_SIZED_NUMERIC_PLUSF_2("Neg", CEOI_FrameRef, CEOI_FrameRef),
 	CEOPINFO_SIZED_NUMERIC_PLUSF_2("Neg", CEOI_FrameRef, CEOI_FrameRef),
@@ -441,12 +472,6 @@ void CeBuilder::EmitSizedOp(CeOp baseOp, const CeOperand& operand, CeOperand* ou
 	
 	
 	Emit(op);
 	Emit(op);
 
 
-	if (outResult != NULL)
-	{
-		*outResult = FrameAlloc(operand.mType);
-		EmitFrameOffset(*outResult);
-	}
-
 	if (!isStdSize)
 	if (!isStdSize)
 	{
 	{
 		if (!allowNonStdSize)
 		if (!allowNonStdSize)
@@ -454,6 +479,12 @@ void CeBuilder::EmitSizedOp(CeOp baseOp, const CeOperand& operand, CeOperand* ou
 		Emit((int32)operand.mType->mSize);
 		Emit((int32)operand.mType->mSize);
 	}
 	}
 
 
+	if (outResult != NULL)
+	{
+		*outResult = FrameAlloc(operand.mType);
+		EmitFrameOffset(*outResult);
+	}	
+
 	EmitFrameOffset(operand);		
 	EmitFrameOffset(operand);		
 }
 }
 
 
@@ -468,7 +499,7 @@ CeOperand CeBuilder::FrameAlloc(BeType* type)
 	return result;
 	return result;
 }
 }
 
 
-CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca)
+CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImmediate)
 {
 {
 	if (value == NULL)
 	if (value == NULL)
 		return CeOperand();
 		return CeOperand();
@@ -530,11 +561,20 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca)
 			CeOperand mcOperand;
 			CeOperand mcOperand;
 			switch (constant->mType->mTypeCode)
 			switch (constant->mType->mTypeCode)
 			{
 			{
-			case BeTypeCode_Boolean:
 			case BeTypeCode_Int8:
 			case BeTypeCode_Int8:
 			case BeTypeCode_Int16:
 			case BeTypeCode_Int16:
 			case BeTypeCode_Int32:
 			case BeTypeCode_Int32:
-			case BeTypeCode_Int64:			
+			case BeTypeCode_Int64:
+				if (allowImmediate)
+				{
+					CeOperand result;
+					result.mKind = CeOperandKind_Immediate;
+					result.mImmediate = constant->mInt32;
+					result.mType = constant->mType;
+					return result;
+				}
+
+			case BeTypeCode_Boolean:			
 			case BeTypeCode_Double:
 			case BeTypeCode_Double:
 				dataPtr = &constant->mUInt64;
 				dataPtr = &constant->mUInt64;
 				dataSize = constant->mType->mSize;
 				dataSize = constant->mType->mSize;
@@ -572,17 +612,25 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca)
 				}
 				}
 			}
 			}
 			break;
 			break;
-// 			case BeTypeCode_Struct:
-// 			case BeTypeCode_SizedArray:
-// 			case BeTypeCode_Vector:
-// 				mcOperand.mImmediate = constant->mInt64;
-// 				mcOperand.mKind = CeOperandKind_Immediate_i64;
-// 				break;
+ 			case BeTypeCode_Struct:
+ 			case BeTypeCode_SizedArray:
+ 			case BeTypeCode_Vector:
+				{
+					auto beType = constant->mType;
+					auto result = FrameAlloc(beType);
+					Emit(CeOp_Zero);
+					EmitFrameOffset(result);
+					Emit((int32)beType->mSize);
+					return result;
+				}
+ 				//mcOperand.mImmediate = constant->mInt64;
+ 				//mcOperand.mKind = CeOperandKind_Immediate_i64;
+ 				break;
 // 			default:
 // 			default:
 // 				Fail("Unhandled constant type");
 // 				Fail("Unhandled constant type");
 			}
 			}
 
 
-			if (dataPtr != NULL)
+			if (dataSize != 0)
 			{
 			{
 				auto beType = constant->mType;
 				auto beType = constant->mType;
 				auto result = FrameAlloc(beType);
 				auto result = FrameAlloc(beType);
@@ -592,7 +640,13 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca)
 				EmitFrameOffset(result);
 				EmitFrameOffset(result);
 				if (sizeClass == CeSizeClass_X)						
 				if (sizeClass == CeSizeClass_X)						
 					Emit((int32)dataSize);
 					Emit((int32)dataSize);
-				Emit(dataPtr, dataSize);				
+				if (dataPtr != 0)
+					Emit(dataPtr, dataSize);				
+				else
+				{
+					for (int i = 0; i < dataSize; i++)
+						Emit((uint8)0);
+				}
 
 
 				return result;
 				return result;
 			}						
 			}						
@@ -952,6 +1006,7 @@ void CeBuilder::Build()
 	dupMethodInstance.mMethodProcessRequest = NULL;
 	dupMethodInstance.mMethodProcessRequest = NULL;
 	dupMethodInstance.mIsReified = true;
 	dupMethodInstance.mIsReified = true;
 	dupMethodInstance.mHotMethod = NULL;
 	dupMethodInstance.mHotMethod = NULL;
+	dupMethodInstance.mInCEMachine = false; // Only have the original one
 
 
 	mCeMachine->mCeModule->ProcessMethod(&dupMethodInstance, true);
 	mCeMachine->mCeModule->ProcessMethod(&dupMethodInstance, true);
 
 
@@ -1147,6 +1202,24 @@ void CeBuilder::Build()
 					case BeBinaryOpKind_Add:
 					case BeBinaryOpKind_Add:
 						EmitBinaryOp(CeOp_Add_I8, CeOp_Add_F32, ceLHS, ceRHS, result);
 						EmitBinaryOp(CeOp_Add_I8, CeOp_Add_F32, ceLHS, ceRHS, result);
 						break;
 						break;
+					case BeBinaryOpKind_Subtract:
+						EmitBinaryOp(CeOp_Sub_I8, CeOp_Sub_F32, ceLHS, ceRHS, result);
+						break;
+					case BeBinaryOpKind_Multiply:
+						EmitBinaryOp(CeOp_Mul_I8, CeOp_Mul_F32, ceLHS, ceRHS, result);
+						break;
+					case BeBinaryOpKind_SDivide:
+						EmitBinaryOp(CeOp_SDiv_I8, CeOp_SDiv_F32, ceLHS, ceRHS, result);
+						break;
+					case BeBinaryOpKind_UDivide:
+						EmitBinaryOp(CeOp_UDiv_I8, CeOp_InvalidOp, ceLHS, ceRHS, result);
+						break;
+					case BeBinaryOpKind_SModulus:
+						EmitBinaryOp(CeOp_SMod_I8, CeOp_SMod_F32, ceLHS, ceRHS, result);
+						break;
+					case BeBinaryOpKind_UModulus:
+						EmitBinaryOp(CeOp_UMod_I8, CeOp_InvalidOp, ceLHS, ceRHS, result);
+						break;
 					default:
 					default:
 						Fail("Invalid binary op");
 						Fail("Invalid binary op");
 					}
 					}
@@ -1274,6 +1347,16 @@ void CeBuilder::Build()
 						iOp = CeOp_Cmp_SLT_I8;
 						iOp = CeOp_Cmp_SLT_I8;
 						fOp = CeOp_Cmp_SLT_F32;
 						fOp = CeOp_Cmp_SLT_F32;
 						break;
 						break;
+					case BeCmpKind_ULT:
+						iOp = CeOp_Cmp_ULT_I8;
+						break;
+					case BeCmpKind_SLE:
+						iOp = CeOp_Cmp_SLE_I8;
+						fOp = CeOp_Cmp_SLE_F32;
+						break;
+					case BeCmpKind_ULE:
+						iOp = CeOp_Cmp_ULE_I8;
+						break;
 					}
 					}
 
 
 					if (iOp == CeOp_InvalidOp)
 					if (iOp == CeOp_InvalidOp)
@@ -1299,6 +1382,128 @@ void CeBuilder::Build()
 // 					mcInst->mResult = result;
 // 					mcInst->mResult = result;
 				}
 				}
 				break;
 				break;
+			case BeGEPInst::TypeId:
+				{
+					auto castedInst = (BeGEPInst*)inst;
+
+					auto mcVal = GetOperand(castedInst->mPtr);
+					auto mcIdx0 = GetOperand(castedInst->mIdx0, false, true);
+
+					BePointerType* ptrType = (BePointerType*)mcVal.mType;
+					BF_ASSERT(ptrType->mTypeCode == BeTypeCode_Pointer);
+
+					result = mcVal;
+					if (castedInst->mIdx1 != NULL)
+					{
+						// We assume we never do both an idx0 and idx1 at once.  Fix if we change that.
+						BF_ASSERT(castedInst->mIdx0);
+
+						auto mcIdx1 = GetOperand(castedInst->mIdx1);
+						if (!mcIdx1.IsImmediate())
+						{
+							// This path is used when we have a const array that gets indexed by a non-const index value
+// 							if (ptrType->mElementType->mTypeCode == BeTypeCode_SizedArray)
+// 							{
+// 								auto arrayType = (BeSizedArrayType*)ptrType->mElementType;
+// 
+// 								auto elementPtrType = mModule->mContext->GetPointerTo(arrayType->mElementType);
+// 
+// 								auto ptrValue = AllocVirtualReg(elementPtrType);
+// 								auto ptrInfo = GetVRegInfo(ptrValue);
+// 								ptrInfo->mIsExpr = true;
+// 								ptrInfo->mRelTo = result;
+// 								CreateDefineVReg(ptrValue);
+// 								result = ptrValue;
+// 
+// 								BeMCOperand mcRelOffset;
+// 								int relScale = 1;
+// 								if (mcIdx1.IsImmediate())
+// 								{
+// 									mcRelOffset = BeMCOperand::FromImmediate(mcIdx1.mImmediate * arrayType->mElementType->mSize);
+// 								}
+// 								else
+// 								{
+// 									mcRelOffset = mcIdx1;
+// 									relScale = arrayType->mElementType->mSize;
+// 								}
+// 
+// 								result = AllocRelativeVirtualReg(elementPtrType, result, mcRelOffset, relScale);
+// 								// The def is primary to create a single 'master location' for the GEP vreg to become legalized before use
+// 								CreateDefineVReg(result);
+// 								//TODO: Always correct?
+// 								result.mKind = BeMCOperandKind_VReg;
+// 
+// 							}
+// 							else
+// 								SoftFail("Invalid GEP", inst->mDbgLoc);
+							Fail("Invalid GEP");
+						}
+						else
+						{
+							BF_ASSERT(mcIdx1.IsImmediate());
+							int byteOffset = 0;
+							BeType* elementType = NULL;
+							if (ptrType->mElementType->mTypeCode == BeTypeCode_Struct)
+							{
+								BeStructType* structType = (BeStructType*)ptrType->mElementType;
+								auto& structMember = structType->mMembers[mcIdx1.mImmediate];
+								elementType = structMember.mType;
+								byteOffset = structMember.mByteOffset;
+							}
+							else if (ptrType->mElementType->mTypeCode == BeTypeCode_SizedArray)
+							{
+								auto arrayType = (BeSizedArrayType*)ptrType->mElementType;
+								elementType = arrayType->mElementType;
+								byteOffset = mcIdx1.mImmediate * elementType->mSize;
+							}
+							else if (ptrType->mElementType->mTypeCode == BeTypeCode_Vector)
+							{
+								auto arrayType = (BeVectorType*)ptrType->mElementType;
+								elementType = arrayType->mElementType;
+								byteOffset = mcIdx1.mImmediate * elementType->mSize;
+							}
+							else
+							{
+								Fail("Invalid gep target");
+							}
+							
+							auto elementPtrType = beModule->mContext->GetPointerTo(elementType);
+							
+							
+
+							//result = AllocRelativeVirtualReg(elementPtrType, result, GetImmediate(byteOffset), 1);
+							// The def is primary to create a single 'master location' for the GEP vreg to become legalized before use
+							//CreateDefineVReg(result);
+							//result.mKind = BeMCOperandKind_VReg;
+						}
+					}
+					else
+					{
+						// It's temping to do a (IsNonZero) precondition, but if we make a reference to a VReg that is NOT in Addr form,
+						//  then this will encode that so we will know we need to do a Load on that value at the Def during legalization
+
+						Fail("Unhandled gep");
+
+// 						BeMCOperand mcRelOffset;
+// 						int relScale = 1;
+// 						if (mcIdx0.IsImmediate())
+// 						{
+// 							mcRelOffset = BeMCOperand::FromImmediate(mcIdx0.mImmediate * ptrType->mElementType->mSize);
+// 						}
+// 						else
+// 						{
+// 							mcRelOffset = mcIdx0;
+// 							relScale = ptrType->mElementType->mSize;
+// 						}
+// 
+// 						result = AllocRelativeVirtualReg(ptrType, result, mcRelOffset, relScale);
+// 						// The def is primary to create a single 'master location' for the GEP vreg to become legalized before use
+// 						CreateDefineVReg(result);
+// 						//TODO: Always correct?
+// 						result.mKind = BeMCOperandKind_VReg;
+					}
+				}
+				break;
 			case BeBrInst::TypeId:
 			case BeBrInst::TypeId:
 				{
 				{
 					auto castedInst = (BeBrInst*)inst;
 					auto castedInst = (BeBrInst*)inst;
@@ -1373,7 +1578,7 @@ void CeBuilder::Build()
 					bool isVarArg = false;
 					bool isVarArg = false;
 
 
 					bool useAltArgs = false;
 					bool useAltArgs = false;
-					SizedArray<BeValue*, 6> args;
+					//SizedArray<BeValue*, 6> args;
 
 
 					int callIdx = -1;
 					int callIdx = -1;
 
 
@@ -1394,6 +1599,13 @@ void CeBuilder::Build()
 
 
 						callIdx = *callIdxPtr;
 						callIdx = *callIdxPtr;
 
 
+						for (int argIdx = (int)castedInst->mArgs.size() - 1; argIdx >= 0; argIdx--)
+						{
+							auto& arg = castedInst->mArgs[argIdx];
+							auto ceArg = GetOperand(arg.mValue);
+							EmitSizedOp(CeOp_Push_8, ceArg, NULL, true);
+						}
+
 						int stackAdjust = 0;
 						int stackAdjust = 0;
 
 
 						auto beFuncType = beFunction->GetFuncType();
 						auto beFuncType = beFunction->GetFuncType();
@@ -1407,6 +1619,12 @@ void CeBuilder::Build()
 						Emit(CeOp_Call);
 						Emit(CeOp_Call);
 						Emit((int32)callIdx);
 						Emit((int32)callIdx);
 
 
+						if (beFuncType->mReturnType->mSize > 0)
+						{
+							result = FrameAlloc(beFuncType->mReturnType);
+							EmitSizedOp(CeOp_Pop_8, result, NULL, true);
+						}
+
 						if (stackAdjust > 0)
 						if (stackAdjust > 0)
 						{
 						{
 							Emit(CeOp_AdjustSP);
 							Emit(CeOp_AdjustSP);
@@ -1497,6 +1715,8 @@ CeMachine::CeMachine(BfCompiler* compiler)
 	mCeModule = NULL;	
 	mCeModule = NULL;	
 	mStackMin = NULL;
 	mStackMin = NULL;
 	mRevision = 0;
 	mRevision = 0;
+	mCurTargetSrc = NULL;
+	mCurModule = NULL;
 }
 }
 
 
 CeMachine::~CeMachine()
 CeMachine::~CeMachine()
@@ -1504,6 +1724,11 @@ CeMachine::~CeMachine()
 	delete mCeModule;
 	delete mCeModule;
 }
 }
 
 
+void CeMachine::Fail(const CeFrame& curFrame, const StringImpl& str)
+{
+	mCurModule->Fail(str, mCurTargetSrc);
+}
+
 void CeMachine::Init()
 void CeMachine::Init()
 {
 {
 	mCeModule = new BfModule(mCompiler->mContext, "__constEval");
 	mCeModule = new BfModule(mCompiler->mContext, "__constEval");
@@ -1535,8 +1760,12 @@ void CeMachine::RemoveMethod(BfMethodInstance* methodInstance)
 {
 {
 	auto itr = mFunctions.Find(methodInstance);
 	auto itr = mFunctions.Find(methodInstance);
 	auto ceFunction = itr->mValue;
 	auto ceFunction = itr->mValue;
-	mNamedFunctionMap.Remove(ceFunction->mName);
-	mFunctions.Remove(itr);
+	BF_ASSERT(itr != mFunctions.end());
+	if (itr != mFunctions.end())
+	{
+		mNamedFunctionMap.Remove(ceFunction->mName);
+		mFunctions.Remove(itr);
+	}
 }
 }
 
 
 int CeMachine::GetConstantSize(BfConstant* constant)
 int CeMachine::GetConstantSize(BfConstant* constant)
@@ -1607,6 +1836,12 @@ void CeMachine::WriteConstant(uint8* ptr, BfConstant* constant)
 		return;
 		return;
 	}
 	}
 }
 }
+#define CE_CHECKSTACK() \
+	if (stackPtr < mStackMin) \
+	{ \
+		_Fail("Stack overflow"); \
+		return false; \
+	}
 
 
 #define CE_GETINST(T) *((T*)(instPtr += sizeof(T)) - 1)
 #define CE_GETINST(T) *((T*)(instPtr += sizeof(T)) - 1)
 #define CE_GETFRAME(T) *(T*)(framePtr + *((int32*)(instPtr += sizeof(int32)) - 1))
 #define CE_GETFRAME(T) *(T*)(framePtr + *((int32*)(instPtr += sizeof(int32)) - 1))
@@ -1636,27 +1871,50 @@ void CeMachine::WriteConstant(uint8* ptr, BfConstant* constant)
 		auto val = CE_GETFRAME(TFROM); \
 		auto val = CE_GETFRAME(TFROM); \
 		result = (TTO)val; \
 		result = (TTO)val; \
 	}
 	}
-#define CE_MOVE(T) \
+#define CEOP_MOVE(T) \
 	{ \
 	{ \
 		auto val = CE_GETFRAME(T); \
 		auto val = CE_GETFRAME(T); \
 		auto& ptr = CE_GETFRAME(T); \
 		auto& ptr = CE_GETFRAME(T); \
 		ptr = val; \
 		ptr = val; \
 	}
 	}
+#define CEOP_PUSH(T) \
+	{ \
+		stackPtr -= sizeof(T); \
+		auto val = CE_GETFRAME(T); \
+		*((T*)stackPtr) = val; \
+		CE_CHECKSTACK(); \
+	}
+#define CEOP_POP(T) \
+	{ \
+		auto& result = CE_GETFRAME(T); \
+		result = *((T*)stackPtr); \
+		stackPtr += sizeof(T); \
+	}
 
 
-bool CeMachine::Execute()
+bool CeMachine::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr)
 {	
 {	
-	uint8* memStart = &mMemory[0];
-	uint8* framePtr;
-	uint8* instPtr;
-	uint8* stackPtr;
-	// 
+	CeFunction* ceFunction = startFunction;
+	uint8* memStart = &mMemory[0];	
+	uint8* instPtr = &ceFunction->mCode[0];
+	uint8* stackPtr = startStackPtr;
+	uint8* framePtr = startFramePtr;
+	
+	auto _GetCurFrame = [&]()
 	{
 	{
-		auto& ceFrame = mCallStack.back();
-		instPtr = ceFrame.mInstPtr;
-		stackPtr = ceFrame.mStackPtr;
-		framePtr = ceFrame.mFramePtr;
-		framePtr = mCallStack.back().mFramePtr;
-	}
+		CeFrame ceFrame;
+		ceFrame.mFunction = ceFunction;
+		ceFrame.mFramePtr = framePtr;
+		ceFrame.mStackPtr = stackPtr;
+		ceFrame.mInstPtr = instPtr;
+		return ceFrame;
+	};
+
+	auto _Fail = [&](const StringImpl& error)
+	{
+		Fail(_GetCurFrame(), error);
+	};
+	
+	int callCount = 0;
 
 
 	while (true)
 	while (true)
 	{
 	{
@@ -1665,15 +1923,16 @@ bool CeMachine::Execute()
 		{
 		{
 		case CeOp_Ret:
 		case CeOp_Ret:
 			{
 			{
+				if (mCallStack.mSize == 0)
+					return true;
+
 				auto& ceFrame = mCallStack.back();
 				auto& ceFrame = mCallStack.back();
+				ceFunction = ceFrame.mFunction;
 				instPtr = ceFrame.mInstPtr;
 				instPtr = ceFrame.mInstPtr;
 				stackPtr = ceFrame.mStackPtr;
 				stackPtr = ceFrame.mStackPtr;
 				framePtr = ceFrame.mFramePtr;
 				framePtr = ceFrame.mFramePtr;
 
 
-				mCallStack.pop_back();
-
-				if (mCallStack.mSize == 0)
-					return true;
+				mCallStack.pop_back();				
 			}
 			}
 			break;
 			break;
 		case CeOp_Jmp:
 		case CeOp_Jmp:
@@ -1705,6 +1964,13 @@ bool CeMachine::Execute()
 				result = addr - memStart;
 				result = addr - memStart;
 			}
 			}
 			break;
 			break;
+		case CeOp_Zero:
+			{
+				auto resultPtr = &CE_GETFRAME(uint8);
+				int32 constSize = CE_GETINST(int32);
+				memset(resultPtr, 0, constSize);
+			}
+			break;
 		case CeOp_Const_8:
 		case CeOp_Const_8:
 			{
 			{
 				auto& result = CE_GETFRAME(int8);
 				auto& result = CE_GETFRAME(int8);
@@ -1749,18 +2015,93 @@ bool CeMachine::Execute()
 				}
 				}
 				result = *(uint32*)(memStart + ceAddr);
 				result = *(uint32*)(memStart + ceAddr);
 			}
 			}
-			break;		
+			break;
 		case CeOp_Move_8:
 		case CeOp_Move_8:
-			CE_MOVE(int8);
+			CEOP_MOVE(int8);
 			break;
 			break;
 		case CeOp_Move_16:
 		case CeOp_Move_16:
-			CE_MOVE(int16);
+			CEOP_MOVE(int16);
 			break;
 			break;
 		case CeOp_Move_32:
 		case CeOp_Move_32:
-			CE_MOVE(int32);
+			CEOP_MOVE(int32);
 			break;
 			break;
 		case CeOp_Move_64:
 		case CeOp_Move_64:
-			CE_MOVE(int64);	
+			CEOP_MOVE(int64);	
+			break;
+		case CeOp_Move_X:
+			{
+				int32 size = CE_GETINST(int32);
+				auto valPtr = &CE_GETFRAME(uint8);
+				auto destPtr = &CE_GETFRAME(uint8);
+				memcpy(destPtr, valPtr, size);
+			}
+			break;
+		case CeOp_Push_8:
+			CEOP_PUSH(int8);
+			break;
+		case CeOp_Push_16:
+			CEOP_PUSH(int16);
+			break;
+		case CeOp_Push_32:
+			CEOP_PUSH(int32);
+			break;
+		case CeOp_Push_64:
+			CEOP_PUSH(int64);
+			break;
+		case CeOp_Pop_8:
+			CEOP_POP(int8);
+			break;
+		case CeOp_Pop_16:
+			CEOP_POP(int16);
+			break;
+		case CeOp_Pop_32:
+			CEOP_POP(int32);
+			break;
+		case CeOp_Pop_64:
+			CEOP_POP(int64);
+			break;
+		case CeOp_AdjustSP:
+			{
+				int32 adjust = CE_GETINST(int32);
+				stackPtr += adjust;
+			}
+			break;
+		case CeOp_Call:
+			{
+				callCount++;
+
+				int32 callIdx = CE_GETINST(int32);
+				auto& callEntry = ceFunction->mCallTable[callIdx];
+				if (callEntry.mBindRevision != mRevision)
+				{
+					callEntry.mFunction = NULL;
+					mNamedFunctionMap.TryGetValue(callEntry.mFunctionName, &callEntry.mFunction);
+					callEntry.mBindRevision = mRevision;
+				}
+
+				if (callEntry.mFunction == NULL)
+				{
+					_Fail("Unable to locate function entry");
+					break;
+				}
+
+// 				if (callEntry.mFunction->mName.Contains("__static_dump"))
+// 				{
+// 					int32 val = *(int32*)(stackPtr);
+// 					OutputDebugStrF("__static_dump: %d\n", val);
+// 				}
+
+				if (callEntry.mFunction != NULL)
+				{
+					mCallStack.Add(_GetCurFrame());
+
+					ceFunction = callEntry.mFunction;
+					framePtr = stackPtr;
+					stackPtr -= ceFunction->mFrameSize;
+					instPtr = &ceFunction->mCode[0];
+					CE_CHECKSTACK();
+				}
+			}
 			break;
 			break;
 		case CeOp_Conv_I32_I64:
 		case CeOp_Conv_I32_I64:
 			CE_CAST(int32, int64);
 			CE_CAST(int32, int64);
@@ -1771,12 +2112,36 @@ bool CeMachine::Execute()
 		case CeOp_Add_I64:
 		case CeOp_Add_I64:
 			CEOP_BIN(+, int64);
 			CEOP_BIN(+, int64);
 			break;
 			break;
+		case CeOp_Sub_I32:
+			CEOP_BIN(-, int32);
+			break;
+		case CeOp_Sub_I64:
+			CEOP_BIN(-, int64);
+			break;
+		case CeOp_Mul_I32:
+			CEOP_BIN(*, int32);
+			break;
+		case CeOp_Mul_I64:
+			CEOP_BIN(*, int64);
+			break;
 		case CeOp_Cmp_EQ_I32:
 		case CeOp_Cmp_EQ_I32:
 			CEOP_CMP(==, int32);
 			CEOP_CMP(==, int32);
 			break;
 			break;
 		case CeOp_Cmp_SLT_I32:
 		case CeOp_Cmp_SLT_I32:
 			CEOP_CMP(<, int32);
 			CEOP_CMP(<, int32);
 			break;
 			break;
+		case CeOp_Cmp_ULT_I32:
+			CEOP_CMP(<, uint32);
+			break;
+		case CeOp_Cmp_SLE_I32:
+			CEOP_CMP(<=, int32);
+			break;
+		case CeOp_Cmp_SLE_I64:
+			CEOP_CMP(<= , int64);
+			break;
+		case CeOp_Cmp_ULE_I32:
+			CEOP_CMP(<=, uint32);
+			break;
 		case CeOp_Neg_I32:
 		case CeOp_Neg_I32:
 			CEOP_UNARY(-, int32);
 			CEOP_UNARY(-, int32);
 			break;
 			break;
@@ -1784,7 +2149,7 @@ bool CeMachine::Execute()
 			CEOP_UNARY(-, int64);
 			CEOP_UNARY(-, int64);
 			break;
 			break;
 		default:
 		default:
-			BF_FATAL("CeMachine op failure");
+			_Fail("Unhandled op");
 			return false;
 			return false;
 		}
 		}
 	}
 	}
@@ -1829,12 +2194,13 @@ void CeMachine::ProcessWorkQueue()
 	}
 	}
 }
 }
 
 
-CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance)
+CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, bool& added)
 {		
 {		
 	CeFunction** functionValuePtr = NULL;
 	CeFunction** functionValuePtr = NULL;
 	CeFunction* ceFunction = NULL;
 	CeFunction* ceFunction = NULL;
 	if (mFunctions.TryAdd(methodInstance, NULL, &functionValuePtr))
 	if (mFunctions.TryAdd(methodInstance, NULL, &functionValuePtr))
 	{
 	{
+		added = true;
 		auto module = methodInstance->GetOwner()->mModule;
 		auto module = methodInstance->GetOwner()->mModule;
 		
 		
 		BF_ASSERT(!methodInstance->mInCEMachine);
 		BF_ASSERT(!methodInstance->mInCEMachine);
@@ -1852,12 +2218,13 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance)
 
 
 void CeMachine::QueueMethod(BfMethodInstance* methodInstance)
 void CeMachine::QueueMethod(BfMethodInstance* methodInstance)
 {
 {
-	auto ceFunction = GetFunction(methodInstance);
-	if (!ceFunction->mInitialized)
+	bool added = false;
+	auto ceFunction = GetFunction(methodInstance, added);
+	if (added)
 		mWorkQueue.Add(ceFunction);
 		mWorkQueue.Add(ceFunction);
 }
 }
 
 
-BfTypedValue CeMachine::Call(BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags)
+BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags)
 {	
 {	
 // 	for (int argIdx = 0; argIdx < (int)args.size(); argIdx++)
 // 	for (int argIdx = 0; argIdx < (int)args.size(); argIdx++)
 // 	{
 // 	{
@@ -1869,6 +2236,9 @@ BfTypedValue CeMachine::Call(BfModule* module, BfMethodInstance* methodInstance,
 	// DISABLED
 	// DISABLED
 	return BfTypedValue();
 	return BfTypedValue();
 
 
+	SetAndRestoreValue<BfAstNode*> prevTargetSrc(mCurTargetSrc, targetSrc);
+	SetAndRestoreValue<BfModule*> prevModule(mCurModule, module);
+
 	BF_ASSERT(mCallStack.IsEmpty());
 	BF_ASSERT(mCallStack.IsEmpty());
 	
 	
 	auto methodDef = methodInstance->mMethodDef;
 	auto methodDef = methodInstance->mMethodDef;
@@ -1878,7 +2248,8 @@ BfTypedValue CeMachine::Call(BfModule* module, BfMethodInstance* methodInstance,
 			return BfTypedValue();
 			return BfTypedValue();
 	}
 	}
 
 
-	CeFunction* ceFunction = GetFunction(methodInstance);
+	bool added = false;
+	CeFunction* ceFunction = GetFunction(methodInstance, added);
 	if (!ceFunction->mInitialized)
 	if (!ceFunction->mInitialized)
 	{
 	{
 		PrepareFunction(ceFunction);
 		PrepareFunction(ceFunction);
@@ -1914,14 +2285,7 @@ BfTypedValue CeMachine::Call(BfModule* module, BfMethodInstance* methodInstance,
 		retPtr = stackPtr;
 		retPtr = stackPtr;
 	}
 	}
 
 
-	CeFrame ceFrame;
-	ceFrame.mFunction = ceFunction;
-	ceFrame.mFramePtr = stackPtr;
-	ceFrame.mStackPtr = stackPtr - ceFunction->mFrameSize;
-	ceFrame.mInstPtr = &ceFunction->mCode[0];
-	mCallStack.Add(ceFrame);	
-	
-	bool success = Execute();
+	bool success = Execute(ceFunction, stackPtr - ceFunction->mFrameSize, stackPtr);
 
 
 	mCallStack.Clear();
 	mCallStack.Clear();
 	
 	

+ 34 - 8
IDEHelper/Compiler/CeMachine.h

@@ -49,20 +49,32 @@ enum CeOp : int16
 	CeOp_FrameAddr32,
 	CeOp_FrameAddr32,
 	CeOp_FrameAddr64,
 	CeOp_FrameAddr64,
 
 
+	CeOp_Zero,
 	CEOP_SIZED(Const),
 	CEOP_SIZED(Const),
 	CEOP_SIZED(Load),
 	CEOP_SIZED(Load),
-	CEOP_SIZED(Store),	
+	CEOP_SIZED(Store),
 	CEOP_SIZED(Move),
 	CEOP_SIZED(Move),
 	CEOP_SIZED(Push),
 	CEOP_SIZED(Push),
-	
+	CEOP_SIZED(Pop),
+
 	CeOp_AdjustSP,
 	CeOp_AdjustSP,
 	CeOp_Call,
 	CeOp_Call,
 
 
 	CeOp_Conv_I32_I64,
 	CeOp_Conv_I32_I64,
 
 
-	CEOP_SIZED_NUMERIC_PLUSF(Add),	
+	CEOP_SIZED_NUMERIC_PLUSF(AddConst),
+	CEOP_SIZED_NUMERIC_PLUSF(Add),
+	CEOP_SIZED_NUMERIC_PLUSF(Sub),
+	CEOP_SIZED_NUMERIC_PLUSF(Mul),	
+	CEOP_SIZED_NUMERIC_PLUSF(SDiv),
+	CEOP_SIZED_NUMERIC(UDiv),
+	CEOP_SIZED_NUMERIC_PLUSF(SMod),
+	CEOP_SIZED_NUMERIC(UMod),
 	CEOP_SIZED_NUMERIC_PLUSF(Cmp_EQ),
 	CEOP_SIZED_NUMERIC_PLUSF(Cmp_EQ),
 	CEOP_SIZED_NUMERIC_PLUSF(Cmp_SLT),
 	CEOP_SIZED_NUMERIC_PLUSF(Cmp_SLT),
+	CEOP_SIZED_NUMERIC(Cmp_ULT),
+	CEOP_SIZED_NUMERIC_PLUSF(Cmp_SLE),
+	CEOP_SIZED_NUMERIC(Cmp_ULE),
 
 
 	CEOP_SIZED_NUMERIC_PLUSF(Neg),
 	CEOP_SIZED_NUMERIC_PLUSF(Neg),
 
 
@@ -127,6 +139,7 @@ enum CeOperandKind
 	CeOperandKind_FrameOfs,
 	CeOperandKind_FrameOfs,
 	CeOperandKind_AllocaAddr,
 	CeOperandKind_AllocaAddr,
 	CeOperandKind_Block,
 	CeOperandKind_Block,
+	CeOperandKind_Immediate
 };
 };
 
 
 class CeOperand
 class CeOperand
@@ -137,6 +150,7 @@ public:
 	{
 	{
 		int mFrameOfs;
 		int mFrameOfs;
 		int mBlockIdx;
 		int mBlockIdx;
+		int mImmediate;
 	};
 	};
 	BeType* mType;
 	BeType* mType;
 
 
@@ -152,6 +166,11 @@ public:
 	{
 	{
 		return mKind != CeOperandKind_None;
 		return mKind != CeOperandKind_None;
 	}
 	}
+
+	bool IsImmediate()
+	{
+		return mKind == CeOperandKind_Immediate;
+	}
 };
 };
 
 
 #define BF_CE_STACK_SIZE 1024*1024
 #define BF_CE_STACK_SIZE 1024*1024
@@ -164,6 +183,8 @@ enum CeOperandInfoKind
 	CEOI_IMM16,
 	CEOI_IMM16,
 	CEOI_IMM32,
 	CEOI_IMM32,
 	CEOI_IMM64,
 	CEOI_IMM64,
+	CEOI_IMMF32,
+	CEOI_IMMF64,
 	CEOI_IMM_VAR,
 	CEOI_IMM_VAR,
 	CEOI_JMPREL
 	CEOI_JMPREL
 };
 };
@@ -254,7 +275,7 @@ public:
 	void Fail(const StringImpl& error);
 	void Fail(const StringImpl& error);
 
 
 	CeOperand FrameAlloc(BeType* type);
 	CeOperand FrameAlloc(BeType* type);
-	CeOperand GetOperand(BeValue* value, bool allowAlloca = false);
+	CeOperand GetOperand(BeValue* value, bool allowAlloca = false, bool allowImmediate = false);
 	CeSizeClass GetSizeClass(int size);
 	CeSizeClass GetSizeClass(int size);
 	int GetCodePos();
 	int GetCodePos();
 
 
@@ -309,25 +330,30 @@ public:
 	uint8* mStackMin;
 	uint8* mStackMin;
 	Array<CeFunction*> mWorkQueue;
 	Array<CeFunction*> mWorkQueue;
 
 
+	BfAstNode* mCurTargetSrc;
+	BfModule* mCurModule;
+
 public:
 public:
 	CeMachine(BfCompiler* compiler);
 	CeMachine(BfCompiler* compiler);
 	~CeMachine();
 	~CeMachine();
 	
 	
+	void Fail(const CeFrame& curFrame, const StringImpl& error);
+
 	void Init();	
 	void Init();	
 	void RemoveMethod(BfMethodInstance* methodInstance);
 	void RemoveMethod(BfMethodInstance* methodInstance);
 	int GetConstantSize(BfConstant* constant);
 	int GetConstantSize(BfConstant* constant);
 	void WriteConstant(uint8* ptr, BfConstant* constant);
 	void WriteConstant(uint8* ptr, BfConstant* constant);
 	void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);		
 	void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);		
-	bool Execute();
+	bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr);
 
 
 	void PrepareFunction(CeFunction* methodInstance);
 	void PrepareFunction(CeFunction* methodInstance);
-	void ProcessWorkQueue();
-	CeFunction* GetFunction(BfMethodInstance* methodInstance);
+	void ProcessWorkQueue();	
+	CeFunction* GetFunction(BfMethodInstance* methodInstance, bool& added);
 
 
 public:
 public:
 	void CompileStarted();
 	void CompileStarted();
 	void QueueMethod(BfMethodInstance* methodInstance);
 	void QueueMethod(BfMethodInstance* methodInstance);
-	BfTypedValue Call(BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags);
+	BfTypedValue Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags);
 };
 };
 
 
 NS_BF_END
 NS_BF_END