/// <summary> /// 解释执行1个方法 /// </summary> /// <param name="methodInfo"></param> public void interpret(MemberInfo methodInfo) { Code code = GetCode(methodInfo); ushort maxStack = code.MaxStack; ushort maxLocals = code.MaxLocals; byte[] byteCode = code.CodeData; VMThread thread = new VMThread(); thread.Pc = 0; Frame frame = thread.CreateFrame(maxLocals, maxStack); thread.Push(frame); while (true) { byte operateCode = ByteCodeReader.ReadOperateCode(thread, byteCode); Instruction instruction = Instruction.GetInstruction(operateCode); if (instruction == null) { if (Switchs.DebugInterpret) { Console.Out.WriteLine("缺少指令:" + BitConverter.ToString(new byte[] { operateCode })); } throw new Exception("No shuch instruction error"); } instruction.Execute(thread, byteCode, frame); } }
public void ThreadIdle(VMThread thread) { ThreadEvents.Add(new VMStateChangeEvent { NewState = VMThreadState.Idle, Thread = thread }); }
public static short ReadShort(VMThread thread, byte[] byteCode) { byte high = ReadU1(thread, byteCode); byte low = ReadU1(thread, byteCode); return((short)((high << 8) | low)); }
public override void Execute(VMThread thread, byte[] byteCode, Frame frame) { int value2 = frame.OperandStack.PopInt(); int value1 = frame.OperandStack.PopInt(); frame.OperandStack.PushInt(value1 * value2); }
public override void Execute(VMThread thread, byte[] byteCode, Frame frame) { byte[] bytes = this.FetchOperands(thread, byteCode); int val = (bytes[0] << 8) | bytes[1]; frame.OperandStack.PushInt(val); }
public void ThreadRemove(VMThread thread) { ThreadEvents.Add(new VMStateChangeEvent { NewState = VMThreadState.Removed, Thread = thread }); }
public override void Execute(VMThread thread, byte[] byteCode, Frame frame) { //操作数栈 OperandStack operandStack = frame.OperandStack; //操作数栈顶存入0 operandStack.PushInt(0); }
public static byte[] ReadBytes(VMThread thread, byte[] byteCode, int n) { byte[] result = new byte[n]; for (int i = 0; i < n; i++) { result[i] = byteCode[thread.Pc++]; } return(result); }
public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args) { var operand = (VMRunFunctionalTreeOperand)args; var entry = VMFindBestObjectForFunction.FunctionToEntryPoint[operand.Function]; var ent = context.StackObject; if (ent.EntryPoints[entry].ActionFunction != 0) { bool Execute; if (ent.EntryPoints[entry].ConditionFunction != 0) //check if we can definitely execute this... { var Behavior = ent.GetBHAVWithOwner(ent.EntryPoints[entry].ConditionFunction, context.VM.Context); Execute = (VMThread.EvaluateCheck(context.VM.Context, context.Caller, new VMQueuedAction() { Callee = ent, CodeOwner = Behavior.owner, StackObject = ent, Routine = context.VM.Assemble(Behavior.bhav), }) == VMPrimitiveExitCode.RETURN_TRUE); } else { Execute = true; } if (Execute) { //push it onto our stack, except now the stack object owns our soul! var Behavior = ent.GetBHAVWithOwner(ent.EntryPoints[entry].ActionFunction, context.VM.Context); var routine = context.VM.Assemble(Behavior.bhav); var childFrame = new VMStackFrame { Routine = routine, Caller = context.Caller, Callee = ent, CodeOwner = Behavior.owner, StackObject = ent }; if (operand.Flags > 0) { context.Thread.Queue[0].IconOwner = context.StackObject; } childFrame.Args = new short[routine.Arguments]; context.Thread.Push(childFrame); return(VMPrimitiveExitCode.CONTINUE); } else { return(VMPrimitiveExitCode.GOTO_FALSE); } } else { return(VMPrimitiveExitCode.GOTO_FALSE); } }
public override IEnumerable<Item> Perform(IEnumerable<Item> items, IEnumerable<Item> modifierItems) { VMItem vm = items.First () as VMItem; VMThread thread = new VMThread("VBoxManage", "snapshot " + vm.Uuid + " discardcurrent -state", vm.Status, ref vm); Thread t = new Thread (new ThreadStart(thread.DoAction)); t.IsBackground = true; t.Start(); yield break; }
public override void Execute(VMThread thread, byte[] byteCode, Frame frame) { int value2 = frame.OperandStack.PopInt(); int value1 = frame.OperandStack.PopInt(); if (value2 == 0) { throw new Exception("Div by zero exception"); } frame.OperandStack.PushInt(value1 / value2); }
public virtual void Init(VMContext context) { GenerateTreeByName(context); this.Thread = new VMThread(context, this, this.Object.OBJ.StackSize); ExecuteEntryPoint(0, context); if (Object.OBJ.GUID == 0x98E0F8BD || Object.OBJ.GUID == 0x5D7B6688) //let aquarium & flowers run main { ExecuteEntryPoint(1, context); } }
public override void Execute(VMThread thread, byte[] byteCode, Frame frame) { //操作数栈 OperandStack operandStack = frame.OperandStack; //局部变量表 LocalVarsTable localVarsTable = frame.LocalVars; //弹出操作数栈顶元素 int val = operandStack.PopInt(); //存入局部变量表0号位置 localVarsTable.PutInt(0, val); }
public virtual void Init(VMContext context) { GenerateTreeByName(context); this.Thread = new VMThread(context,this,this.Object.OBJ.StackSize); ExecuteEntryPoint(0,context,true); //Init //ExecuteEntryPoint(11, context); //User Placement //if (Object.OBJ.GUID == 0x98E0F8BD || Object.OBJ.GUID == 0x5D7B6688 || Object.OBJ.GUID == 0x24C95F99) //let aquarium & flowers run main //{ ExecuteEntryPoint(1,context,false); //} }
public override void Execute(VMThread thread, byte[] byteCode, Frame frame) { //操作数栈 OperandStack operandStack = frame.OperandStack; //局部变量表 LocalVarsTable localVarsTable = frame.LocalVars; //取局部变量 Slot value = localVarsTable.Get(0); //入操作数栈 operandStack.PushObjectRef(value.ObjectRef); }
public override IEnumerable<Item> Perform(IEnumerable<Item> items, IEnumerable<Item> modifierItems) { foreach (Item i in items) { VMItem vm = (i as VMItem); VMThread thread = new VMThread(VMState.saved, ref vm); Thread t = new Thread (new ThreadStart(thread.DoAction)); t.IsBackground = true; t.Start(); } yield break; }
public override VMPrimitiveExitCode Execute(VMStackFrame context) { var operand = context.GetCurrentOperand <VMFindBestObjectForFunctionOperand>(); var entities = context.VM.Entities; var entry = VMFindBestObjectForFunction.FunctionToEntryPoint[operand.Function]; for (int i = 0; i < entities.Count; i++) { var ent = entities[i]; if (ent.ObjectData[(int)VMStackObjectVariable.LockoutCount] > 0) { continue; //this object is not important!!! } if (ent.EntryPoints[entry].ActionFunction != 0) { bool Execute; if (ent.EntryPoints[entry].ConditionFunction != 0) { var Behavior = ent.GetBHAVWithOwner(ent.EntryPoints[entry].ConditionFunction, context.VM.Context); var test = VMThread.EvaluateCheck(context.VM.Context, context.Caller, new VMQueuedAction() { Callee = ent, CodeOwner = Behavior.owner, StackObject = ent, Routine = context.VM.Assemble(Behavior.bhav), }); Execute = (test == VMPrimitiveExitCode.RETURN_TRUE); } else { Execute = true; } if (Execute) { //we can run this, it's suitable, yes I'LL TAKE IT context.StackObject = ent; return(VMPrimitiveExitCode.GOTO_TRUE); } //if not just keep searching } } return(VMPrimitiveExitCode.GOTO_FALSE); //couldn't find an object! :'( }
// End Container SLOTs interface public List <VMPieMenuInteraction> GetPieMenu(VM vm,VMEntity caller) { var pie = new List <VMPieMenuInteraction>(); if (TreeTable == null) { return(pie); } for (int i = 0; i < TreeTable.Interactions.Length; i++) { var action = TreeTable.Interactions[i]; bool CanRun = false; if (action.TestFunction != 0 && (((TTABFlags)action.Flags & TTABFlags.Debug) != TTABFlags.Debug)) { caller.ObjectData[(int)VMStackObjectVariable.HideInteraction] = 0; var Behavior = GetBHAVWithOwner(action.TestFunction,vm.Context); CanRun = (VMThread.EvaluateCheck(vm.Context,caller,new VMQueuedAction() { Callee = this, CodeOwner = Behavior.owner, StackObject = this, Routine = vm.Assemble(Behavior.bhav), }) == VMPrimitiveExitCode.RETURN_TRUE); if (caller.ObjectData[(int)VMStackObjectVariable.HideInteraction] == 1) { CanRun = false; } } else { CanRun = true; } if (CanRun) { pie.Add(new VMPieMenuInteraction() { Name = TreeTableStrings.GetString((int)action.TTAIndex), ID = (byte)action.TTAIndex }); } } return(pie); }
public virtual void Init(VMContext context) { GenerateTreeByName(context); if (!GhostImage) { this.Thread = new VMThread(context,this,this.Object.OBJ.StackSize); } ExecuteEntryPoint(0,context,true); //Init if (!GhostImage) { short[] Args = null; VMEntity StackOBJ = null; if (MainParam != 0) { Args = new short[4]; Args[0] = MainParam; MainParam = 0; } if (MainStackOBJ != 0) { StackOBJ = context.VM.GetObjectById(MainStackOBJ); MainStackOBJ = 0; } ExecuteEntryPoint(1,context,false,StackOBJ,Args); //Main } else { SetValue(VMStackObjectVariable.Room,-1); if (this is VMGameObject) { ((VMGameObject)this).RefreshLight(); } } }
public void ThreadActive(VMThread thread) { /** Switch thread to active **/ VM.ThreadActive(thread); }
public void ThreadIdle(VMThread thread) { /** Switch thread to idle **/ VM.ThreadIdle(thread); }
public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args) { var operand = (VMRunFunctionalTreeOperand)args; if (operand.Function == 65535) { return(VMPrimitiveExitCode.GOTO_FALSE); //wedding cake: invalid primitive operand } var entry = VMFindBestObjectForFunction.FunctionToEntryPoint[operand.Function]; var ent = context.StackObject; if (ent == null || ent.Dead) { return(VMPrimitiveExitCode.GOTO_FALSE); } if (ent.EntryPoints[entry].ActionFunction != 0) { bool Execute; if (ent.EntryPoints[entry].ConditionFunction != 0) //check if we can definitely execute this... { var Behavior = ent.GetRoutineWithOwner(ent.EntryPoints[entry].ConditionFunction, context.VM.Context); if (Behavior != null) { Execute = (VMThread.EvaluateCheck(context.VM.Context, context.Caller, new VMStackFrame() { Caller = context.Caller, Callee = ent, CodeOwner = Behavior.owner, StackObject = ent, Routine = Behavior.routine, Args = new short[4] }) == VMPrimitiveExitCode.RETURN_TRUE); } else { Execute = true; } } else { Execute = true; } if (Execute) { //push it onto our stack, except now the stack object owns our soul! var tree = ent.GetRoutineWithOwner(ent.EntryPoints[entry].ActionFunction, context.VM.Context); if (tree == null) { return(VMPrimitiveExitCode.GOTO_FALSE); //does not exist } var routine = tree.routine; var childFrame = new VMStackFrame { Routine = routine, Caller = context.Caller, Callee = ent, CodeOwner = tree.owner, StackObject = ent, ActionTree = context.ActionTree }; if (operand.Flags > 0 && context.ActionTree) { context.Thread.ActiveAction.IconOwner = context.StackObject; } childFrame.Args = new short[routine.Arguments]; context.Thread.Push(childFrame); return(VMPrimitiveExitCode.CONTINUE); } else { return(VMPrimitiveExitCode.GOTO_FALSE); } } else { return(VMPrimitiveExitCode.GOTO_FALSE); } }
public override IEnumerable<Item> Perform(IEnumerable<Item> items, IEnumerable<Item> modItems) { VMItem vm = (items.First () as VMItem); string SnapshotName; if (modItems.Any ()) SnapshotName = (modItems.First () as ITextItem).Text; else SnapshotName = AddinManager.CurrentLocalizer.GetString("Snapshot (") + DateTime.Now + ")"; VMThread thread = new VMThread("VBoxManage", "snapshot " + vm.Uuid + " take '" + SnapshotName + "'", vm.Status, ref vm); Thread t = new Thread (new ThreadStart(thread.DoAction)); t.IsBackground = true; t.Start(); yield break; }
public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args) { var operand = (VMFindBestObjectForFunctionOperand)args; var entities = context.VM.Entities; int bestScore = int.MinValue; VMEntity bestObj = null; var entry = FunctionToEntryPoint[operand.Function]; for (int i = 0; i < entities.Count; i++) { var ent = entities[i]; if (ent.GetValue(VMStackObjectVariable.LockoutCount) > 0 || (ent is VMGameObject && ((VMGameObject)ent).Disabled > 0) || ent.Position == LotTilePos.OUT_OF_WORLD) { continue; //this object is not important!!! } if (ent.EntryPoints[entry].ActionFunction != 0) { bool Execute; if (ent.EntryPoints[entry].ConditionFunction != 0) { var Behavior = ent.GetRoutineWithOwner(ent.EntryPoints[entry].ConditionFunction, context.VM.Context); if (Behavior != null) { var test = VMThread.EvaluateCheck(context.VM.Context, context.Caller, new VMStackFrame() { Caller = context.Caller, Callee = ent, CodeOwner = Behavior.owner, StackObject = ent, Routine = Behavior.routine, Args = new short[4] }); Execute = (test == VMPrimitiveExitCode.RETURN_TRUE); } else { Execute = true; } } else if (SurfaceFunctions.Contains(entry)) { //ts1: surface functions that have no check tree rely on the engine to check there is nothing in slot 0. Execute = ent.GetSlot(0) == null; } else { Execute = true; } if (Execute) { if (ent.IsInUse(context.VM.Context, true)) { continue; //this object is in use. this check is more expensive than check trees, so do it last. } //calculate the score for this object. int score = 0; if (ScoreVar[operand.Function] != VMStackObjectVariable.Invalid) { var funcVar = ScoreVar[operand.Function]; score = ent.GetValue(funcVar); if (context.VM.TS1 || funcVar != VMStackObjectVariable.RepairState) { if (Thresholds.TryGetValue(funcVar, out var threshold) && score < threshold) { continue; } } else if (ent is VMAvatar || !((Model.TSOPlatform.VMTSOObjectState)ent.TSOState).Broken) { continue; } } LotTilePos posDiff = ent.Position - context.Caller.Position; score -= (int)Math.Sqrt(posDiff.x * posDiff.x + posDiff.y * posDiff.y + (posDiff.Level * posDiff.Level * 900 * 256)) / 3; if (score > bestScore) { bestScore = score; bestObj = ent; } } } } if (bestObj != null) { context.StackObject = bestObj; return(VMPrimitiveExitCode.GOTO_TRUE); } else { return(VMPrimitiveExitCode.GOTO_FALSE); //couldn't find an object! :'( } }
public override void Execute(VMThread thread, byte[] byteCode, Frame frame) { }
public override void Execute(VMThread thread, byte[] byteCode, Frame frame) { OperandStack operandStack = frame.OperandStack; operandStack.PushObjectRef(null); }
public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args) { var operand = (VMFindBestObjectForFunctionOperand)args; var entities = context.VM.Entities; int bestScore = int.MinValue; VMEntity bestObj = null; var entry = VMFindBestObjectForFunction.FunctionToEntryPoint[operand.Function]; for (int i = 0; i < entities.Count; i++) { var ent = entities[i]; if (ent.ObjectData[(int)VMStackObjectVariable.LockoutCount] > 0) { continue; //this object is not important!!! } if (ent.EntryPoints[entry].ActionFunction != 0) { bool Execute; if (ent.EntryPoints[entry].ConditionFunction != 0) { var Behavior = ent.GetBHAVWithOwner(ent.EntryPoints[entry].ConditionFunction, context.VM.Context); if (Behavior != null) { var test = VMThread.EvaluateCheck(context.VM.Context, context.Caller, new VMStackFrame() { Caller = context.Caller, Callee = ent, CodeOwner = Behavior.owner, StackObject = ent, Routine = context.VM.Assemble(Behavior.bhav), Args = new short[4] }); Execute = (test == VMPrimitiveExitCode.RETURN_TRUE); } else { Execute = true; } } else { Execute = true; } if (Execute) { //calculate the score for this object. int score = 0; if (ScoreVar[operand.Function] != VMStackObjectVariable.Invalid) { score = ent.GetValue(ScoreVar[operand.Function]); if (ScoreVar[operand.Function] == VMStackObjectVariable.DirtyLevel && score < 800) { continue; //only clean "dirty" things. } } LotTilePos posDiff = ent.Position - context.Caller.Position; score -= (int)Math.Sqrt(posDiff.x * posDiff.x + posDiff.y * posDiff.y + (posDiff.Level * posDiff.Level * 900 * 256)) / 3; if (score > bestScore) { bestScore = score; bestObj = ent; } } } } if (bestObj != null) { context.StackObject = bestObj; return(VMPrimitiveExitCode.GOTO_TRUE); } else { return(VMPrimitiveExitCode.GOTO_FALSE); //couldn't find an object! :'( } }
public override IEnumerable<Item> Perform(IEnumerable<Item> items, IEnumerable<Item> modItems) { foreach (Item i in items) { VMItem vm = (i as VMItem); VMThread thread; Thread t; if (modItems.Any ()) { thread = new VMThread(ref vm); t = new Thread (new ThreadStart(thread.DoShutdownRestoreAction)); } else { thread = new VMThread(VMState.off, ref vm); t = new Thread (new ThreadStart(thread.DoAction)); } t.IsBackground = true; t.Start(); } yield break; }
/// <summary> /// 执行指令 /// </summary> /// <param name="thread"></param> /// <param name="frame"></param> public abstract void Execute(VMThread thread, byte[] byteCode, Frame frame);
public bool ExecuteEntryPoint(int entry,VMContext context,bool runImmediately,VMEntity stackOBJ,short[] args) { if (entry == 11) { //user placement, hack to do auto floor removal/placement for stairs if (Object.OBJ.LevelOffset > 0 && Position != LotTilePos.OUT_OF_WORLD) { var floor = context.Architecture.GetFloor(Position.TileX,Position.TileY,Position.Level); var placeFlags = (VMPlacementFlags)ObjectData[(int)VMStackObjectVariable.PlacementFlags]; if ((placeFlags & VMPlacementFlags.InAir) > 0) { context.Architecture.SetFloor(Position.TileX,Position.TileY,Position.Level,new FloorTile(),true); } if ((placeFlags & VMPlacementFlags.OnFloor) > 0 && (floor.Pattern == 0)) { context.Architecture.SetFloor(Position.TileX,Position.TileY,Position.Level,new FloorTile { Pattern = 1 },true); } } } bool result = false; if (EntryPoints[entry].ActionFunction > 255) { VMSandboxRestoreState SandboxState = null; if (GhostImage && runImmediately) { SandboxState = context.VM.Sandbox(); for (int i = 0; i < MultitileGroup.Objects.Count; i++) { var obj = MultitileGroup.Objects[i]; context.VM.AddEntity(obj); } } BHAV bhav; GameObject CodeOwner; ushort ActionID = EntryPoints[entry].ActionFunction; if (ActionID < 4096) { //global bhav = context.Globals.Resource.Get <BHAV>(ActionID); } else if (ActionID < 8192) { //local bhav = Object.Resource.Get <BHAV>(ActionID); } else { //semi-global bhav = SemiGlobal.Get <BHAV>(ActionID); } CodeOwner = Object; if (bhav != null) { var routine = context.VM.Assemble(bhav); var action = new VMQueuedAction { Callee = this, CodeOwner = CodeOwner, /** Main function **/ StackObject = stackOBJ, Routine = routine, Args = args }; if (runImmediately) { var checkResult = VMThread.EvaluateCheck(context,this,action); result = (checkResult == VMPrimitiveExitCode.RETURN_TRUE); } else { this.Thread.EnqueueAction(action); } } if (GhostImage && runImmediately) { //restore state context.VM.SandboxRestore(SandboxState); } return(result); } else { return(false); } }
public override void Execute(VMThread thread, byte[] byteCode, Frame frame) { frame.OperandStack.PushObjectRef(frame.LocalVars.Get(1).ObjectRef); }
public override IEnumerable<Item> Perform(IEnumerable<Item> items, IEnumerable<Item> modifierItems) { foreach (Item i in items) { VMItem vm = (i as VMItem); VMState NewState; VMDynItm mod; if (modifierItems.Any ()) { mod = modifierItems.First () as VMDynItm; NewState = mod.Mode; } else NewState = VMState.on; VMThread thread = new VMThread(NewState, ref vm); Thread t = new Thread (new ThreadStart(thread.DoAction)); t.IsBackground = true; t.Start(); } yield break; }
public void ThreadRemove(VMThread thread) { /** Stop updating a thread **/ VM.ThreadRemove(thread); }
public void ExecuteEntryPoint(int entry,VMContext context,bool runImmediately) { if (EntryPoints[entry].ActionFunction > 255) { BHAV bhav; GameIffResource CodeOwner; ushort ActionID = EntryPoints[entry].ActionFunction; if (ActionID < 4096) { //global bhav = context.Globals.Resource.Get <BHAV>(ActionID); CodeOwner = context.Globals.Resource; } else if (ActionID < 8192) { //local bhav = Object.Resource.Get <BHAV>(ActionID); CodeOwner = Object.Resource; } else { //semi-global bhav = SemiGlobal.Resource.Get <BHAV>(ActionID); CodeOwner = SemiGlobal.Resource; } var routine = context.VM.Assemble(bhav); if (bhav == null) { return; //throw new Exception("Invalid BHAV call!"); } short[] Args = null; VMEntity StackOBJ = null; if (entry == 1) { if (MainParam != 0) { Args = new short[4]; Args[0] = MainParam; MainParam = 0; } if (MainStackOBJ != 0) { StackOBJ = context.VM.GetObjectById(MainStackOBJ); MainStackOBJ = 0; } } var action = new TSO.Simantics.engine.VMQueuedAction { Callee = this, CodeOwner = CodeOwner, /** Main function **/ StackObject = StackOBJ, Routine = routine, Args = Args }; if (runImmediately) { VMThread.EvaluateCheck(context,this,action); } else { this.Thread.EnqueueAction(action); } } }
/// <summary> /// 读取操作数 /// </summary> /// <param name="byteCode"></param> /// <returns></returns> public virtual byte[] FetchOperands(VMThread thread, byte[] byteCode) { return(new byte[0]); }