public async Task StartVmSignsBeforeRunningState() { // --- Arrange var mc = GetMachineController(); VmState oldState = 0; VmState newState = 0; var msgCount = 0; mc.VmStateChanged += (sender, args) => { if (++msgCount == 2) { oldState = args.OldState; newState = args.NewState; } }; // --- Act mc.StartVm(new ExecuteCycleOptions(EmulationMode.UntilFrameEnds)); await mc.StarterTask; // --- Assert oldState.ShouldBe(VmState.BuildingMachine); newState.ShouldBe(VmState.BeforeRun); mc.IsFirstStart.ShouldBeTrue(); }
public async Task StopVmSignsReachesStoppedState() { // --- Arrange var mc = GetMachineController(); var before = mc.SpectrumVm; mc.StartVm(new ExecuteCycleOptions(EmulationMode.UntilFrameEnds)); await mc.StarterTask; VmState oldState = 0; VmState newState = 0; var msgCount = 0; mc.VmStateChanged += (sender, args) => { if (++msgCount == 2) { oldState = args.OldState; newState = args.NewState; } }; // --- Act mc.StopVm(); await mc.CompletionTask; // --- Assert before.ShouldBeNull(); mc.SpectrumVm.ShouldNotBeNull(); mc.IsFirstStart.ShouldBeTrue(); oldState.ShouldBe(VmState.Stopping); newState.ShouldBe(VmState.Stopped); }
private void Resolve(VmState state, byte[] value, int destination) { foreach (var b in value) { state.memory[destination++] = b; } }
/// <summary> /// Moves the virtual machine to the specified new state /// </summary> /// <param name="newState">New machine state</param> protected void MoveToState(VmState newState) { var oldState = VmState; VmState = newState; VmStateChanged?.Invoke(this, new VmStateChangedEventArgs(oldState, newState)); }
private byte[] Resolve(VmState state, int length, int source) { var bytes = new byte[length]; Array.Copy(state.memory, bytes, length); return bytes; }
/// <summary> /// Override this message to respond to vm state changes events /// </summary> protected override void OnVmStateChanged(VmState oldState, VmState newState) { if (newState == VmState.Paused) { Vm.Refresh(); } }
private async Task <string> GetVmStatesAsync() { var vmList = new List <VmState>(); var hypers = await _context.Hypervisors.Include(h => h.VirtualMachines).ToListAsync(); if (hypers == null || hypers.Count == 0) { return(null); } foreach (var h in hypers) { foreach (var vm in h.VirtualMachines) { var s = new VmState(); s.VmId = vm.Id; s.Hypervisor = h.Name; s.Name = vm.Name; s.Status = vm.Status; s.PercentComplete = vm.PercentComplete; s.StatusUpdated = vm.StatusUpdated; s.LastBackup = vm.LastBackup; vmList.Add(s); } } return(JsonConvert.SerializeObject(vmList)); }
/// <summary> /// Changes the caption according to machine state /// </summary> /// <param name="state"></param> protected void ChangeCaption(VmState state) { var additional = string.Empty; switch (state) { case VmState.None: additional = " (Not Started)"; break; case VmState.Stopped: additional = " (Stopped)"; break; case VmState.Paused: additional = " (Paused)"; break; case VmState.Running: var vm = SpectNetPackage.Default.MachineViewModel; if (vm.RunsInDebugMode) { additional = " (Debugging)"; } break; } Caption = BaseCaption + additional; }
public async Task StartDoesNotInitializeVmAfterStop() { // --- Arrange var mc = GetMachineController(); mc.StartVm(new ExecuteCycleOptions(EmulationMode.UntilFrameEnds)); await mc.StarterTask; var before = mc.SpectrumVm; mc.StopVm(); await mc.CompletionTask; VmState oldState = 0; VmState newState = 0; var msgCount = 0; mc.VmStateChanged += (sender, args) => { if (++msgCount == 1) { oldState = args.OldState; newState = args.NewState; } }; // --- Act mc.StartVm(new ExecuteCycleOptions(EmulationMode.UntilFrameEnds)); await mc.StarterTask; // --- Assert before.ShouldNotBeNull(); mc.SpectrumVm.ShouldBeSameAs(before); oldState.ShouldBe(VmState.Stopped); newState.ShouldBe(VmState.BeforeRun); }
static void Main(string[] args) { string[] Vms = { "20361700", "20361698" }; var login = ConfigurationSettings.AppSettings["login"]; var psw = ConfigurationSettings.AppSettings["psw"]; var baseurl = ConfigurationSettings.AppSettings["baseurl"]; var configid = ConfigurationSettings.AppSettings["configid"]; VmState vMState = new VmState(baseurl, configid); foreach (var vm in Vms) { Console.WriteLine("Starting :... "); Console.WriteLine(vMState.Run(login, psw, vm)); Console.WriteLine("Suspending :... "); Console.WriteLine(vMState.Suspend(login, psw, vm)); Console.WriteLine("Resumeing :... "); Console.WriteLine(vMState.Resume(login, psw, vm)); Console.WriteLine("SwitchOffing :... "); Console.WriteLine(vMState.SwitchOff(login, psw, vm)); } Console.ReadKey(); }
private static VmState RunOnce(Instruction[] bytecode, VmState initialState = default) { var visited = new HashSet <int>(); return(Run(bytecode, initialState) .TakeWhile(x => visited.Add(x.InstrPointer)) .Last()); }
public void Execute(VmState state) { state.registers[RegisterName.SP] -= 4; var value = BitConverter.ToUInt32(state.memory, (int) state.registers[RegisterName.SP]); state.registers[destination] = value; state.registers[RegisterName.PC] += 4; }
public void Execute(VmState state) { var bytes = state.registers.GetBytes(source); state.memory[destination] = bytes[0]; state.memory[destination + 1] = bytes[1]; state.memory[destination + 2] = bytes[2]; state.memory[destination + 3] = bytes[3]; state.registers[RegisterName.PC] += 4; }
public void Execute(VmState state) { var bytes = state.registers.GetBytes(toPush); state.memory[state.registers[RegisterName.SP]] = bytes[0]; state.memory[state.registers[RegisterName.SP] + 1] = bytes[1]; state.memory[state.registers[RegisterName.SP] + 2] = bytes[2]; state.memory[state.registers[RegisterName.SP] + 3] = bytes[3]; state.registers[RegisterName.SP] += 4; state.registers[RegisterName.PC] += 4; }
private void SendBroadcast(Vm vm, string action) { VmState state = new VmState { Id = vm.Id, Name = vm.Name.Untagged(), IsRunning = vm.State == VmPowerState.Running }; _hub.Clients.Group(vm.Name.Tag()).VmEvent(new BroadcastEvent <VmState>(User, "VM." + action.ToUpper(), state)); }
public void Execute(VmState state) { var oldPc = BitConverter.ToUInt32(state.memory, (int) state.registers[RegisterName.FP] - 4); var oldFrame = BitConverter.ToUInt32(state.memory, (int) state.registers[RegisterName.FP] - 8); var oldStack = BitConverter.ToUInt32(state.memory, (int) state.registers[RegisterName.FP] - 12); state.registers[RegisterName.SP] = oldStack; state.registers[RegisterName.FP] = oldFrame; state.registers[RegisterName.PC] = oldPc; state.registers[RegisterName.PC] += 4; }
public void Execute(VmState state) { // push stack pointer, frame pointer, and program counter then reset PC var pc = state.registers[RegisterName.PC]; new Push(RegisterName.SP).Execute(state); new Push(RegisterName.FP).Execute(state); new PushIm(pc).Execute(state); state.registers[RegisterName.PC] = pc; state.registers[RegisterName.FP] = state.registers[RegisterName.SP]; state.registers[RegisterName.SP] = state.registers[RegisterName.FP]; state.registers[RegisterName.PC] = location; }
public void Execute(VmState state) { // offset is a signed short, who's max value is +/- 32767 // by shifting left, we multiply by 4, which gives us aligned access only // but allows me to offset by up to +/- 131068 int intOffset = offset; intOffset <<= 2; int location = (int) state.registers[source] + intOffset; var value = BitConverter.ToUInt32(state.memory, location); state.registers[destination] = value; state.registers[RegisterName.PC] += 4; }
public void Problem1(string input, long expected) { var vmState = new VmState(); var prog = LoadProgram(input); try { ExecuteUntilLoop(vmState, prog); Oh.Bugger(); } catch (Utils.VM.Halt) { vmState.Acc.Should().Be(expected); } }
/// <summary> /// Moves the virtual machine to the specified new state /// </summary> /// <param name="newState">New machine state</param> protected void MoveToState(VmState newState) { CheckMainThread(); var oldState = VmState; VmState = newState; OnVmStateChanged(oldState, VmState); VmStateChanged?.Invoke(this, new VmStateChangedEventArgs(oldState, VmState)); if (oldState == VmState.BeforeRun && newState == VmState.Running) { // --- We have just got the notification from the execution cycle // --- about the successful start. _vmStarterCompletionSource.SetResult(true); } }
public static void MergeVms(this GameState state, Vm[] vms) { foreach (Vm vm in vms) { string name = vm.Name.Untagged(); VmState vs = state.Vms .Where(t => t.Name == name && !t.Id.NotEmpty()) .FirstOrDefault(); if (vs != null) { vs.Id = vm.Id; vs.IsRunning = vm.State == VmPowerState.Running; } } }
public void Execute(VmState state) { // offset is a signed short, who's max value is +/- 32767 // by shifting left, we multiply by 4, which gives us aligned access only // but allows me to offset by up to +/- 131068 int intOffset = offset; intOffset <<= 2; int location = (int) state.registers[destination] + intOffset; var bytes = state.registers.GetBytes(source); state.memory[location] = bytes[0]; state.memory[location + 1] = bytes[1]; state.memory[location + 2] = bytes[2]; state.memory[location + 3] = bytes[3]; state.registers[RegisterName.PC] += 4; }
public async Task <ActionResult <Vm> > Deploy(int id) { VmTemplate template = await _templateService.GetDeployableTemplate(id, null); Vm vm = await _pod.Deploy(template); // SendBroadcast(vm, "deploy"); VmState state = new VmState { Id = id.ToString(), Name = vm.Name.Untagged(), IsRunning = vm.State == VmPowerState.Running }; await _hub.Clients.Group(vm.Name.Tag()).VmEvent(new BroadcastEvent <VmState>(User, "VM.DEPLOY", state)); return(Ok(vm)); }
public async Task <ActionResult <Vm> > DeployVm(string id) { VmTemplate template = await _templateService .GetDeployableTemplate(id, null) ; string name = $"{template.Name}#{template.IsolationTag}"; AuthorizeAny( () => Actor.IsAdmin, () => CanManageVm(name, Actor.Id).Result ); Vm vm = await _pod.Deploy(template, Actor.IsBuilder); if (template.HostAffinity) { await _pod.SetAffinity( template.IsolationTag, new Vm[] { vm }, true ); vm.State = VmPowerState.Running; } // SendBroadcast(vm, "deploy"); VmState state = new VmState { Id = template.Id.ToString(), Name = vm.Name.Untagged(), IsolationId = vm.Name.Tag(), IsRunning = vm.State == VmPowerState.Running }; await Hub.Clients .Group(state.IsolationId) .VmEvent(new BroadcastEvent <VmState>(User, "VM.DEPLOY", state)) ; return(Ok(vm)); }
/// <summary> /// Changes the caption according to machine state /// </summary> /// <param name="state"></param> protected void ChangeCaption(VmState state) { var additional = string.Empty; switch (state) { case VmState.None: additional = " (Not Started)"; break; case VmState.Stopped: additional = " (Stopped)"; break; case VmState.Paused: additional = " (Paused)"; break; } Caption = BaseCaption + additional; }
/// <summary> /// Cancels the execution of the virtual machine. /// </summary> /// <param name="cancelledState">Virtual machine state after cancellation</param> private async Task CancelVmExecution(VmState cancelledState) { try { // --- Wait for cancellation _cancellationTokenSource?.Cancel(); ExecutionCompletionReason = await _completionTask; } catch (TaskCanceledException) { // --- Ok, run successfully cancelled ExecutionCompletionReason = ExecutionCompletionReason.Cancelled; } catch (Exception ex) { // --- Some other exception raised ExceptionRaised?.Invoke(this, new VmExceptionArgs(ex)); } finally { // --- Now, it's cancelled MachineState = cancelledState; } }
byte[] ISourceValue.Resolve(VmState state, int length, object source) { return Resolve(state, length, (int) source); }
void IDestinationValue.Resolve(VmState state, byte[] value, object destination) { Resolve(state, value, (int) destination); }
void IDestinationValue.Resolve(VmState state, byte[] value, object destination) { Resolve(state, value, (RegisterName) destination); }
static Instruction[] LoadProgram(string input) { var program = new List <Instruction>(); foreach (var line in FileIterator.Lines(input)) { var split = line.Split(' '); OpCode opCode = split[0] switch { "acc" => OpCode.ACC, "jmp" => OpCode.JMP, _ => OpCode.NOP }; var value = long.Parse(split[1]); program.Add(new Instruction(opCode, value)); } return(program.ToArray()); } void ExecuteUntilLoop(VmState vmState, Instruction[] program) { var visited = new HashSet <long>(); while (true) { if (vmState.Ip >= program.Length) { return; } if (visited.Contains(vmState.Ip)) { throw new Utils.VM.Halt(); } visited.Add(vmState.Ip); var instruction = program[vmState.Ip]; OpCodeCount++; switch (instruction.OpCode) { case OpCode.NOP: break; case OpCode.ACC: vmState.Acc += instruction.Value; break; case OpCode.JMP: vmState.Ip += (instruction.Value - 1); // We need to take into account that the IP is auto incremented break; } vmState.Ip++; } } long PatchAndExecute(Instruction[] program) { for (var i = 0; i < program.Length; i++) { var patchedInstruction = program[i]; switch (patchedInstruction.OpCode) { case OpCode.NOP: program[i] = new Instruction(OpCode.JMP, patchedInstruction.Value); break; case OpCode.JMP: program[i] = new Instruction(OpCode.NOP, patchedInstruction.Value); break; default: continue; } try { var vmState = new VmState(); ExecuteUntilLoop(vmState, program); return(vmState.Acc); } catch (Utils.VM.Halt) {} // Loop detected, so continue the search... // Restore the program program[i] = patchedInstruction; } throw new Expletive("Bugger"); } long ExecutionGraph(Instruction[] program, HashSet <long> visited, long ip, long acc, bool branching) { if (ip >= program.Length) { return(acc); } if (visited.Contains(ip)) { throw new Utils.VM.Halt(); } visited.Add(ip); var instuction = program[ip]; try { OpCodeCount++; switch (instuction.OpCode) { case OpCode.NOP: try { return(ExecutionGraph(program, visited, ip + 1, acc, branching)); } catch (Utils.VM.Halt) { if (!branching) { OpCodeCount++; return(ExecutionGraph(program, visited, ip + instuction.Value, acc, true)); } else { throw; } } case OpCode.JMP: try { return(ExecutionGraph(program, visited, ip + instuction.Value, acc, branching)); } catch (Utils.VM.Halt) { if (!branching) { OpCodeCount++; return(ExecutionGraph(program, visited, ip + 1, acc, true)); } else { throw; } } case OpCode.ACC: return(ExecutionGraph(program, visited, ip + 1, acc + instuction.Value, branching)); default: throw new Expletive("Shit"); } } finally { visited.Remove(ip); } }
public void Execute(VmState state) { state.registers[result] = state.registers[target] >> (int) state.registers[source]; state.registers[RegisterName.PC] += 4; }
/// <summary> /// Executes the <paramref name="entry" />. /// </summary> /// <param name="entry">Transaction entry to be executed inside the <see cref="VirtualMachine" />.</param> /// <param name="stateUpdate"><see cref="Delta" /> to be used for execution environment construction</param> /// <param name="txTracer">Tracer to extract the execution steps for debugging or analytics.</param> /// <param name="readOnly">Defines whether the state should be reverted after the execution.</param> /// <exception cref="TransactionCollisionException">Thrown when deployment address already has some code.</exception> /// <exception cref="OutOfGasException">Thrown when not enough gas is available for deposit.</exception> private void Execute(PublicEntry entry, StateUpdate stateUpdate, ITxTracer txTracer, bool readOnly) { var spec = _specProvider.GetSpec(stateUpdate.Number); var(sender, recipient) = ExtractSenderAndRecipient(entry); var isPrecompile = recipient.IsPrecompiled(spec); var env = PrepareEnv(entry, sender, recipient, stateUpdate, isPrecompile); var gasLimit = entry.GasLimit; var intrinsicGas = CalculateIntrinsicGas(entry, spec); if (_logger.IsEnabled(LogEventLevel.Verbose)) { _logger.Verbose("Executing entry {entry}", entry); } if (!ValidateSender(entry, env, txTracer)) { return; } if (!ValidateIntrinsicGas(entry, env, intrinsicGas, txTracer)) { return; } if (!ValidateDeltaGasLimit(entry, env, txTracer)) { return; } if (!_stateProvider.AccountExists(env.Sender)) { if (env.GasPrice == UInt256.Zero) { _stateProvider.CreateAccount(env.Sender, UInt256.Zero); } } if (!ValidateSenderBalance(entry, env, intrinsicGas, txTracer)) { return; } if (!ValidateNonce(entry, env, txTracer)) { return; } InitEntryExecution(env, gasLimit, spec, txTracer); // we prepare two fields to track the amount of gas spent / left var unspentGas = gasLimit - intrinsicGas; var spentGas = gasLimit; // the snapshots are needed to revert the subroutine state changes in case of an VM exception var stateSnapshot = _stateProvider.TakeSnapshot(); var storageSnapshot = _storageProvider.TakeSnapshot(); // we subtract value from sender // it will be added to recipient at the later stage (inside the VM) _stateProvider.SubtractFromBalance(sender, env.Value, spec); // we fail unless we succeed var statusCode = StatusCode.Failure; TransactionSubstate substate = null; try { if (entry.IsValidDeploymentEntry) { PrepareContractAccount(env.CodeSource); } var executionType = entry.IsValidDeploymentEntry ? ExecutionType.Create : ExecutionType.Call; using (var state = new VmState((long)unspentGas, env, executionType, isPrecompile, true, false)) { substate = _virtualMachine.Run(state, txTracer); unspentGas = (ulong)state.GasAvailable; } if (substate.ShouldRevert || substate.IsError) { if (_logger.IsEnabled(LogEventLevel.Verbose)) { _logger.Verbose("Restoring state from before transaction"); } _stateProvider.Restore(stateSnapshot); _storageProvider.Restore(storageSnapshot); } else { if (entry.IsValidDeploymentEntry) { DeployCode(env, substate, ref unspentGas, spec); } DestroyAccounts(substate); statusCode = StatusCode.Success; } spentGas = Refund(gasLimit, unspentGas, substate, env, spec); } catch (Exception ex) when(ex is EvmException || ex is OverflowException) { if (_logger.IsEnabled(LogEventLevel.Verbose)) { _logger.Verbose($"EVM EXCEPTION: {ex.GetType().Name}"); } _stateProvider.Restore(stateSnapshot); _storageProvider.Restore(storageSnapshot); } if (_logger.IsEnabled(LogEventLevel.Verbose)) { _logger.Verbose("Gas spent: " + spentGas); } var gasBeneficiary = stateUpdate.GasBeneficiary; var wasBeneficiaryAccountDestroyed = statusCode != StatusCode.Failure && (substate?.DestroyList.Contains(gasBeneficiary) ?? false); if (!wasBeneficiaryAccountDestroyed) { if (!_stateProvider.AccountExists(gasBeneficiary)) { _stateProvider.CreateAccount(gasBeneficiary, spentGas * env.GasPrice); } else { _stateProvider.AddToBalance(gasBeneficiary, spentGas * env.GasPrice, spec); } } if (!readOnly) { _storageProvider.Commit(txTracer.IsTracingState ? txTracer : null); _stateProvider.Commit(spec, txTracer.IsTracingState ? txTracer : null); stateUpdate.GasUsed += (long)spentGas; } else { _storageProvider.Reset(); _stateProvider.Reset(); } if (txTracer.IsTracingReceipt) { if (statusCode == StatusCode.Failure) { txTracer.MarkAsFailed(env.CodeSource, (long)spentGas, substate?.ShouldRevert ?? false ? substate.Output : Bytes.Empty, substate?.Error); } else { if (substate == null) { throw new InvalidOperationException("Substate should not be null after a successful VM run."); } txTracer.MarkAsSuccess(env.CodeSource, (long)spentGas, substate.Output, substate.Logs.Any() ? substate.Logs.ToArray() : LogEntry.EmptyLogs); } } }
/// <summary> /// Overrid this method to handle vm state changes within the controller /// </summary> /// <param name="oldState">Old VM state</param> /// <param name="newState">New VM state</param> protected virtual void OnVmStateChanged(VmState oldState, VmState newState) { }
private byte[] Resolve(VmState state, int length, RegisterName source) { var bytes = BitConverter.GetBytes(state.registers[source]); return bytes; }
/// <summary>Initializes a new instance of the MessageBase class.</summary> public MachineStateChangedMessage(VmState oldState, VmState newState) { OldState = oldState; NewState = newState; }
/// <summary> /// Overrid this method to handle vm state changes within the controller /// </summary> /// <param name="oldState">Old VM state</param> /// <param name="newState">New VM state</param> protected override void OnVmStateChanged(VmState oldState, VmState newState) { var pane = OutputWindow.GetPane <SpectrumVmOutputPane>(); pane.WriteLine($"Machine state changed: {oldState} --> {newState}."); }
public void Execute(VmState state) { state.registers[result] = state.registers[arg1] / state.registers[arg2]; state.registers[RegisterName.PC] += 4; }
/// <summary> /// Initializes the event arguments /// </summary> /// <param name="oldState">Old vm state</param> /// <param name="newState">New vm state</param> public VmStateChangedEventArgs(VmState oldState, VmState newState) { OldState = oldState; NewState = newState; }
public void Execute(VmState state) { state.registers[destination] = toLoad; state.registers[RegisterName.PC] += 4; }
public void UpdateStateForAssignment(VmState vmState, ResourceRetrievalResult?assetRetrievalResult = null, ResourceRetrievalResult?imageRetrievalResult = null, bool forceSave = false) { }
private void Resolve(VmState state, byte[] value, RegisterName destination) { state.registers[destination] = BitConverter.ToUInt32(value, 0); }