本文整理汇总了C#中ICpu.BuiltInExists方法的典型用法代码示例。如果您正苦于以下问题:C# ICpu.BuiltInExists方法的具体用法?C# ICpu.BuiltInExists怎么用?C# ICpu.BuiltInExists使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ICpu
的用法示例。
在下文中一共展示了ICpu.BuiltInExists方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: StaticExecute
/// <summary>
/// Performs the actual execution of a subroutine call, either from this opcode or externally from elsewhere.
/// All "call a routine" logic should shunt through this code here, which handles all the complex cases,
/// or at least it should.
/// Note that in the case of a user function, this does not *ACTUALLY* execute the function yet. It just
/// arranges the stack correctly for the call and returns the new location that the IP should be jumped to
/// on the next instruction to begin the subroutine. For all built-in cases, it actually executes the
/// call right now and doesn't return until it's done. But for User functions it can't do that - it can only
/// advise on where to jump on the next instruction to begin the function.
/// </summary>
/// <param name="cpu">the cpu its running on</param>
/// <param name="direct">same meaning as OpcodeCall.Direct</param>
/// <param name="destination">if direct, then this is the function name</param>
/// <param name="calledFromKOSDelegateCall">true if KOSDelegate.Call() brought us here. If true that
/// means any pre-bound args are already on the stack. If false it means they aren't and this will have to
/// put them there.</param>
/// <returns>new IP to jump to, if this should be followed up by a jump. If -1 then it means don't jump.</returns>
public static int StaticExecute(ICpu cpu, bool direct, object destination, bool calledFromKOSDelegateCall)
{
object functionPointer;
object delegateReturn = null;
int newIP = -1; // new instruction pointer to jump to, next, if any.
if (direct)
{
functionPointer = cpu.GetValue(destination);
if (functionPointer == null)
throw new KOSException("Attempt to call function failed - Value of function pointer for " + destination + " is null.");
}
else // for indirect calls, dig down to find what's underneath the argument list in the stack and use that:
{
bool foundBottom = false;
int digDepth;
int argsCount = 0;
for (digDepth = 0; (! foundBottom) && digDepth < cpu.GetStackSize() ; ++digDepth)
{
object arg = cpu.PeekValue(digDepth);
if (arg != null && arg.GetType() == ArgMarkerType)
foundBottom = true;
else
++argsCount;
}
functionPointer = cpu.PeekValue(digDepth);
if (! ( functionPointer is Delegate || functionPointer is KOSDelegate || functionPointer is ISuffixResult))
{
// Indirect calls are meant to be delegates. If they are not, then that means the
// function parentheses were put on by the user when they weren't required. Just dig
// through the stack to the result of the getMember and skip the rest of the execute logic
// If args were passed to a non-method, then clean them off the stack, and complain:
if (argsCount>0)
{
for (int i=1 ; i<=argsCount; ++i)
cpu.PopValue();
throw new KOSArgumentMismatchException(
0, argsCount, "\n(In fact in this case the parentheses are entirely optional)");
}
cpu.PopValue(); // pop the ArgMarkerString too.
return -1;
}
}
// If it's a string it might not really be a built-in, it might still be a user func.
// Detect whether it's built-in, and if it's not, then convert it into the equivalent
// user func call by making it be an integer instruction pointer instead:
if (functionPointer is string || functionPointer is StringValue)
{
string functionName = functionPointer.ToString();
if (functionName.EndsWith("()"))
functionName = functionName.Substring(0, functionName.Length - 2);
if (!(cpu.BuiltInExists(functionName)))
{
// It is not a built-in, so instead get its value as a user function pointer variable, despite
// the fact that it's being called AS IF it was direct.
if (!functionName.EndsWith("*")) functionName = functionName + "*";
if (!functionName.StartsWith("$")) functionName = "$" + functionName;
functionPointer = cpu.GetValue(functionName);
}
}
KOSDelegate kosDelegate = functionPointer as KOSDelegate;
if (kosDelegate != null)
{
if (! calledFromKOSDelegateCall)
kosDelegate.InsertPreBoundArgs();
}
IUserDelegate userDelegate = functionPointer as IUserDelegate;
if (userDelegate != null)
functionPointer = userDelegate.EntryPoint;
BuiltinDelegate builtinDel = functionPointer as BuiltinDelegate;
if (builtinDel != null && (! calledFromKOSDelegateCall) )
functionPointer = builtinDel.Name;
// If the IP for a jump location got encapsulated as a user int when it got stored
// into the internal variable, then get the primitive int back out of it again:
ScalarIntValue userInt = functionPointer as ScalarIntValue;
if (userInt != null)
functionPointer = userInt.GetIntValue();
//.........这里部分代码省略.........
示例2: Execute
public override void Execute(ICpu cpu)
{
object functionPointer;
object delegateReturn = null;
if (Direct)
{
functionPointer = cpu.GetValue(Destination);
if (functionPointer == null)
throw new KOSException("Attempt to call function failed - Value of function pointer for " + Destination + " is null.");
}
else // for indirect calls, dig down to find what's underneath the argument list in the stack and use that:
{
bool foundBottom = false;
int digDepth;
int argsCount = 0;
for (digDepth = 0; (! foundBottom) && digDepth < cpu.GetStackSize() ; ++digDepth)
{
object arg = cpu.PeekValue(digDepth);
if (arg != null && arg.GetType() == ArgMarkerType)
foundBottom = true;
else
++argsCount;
}
functionPointer = cpu.PeekValue(digDepth);
if (! ( functionPointer is Delegate))
{
// Indirect calls are meant to be delegates. If they are not, then that means the
// function parentheses were put on by the user when they weren't required. Just dig
// through the stack to the result of the getMember and skip the rest of the execute logic
// If args were passed to a non-method, then clean them off the stack, and complain:
if (argsCount>0)
{
for (int i=1 ; i<=argsCount; ++i)
cpu.PopValue();
throw new KOSArgumentMismatchException(
0, argsCount, "\n(In fact in this case the parentheses are entirely optional)");
}
cpu.PopValue(); // pop the ArgMarkerString too.
return;
}
}
// If it's a string it might not really be a built-in, it might still be a user func.
// Detect whether it's built-in, and if it's not, then convert it into the equivalent
// user func call by making it be an integer instruction pointer instead:
if (functionPointer is string)
{
string functionName = functionPointer as string;
if (functionName.EndsWith("()"))
functionName = functionName.Substring(0, functionName.Length - 2);
if (!(cpu.BuiltInExists(functionName)))
{
// It is not a built-in, so instead get its value as a user function pointer variable, despite
// the fact that it's being called AS IF it was direct.
if (!functionName.EndsWith("*")) functionName = functionName + "*";
if (!functionName.StartsWith("$")) functionName = "$" + functionName;
functionPointer = cpu.GetValue(functionName);
}
}
IUserDelegate userDelegate = functionPointer as IUserDelegate;
if (userDelegate != null)
functionPointer = userDelegate.EntryPoint;
if (functionPointer is int)
{
ReverseStackArgs(cpu);
int currentPointer = cpu.InstructionPointer;
DeltaInstructionPointer = (int)functionPointer - currentPointer;
var contextRecord = new SubroutineContext(currentPointer+1);
cpu.PushAboveStack(contextRecord);
if (userDelegate != null)
{
cpu.AssertValidDelegateCall(userDelegate);
// Reverse-push the closure's scope record, just after the function return context got put on the stack.
for (int i = userDelegate.Closure.Count - 1 ; i >= 0 ; --i)
cpu.PushAboveStack(userDelegate.Closure[i]);
}
}
else if (functionPointer is string)
{
// Built-ins don't need to dereference the stack values because they
// don't leave the scope - they're not implemented that way. But later we
// might want to change that.
var name = functionPointer as string;
string functionName = name;
if (functionName.EndsWith("()"))
functionName = functionName.Substring(0, functionName.Length - 2);
cpu.CallBuiltinFunction(functionName);
}
else if (functionPointer is Delegate)
{
delegateReturn = ExecuteDelegate(cpu, (Delegate)functionPointer);
}
else
{
// This is one of those "the user had better NEVER see this error" sorts of messages that's here to keep us in check:
throw new Exception(
string.Format("kOS internal error: OpcodeCall calling a function described using {0} which is of type {1} and kOS doesn't know how to call that.", functionPointer, functionPointer.GetType().Name)
//.........这里部分代码省略.........