private Encapsulation.Structure InvokeDelegate(Lexicon map, string suffixName, params Encapsulation.Structure[] parameters) { ISuffixResult lengthResult = map.GetSuffix(suffixName); Assert.IsNotNull(lengthResult); if (!lengthResult.HasValue) { var delegateResult = lengthResult as DelegateSuffixResult; if (delegateResult != null) { cpu.PushArgumentStack(null); // fake delegate info cpu.PushArgumentStack(new KOSArgMarkerType()); foreach (var param in parameters) { cpu.PushArgumentStack(param); } delegateResult.Invoke(cpu); return(delegateResult.Value); } } return(lengthResult.Value); }
/// <summary> /// Take the topmost arguments down to the ARG_MARKER_STRING, pop them off, and then /// put them back again in reversed order so a function can read them in normal order. /// Note that if this is an indirect call, it will also consume the thing just under /// the ARG_MARKER, since that's expected to be the delegate or KOSDelegate that we already /// read and pulled the needed information from. /// <param name="cpu">the cpu we are running on, fur stack manipulation purposes</param> /// <param name="direct">need to know if this was a direct or indirect call. If indirect, /// then that means it also needs to consume the indirect reference off the stack just under /// the args</param> /// </summary> public static void ReverseStackArgs(ICpu cpu, bool direct) { List <object> args = new List <object>(); object arg = cpu.PopValueArgument(); while (cpu.GetArgumentStackSize() > 0 && arg.GetType() != ArgMarkerType) { args.Add(arg); // It's important to dereference with PopValue, not using PopArgumentStack, because the function // being called might not even be able to see the variable in scope anyway. // In other words, if calling a function like so: // declare foo to 3. // myfunc(foo). // The code inside myfunc needs to see that as being identical to just saying: // myfunc(3). // It has to be unaware of the fact that the name of the argument was 'foo'. It just needs to // see the contents that were inside foo. arg = cpu.PopValueArgument(); } if (!direct) { cpu.PopArgumentStack(); // throw away the delegate or KOSDelegate info - we already snarfed it by now. } // Push the arg marker back on again. cpu.PushArgumentStack(new KOSArgMarkerType()); // Push the arguments back on again, which will invert their order: foreach (object item in args) { cpu.PushArgumentStack(item); } }
public void CanGetDelegateValue() { var obj = new MockStructure(); var suffix = new NoArgsSuffix <Encapsulation.Structure>(() => obj); var del = suffix.Get(); Assert.IsNotNull(del); cpu.PushArgumentStack(null); // dummy variable for ReverseStackArgs to pop cpu.PushArgumentStack(new KOSArgMarkerType()); del.Invoke(cpu); var value = del.Value; Assert.IsNotNull(value); Assert.AreSame(obj, value); }
protected object InvokeDelegate(SerializableStructure stack, string suffixName, params object[] parameters) { var lengthObj = stack.GetSuffix(suffixName) as DelegateSuffixResult; Assert.IsNotNull(lengthObj); cpu.PushArgumentStack(null); // fake delegate info cpu.PushArgumentStack(new KOSArgMarkerType()); foreach (object param in parameters) { cpu.PushArgumentStack(param); } lengthObj.Invoke(cpu); return(lengthObj.Value); }
public void CanGetListIndex() { var list = new ListValue(); list.Add(new StringValue("bar")); cpu.PushArgumentStack(list); const int INDEX = 0; cpu.PushArgumentStack(INDEX); var opcode = new OpcodeGetIndex(); opcode.Execute(cpu); Assert.AreEqual(1, list.Count()); Assert.AreEqual(new StringValue("bar"), cpu.PopArgumentStack()); }
public void CanExecuteDelegate() { var mockDel = Substitute.For <TwoArgsSuffix <kOS.Safe.Encapsulation.Structure, kOS.Safe.Encapsulation.Structure> .Del <kOS.Safe.Encapsulation.Structure, kOS.Safe.Encapsulation.Structure> >(); // Wrap it in a lambda to avoid the weird third closure arg var suffix = new TwoArgsSuffix <kOS.Safe.Encapsulation.Structure, kOS.Safe.Encapsulation.Structure>((one, two) => mockDel(one, two)); var del = suffix.Get() as DelegateSuffixResult; Assert.IsNotNull(del); // Add fake arguments to the stack for the call cpu.PushArgumentStack(null); cpu.PushArgumentStack(new KOSArgMarkerType()); cpu.PushArgumentStack(ScalarIntValue.Zero); cpu.PushArgumentStack(ScalarIntValue.Zero); del.Invoke(cpu); mockDel.ReceivedWithAnyArgs(1); }
public void CanSetListIndex() { var list = new ListValue(); list.Add(new StringValue("bar")); cpu.PushArgumentStack(list); const int INDEX = 0; cpu.PushArgumentStack(INDEX); const string VALUE = "foo"; cpu.PushArgumentStack(VALUE); var opcode = new OpcodeSetIndex(); opcode.Execute(cpu); Assert.AreEqual(1, list.Count); Assert.AreNotEqual(new StringValue("bar"), list[0]); Assert.AreEqual(new StringValue("foo"), list[0]); }