| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using MoonSharp.Interpreter.DataStructs;
- using MoonSharp.Interpreter.Debugging;
- namespace MoonSharp.Interpreter.Execution.VM
- {
- sealed partial class Processor
- {
- public RValue Execute()
- {
- while (m_InstructionPtr < m_CurChunk.Code.Count && !m_Terminate)
- {
- Instruction i = m_CurChunk.Code[m_InstructionPtr];
- if (m_DebuggerAttached != null)
- {
- ListenDebugger(i);
- }
- ++m_InstructionPtr;
- switch (i.OpCode)
- {
- case OpCode.Nop:
- case OpCode.Debug:
- case OpCode.DebugFn:
- break;
- case OpCode.Pop:
- m_ValueStack.RemoveLast(i.NumVal);
- break;
- case OpCode.Load:
- m_ValueStack.Push(m_Scope.Get(i.Symbol));
- break;
- case OpCode.Literal:
- m_ValueStack.Push(i.Value);
- break;
- case OpCode.Bool:
- Bool(i);
- break;
- case OpCode.Add:
- ExecAdd(i);
- break;
- case OpCode.Neg:
- ExecNeg(i);
- break;
- case OpCode.Sub:
- ExecSub(i);
- break;
- case OpCode.Mul:
- ExecMul(i);
- break;
- case OpCode.Div:
- ExecDiv(i);
- break;
- case OpCode.Power:
- ExecPower(i);
- break;
- case OpCode.Eq:
- ExecEq(i);
- break;
- case OpCode.LessEq:
- ExecLessEq(i);
- break;
- case OpCode.Less:
- ExecLess(i);
- break;
- case OpCode.Call:
- ExecCall(i);
- break;
- case OpCode.Jf:
- JumpBool(i, false);
- break;
- case OpCode.Not:
- ExecNot(i);
- break;
- case OpCode.JfOrPop:
- case OpCode.JtOrPop:
- ExecShortCircuitingOperator(i);
- break;
- case OpCode.JNil:
- ExecJNil(i);
- break;
- case OpCode.Store:
- ExecStore(i);
- break;
- case OpCode.Symbol:
- m_ValueStack.Push(new RValue(i.Symbol));
- break;
- case OpCode.Assign:
- ExecAssign(i);
- break;
- case OpCode.Jump:
- m_InstructionPtr = i.NumVal;
- break;
- case OpCode.MkTuple:
- m_ValueStack.Push(RValue.FromPotentiallyNestedTuple(StackTopToArrayReverse(i.NumVal, true)));
- break;
- case OpCode.Enter:
- m_Scope.PushFrame(i.Frame);
- break;
- case OpCode.Leave:
- m_Scope.PopFrame();
- break;
- case OpCode.Exit:
- ExecExit(i);
- break;
- case OpCode.Closure:
- m_ValueStack.Push(new RValue(new Closure(i.NumVal, i.SymbolList, m_Scope)));
- break;
- case OpCode.ExitClsr:
- m_Scope.LeaveClosure();
- break;
- case OpCode.Args:
- ExecArgs(i);
- break;
- case OpCode.Ret:
- ExecRet(i);
- break;
- case OpCode.Incr:
- ExecIncr(i);
- break;
- case OpCode.ToNum:
- m_ValueStack.Push(m_ValueStack.Pop().AsNumber());
- break;
- case OpCode.SymStorN:
- ExecSymStorN(i);
- break;
- case OpCode.JFor:
- ExecJFor(i);
- break;
- case OpCode.Index:
- ExecIndexGet(i);
- break;
- case OpCode.IndexRef:
- ExecIndexRef(i, false);
- break;
- case OpCode.IndexRefN:
- ExecIndexRef(i, true);
- break;
- case OpCode.NewTable:
- m_ValueStack.Push(new RValue(new Table()));
- break;
- case OpCode.TmpClear:
- m_TempRegs[i.NumVal] = null;
- break;
- case OpCode.TmpPeek:
- m_TempRegs[i.NumVal] = m_ValueStack.Peek();
- break;
- case OpCode.TmpPop:
- m_TempRegs[i.NumVal] = m_ValueStack.Pop();
- break;
- case OpCode.Reverse:
- ExecReverse(i);
- break;
- case OpCode.Len:
- ExecLen(i);
- break;
- case OpCode.TmpPush:
- m_ValueStack.Push(m_TempRegs[i.NumVal]);
- break;
- case OpCode.IterPrep:
- ExecIterPrep(i);
- break;
- case OpCode.IterUpd:
- ExecIterUpd(i);
- break;
- case OpCode.ExpTuple:
- ExecExpTuple(i);
- break;
- case OpCode.Invalid:
- throw new NotImplementedException(string.Format("Compilation for {0} not implented yet!", i.Name));
- default:
- throw new NotImplementedException(string.Format("Execution for {0} not implented yet!", i.OpCode));
- }
- }
- if (m_ValueStack.Count == 1)
- return m_ValueStack.Pop();
- else if (m_ValueStack.Count == 0)
- return RValue.Nil;
- else
- throw new InternalErrorException("Unexpected value stack count at program end : {0}", m_ValueStack.Count);
- }
- private void ExecJNil(Instruction i)
- {
- RValue v = m_ValueStack.Pop();
- if (v.Type == DataType.Nil)
- m_InstructionPtr = i.NumVal;
- }
- private void ExecIterUpd(Instruction i)
- {
- RValue v = m_ValueStack.Peek(0);
- RValue t = m_ValueStack.Peek(1);
- t.Tuple[2] = v;
- }
- private void ExecExpTuple(Instruction i)
- {
- RValue t = m_ValueStack.Peek(i.NumVal);
- if (t.Type == DataType.Tuple)
- {
- for (int idx = 0; idx < t.Tuple.Length; idx++)
- m_ValueStack.Push(t.Tuple[idx]);
- }
- else
- {
- m_ValueStack.Push(t);
- }
- }
- private void ExecIterPrep(Instruction i)
- {
- RValue v = m_ValueStack.Pop();
- if (v.Type != DataType.Tuple)
- {
- v = new RValue(new RValue[] { v, RValue.Nil, RValue.Nil });
- }
- else if (v.Tuple.Length > 3)
- {
- v = new RValue(new RValue[] { v.Tuple[0], v.Tuple[1], v.Tuple[2] });
- }
- else if (v.Tuple.Length == 2)
- {
- v = new RValue(new RValue[] { v.Tuple[0], v.Tuple[1], RValue.Nil });
- }
- else if (v.Tuple.Length == 1)
- {
- v = new RValue(new RValue[] { v.Tuple[0], RValue.Nil, RValue.Nil });
- }
- m_ValueStack.Push(v);
- }
- private void ExecReverse(Instruction i)
- {
- int cnt = i.NumVal;
- int cnth = cnt / 2;
- int len = m_ValueStack.Count - 1;
- for (int idx = 0; idx < cnth; idx++)
- {
- var tmp = m_ValueStack[len - idx];
- m_ValueStack[len - idx] = m_ValueStack[len - (cnt - 1 - idx)];
- m_ValueStack[len - (cnt - 1 - idx)] = tmp;
- }
- }
- private void ExecExit(Instruction i)
- {
- if (i.Frame == null)
- {
- m_Scope.PopFramesToFunction();
- if (m_ExecutionStack.Count > 0)
- m_Scope.LeaveClosure();
- }
- else
- {
- m_Scope.PopFramesToFrame(i.Frame);
- }
- }
- private void ExecJFor(Instruction i)
- {
- double val = m_ValueStack.Peek(0).Number;
- double step = m_ValueStack.Peek(1).Number;
- double stop = m_ValueStack.Peek(2).Number;
- bool whileCond = (step > 0) ? val <= stop : val >= stop;
- if (!whileCond)
- m_InstructionPtr = i.NumVal;
- }
- private void ExecIncr(Instruction i)
- {
- RValue top = m_ValueStack.Peek(0);
- RValue btm = m_ValueStack.Peek(i.NumVal);
- if (top.ReadOnly)
- {
- m_ValueStack.Pop();
- top = top.CloneAsWritable();
- m_ValueStack.Push(top);
- }
- top.Assign(top.Number + btm.Number);
- }
- private void ExecNot(Instruction i)
- {
- RValue v = m_ValueStack.Pop();
- m_ValueStack.Push(new RValue(!(v.TestAsBoolean())));
- }
- private void ExecRet(Instruction i)
- {
- if (m_ExecutionStack.Count == 0)
- {
- m_Terminate = true;
- return;
- }
- if (i.NumVal == 0)
- {
- int retpoint = PopToBasePointer();
- var argscnt = (int)(m_ValueStack.Pop().Number);
- m_ValueStack.RemoveLast(argscnt + 1);
- m_ValueStack.Push(RValue.Nil);
- m_InstructionPtr = retpoint;
- }
- else if (i.NumVal == 1)
- {
- var retval = m_ValueStack.Pop();
- int retpoint = PopToBasePointer();
- var argscnt = (int)(m_ValueStack.Pop().Number);
- m_ValueStack.RemoveLast(argscnt + 1);
- m_ValueStack.Push(retval);
- m_InstructionPtr = retpoint;
- }
- else
- {
- throw new InternalErrorException("RET supports only 0 and 1 ret val scenarios");
- }
- }
- private int PopToBasePointer()
- {
- var xs = m_ExecutionStack.Pop();
- m_ValueStack.CropAtCount(xs.BasePointer);
- return xs.ReturnAddress;
- }
- private int PopExecStackAndCheckVStack(int vstackguard)
- {
- var xs = m_ExecutionStack.Pop();
- if (vstackguard != xs.BasePointer)
- throw new InternalErrorException("StackGuard violation");
- return xs.ReturnAddress;
- }
- private void ExecArgs(Instruction I)
- {
- for (int i = 0; i < I.SymbolList.Length; i++)
- {
- m_Scope.Assign(I.SymbolList[i], m_ValueStack.Peek(i + 1));
- }
- }
- private void ExecCall(Instruction i)
- {
- RValue fn = m_ValueStack.Peek(i.NumVal);
- if (fn.Type == DataType.ClrFunction)
- {
- RValue[] args = StackTopToArray(i.NumVal, true);
- m_ValueStack.Pop();
- var ret = fn.Callback.Invoke(args);
- m_ValueStack.Push(ret);
- }
- else if (fn.Type == DataType.Function)
- {
- m_ValueStack.Push(new RValue(i.NumVal));
- m_ExecutionStack.Push(new CallStackItem()
- {
- BasePointer = m_ValueStack.Count,
- ReturnAddress = m_InstructionPtr,
- Debug_EntryPoint = fn.Function.ByteCodeLocation
- });
- m_InstructionPtr = fn.Function.ByteCodeLocation;
- fn.Function.EnterClosureBeforeCall(m_Scope);
- }
- else
- {
- throw new NotImplementedException("Meta");
- }
- }
- private void JumpBool(Instruction i, bool expectedValueForJump)
- {
- RValue op = m_ValueStack.Pop();
- if (op.TestAsBoolean() == expectedValueForJump)
- m_InstructionPtr = i.NumVal;
- }
- private void ExecShortCircuitingOperator(Instruction i)
- {
- bool expectedValToShortCircuit = i.OpCode == OpCode.JtOrPop;
- RValue op = m_ValueStack.Peek();
- if (op.TestAsBoolean() == expectedValToShortCircuit)
- m_InstructionPtr = i.NumVal;
- else
- m_ValueStack.Pop();
- }
- private void Bool(Instruction i)
- {
- RValue v = m_ValueStack.Peek();
- if (v.Type != DataType.Boolean)
- {
- m_ValueStack.Pop();
- m_ValueStack.Push(v.ToSimplestValue().AsBoolean());
- }
- }
- private void ExecLen(Instruction i)
- {
- RValue r = m_ValueStack.Pop();
- if (r.Type == DataType.Table)
- m_ValueStack.Push(new RValue(r.Table.Length));
- else if (r.Type == DataType.String)
- m_ValueStack.Push(new RValue(r.String.Length));
- else
- throw new NotImplementedException("Meta operators");
- }
- private void ExecAdd(Instruction i)
- {
- RValue r = m_ValueStack.Pop();
- RValue l = m_ValueStack.Pop();
- if (r.Type == DataType.Number && l.Type == DataType.Number)
- m_ValueStack.Push(new RValue(l.Number + r.Number));
- else
- throw new NotImplementedException("Meta operators");
- }
- private void ExecSub(Instruction i)
- {
- RValue r = m_ValueStack.Pop();
- RValue l = m_ValueStack.Pop();
- if (r.Type == DataType.Number && l.Type == DataType.Number)
- m_ValueStack.Push(new RValue(l.Number - r.Number));
- else
- throw new NotImplementedException("Meta operators");
- }
- private void ExecNeg(Instruction i)
- {
- RValue r = m_ValueStack.Pop();
- if (r.Type == DataType.Number)
- m_ValueStack.Push(new RValue(-r.Number));
- else
- throw new NotImplementedException("Meta operators");
- }
- private void ExecPower(Instruction i)
- {
- RValue r = m_ValueStack.Pop();
- RValue l = m_ValueStack.Pop();
- if (r.Type == DataType.Number && l.Type == DataType.Number)
- m_ValueStack.Push(new RValue(Math.Pow(l.Number, r.Number)));
- else
- throw new NotImplementedException("Meta operators");
- }
- private void ExecMul(Instruction i)
- {
- RValue r = m_ValueStack.Pop();
- RValue l = m_ValueStack.Pop();
- if (r.Type == DataType.Number && l.Type == DataType.Number)
- m_ValueStack.Push(new RValue(l.Number * r.Number));
- else
- throw new NotImplementedException("Meta operators");
- }
- private void ExecEq(Instruction i)
- {
- RValue r = m_ValueStack.Pop();
- RValue l = m_ValueStack.Pop();
- m_ValueStack.Push(new RValue(r.Equals(l)));
- }
- private void ExecLess(Instruction i)
- {
- RValue r = m_ValueStack.Pop();
- RValue l = m_ValueStack.Pop();
- if (r.Type == DataType.Number && r.Type == DataType.Number)
- {
- m_ValueStack.Push(new RValue(l.Number < r.Number));
- }
- else
- {
- throw new NotImplementedException("Comparison between non numbers!");
- }
- }
- private void ExecLessEq(Instruction i)
- {
- RValue r = m_ValueStack.Pop();
- RValue l = m_ValueStack.Pop();
- if (r.Type == DataType.Number && r.Type == DataType.Number)
- {
- m_ValueStack.Push(new RValue(l.Number <= r.Number));
- }
- else
- {
- throw new NotImplementedException("Comparison between non numbers!");
- }
- }
- private void ExecDiv(Instruction i)
- {
- RValue r = m_ValueStack.Pop();
- RValue l = m_ValueStack.Pop();
- if (r.Type == DataType.Number && l.Type == DataType.Number)
- m_ValueStack.Push(new RValue(l.Number / r.Number));
- else
- throw new NotImplementedException("Meta operators");
- }
- private void Internal_Assign(LRef l, RValue r)
- {
- if (l.i_Type == LRefType.Index)
- {
- l.i_TableRefObject.Table[l.i_TableRefIndex] = r;
- }
- else
- {
- m_Scope.Assign(l, r.ToSimplestValue());
- }
- }
- private void Internal_Assign(RValue l, RValue r)
- {
- if (l.Type == DataType.Symbol)
- {
- Internal_Assign(l.Symbol, r);
- }
- else
- {
- throw new NotImplementedException("How should we manage this ?");
- }
- }
- private void ExecIndexGet(Instruction i)
- {
- RValue indexValue = m_ValueStack.Pop();
- RValue baseValue = m_ValueStack.Pop();
- if (baseValue.Type != DataType.Table)
- {
- throw new NotImplementedException("META! : Can't index non-table yet");
- }
- else
- {
- RValue v = baseValue.Table[indexValue];
- m_ValueStack.Push(v.AsReadOnly());
- }
- }
- private void ExecIndexRef(Instruction i, bool keepOnStack)
- {
- RValue indexValue = m_ValueStack.Pop();
- RValue baseValue = keepOnStack ? m_ValueStack.Peek() : m_ValueStack.Pop();
- if (baseValue.Type != DataType.Table)
- {
- throw new NotImplementedException("META! : Can't index non-table yet");
- }
- else
- {
- LRef s = LRef.ObjIndex(baseValue, indexValue);
- m_ValueStack.Push(new RValue(s));
- }
- }
- private void ExecStore(Instruction i)
- {
- RValue r = m_ValueStack.Pop();
- RValue l = m_ValueStack.Pop();
- Internal_Assign(l, r);
- }
- private void ExecSymStorN(Instruction i)
- {
- m_Scope.Assign(i.Symbol, m_ValueStack.Peek());
- }
- private void ExecAssign(Instruction i)
- {
- Slice<RValue> rvalues = new Slice<RValue>(m_ValueStack, m_ValueStack.Count - i.NumVal2, i.NumVal2, false);
- Slice<RValue> lvalues = new Slice<RValue>(m_ValueStack, m_ValueStack.Count - i.NumVal2 - i.NumVal, i.NumVal, false);
- Internal_MultiAssign(lvalues, rvalues);
- m_ValueStack.CropAtCount(m_ValueStack.Count - i.NumVal - i.NumVal2);
- }
- private void Internal_MultiAssign(Slice<RValue> lValues, Slice<RValue> rValues)
- {
- int li = 0;
- int rValues_Count = rValues.Count;
- int lValues_Count = lValues.Count;
- for (int ri = 0; ri < rValues_Count && li < lValues_Count; ri++, li++)
- {
- RValue vv = rValues[ri];
- if ((ri != rValues_Count - 1) || (vv.Type != DataType.Tuple))
- {
- Internal_Assign(lValues[li], vv.ToSingleValue());
- }
- else
- {
- for (int rri = 0, len = vv.Tuple.Length; rri < len && li < lValues_Count; rri++, li++)
- {
- Internal_Assign(lValues[li], vv.Tuple[rri].ToSingleValue());
- }
- }
- }
- }
- }
- }
|