本文整理汇总了C#中ProtoCore.DSASM.StackFrame类的典型用法代码示例。如果您正苦于以下问题:C# StackFrame类的具体用法?C# StackFrame怎么用?C# StackFrame使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
StackFrame类属于ProtoCore.DSASM命名空间,在下文中一共展示了StackFrame类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: GetExactMatchStatistics
/// <summary>
/// For a given list of formal parameters, get the function end points that resolve
/// </summary>
/// <param name="context"></param>
/// <param name="formalParams"></param>
/// <param name="replicationInstructions"></param>
/// <param name="stackFrame"></param>
/// <param name="core"></param>
/// <param name="unresolvable">The number of argument sets that couldn't be resolved</param>
/// <returns></returns>
public Dictionary<FunctionEndPoint, int> GetExactMatchStatistics(
Runtime.Context context,
List<List<StackValue>> reducedFormalParams, StackFrame stackFrame, RuntimeCore runtimeCore, out int unresolvable)
{
List<ReplicationInstruction> replicationInstructions = new List<ReplicationInstruction>(); //We've already done the reduction before calling this
unresolvable = 0;
Dictionary<FunctionEndPoint, int> ret = new Dictionary<FunctionEndPoint, int>();
foreach (List<StackValue> formalParamSet in reducedFormalParams)
{
List<FunctionEndPoint> feps = GetExactTypeMatches(context,
formalParamSet, replicationInstructions, stackFrame,
runtimeCore);
if (feps.Count == 0)
{
//We have an arugment set that couldn't be resolved
unresolvable++;
}
foreach (FunctionEndPoint fep in feps)
{
if (ret.ContainsKey(fep))
ret[fep]++;
else
ret.Add(fep, 1);
}
}
return ret;
}
示例2: Evaluate
public StackValue Evaluate(List<StackValue> args, StackFrame stackFrame)
{
//
// Build the stackframe
int classScopeCaller = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kClass).opdata;
int returnAddr = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kReturnAddress).opdata;
int blockDecl = (int)mProcNode.runtimeIndex;
int blockCaller = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kFunctionCallerBlock).opdata;
int framePointer = mRunTime.runtime.Core.Rmem.FramePointer;
StackValue thisPtr = StackUtils.BuildPointer(-1);
// Comment Jun: the caller type is the current type in the stackframe
StackFrameType callerType = (StackFrameType)stackFrame.GetAt(StackFrame.AbsoluteIndex.kStackFrameType).opdata;
StackFrameType type = StackFrameType.kTypeFunction;
int depth = 0;
List<StackValue> registers = new List<StackValue>();
// Comment Jun: Calling convention data is stored on the TX register
StackValue svCallconvention = StackUtils.BuildNode(AddressType.CallingConvention, (long)ProtoCore.DSASM.CallingConvention.BounceType.kImplicit);
mRunTime.runtime.TX = svCallconvention;
StackValue svBlockDecl = StackUtils.BuildNode(AddressType.BlockIndex, blockDecl);
mRunTime.runtime.SX = svBlockDecl;
mRunTime.runtime.SaveRegisters(registers);
ProtoCore.DSASM.StackFrame newStackFrame = new StackFrame(thisPtr, classScopeCaller, 1, returnAddr, blockDecl, blockCaller, callerType, type, depth, framePointer, registers);
List<List<int>> replicationGuides = new List<List<int>>();
if (mRunTime.runtime.Core.Options.IDEDebugMode && mRunTime.runtime.Core.ExecMode != ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
{
mRunTime.runtime.Core.DebugProps.SetUpCallrForDebug(mRunTime.runtime.Core, mRunTime.runtime, mProcNode, returnAddr - 1,
false, mCallSite, args, replicationGuides, newStackFrame);
}
StackValue rx = mCallSite.JILDispatchViaNewInterpreter(new Runtime.Context(), args, replicationGuides, newStackFrame, mRunTime.runtime.Core);
if (mRunTime.runtime.Core.Options.IDEDebugMode && mRunTime.runtime.Core.ExecMode != ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
{
mRunTime.runtime.Core.DebugProps.RestoreCallrForNoBreak(mRunTime.runtime.Core, mProcNode);
}
return rx;
}
示例3: CanGetExactMatchStatics
/// <summary>
/// For a given list of formal parameters, get the function end points that resolve
/// </summary>
/// <param name="context"></param>
/// <param name="formalParams"></param>
/// <param name="replicationInstructions"></param>
/// <param name="stackFrame"></param>
/// <param name="core"></param>
/// <param name="unresolvable">The number of argument sets that couldn't be resolved</param>
/// <returns></returns>
public bool CanGetExactMatchStatics(
Runtime.Context context,
List<List<StackValue>> reducedFormalParams,
StackFrame stackFrame,
RuntimeCore runtimeCore,
out HashSet<FunctionEndPoint> lookup)
{
lookup = new HashSet<FunctionEndPoint>();
foreach (List<StackValue> formalParamSet in reducedFormalParams)
{
List<FunctionEndPoint> feps = GetExactTypeMatches(context, formalParamSet, new List<ReplicationInstruction>(), stackFrame, runtimeCore);
if (feps.Count == 0)
{
return false;
}
foreach (FunctionEndPoint fep in feps)
{
lookup.Add(fep);
}
}
return true;
}
示例4: PushStackFrame
public void PushStackFrame(StackFrame stackFrame, int localSize, int executionStates)
{
// TODO Jun: Performance
// Push frame should only require adjusting the frame index instead of pushing dummy elements
Validity.Assert(StackFrame.kStackFrameSize == stackFrame.Frame.Length);
PushFrame(localSize);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kFramePointer]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterTX]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterSX]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterRX]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterLX]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterFX]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterEX]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterDX]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterCX]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterBX]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterAX]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kExecutionStates]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kLocalVariables]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kStackFrameDepth]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kStackFrameType]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kCallerStackFrameType]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kFunctionCallerBlock]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kFunctionBlock]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kReturnAddress]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kFunction]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kClass]);
Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kThisPtr]);
FramePointer = Stack.Count;
}
示例5: ExecuteVM
/// <summary>
/// Execute the data stored in core
/// This is the entry point of all DS code to be executed
/// </summary>
/// <param name="core"></param>
/// <returns></returns>
public ProtoCore.RuntimeCore ExecuteVM(ProtoCore.Core core)
{
ProtoCore.RuntimeCore runtimeCore = CreateRuntimeCore(core);
runtimeCore.StartTimer();
try
{
foreach (ProtoCore.DSASM.CodeBlock codeblock in core.CodeBlockList)
{
// Comment Jun:
// On first bounce, the stackframe depth is initialized to -1 in the Stackfame constructor.
// Passing it to bounce() increments it so the first depth is always 0
ProtoCore.DSASM.StackFrame stackFrame = new ProtoCore.DSASM.StackFrame(core.GlobOffset);
stackFrame.FramePointer = runtimeCore.RuntimeMemory.FramePointer;
// Comment Jun: Tell the new bounce stackframe that this is an implicit bounce
// Register TX is used for this.
StackValue svCallConvention = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.BounceType.kImplicit);
stackFrame.TX = svCallConvention;
// Initialize the entry point interpreter
int locals = 0; // This is the global scope, there are no locals
ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(runtimeCore);
runtimeCore.CurrentExecutive.CurrentDSASMExec = interpreter.runtime;
runtimeCore.CurrentExecutive.CurrentDSASMExec.Bounce(codeblock.codeBlockId, codeblock.instrStream.entrypoint, stackFrame, locals);
}
runtimeCore.NotifyExecutionEvent(ProtoCore.ExecutionStateEventArgs.State.kExecutionEnd);
}
catch
{
runtimeCore.NotifyExecutionEvent(ProtoCore.ExecutionStateEventArgs.State.kExecutionEnd);
throw;
}
return runtimeCore;
}
示例6: Execute
public override StackValue Execute(ProtoCore.Runtime.Context c, List<StackValue> formalParameters, ProtoCore.DSASM.StackFrame stackFrame, RuntimeCore runtimeCore)
{ // ensure there is no data race, function resolution and execution happens in parallel
// but for FFI we want it to be serial cause the code we are calling into may not cope
// with parallelism.
//
// we are always looking and putting our function pointers in handler with each lang
// so better lock for FFIHandler (being static) it will be good object to lock
//
lock (FFIHandlers)
{
Interpreter interpreter = new Interpreter(runtimeCore, true);
// Setup the stack frame data
StackValue svThisPtr = stackFrame.ThisPtr;
int ci = activation.JILRecord.classIndex;
int fi = activation.JILRecord.funcIndex;
int returnAddr = stackFrame.ReturnPC;
int blockDecl = stackFrame.FunctionBlock;
int blockCaller = stackFrame.FunctionCallerBlock;
int framePointer = runtimeCore.RuntimeMemory.FramePointer;
int locals = activation.JILRecord.locals;
FFIHandler handler = FFIHandlers[activation.ModuleType];
FFIActivationRecord r = activation;
string className = "";
if (activation.JILRecord.classIndex > 0)
{
className = runtimeCore.DSExecutable.classTable.ClassNodes[activation.JILRecord.classIndex].Name;
}
List<ProtoCore.Type> argTypes = new List<Type>(r.ParameterTypes);
ProcedureNode fNode = null;
if (ProtoCore.DSASM.Constants.kInvalidIndex != ci)
{
fNode = interpreter.runtime.exe.classTable.ClassNodes[ci].ProcTable.Procedures[fi];
}
// Check if this is a 'this' pointer function overload that was generated by the compiler
if (null != fNode && fNode.IsAutoGeneratedThisProc)
{
int thisPtrIndex = 0;
bool isStaticCall = svThisPtr.IsPointer && Constants.kInvalidPointer == svThisPtr.Pointer;
if (isStaticCall)
{
stackFrame.ThisPtr = formalParameters[thisPtrIndex];
}
argTypes.RemoveAt(thisPtrIndex);
// Comment Jun: Execute() can handle a null this pointer.
// But since we dont even need to to reach there if we dont have a valid this pointer, then just return null
if (formalParameters[thisPtrIndex].IsNull)
{
runtimeCore.RuntimeStatus.LogWarning(ProtoCore.Runtime.WarningID.DereferencingNonPointer, Resources.kDeferencingNonPointer);
return StackValue.Null;
}
// These are the op types allowed.
Validity.Assert(formalParameters[thisPtrIndex].IsPointer ||
formalParameters[thisPtrIndex].IsDefaultArgument);
svThisPtr = formalParameters[thisPtrIndex];
formalParameters.RemoveAt(thisPtrIndex);
}
FFIFunctionPointer functionPointer = handler.GetFunctionPointer(r.ModuleName, className, r.FunctionName, argTypes, r.ReturnType);
mFunctionPointer = Validate(functionPointer) ? functionPointer : null;
mFunctionPointer.IsDNI = activation.IsDNI;
if (mFunctionPointer == null)
{
return ProtoCore.DSASM.StackValue.Null;
}
{
interpreter.runtime.executingBlock = runtimeCore.RunningBlock;
activation.JILRecord.globs = runtimeCore.DSExecutable.runtimeSymbols[runtimeCore.RunningBlock].GetGlobalSize();
// Params
formalParameters.Reverse();
for (int i = 0; i < formalParameters.Count; i++)
{
interpreter.Push(formalParameters[i]);
}
List<StackValue> registers = new List<DSASM.StackValue>();
interpreter.runtime.SaveRegisters(registers);
// Comment Jun: the depth is always 0 for a function call as we are reseting this for each function call
// This is only incremented for every language block bounce
int depth = 0;
StackFrameType callerType = stackFrame.CallerStackFrameType;
// FFI calls do not have execution states
runtimeCore.RuntimeMemory.PushFrameForLocals(locals);
StackFrame newStackFrame = new StackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, StackFrameType.Function, depth, framePointer, registers, 0);
//.........这里部分代码省略.........
示例7: Callr
//.........这里部分代码省略.........
// Comment Jun: These function do not require replication guides
// TODO Jun: Move these conditions or refactor JIL code emission so these checks dont reside here (Post R1)
if (Constants.kDotMethodName != fNode.Name
&& Constants.kFunctionRangeExpression != fNode.Name)
{
// Comment Jun: If this is a non-dot call, cache the guides first and retrieve them on the actual function call
// TODO Jun: Ideally, cache the replication guides in the dynamic function node
replicationGuides = GetCachedReplicationGuides(arguments.Count);
atLevels = GetCachedAtLevels(arguments.Count);
}
// if is dynamic call, the final pointer has been resovled in the ProcessDynamicFunction function
StackValue svThisPtr = StackValue.Null;
if (depth > 0)
{
svThisPtr = rmem.Pop();
if (!svThisPtr.IsPointer)
{
string message = String.Format(Resources.kInvokeMethodOnInvalidObject, fNode.Name);
runtimeCore.RuntimeStatus.LogWarning(WarningID.DereferencingNonPointer, message);
return StackValue.Null;
}
}
else
{
// There is no depth, but check if the function is a member function
// If its a member function, the this pointer is required by the core to pass on to the FEP call
if (isCallingMemberFunction && !fNode.IsConstructor && !fNode.IsStatic)
{
// A member function
// Get the this pointer as this class instance would have already been cosntructed
svThisPtr = rmem.CurrentStackFrame.ThisPtr;
}
else if (fNode.Name.Equals(Constants.kInlineConditionalMethodName))
{
// The built-in inlinecondition function is global but it is treated as a conditional execution rather than a normal function call
// This is why the class scope needs to be preserved such that the auto-generated language blocks in an inline conditional can still refer to member functions and properties
svThisPtr = rmem.CurrentStackFrame.ThisPtr;
}
else
{
// Global
svThisPtr = StackValue.BuildPointer(Constants.kInvalidPointer);
}
}
if (svThisPtr.IsPointer &&
svThisPtr.Pointer != Constants.kInvalidIndex &&
svThisPtr.metaData.type != Constants.kInvalidIndex)
{
int runtimeClassIndex = svThisPtr.metaData.type;
ClassNode runtimeClass = exe.classTable.ClassNodes[runtimeClassIndex];
if (runtimeClass.IsMyBase(classIndex))
{
classIndex = runtimeClassIndex;
}
}
// Build the stackframe
//int thisPtr = (int)svThisPtr.opdata;
int ci = classIndex; // Constants.kInvalidIndex; // Handled at FEP
int fi = Constants.kInvalidIndex; // Handled at FEP
int returnAddr = pc + 1;
示例8: BOUNCE_Handler
private void BOUNCE_Handler(Instruction instruction)
{
// We disallow language blocks inside watch window currently - pratapa
Validity.Assert(InterpreterMode.Expression != runtimeCore.Options.RunMode);
int blockId = instruction.op1.BlockIndex;
// Comment Jun: On a bounce, update the debug property to reflect this.
// Before the explicit bounce, this was done in Execute() which is now no longer the case
// as Execute is only called once during first bounce and succeeding bounce reuse the same interpreter
runtimeCore.DebugProps.CurrentBlockId = blockId;
// TODO(Jun/Jiong): Considering store the orig block id to stack frame
runtimeCore.RunningBlock = blockId;
runtimeCore.RuntimeMemory = rmem;
if (runtimeCore.Options.RunMode != InterpreterMode.Expression)
{
runtimeCore.RuntimeMemory.PushConstructBlockId(blockId);
}
int ci = Constants.kInvalidIndex;
int fi = Constants.kInvalidIndex;
if (rmem.Stack.Count >= StackFrame.StackFrameSize)
{
StackValue sci = rmem.GetAtRelative(StackFrame.FrameIndexClassIndex);
StackValue sfi = rmem.GetAtRelative(StackFrame.FrameIndexFunctionIndex);
if (sci.IsClassIndex && sfi.IsFunctionIndex)
{
ci = sci.ClassIndex;
fi = sfi.FunctionIndex;
}
}
StackValue svThisPtr;
if (rmem.CurrentStackFrame == null)
{
svThisPtr = StackValue.BuildPointer(Constants.kInvalidPointer);
}
else
{
svThisPtr = rmem.CurrentStackFrame.ThisPtr;
}
int returnAddr = pc + 1;
Validity.Assert(Constants.kInvalidIndex != executingBlock);
//int blockDecl = executingBlock;
int blockDecl = rmem.GetAtRelative(StackFrame.FrameIndexFunctionBlockIndex).BlockIndex;
int blockCaller = executingBlock;
StackFrameType type = StackFrameType.LanguageBlock;
int depth = (int)rmem.GetAtRelative(StackFrame.FrameIndexStackFrameDepth).IntegerValue;
int framePointer = runtimeCore.RuntimeMemory.FramePointer;
// Comment Jun: Use the register TX to store explicit/implicit bounce state
bounceType = CallingConvention.BounceType.Explicit;
TX = StackValue.BuildCallingConversion((int)CallingConvention.BounceType.Explicit);
List<StackValue> registers = GetRegisters();
StackFrameType callerType = (fepRun) ? StackFrameType.Function : StackFrameType.LanguageBlock;
if (runtimeCore.Options.IDEDebugMode && runtimeCore.Options.RunMode != InterpreterMode.Expression)
{
// Comment Jun: Temporarily disable debug mode on bounce
//Validity.Assert(false);
//Validity.Assert(runtimeCore.Breakpoints != null);
//blockDecl = blockCaller = runtimeCore.DebugProps.CurrentBlockId;
runtimeCore.DebugProps.SetUpBounce(this, blockCaller, returnAddr);
StackFrame stackFrame = new StackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, type, depth + 1, framePointer, 0, registers, 0);
Language bounceLangauge = exe.instrStreamList[blockId].language;
BounceExplicit(blockId, 0, bounceLangauge, stackFrame, runtimeCore.Breakpoints);
}
else //if (runtimeCore.Breakpoints == null)
{
StackFrame stackFrame = new StackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, type, depth + 1, framePointer, 0, registers, 0);
Language bounceLangauge = exe.instrStreamList[blockId].language;
BounceExplicit(blockId, 0, bounceLangauge, stackFrame);
}
}
示例9: DispatchNew
//Dispatch
private StackValue DispatchNew(
Context context,
List<StackValue> arguments,
List<List<ReplicationGuide>> partialReplicationGuides,
List<AtLevel> atLevels,
StackFrame stackFrame, RuntimeCore runtimeCore)
{
// Update the CallsiteExecutionState with
// TODO: Replace this with the real data
UpdateCallsiteExecutionState(null, runtimeCore);
Stopwatch sw = new Stopwatch();
sw.Start();
StringBuilder log = new StringBuilder();
log.AppendLine("Method name: " + methodName);
#region Get Function Group
//@PERF: Possible optimisation point here, to deal with static dispatches that don't need replication analysis
//Handle resolution Pass 1: Name -> Method Group
FunctionGroup funcGroup = GetFuncGroup(runtimeCore);
if (funcGroup == null)
{
log.AppendLine("Function group not located");
log.AppendLine("Resolution failed in: " + sw.ElapsedMilliseconds);
if (runtimeCore.Options.DumpFunctionResolverLogic)
runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());
return ReportFunctionGroupNotFound(runtimeCore, arguments);
}
//check accesibility of function group
bool methodAccessible = IsFunctionGroupAccessible(runtimeCore, ref funcGroup);
if (!methodAccessible)
{
return ReportMethodNotAccessible(runtimeCore);
}
//If we got here then the function group got resolved
log.AppendLine("Function group resolved: " + funcGroup);
#endregion
arguments = GetArgumentsAtLevels(arguments, atLevels, runtimeCore).Select(a => a.Argument).ToList();
partialReplicationGuides = PerformRepGuideDemotion(arguments, partialReplicationGuides, runtimeCore);
//Replication Control is an ordered list of the elements that we have to replicate over
//Ordering implies containment, so element 0 is the outer most forloop, element 1 is nested within it etc.
//Take the explicit replication guides and build the replication structure
//Turn the replication guides into a guide -> List args data structure
var partialInstructions = Replicator.BuildPartialReplicationInstructions(partialReplicationGuides);
//Get the fep that are resolved
List<FunctionEndPoint> resolvesFeps;
List<ReplicationInstruction> replicationInstructions;
arguments = PerformRepGuideForcedPromotion(arguments, partialReplicationGuides, runtimeCore);
ComputeFeps(log, context, arguments, funcGroup, partialInstructions, partialReplicationGuides, stackFrame, runtimeCore, out resolvesFeps, out replicationInstructions);
if (resolvesFeps.Count == 0)
{
log.AppendLine("Resolution Failed");
if (runtimeCore.Options.DumpFunctionResolverLogic)
runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());
return ReportMethodNotFoundForArguments(runtimeCore, arguments);
}
arguments.ForEach(x => runtimeCore.AddCallSiteGCRoot(CallSiteID, x));
StackValue ret = Execute(resolvesFeps, context, arguments, replicationInstructions, stackFrame, runtimeCore, funcGroup);
runtimeCore.RemoveCallSiteGCRoot(CallSiteID);
return ret;
}
示例10: JILDispatch
public StackValue JILDispatch(
List<StackValue> arguments,
List<List<ReplicationGuide>> replicationGuides,
List<AtLevel> atLevels,
StackFrame stackFrame,
RuntimeCore runtimeCore,
Context context)
{
#if DEBUG
ArgumentSanityCheck(arguments);
#endif
// Dispatch method
return DispatchNew(context, arguments, replicationGuides, atLevels, stackFrame, runtimeCore);
}
示例11: JILDispatchViaNewInterpreter
//Inbound methods
public StackValue JILDispatchViaNewInterpreter(
Context context,
List<StackValue> arguments,
List<List<ReplicationGuide>> replicationGuides,
List<AtLevel> atLevels,
StackFrame stackFrame, RuntimeCore runtimeCore)
{
#if DEBUG
ArgumentSanityCheck(arguments);
#endif
// Dispatch method
context.IsImplicitCall = true;
return DispatchNew(context, arguments, replicationGuides, atLevels, stackFrame, runtimeCore);
}
示例12: SelectFinalFep
private FunctionEndPoint SelectFinalFep(Context context,
List<FunctionEndPoint> functionEndPoint,
List<StackValue> formalParameters, StackFrame stackFrame, RuntimeCore runtimeCore)
{
List<ReplicationInstruction> replicationControl = new List<ReplicationInstruction>();
//We're never going to replicate so create an empty structure to allow us to use
//the existing utility methods
//Filter for exact matches
List<FunctionEndPoint> exactTypeMatchingCandindates = new List<FunctionEndPoint>();
foreach (FunctionEndPoint possibleFep in functionEndPoint)
{
if (possibleFep.DoesTypeDeepMatch(formalParameters, runtimeCore))
{
exactTypeMatchingCandindates.Add(possibleFep);
}
}
//There was an exact match, so dispath to it
if (exactTypeMatchingCandindates.Count > 0)
{
FunctionEndPoint fep = null;
if (exactTypeMatchingCandindates.Count == 1)
{
fep = exactTypeMatchingCandindates[0];
}
else
{
fep = SelectFEPFromMultiple(stackFrame, runtimeCore,
exactTypeMatchingCandindates, formalParameters);
}
return fep;
}
else
{
Dictionary<FunctionEndPoint, int> candidatesWithDistances = new Dictionary<FunctionEndPoint, int>();
Dictionary<FunctionEndPoint, int> candidatesWithCastDistances = new Dictionary<FunctionEndPoint, int>();
foreach (FunctionEndPoint fep in functionEndPoint)
{
//@TODO(Luke): Is this value for allow array promotion correct?
int distance = fep.ComputeTypeDistance(formalParameters, runtimeCore.DSExecutable.classTable, runtimeCore, false);
if (distance !=
(int) ProcedureDistance.kInvalidDistance)
candidatesWithDistances.Add(fep, distance);
}
foreach (FunctionEndPoint fep in functionEndPoint)
{
int dist = fep.ComputeCastDistance(formalParameters, runtimeCore.DSExecutable.classTable, runtimeCore);
candidatesWithCastDistances.Add(fep, dist);
}
List<FunctionEndPoint> candidateFunctions = GetCandidateFunctions(stackFrame, candidatesWithDistances);
if (candidateFunctions.Count == 0)
{
runtimeCore.RuntimeStatus.LogWarning(WarningID.kAmbiguousMethodDispatch,
Resources.kAmbigousMethodDispatch);
return null;
}
FunctionEndPoint compliantTarget = GetCompliantTarget(context, formalParameters, replicationControl,
stackFrame, runtimeCore, candidatesWithCastDistances,
candidateFunctions, candidatesWithDistances);
return compliantTarget;
}
}
示例13: GetCandidateFunctions
private List<FunctionEndPoint> GetCandidateFunctions(StackFrame stackFrame,
Dictionary<FunctionEndPoint, int> candidatesWithDistances)
{
List<FunctionEndPoint> candidateFunctions = new List<FunctionEndPoint>();
foreach (FunctionEndPoint fep in candidatesWithDistances.Keys)
{
if ((stackFrame.ThisPtr.IsPointer &&
stackFrame.ThisPtr.opdata == -1 && fep.procedureNode != null
&& !fep.procedureNode.IsConstructor) && !fep.procedureNode.IsStatic
&& (fep.procedureNode.ClassID != -1))
{
continue;
}
candidateFunctions.Add(fep);
}
return candidateFunctions;
}
示例14: GetCompliantTarget
private FunctionEndPoint GetCompliantTarget(Context context, List<StackValue> formalParams,
List<ReplicationInstruction> replicationControl,
StackFrame stackFrame, RuntimeCore runtimeCore,
Dictionary<FunctionEndPoint, int> candidatesWithCastDistances,
List<FunctionEndPoint> candidateFunctions,
Dictionary<FunctionEndPoint, int> candidatesWithDistances)
{
FunctionEndPoint compliantTarget = null;
//Produce an ordered list of the graph costs
Dictionary<int, List<FunctionEndPoint>> conversionCostList = new Dictionary<int, List<FunctionEndPoint>>();
foreach (FunctionEndPoint fep in candidateFunctions)
{
int cost = candidatesWithDistances[fep];
if (conversionCostList.ContainsKey(cost))
conversionCostList[cost].Add(fep);
else
conversionCostList.Add(cost, new List<FunctionEndPoint> {fep});
}
List<int> conversionCosts = new List<int>(conversionCostList.Keys);
conversionCosts.Sort();
List<FunctionEndPoint> fepsToSplit = new List<FunctionEndPoint>();
foreach (int cost in conversionCosts)
{
foreach (FunctionEndPoint funcFep in conversionCostList[cost])
{
if (funcFep.DoesPredicateMatch(context, formalParams, replicationControl))
{
compliantTarget = funcFep;
fepsToSplit.Add(funcFep);
}
}
if (compliantTarget != null)
break;
}
if (fepsToSplit.Count > 1)
{
int lowestCost = candidatesWithCastDistances[fepsToSplit[0]];
compliantTarget = fepsToSplit[0];
List<FunctionEndPoint> lowestCostFeps = new List<FunctionEndPoint>();
foreach (FunctionEndPoint fep in fepsToSplit)
{
if (candidatesWithCastDistances[fep] < lowestCost)
{
lowestCost = candidatesWithCastDistances[fep];
compliantTarget = fep;
lowestCostFeps = new List<FunctionEndPoint>() { fep };
}
else if (candidatesWithCastDistances[fep] == lowestCost)
{
lowestCostFeps.Add(fep);
}
}
//We have multiple feps, e.g. form overriding
if (lowestCostFeps.Count > 0)
compliantTarget = SelectFEPFromMultiple(stackFrame, runtimeCore, lowestCostFeps, formalParams);
}
return compliantTarget;
}
示例15: SelectFEPFromMultiple
private FunctionEndPoint SelectFEPFromMultiple(StackFrame stackFrame, RuntimeCore runtimeCore,
List<FunctionEndPoint> feps, List<StackValue> argumentsList)
{
StackValue svThisPtr = stackFrame.ThisPtr;
Validity.Assert(svThisPtr.IsPointer,
"this pointer wasn't a pointer. {89635B06-AD53-4170-ADA5-065EB2AE5858}");
int typeID = svThisPtr.metaData.type;
//Test for exact match
List<FunctionEndPoint> exactFeps = new List<FunctionEndPoint>();
foreach (FunctionEndPoint fep in feps)
if (fep.ClassOwnerIndex == typeID)
exactFeps.Add(fep);
if (exactFeps.Count == 1)
{
return exactFeps[0];
}
//Walk the class tree structure to find the method
while (runtimeCore.DSExecutable.classTable.ClassNodes[typeID].Bases.Count > 0)
{
Validity.Assert(runtimeCore.DSExecutable.classTable.ClassNodes[typeID].Bases.Count == 1,
"Multiple inheritence not yet supported {B93D8D7F-AB4D-4412-8483-33DE739C0ADA}");
typeID = runtimeCore.DSExecutable.classTable.ClassNodes[typeID].Bases[0];
foreach (FunctionEndPoint fep in feps)
if (fep.ClassOwnerIndex == typeID)
return fep;
}
//We weren't able to distinguish based on class hiearchy, try to sepearete based on array ranking
List<int> numberOfArbitraryRanks = new List<int>();
foreach (FunctionEndPoint fep in feps)
{
int noArbitraries = 0;
for (int i = 0; i < argumentsList.Count; i++)
{
if (fep.FormalParams[i].rank == Constants.kArbitraryRank)
noArbitraries++;
numberOfArbitraryRanks.Add(noArbitraries);
}
}
int smallest = Int32.MaxValue;
List<int> indeciesOfSmallest = new List<int>();
for (int i = 0; i < feps.Count; i++)
{
if (numberOfArbitraryRanks[i] < smallest)
{
smallest = numberOfArbitraryRanks[i];
indeciesOfSmallest.Clear();
indeciesOfSmallest.Add(i);
}
else if (numberOfArbitraryRanks[i] == smallest)
indeciesOfSmallest.Add(i);
}
Validity.Assert(indeciesOfSmallest.Count > 0,
"Couldn't find a fep when there should have been multiple: {EB589F55-F36B-404A-91DC-8D0EDC527E72}");
if (indeciesOfSmallest.Count == 1)
return feps[indeciesOfSmallest[0]];
if (!CoreUtils.IsInternalMethod(feps[0].procedureNode.Name) || CoreUtils.IsGetterSetter(feps[0].procedureNode.Name))
{
//If this has failed, we have multiple feps, which can't be distiquished by class hiearchy. Emit a warning and select one
StringBuilder possibleFuncs = new StringBuilder();
possibleFuncs.Append(Resources.MultipleFunctionsFound);
foreach (FunctionEndPoint fep in feps)
possibleFuncs.AppendLine("\t" + fep.ToString());
possibleFuncs.AppendLine(string.Format(Resources.ErrorCode, "{DCE486C0-0975-49F9-BE2C-2E7D8CCD17DD}"));
runtimeCore.RuntimeStatus.LogWarning(WarningID.kAmbiguousMethodDispatch, possibleFuncs.ToString());
}
return feps[0];
}