本文整理汇总了C#中ICpu.PopAboveStack方法的典型用法代码示例。如果您正苦于以下问题:C# ICpu.PopAboveStack方法的具体用法?C# ICpu.PopAboveStack怎么用?C# ICpu.PopAboveStack使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ICpu
的用法示例。
在下文中一共展示了ICpu.PopAboveStack方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: DoPopScope
/// <summary>
/// Do the actual work of the Execute() method. This was pulled out
/// to a separate static method so that others can call it without needing
/// an actual popscope object. Everything OpcodePopScope.Execute() does
/// should actually be done here, so as to ensure that external callers of
/// this get exactly the same behaviour as a full popstack opcode.
/// </summary>
/// <param name="cpuObj">the shared.cpu to operate on.</param>
/// <param name="levels">number of levels to popscope.</param>
public static void DoPopScope(ICpu cpuObj, Int16 levels)
{
cpuObj.PopAboveStack(levels);
}
示例2: Execute
public override void Execute(ICpu cpu)
{
// Return value should be atop the stack.
// Pop it, eval it, and push it back,
// i.e. if the statement was RETURN X, and X is 2, then you want
// it to return the number 2, not the variable name $x, which could
// be a variable local to this function which is about to go out of scope
// so the caller can't access it:
object returnVal = cpu.PopValue();
// Now dig down through the stack until the argbottom is found.
// anything still leftover above that should be unread parameters we
// should throw away:
object shouldBeArgMarker = 0; // just a temp to force the loop to execute at least once.
while (shouldBeArgMarker == null || (shouldBeArgMarker.GetType() != OpcodeCall.ArgMarkerType))
{
if (cpu.GetStackSize() <= 0)
{
throw new KOSArgumentMismatchException(
string.Format("Something is wrong with the stack - no arg bottom mark when doing a return. This is an internal problem with kOS")
);
}
shouldBeArgMarker = cpu.PopStack();
}
cpu.PushStack(Structure.FromPrimitive(returnVal));
// Now, after the eval was done, NOW finally pop the scope, after we don't need local vars anymore:
if( Depth > 0 )
OpcodePopScope.DoPopScope(cpu, Depth);
// The only thing on the "above stack" now that is allowed to get in the way of
// finding the context record that tells us where to jump back to, are the potential
// closure scope frames that might have been pushed if this subroutine was
// called via a delegate reference. Consume any of those that are in
// the way, then expect the context record. Any other pattern encountered
// is proof the stack alignment got screwed up:
bool okay;
VariableScope peeked = cpu.PeekRaw(-1, out okay) as VariableScope;
while (okay && peeked != null && peeked.IsClosure)
{
cpu.PopAboveStack(1);
peeked = cpu.PeekRaw(-1, out okay) as VariableScope;
}
object shouldBeContextRecord = cpu.PopAboveStack(1);
if ( !(shouldBeContextRecord is SubroutineContext) )
{
// This should never happen with any user code:
throw new Exception( "kOS internal error: Stack misalignment detected when returning from routine.");
}
var contextRecord = shouldBeContextRecord as SubroutineContext;
// Special case for when the subroutine was really being called as an interrupt
// trigger from the kOS CPU itself. In that case we don't want to leave the
// return value atop the stack, and instead want to pop it and use it to decide
// whether or not the re-insert the trigger for next time:
if (contextRecord.IsTrigger)
{
cpu.PopStack(); // already got the return value up above, just ignore it.
if (returnVal is bool || returnVal is BooleanValue )
if (Convert.ToBoolean(returnVal))
cpu.AddTrigger(contextRecord.TriggerPointer);
}
int destinationPointer = contextRecord.CameFromInstPtr;
int currentPointer = cpu.InstructionPointer;
DeltaInstructionPointer = destinationPointer - currentPointer;
}
示例3: Execute
public override void Execute(ICpu cpu)
{
// Return value should be atop the stack - we have to pop it so that
// we can reach the arg start marker under it:
object returnVal = cpu.PopValue();
// The next thing on the stack under the return value should be the marker that indicated where
// the parameters started. It should be thrown away now. If the next thing is NOT the marker
// of where the parameters started, that is proof the stack is misaligned, probably because the
// number of args passed didn't match the number of DECLARE PARAMETER statements in the function:
string shouldBeArgMarker = cpu.PopStack() as string;
if ( (shouldBeArgMarker == null) || (!(shouldBeArgMarker.Equals(OpcodeCall.ARG_MARKER_STRING))) )
{
throw new KOSArgumentMismatchException(
string.Format("(detected when returning from function and the stack still had {0} on it)",
(shouldBeArgMarker ?? "a non-string value"))
);
}
// If the proper argument marker was found, then it's all okay, so put the return value
// back, where it belongs, now that the arg start marker was popped off:
cpu.PushStack(returnVal);
// Now, after the eval was done, NOW finally pop the scope, after we don't need local vars anymore:
if( Depth > 0 )
OpcodePopScope.DoPopScope(cpu, Depth);
// The only thing on the "above stack" now that is allowed to get in the way of
// finding the context record that tells us where to jump back to, are the potential
// closure scope frames that might have been pushed if this subroutine was
// called via a delegate reference. Consume any of those that are in
// the way, then expect the context record. Any other pattern encountered
// is proof the stack alignment got screwed up:
bool okay;
VariableScope peeked = cpu.PeekRaw(-1, out okay) as VariableScope;
while (okay && peeked != null && peeked.IsClosure)
{
cpu.PopAboveStack(1);
peeked = cpu.PeekRaw(-1, out okay) as VariableScope;
}
object shouldBeContextRecord = cpu.PopAboveStack(1);
if ( !(shouldBeContextRecord is SubroutineContext) )
{
// This should never happen with any user code:
throw new Exception( "kOS internal error: Stack misalignment detected when returning from routine.");
}
var contextRecord = shouldBeContextRecord as SubroutineContext;
int destinationPointer = contextRecord.CameFromInstPtr;
int currentPointer = cpu.InstructionPointer;
DeltaInstructionPointer = destinationPointer - currentPointer;
}