public static ITypeDescriptor ToMetadataType(this VMType type, ModuleDefinition module) { switch (type) { case VMType.Unknown: case VMType.Object: return(module.CorLibTypeFactory.Object); case VMType.Pointer: return(module.CorLibTypeFactory.IntPtr); case VMType.Byte: return(module.CorLibTypeFactory.Byte); case VMType.Word: return(module.CorLibTypeFactory.UInt16); case VMType.Dword: return(module.CorLibTypeFactory.UInt32); case VMType.Qword: return(module.CorLibTypeFactory.UInt64); case VMType.Real32: return(module.CorLibTypeFactory.Single); case VMType.Real64: return(module.CorLibTypeFactory.Double); default: throw new ArgumentOutOfRangeException(nameof(type), type, null); } }
public ContractEvent(byte value, string name, VMType returnType, byte[] description) { this.value = value; this.name = name; this.returnType = returnType; this.description = description; }
public static ITypeDescriptor ToMetadataType(this VMType type, MetadataImage image) { switch (type) { case VMType.Unknown: case VMType.Object: return(image.TypeSystem.Object); case VMType.Pointer: return(image.TypeSystem.IntPtr); case VMType.Byte: return(image.TypeSystem.Byte); case VMType.Word: return(image.TypeSystem.UInt16); case VMType.Dword: return(image.TypeSystem.UInt32); case VMType.Qword: return(image.TypeSystem.UInt64); case VMType.Real32: return(image.TypeSystem.Single); case VMType.Real64: return(image.TypeSystem.Double); default: throw new ArgumentOutOfRangeException(nameof(type), type, null); } }
public async Task <IActionResult> Crear([FromBody] CrearViewModel model) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } VMType vMType = new VMType { vmtypename = model.vmtypename, vmtypedescription = model.vmtypedescription, vmtypeestado = true }; _context.VMTypes.Add(vMType); try { await _context.SaveChangesAsync(); } catch (Exception ex) { return(BadRequest()); } return(Ok()); }
public static VMObject CastTo(VMObject srcObj, VMType type) { if (srcObj.Type == type) { var result = new VMObject(); result.Copy(srcObj); return(result); } switch (type) { case VMType.None: return(new VMObject()); case VMType.String: { var result = new VMObject(); result.SetValue(srcObj.AsString()); // TODO does this work for all types? return(result); } case VMType.Timestamp: { var result = new VMObject(); result.SetValue(srcObj.AsTimestamp()); // TODO does this work for all types? return(result); } case VMType.Bool: { var result = new VMObject(); result.SetValue(srcObj.AsBool()); // TODO does this work for all types? return(result); } case VMType.Bytes: { var result = new VMObject(); result.SetValue(srcObj.AsByteArray()); // TODO does this work for all types? return(result); } case VMType.Number: { var result = new VMObject(); result.SetValue(srcObj.AsNumber()); // TODO does this work for all types? return(result); } case VMType.Struct: switch (srcObj.Type) { case VMType.Object: return(CastViaReflection(srcObj.Data, 0)); default: throw new Exception($"invalid cast: {srcObj.Type} to {type}"); } default: throw new Exception($"invalid cast: {srcObj.Type} to {type}"); } }
public ContractMethod(string name, VMType returnType, int offset, params ContractParameter[] parameters) { this.name = name; this.offset = offset; this.returnType = returnType; this.parameters = parameters; }
public static bool IsValidMethod(string methodName, VMType returnType) { if (string.IsNullOrEmpty(methodName) || methodName.Length < 3) { return(false); } if (methodName.StartsWith("is") && char.IsUpper(methodName[2])) { return(returnType == VMType.Bool); } // trigger if (methodName.StartsWith("on") && char.IsUpper(methodName[2])) { return(returnType == VMType.None); } // property if (methodName.StartsWith("get") && char.IsUpper(methodName[3])) { return(returnType != VMType.None); } return(true); }
private static ASTFunction ParseFunction() { VMType returnType = VMType.None; if (currentTokens[currentToken] is ReservedWordToken) { switch (currentTokens[currentToken].Token) { case "number": returnType = VMType.Number; break; case "string": returnType = VMType.String; break; case "object": returnType = VMType.Object; break; } currentToken++; } //else it is a constructor if (currentTokens[currentToken] is IdentifierToken) { string name = currentTokens[currentToken].Token; currentToken++; List <ASTNode> parameter = ParseFunctionParameter(); List <ASTNode> codeBlock = ParseCodeBlock(); currentToken++; if (returnType == VMType.None) { if (name != currentClassName) { throw new ParserException(string.Format("Constructor '{0}' needs the same name as Class '{1}'.", name, currentClassName), currentTokens[currentToken].LineNumber); } return(new ASTConstructor() { Name = name, Parameter = parameter, CodeBlock = codeBlock, ReturnValue = returnType }); } return(new ASTFunction() { Name = name, Parameter = parameter, CodeBlock = codeBlock, ReturnValue = returnType }); } else { throw new ParserException("Expected Function Name.", currentTokens[currentToken].LineNumber); } }
public void EmitLoad(byte reg, byte[] bytes, VMType type = VMType.Bytes) { Emit(Opcode.LOAD); writer.Write((byte)reg); writer.Write((byte)type); writer.WriteVarInt(bytes.Length); writer.Write(bytes); }
public VMObject SetDefaultValue(VMType type) { this.Type = type; this._localSize = 1; // TODO fixme switch (type) { case VMType.Bytes: { this.Data = new byte[0]; break; } case VMType.Number: { this.Data = new BigInteger(0); break; } case VMType.String: { this.Data = ""; break; } case VMType.Enum: { this.Data = (uint)0; break; } case VMType.Timestamp: { this.Data = new Timestamp(0); break; } case VMType.Bool: { this.Data = false; break; } case VMType.Object: { this.Data = null; break; } default: { throw new Exception("Cannot init default value for vmtype: " + type); } } return(this); }
public ScriptBuilder EmitLoad(byte reg, byte[] bytes, VMType type = VMType.Bytes) { Emit(Opcode.LOAD); writer.Write((byte)reg); writer.Write((byte)type); writer.WriteVarInt(bytes.Length); writer.Write(bytes); return(this); }
public VMObject SetValue(byte[] val, VMType type) { this.Type = type; this._localSize = val.Length; switch (type) { case VMType.Bytes: { this.Data = val; break; } case VMType.Number: { this.Data = (val == null || val.Length == 0) ? new BigInteger(0) : BigInteger.FromSignedArray(val); break; } case VMType.String: { this.Data = Encoding.UTF8.GetString(val); break; } case VMType.Enum: { // TODO this will fail if val is not exactly 4 bytes long. Add code here to autopad with zeros if necessary this.Data = BitConverter.ToUInt32(val, 0); break; } case VMType.Timestamp: { var temp = BitConverter.ToUInt32(val, 0); this.Data = new Timestamp(temp); break; } case VMType.Bool: { this.Data = BitConverter.ToBoolean(val, 0); break; } default: { throw new Exception("Cannot set value for vmtype: " + type); } } return(this); }
public ScriptBuilder EmitLoad(byte reg, byte[] bytes, VMType type = VMType.Bytes) { Throw.If(bytes.Length > 0xFFFF, "tried to load too much data"); Emit(Opcode.LOAD); writer.Write((byte)reg); writer.Write((byte)type); writer.WriteVarInt(bytes.Length); writer.Write(bytes); return(this); }
public void CastTo(VMType type) { if (this.Type == type) { return; } switch (type) { case VMType.String: this.Data = this.Data.ToString(); // TODO does this work for all types? break; case VMType.Bool: switch (this.Type) { case VMType.Number: this.Data = this.AsNumber() != 0; break; case VMType.String: this.Data = !(((string)this.Data).Equals("false", StringComparison.OrdinalIgnoreCase)); break; default: throw new Exception($"invalid cast: {this.Type} to {type}"); } break; case VMType.Bytes: switch (this.Type) { case VMType.Bool: this.Data = new byte[] { (byte)(this.AsBool() ? 1 : 0) }; break; case VMType.String: this.Data = Encoding.UTF8.GetBytes((string)this.Data); break; case VMType.Number: this.Data = ((BigInteger)this.Data).ToByteArray(); break; default: throw new Exception($"invalid cast: {this.Type} to {type}"); } break; case VMType.Number: switch (this.Type) { case VMType.Bool: this.Data = this.AsBool() ? 1 : 0; break; case VMType.String: this.Data = BigInteger.Parse((string)this.Data); break; case VMType.Bytes: this.Data = new BigInteger((byte[])this.Data); break; default: throw new Exception($"invalid cast: {this.Type} to {type}"); } break; default: throw new NotImplementedException(); } }
public VMObject SetValue(byte[] val, VMType type) { this.Type = type; this._localSize = val.Length; switch (type) { case VMType.Bytes: { this.Data = val; break; } case VMType.Number: { this.Data = BigInteger.FromSignedArray(val); break; } case VMType.String: { this.Data = Encoding.UTF8.GetString(val); break; } case VMType.Enum: { this.Data = BitConverter.ToUInt32(val, 0); break; } case VMType.Timestamp: { var temp = BitConverter.ToUInt32(val, 0); this.Data = new Timestamp(temp); break; } case VMType.Bool: { this.Data = BitConverter.ToBoolean(val, 0); break; } default: { throw new Exception("Invalid cast"); } } return(this); }
public bool MergeWith(SymbolicValue value) { if (ReferenceEquals(this, value)) { return(false); } Type = value.Type; int size = DataSources.Count; DataSources.UnionWith(value.DataSources); return(size != DataSources.Count); }
public ContractMethod(string name, VMType returnType, Dictionary <string, int> labels, params ContractParameter[] parameters) { if (!labels.ContainsKey(name)) { throw new Exception("Missing offset in label map for method " + name); } var offset = labels[name]; this.name = name; this.offset = offset; this.returnType = returnType; this.parameters = parameters; }
public static ContractMethod Unserialize(BinaryReader reader) { var name = reader.ReadVarString(); var returnType = (VMType)reader.ReadByte(); var len = reader.ReadByte(); var parameters = new VMType[len]; for (int i = 0; i < len; i++) { parameters[i] = (VMType)reader.ReadByte(); } return(new ContractMethod(name, returnType, parameters)); }
public object AsType(VMType type) { switch (type) { case VMType.Bool: return(AsBool()); case VMType.String: return(AsString()); case VMType.Bytes: return(AsByteArray()); case VMType.Number: return(AsNumber()); default: throw new ArgumentException("Unsupported VM cast"); } }
public static List <SqlColumnInfo> GetVMList(string table_name, VMType vmType, List <SqlColumnInfo> current) { List <SqlColumnInfo> result = new List <SqlColumnInfo>(); var tbInfo = dataList.Find(p => p.db_name == Cache_Next.GetDbName() && p.table_name == table_name); if (tbInfo == null || (vmType == VMType.Add && tbInfo.add_list.Count == 0) || (vmType == VMType.Edit && tbInfo.edit_list.Count == 0) || (vmType == VMType.Query && tbInfo.query_list.Count == 0)) { var info = dataList.Find(p => p.db_name == Cache_Next.GetDbName() && p.type == 0); if (info == null) { return(current); } else { if (vmType == VMType.Add) { return(current.FindAll(p => !info.add_list.Contains(p.Name))); } else if (vmType == VMType.Edit) { return(current.FindAll(p => !info.edit_list.Contains(p.Name))); } else { return(current.FindAll(p => !info.query_list.Contains(p.Name))); } } } else { if (vmType == VMType.Add) { return(current.FindAll(p => tbInfo.add_list.Contains(p.Name))); } else if (vmType == VMType.Edit) { return(current.FindAll(p => tbInfo.edit_list.Contains(p.Name))); } else { return(current.FindAll(p => tbInfo.query_list.Contains(p.Name))); } } }
public VMObject SetValue(byte[] val, VMType type) { this.Type = type; this._localSize = val.Length; switch (type) { case VMType.Bytes: { this.Data = val; break; } case VMType.Number: { this.Data = new BigInteger(val, twosComplementFormatFlag: true); break; } case VMType.String: { this.Data = Encoding.UTF8.GetString(val); break; } case VMType.Enum: { this.Data = BitConverter.ToUInt32(val, 0); break; } case VMType.Bool: { this.Data = BitConverter.ToBoolean(val, 0); break; } default: { throw new Exception("Invalid cast"); } } return(this); }
internal Transaction CreateContractMethodCallTx(ByteString callTxInput, VMType vmType) { var callTxBytes = new CallTx { VmType = vmType, Input = callTxInput }.ToByteString(); var msgTxBytes = new MessageTx { From = this.Caller.ToProtobufAddress(), To = this.Address.ToProtobufAddress(), Data = callTxBytes }.ToByteString(); return(new Transaction { Id = 2, Data = msgTxBytes }); }
public void Step(ref ExecutionFrame frame, Stack <VMObject> stack) { try { opcode = (Opcode)Read8(); frame.VM.ValidateOpcode(opcode); switch (opcode) { case Opcode.NOP: { break; } // args: byte src_reg, byte dest_reg case Opcode.MOVE: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); Expect(dst < frame.Registers.Length, "invalid dst register"); frame.Registers[dst] = frame.Registers[src]; frame.Registers[src] = new VMObject(); break; } // args: byte src_reg, byte dest_reg case Opcode.COPY: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); Expect(dst < frame.Registers.Length, "invalid dst register"); frame.Registers[dst].Copy(frame.Registers[src]); break; } // args: byte dst_reg, byte type, var length, var data_bytes case Opcode.LOAD: { var dst = Read8(); var type = (VMType)Read8(); var len = (int)ReadVar(0xFFFF); Expect(dst < frame.Registers.Length, "invalid dst register"); var bytes = ReadBytes(len); frame.Registers[dst].SetValue(bytes, type); break; } // args: byte src_reg, dst_reg, byte type case Opcode.CAST: { var src = Read8(); var dst = Read8(); var type = (VMType)Read8(); Expect(src < frame.Registers.Length, "invalid src register"); Expect(dst < frame.Registers.Length, "invalid dst register"); var val = frame.Registers[src]; val = VMObject.CastTo(val, type); frame.Registers[dst] = val; break; } // args: byte src_reg case Opcode.PUSH: { var src = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); var val = frame.Registers[src]; var temp = new VMObject(); temp.Copy(val); stack.Push(temp); break; } // args: byte dest_reg case Opcode.POP: { var dst = Read8(); Expect(stack.Count > 0, "stack is empty"); Expect(dst < frame.Registers.Length, "invalid dst register"); frame.Registers[dst] = stack.Pop(); break; } // args: byte src_reg, byte dest_reg case Opcode.SWAP: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); Expect(dst < frame.Registers.Length, "invalid dst register"); var temp = frame.Registers[src]; frame.Registers[src] = frame.Registers[dst]; frame.Registers[dst] = temp; break; } // args: ushort offset, byte regCount case Opcode.CALL: { var count = Read8(); var ofs = Read16(); Expect(ofs < this.Script.Length, "invalid jump offset"); Expect(count >= 1, "at least 1 register required"); Expect(count <= VirtualMachine.MaxRegisterCount, "invalid register allocs"); frame.VM.PushFrame(this, InstructionPointer, count); frame = frame.VM.CurrentFrame; InstructionPointer = ofs; break; } // args: byte srcReg case Opcode.EXTCALL: using (var m = new ProfileMarker("EXTCALL")) { var src = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); var method = frame.Registers[src].AsString(); var state = frame.VM.ExecuteInterop(method); if (state != ExecutionState.Running) { throw new VMException(frame.VM, "VM extcall failed: " + method); } break; } // args: ushort offset, byte src_reg // NOTE: JMP only has offset arg, not the rest case Opcode.JMP: case Opcode.JMPIF: case Opcode.JMPNOT: { bool shouldJump; if (opcode == Opcode.JMP) { shouldJump = true; } else { var src = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); shouldJump = frame.Registers[src].AsBool(); if (opcode == Opcode.JMPNOT) { shouldJump = !shouldJump; } } var newPos = (short)Read16(); Expect(newPos >= 0, "jump offset can't be negative value"); Expect(newPos < this.Script.Length, "trying to jump outside of script bounds"); if (shouldJump) { InstructionPointer = (uint)newPos; } break; } // args: var length, var bytes case Opcode.THROW: { var src = Read8(); Expect(src < frame.Registers.Length, "invalid exception register"); var exception = frame.Registers[src]; var exceptionMessage = exception.AsString(); throw new VMException(frame.VM, exceptionMessage); } // args: none case Opcode.RET: { if (frame.VM.frames.Count > 1) { var temp = frame.VM.PeekFrame(); if (temp.Context.Name == this.Name) { InstructionPointer = frame.VM.PopFrame(); frame = frame.VM.CurrentFrame; } else { SetState(ExecutionState.Halt); } } else { SetState(ExecutionState.Halt); } return; } // args: byte src_a_reg, byte src_b_reg, byte dest_reg case Opcode.CAT: { var srcA = Read8(); var srcB = Read8(); var dst = Read8(); Expect(srcA < frame.Registers.Length, "invalid srcA register"); Expect(srcB < frame.Registers.Length, "invalid srcB register"); Expect(dst < frame.Registers.Length, "invalid dst register"); var A = frame.Registers[srcA]; var B = frame.Registers[srcB]; if (!A.IsEmpty) { if (B.IsEmpty) { frame.Registers[dst].Copy(A); } else { if (A.Type != B.Type) { throw new VMException(frame.VM, "Invalid cast during concat opcode"); } var bytesA = A.AsByteArray(); var bytesB = B.AsByteArray(); var result = new byte[bytesA.Length + bytesB.Length]; Array.Copy(bytesA, result, bytesA.Length); Array.Copy(bytesB, 0, result, bytesA.Length, bytesB.Length); VMType type = A.Type; frame.Registers[dst].SetValue(result, type); } } else { if (B.IsEmpty) { frame.Registers[dst] = new VMObject(); } else { frame.Registers[dst].Copy(B); } } break; } case Opcode.SUBSTR: { throw new NotImplementedException(); } // args: byte src_reg, byte dest_reg, var length case Opcode.LEFT: { var src = Read8(); var dst = Read8(); var len = (int)ReadVar(0xFFFF); Expect(src < frame.Registers.Length, "invalid src register"); Expect(dst < frame.Registers.Length, "invalid dst register"); var src_array = frame.Registers[src].AsByteArray(); Expect(len <= src_array.Length, "invalid length"); var result = new byte[len]; Array.Copy(src_array, result, len); frame.Registers[dst].SetValue(result, VMType.Bytes); break; } // args: byte src_reg, byte dest_reg, byte length case Opcode.RIGHT: { var src = Read8(); var dst = Read8(); var len = (int)ReadVar(0xFFFF); Expect(src < frame.Registers.Length, "invalid src register"); Expect(dst < frame.Registers.Length, "invalid dst register"); var src_array = frame.Registers[src].AsByteArray(); Expect(len <= src_array.Length, "invalid length register"); var ofs = src_array.Length - len; var result = new byte[len]; Array.Copy(src_array, ofs, result, 0, len); frame.Registers[dst].SetValue(result, VMType.Bytes); break; } // args: byte src_reg, byte dest_reg case Opcode.SIZE: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); Expect(dst < frame.Registers.Length, "invalid dst register"); int size; var src_val = frame.Registers[src]; switch (src_val.Type) { case VMType.String: size = src_val.AsString().Length; break; case VMType.Timestamp: case VMType.Number: case VMType.Enum: case VMType.Bool: size = 1; break; case VMType.None: size = 0; break; default: var src_array = src_val.AsByteArray(); size = src_array.Length; break; } frame.Registers[dst].SetValue(size); break; } // args: byte src_reg, byte dest_reg case Opcode.COUNT: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); Expect(dst < frame.Registers.Length, "invalid dst register"); var val = frame.Registers[src]; int count; switch (val.Type) { case VMType.Struct: { var children = val.GetChildren(); count = children.Count; break; } default: count = 1; break; } frame.Registers[dst].SetValue(count); break; } // args: byte src_reg, byte dest_reg case Opcode.NOT: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); Expect(dst < frame.Registers.Length, "invalid dst register"); var val = frame.Registers[src].AsBool(); frame.Registers[dst].SetValue(!val); break; } // args: byte src_a_reg, byte src_b_reg, byte dest_reg case Opcode.AND: case Opcode.OR: case Opcode.XOR: { var srcA = Read8(); var srcB = Read8(); var dst = Read8(); Expect(srcA < frame.Registers.Length, "invalid srcA register"); Expect(srcB < frame.Registers.Length, "invalid srcB register"); Expect(dst < frame.Registers.Length, "invalid dst register"); var valA = frame.Registers[srcA]; var valB = frame.Registers[srcB]; switch (valA.Type) { case VMType.Bool: { Expect(valB.Type == VMType.Bool, $"expected {valA.Type} for logical op"); var a = valA.AsBool(); var b = valB.AsBool(); bool result; switch (opcode) { case Opcode.AND: result = (a && b); break; case Opcode.OR: result = (a || b); break; case Opcode.XOR: result = (a ^ b); break; default: { SetState(ExecutionState.Fault); return; } } frame.Registers[dst].SetValue(result); break; } case VMType.Enum: { Expect(valB.Type == VMType.Enum, $"expected {valA.Type} for flag op"); var numA = valA.AsNumber(); var numB = valB.AsNumber(); Expect(numA.GetBitLength() <= 32, "too many bits"); Expect(numB.GetBitLength() <= 32, "too many bits"); var a = (uint)numA; var b = (uint)numB; if (opcode != Opcode.AND) { SetState(ExecutionState.Fault); } bool result = (a & b) != 0; frame.Registers[dst].SetValue(result); break; } case VMType.Number: { Expect(valB.Type == VMType.Number, $"expected {valA.Type} for logical op"); var numA = valA.AsNumber(); var numB = valB.AsNumber(); Expect(numA.GetBitLength() <= 64, "too many bits"); Expect(numB.GetBitLength() <= 64, "too many bits"); var a = (long)numA; var b = (long)numB; BigInteger result; switch (opcode) { case Opcode.AND: result = (a & b); break; case Opcode.OR: result = (a | b); break; case Opcode.XOR: result = (a ^ b); break; default: { SetState(ExecutionState.Fault); return; } } frame.Registers[dst].SetValue(result); break; } default: throw new VMException(frame.VM, "logical op unsupported for type " + valA.Type); } break; } // args: byte src_a_reg, byte src_b_reg, byte dest_reg case Opcode.EQUAL: { var srcA = Read8(); var srcB = Read8(); var dst = Read8(); Expect(srcA < frame.Registers.Length, "invalid srcA register"); Expect(srcB < frame.Registers.Length, "invalid srcB register"); Expect(dst < frame.Registers.Length, "invalid dst register"); var a = frame.Registers[srcA]; var b = frame.Registers[srcB]; var result = a.Equals(b); frame.Registers[dst].SetValue(result); break; } // args: byte src_a_reg, byte src_b_reg, byte dest_reg case Opcode.LT: case Opcode.GT: case Opcode.LTE: case Opcode.GTE: { var srcA = Read8(); var srcB = Read8(); var dst = Read8(); Expect(srcA < frame.Registers.Length, "invalid srcA register"); Expect(srcB < frame.Registers.Length, "invalid srcB register"); Expect(dst < frame.Registers.Length, "invalid dst register"); var a = frame.Registers[srcA].AsNumber(); var b = frame.Registers[srcB].AsNumber(); bool result; switch (opcode) { case Opcode.LT: result = (a < b); break; case Opcode.GT: result = (a > b); break; case Opcode.LTE: result = (a <= b); break; case Opcode.GTE: result = (a >= b); break; default: { SetState(ExecutionState.Fault); return; } } frame.Registers[dst].SetValue(result); break; } // args: byte reg case Opcode.INC: { var dst = Read8(); Expect(dst < frame.Registers.Length, "invalid dst register"); var val = frame.Registers[dst].AsNumber(); frame.Registers[dst].SetValue(val + 1); break; } // args: byte reg case Opcode.DEC: { var dst = Read8(); Expect(dst < frame.Registers.Length, "invalid dst register"); var val = frame.Registers[dst].AsNumber(); frame.Registers[dst].SetValue(val - 1); break; } // args: byte src_reg, byte dest_reg case Opcode.SIGN: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); Expect(dst < frame.Registers.Length, "invalid dst register"); var val = frame.Registers[src].AsNumber(); if (val == 0) { frame.Registers[dst].SetValue(BigInteger.Zero); } else { frame.Registers[dst].SetValue(val < 0 ? -1 : 1); } break; } // args: byte src_reg, byte dest_reg case Opcode.NEGATE: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); Expect(dst < frame.Registers.Length, "invalid dst register"); var val = frame.Registers[src].AsNumber(); frame.Registers[dst].SetValue(-val); break; } // args: byte src_reg, byte dest_reg case Opcode.ABS: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); Expect(dst < frame.Registers.Length, "invalid dst register"); var val = frame.Registers[src].AsNumber(); frame.Registers[dst].SetValue(val < 0 ? -val : val); break; } // args: byte src_a_reg, byte src_b_reg, byte dest_reg case Opcode.ADD: case Opcode.SUB: case Opcode.MUL: case Opcode.DIV: case Opcode.MOD: case Opcode.SHR: case Opcode.SHL: case Opcode.MIN: case Opcode.MAX: case Opcode.POW: { var srcA = Read8(); var srcB = Read8(); var dst = Read8(); Expect(srcA < frame.Registers.Length, "invalid srcA register"); Expect(srcB < frame.Registers.Length, "invalid srcB register"); Expect(dst < frame.Registers.Length, "invalid dst register"); if (opcode == Opcode.ADD && frame.Registers[srcA].Type == VMType.String) { Expect(frame.Registers[srcB].Type == VMType.String, "invalid string as right operand"); var a = frame.Registers[srcA].AsString(); var b = frame.Registers[srcB].AsString(); var result = a + b; frame.Registers[dst].SetValue(result); } else { var a = frame.Registers[srcA].AsNumber(); var b = frame.Registers[srcB].AsNumber(); BigInteger result; switch (opcode) { case Opcode.ADD: result = a + b; break; case Opcode.SUB: result = a - b; break; case Opcode.MUL: result = a * b; break; case Opcode.DIV: result = a / b; break; case Opcode.MOD: result = a % b; break; case Opcode.SHR: result = a >> (int)b; break; case Opcode.SHL: result = a << (int)b; break; case Opcode.MIN: result = a < b ? a : b; break; case Opcode.MAX: result = a > b ? a : b; break; case Opcode.POW: result = BigInteger.Pow(a, b); break; default: { SetState(ExecutionState.Fault); return; } } frame.Registers[dst].SetValue(result); } break; } // args: byte src_reg, byte dest_reg, byte key case Opcode.PUT: { var src = Read8(); var dst = Read8(); var keyReg = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); Expect(dst < frame.Registers.Length, "invalid dst register"); Expect(keyReg < frame.Registers.Length, "invalid key register"); var key = frame.Registers[keyReg]; Throw.If(key.Type == VMType.None, "invalid key type"); var value = frame.Registers[src]; frame.Registers[dst].SetKey(key, value); break; } // args: byte src_reg, byte dest_reg, byte key case Opcode.GET: { var src = Read8(); var dst = Read8(); var keyReg = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); Expect(dst < frame.Registers.Length, "invalid dst register"); Expect(keyReg < frame.Registers.Length, "invalid key register"); var key = frame.Registers[keyReg]; Throw.If(key.Type == VMType.None, "invalid key type"); var val = frame.Registers[src].GetKey(key); frame.Registers[dst] = val; break; } // args: byte dest_reg case Opcode.CLEAR: { var dst = Read8(); Expect(dst < frame.Registers.Length, "invalid dst register"); frame.Registers[dst] = new VMObject(); break; } // args: byte dest_reg, var key case Opcode.CTX: using (var m = new ProfileMarker("CTX")) { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); Expect(dst < frame.Registers.Length, "invalid dst register"); var contextName = frame.Registers[src].AsString(); ExecutionContext context = frame.VM.FindContext(contextName); if (context == null) { throw new VMException(frame.VM, $"VM ctx instruction failed: could not find context with name '{contextName}'"); } frame.Registers[dst].SetValue(context); break; } // args: byte src_reg case Opcode.SWITCH: using (var m = new ProfileMarker("SWITCH")) { var src = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); var context = frame.Registers[src].AsInterop <ExecutionContext>(); _state = frame.VM.SwitchContext(context, InstructionPointer); if (_state == ExecutionState.Halt) { _state = ExecutionState.Running; frame.VM.PopFrame(); } else { throw new VMException(frame.VM, $"VM switch instruction failed: execution state did not halt"); } break; } // args: byte src_reg dst_reg case Opcode.UNPACK: using (var m = new ProfileMarker("SWITCH")) { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length, "invalid src register"); Expect(dst < frame.Registers.Length, "invalid dst register"); var bytes = frame.Registers[src].AsByteArray(); frame.Registers[dst] = VMObject.FromBytes(bytes); break; } case Opcode.DEBUG: { break; // put here a breakpoint for debugging } default: { throw new VMException(frame.VM, $"Unknown VM opcode: {(int)opcode}"); } } } catch (Exception ex) { ex = ex.ExpandInnerExceptions(); Trace.WriteLine(ex.ToString()); SetState(ExecutionState.Fault); if (!(ex is VMException)) { ex = new VMException(frame.VM, ex.Message); } throw ex; } }
/// <summary> /// Queries the current state of a contract. /// </summary> /// <typeparam name="T">The expected response type, must be deserializable with Newtonsoft.Json.</typeparam> /// <param name="contract">Address of the contract to query.</param> /// <param name="query">Raw query parameters data.</param> /// <param name="caller">Optional caller address.</param> /// <param name="vmType">Virtual machine type.</param> /// <returns>Deserialized response.</returns> internal async Task <T> QueryAsync <T>(Address contract, byte[] query, Address caller = default(Address), VMType vmType = VMType.Plugin) { var queryParams = new QueryParams { ContractAddress = contract.LocalAddress, Params = query, VmType = vmType }; if (caller.LocalAddress != null && caller.ChainId != null) { queryParams.CallerAddress = caller.QualifiedAddress; } return(await this.readClient.SendAsync <T, QueryParams>("query", queryParams)); }
/// <summary> /// Queries the current state of a contract. /// </summary> /// <typeparam name="T">The expected response type, must be deserializable with Newtonsoft.Json.</typeparam> /// <param name="contract">Address of the contract to query.</param> /// <param name="query">Query parameters object.</param> /// <param name="caller">Optional caller address.</param> /// <param name="vmType">Virtual machine type.</param> /// <returns>Deserialized response.</returns> internal async Task <T> QueryAsync <T>(Address contract, IMessage query, Address caller = default(Address), VMType vmType = VMType.Plugin) { return(await QueryAsync <T>(contract, query.ToByteArray(), caller, vmType)); }
public void Step(ExecutionFrame frame, Stack <VMObject> stack) { try { var opcode = (Opcode)Read8(); frame.VM.ValidateOpcode(opcode); switch (opcode) { case Opcode.NOP: { break; } // args: byte src_reg, byte dest_reg case Opcode.MOVE: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length); Expect(dst < frame.Registers.Length); frame.Registers[dst] = frame.Registers[src]; break; } // args: byte src_reg, byte dest_reg case Opcode.COPY: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length); Expect(dst < frame.Registers.Length); frame.Registers[dst].Copy(frame.Registers[src]); break; } // args: byte dst_reg, byte type, var length, var data_bytes case Opcode.LOAD: { var dst = Read8(); var type = (VMType)Read8(); var len = (int)ReadVar(0xFFFF); Expect(dst < frame.Registers.Length); var bytes = ReadBytes(len); frame.Registers[dst].SetValue(bytes, type); break; } // args: byte src_reg, dst_reg, byte type case Opcode.CAST: { var src = Read8(); var dst = Read8(); var type = (VMType)Read8(); Expect(src < frame.Registers.Length); Expect(dst < frame.Registers.Length); var val = frame.Registers[src]; val = VMObject.CastTo(val, type); frame.Registers[dst] = val; break; } // args: byte src_reg case Opcode.PUSH: { var src = Read8(); Expect(src < frame.Registers.Length); var val = frame.Registers[src]; var temp = new VMObject(); temp.Copy(val); stack.Push(temp); break; } // args: byte dest_reg case Opcode.POP: { var dst = Read8(); Expect(stack.Count > 0); Expect(dst < frame.Registers.Length); frame.Registers[dst] = stack.Pop(); break; } // args: byte src_reg, byte dest_reg case Opcode.SWAP: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length); Expect(dst < frame.Registers.Length); var temp = frame.Registers[src]; frame.Registers[src] = frame.Registers[dst]; frame.Registers[dst] = temp; break; } // args: ushort offset, byte regCount case Opcode.CALL: { var count = Read8(); var ofs = Read16(); Expect(ofs < this.Script.Length); Expect(count >= 1); Expect(count <= VirtualMachine.MaxRegisterCount); frame.VM.PushFrame(this, InstructionPointer, count); InstructionPointer = ofs; break; } // args: byte srcReg case Opcode.EXTCALL: using (var m = new ProfileMarker("EXTCALL")) { var src = Read8(); Expect(src < frame.Registers.Length); var method = frame.Registers[src].AsString(); var state = frame.VM.ExecuteInterop(method); if (state != ExecutionState.Running) { throw new VMException(frame.VM, "VM extcall failed: " + method); } break; } // args: ushort offset, byte src_reg // NOTE: JMP only has offset arg, not the rest case Opcode.JMP: case Opcode.JMPIF: case Opcode.JMPNOT: { bool shouldJump; if (opcode == Opcode.JMP) { shouldJump = true; } else { var src = Read8(); Expect(src < frame.Registers.Length); shouldJump = frame.Registers[src].AsBool(); if (opcode == Opcode.JMPNOT) { shouldJump = !shouldJump; } } var newPos = (short)Read16(); Expect(newPos >= 0); Expect(newPos < this.Script.Length); if (shouldJump) { InstructionPointer = (uint)newPos; } break; } // args: var length, var bytes case Opcode.THROW: { var len = (int)ReadVar(1024); if (len > 0) { var bytes = ReadBytes(len); } SetState(ExecutionState.Fault); return; } // args: none case Opcode.RET: { if (frame.VM.frames.Count > 1) { var temp = frame.VM.PeekFrame(); if (temp.Context == this) { InstructionPointer = frame.VM.PopFrame(); //Expect(InstructionPointer == this.Script.Length); } else { SetState(ExecutionState.Halt); } } else { SetState(ExecutionState.Halt); } return; } // args: byte src_a_reg, byte src_b_reg, byte dest_reg case Opcode.CAT: { var srcA = Read8(); var srcB = Read8(); var dst = Read8(); Expect(srcA < frame.Registers.Length); Expect(srcB < frame.Registers.Length); Expect(dst < frame.Registers.Length); var A = frame.Registers[srcA]; var B = frame.Registers[srcB]; if (!A.IsEmpty) { if (B.IsEmpty) { frame.Registers[dst].Copy(A); } else { var bytesA = A.AsByteArray(); var bytesB = B.AsByteArray(); var result = new byte[bytesA.Length + bytesB.Length]; Array.Copy(bytesA, result, bytesA.Length); Array.Copy(bytesB, 0, result, bytesA.Length, bytesB.Length); Expect(A.Type == B.Type); VMType type = A.Type; frame.Registers[dst].SetValue(result, type); } } else { if (B.IsEmpty) { frame.Registers[dst] = new VMObject(); } else { frame.Registers[dst].Copy(B); } } break; } case Opcode.SUBSTR: { throw new NotImplementedException(); } // args: byte src_reg, byte dest_reg, var length case Opcode.LEFT: { var src = Read8(); var dst = Read8(); var len = (int)ReadVar(0xFFFF); Expect(src < frame.Registers.Length); Expect(dst < frame.Registers.Length); var src_array = frame.Registers[src].AsByteArray(); Expect(len <= src_array.Length); var result = new byte[len]; Array.Copy(src_array, result, len); frame.Registers[dst].SetValue(result, VMType.Bytes); break; } // args: byte src_reg, byte dest_reg, byte length case Opcode.RIGHT: { var src = Read8(); var dst = Read8(); var len = (int)ReadVar(0xFFFF); Expect(src < frame.Registers.Length); Expect(dst < frame.Registers.Length); var src_array = frame.Registers[src].AsByteArray(); Expect(len <= src_array.Length); var ofs = src_array.Length - len; var result = new byte[len]; Array.Copy(src_array, ofs, result, 0, len); frame.Registers[dst].SetValue(result, VMType.Bytes); break; } // args: byte src_reg, byte dest_reg case Opcode.SIZE: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length); Expect(dst < frame.Registers.Length); var src_array = frame.Registers[src].AsByteArray(); frame.Registers[dst].SetValue(src_array.Length); break; } // args: byte src_reg, byte dest_reg case Opcode.COUNT: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length); Expect(dst < frame.Registers.Length); var val = frame.Registers[src]; int count; switch (val.Type) { case VMType.Struct: { var children = val.GetChildren(); count = children.Count; break; } default: count = 1; break; } frame.Registers[dst].SetValue(count); break; } // args: byte src_reg, byte dest_reg case Opcode.NOT: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length); Expect(dst < frame.Registers.Length); var val = frame.Registers[src].AsBool(); frame.Registers[dst].SetValue(!val); break; } // args: byte src_a_reg, byte src_b_reg, byte dest_reg case Opcode.AND: case Opcode.OR: case Opcode.XOR: { var srcA = Read8(); var srcB = Read8(); var dst = Read8(); Expect(srcA < frame.Registers.Length); Expect(srcB < frame.Registers.Length); Expect(dst < frame.Registers.Length); var a = frame.Registers[srcA].AsBool(); var b = frame.Registers[srcB].AsBool(); bool result; switch (opcode) { case Opcode.AND: result = (a && b); break; case Opcode.OR: result = (a || b); break; case Opcode.XOR: result = (a ^ b); break; default: { SetState(ExecutionState.Fault); return; } } frame.Registers[dst].SetValue(result); break; } // args: byte src_a_reg, byte src_b_reg, byte dest_reg case Opcode.EQUAL: { var srcA = Read8(); var srcB = Read8(); var dst = Read8(); Expect(srcA < frame.Registers.Length); Expect(srcB < frame.Registers.Length); Expect(dst < frame.Registers.Length); var a = frame.Registers[srcA]; var b = frame.Registers[srcB]; var result = a.Equals(b); frame.Registers[dst].SetValue(result); break; } // args: byte src_a_reg, byte src_b_reg, byte dest_reg case Opcode.LT: case Opcode.GT: case Opcode.LTE: case Opcode.GTE: { var srcA = Read8(); var srcB = Read8(); var dst = Read8(); Expect(srcA < frame.Registers.Length); Expect(srcB < frame.Registers.Length); Expect(dst < frame.Registers.Length); var a = frame.Registers[srcA].AsNumber(); var b = frame.Registers[srcB].AsNumber(); bool result; switch (opcode) { case Opcode.LT: result = (a < b); break; case Opcode.GT: result = (a > b); break; case Opcode.LTE: result = (a <= b); break; case Opcode.GTE: result = (a >= b); break; default: { SetState(ExecutionState.Fault); return; } } frame.Registers[dst].SetValue(result); break; } // args: byte reg case Opcode.INC: { var dst = Read8(); Expect(dst < frame.Registers.Length); var val = frame.Registers[dst].AsNumber(); frame.Registers[dst].SetValue(val + 1); break; } // args: byte reg case Opcode.DEC: { var dst = Read8(); Expect(dst < frame.Registers.Length); var val = frame.Registers[dst].AsNumber(); frame.Registers[dst].SetValue(val - 1); break; } // args: byte src_reg, byte dest_reg case Opcode.SIGN: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length); Expect(dst < frame.Registers.Length); var val = frame.Registers[src].AsNumber(); if (val == 0) { frame.Registers[dst].SetValue(BigInteger.Zero); } else { frame.Registers[dst].SetValue(val < 0 ? -1 : 1); } break; } // args: byte src_reg, byte dest_reg case Opcode.NEGATE: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length); Expect(dst < frame.Registers.Length); var val = frame.Registers[src].AsNumber(); frame.Registers[dst].SetValue(-val); break; } // args: byte src_reg, byte dest_reg case Opcode.ABS: { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length); Expect(dst < frame.Registers.Length); var val = frame.Registers[src].AsNumber(); frame.Registers[dst].SetValue(val < 0 ? -val : val); break; } // args: byte src_a_reg, byte src_b_reg, byte dest_reg case Opcode.ADD: case Opcode.SUB: case Opcode.MUL: case Opcode.DIV: case Opcode.MOD: case Opcode.SHR: case Opcode.SHL: case Opcode.MIN: case Opcode.MAX: { var srcA = Read8(); var srcB = Read8(); var dst = Read8(); Expect(srcA < frame.Registers.Length); Expect(srcB < frame.Registers.Length); Expect(dst < frame.Registers.Length); var a = frame.Registers[srcA].AsNumber(); var b = frame.Registers[srcB].AsNumber(); BigInteger result; switch (opcode) { case Opcode.ADD: result = a + b; break; case Opcode.SUB: result = a - b; break; case Opcode.MUL: result = a * b; break; case Opcode.DIV: result = a / b; break; case Opcode.MOD: result = a % b; break; case Opcode.SHR: result = a >> (int)b; break; case Opcode.SHL: result = a << (int)b; break; case Opcode.MIN: result = a < b ? a : b; break; case Opcode.MAX: result = a > b ? a : b; break; default: { SetState(ExecutionState.Fault); return; } } frame.Registers[dst].SetValue(result); break; } // args: byte src_reg, byte dest_reg, byte key case Opcode.PUT: { var src = Read8(); var dst = Read8(); var keyReg = Read8(); Expect(src < frame.Registers.Length); Expect(dst < frame.Registers.Length); Expect(keyReg < frame.Registers.Length); var key = frame.Registers[keyReg]; var value = frame.Registers[src]; frame.Registers[dst].SetKey(key, value); break; } // args: byte src_reg, byte dest_reg, byte key case Opcode.GET: { var src = Read8(); var dst = Read8(); var keyReg = Read8(); Expect(src < frame.Registers.Length); Expect(dst < frame.Registers.Length); Expect(keyReg < frame.Registers.Length); var key = frame.Registers[keyReg]; var val = frame.Registers[src].GetKey(key); frame.Registers[dst] = val; break; } // args: byte dest_reg case Opcode.THIS: { var dst = Read8(); Expect(dst < frame.Registers.Length); frame.Registers[dst].SetValue(this); break; } // args: byte dest_reg, var key case Opcode.CTX: using (var m = new ProfileMarker("CTX")) { var src = Read8(); var dst = Read8(); Expect(src < frame.Registers.Length); Expect(dst < frame.Registers.Length); var contextName = frame.Registers[src].AsString(); ExecutionContext context = frame.VM.FindContext(contextName); if (context == null) { throw new VMException(frame.VM, $"VM ctx instruction failed: could not find context with name '{contextName}'"); } frame.Registers[dst].SetValue(context); break; } // args: byte src_reg case Opcode.SWITCH: using (var m = new ProfileMarker("SWITCH")) { var src = Read8(); Expect(src < frame.Registers.Length); var context = frame.Registers[src].AsInterop <ExecutionContext>(); _state = frame.VM.SwitchContext(context, InstructionPointer); if (_state == ExecutionState.Halt) { _state = ExecutionState.Running; frame.VM.PopFrame(); } else { throw new VMException(frame.VM, $"VM switch instruction failed: execution state did not halt"); } break; } default: { throw new VMException(frame.VM, $"Unknown VM opcode: {(int)opcode}"); } } } catch (Exception ex) { if (ex is TargetInvocationException) { ex = ((TargetInvocationException)ex).InnerException; } Trace.WriteLine(ex.ToString()); SetState(ExecutionState.Fault); if (!(ex is VMException)) { ex = new VMException(frame.VM, ex.Message); } if (frame.VM.ThrowOnFault) // enable this when debugging difficult stuff in the VM, should not be activated for production code { throw ex; } } }
internal Transaction CreateContractMethodCallTx(string hexData, VMType vmType) { return(CreateContractMethodCallTx(ByteString.CopyFrom(CryptoUtils.HexStringToBytes(hexData)), vmType)); }
private void ProcessLoad(ScriptBuilder sb) { if (Arguments.Length != 2 && Arguments.Length != 3) { throw new CompilerException(LineNumber, ERR_INCORRECT_NUMBER); } if (Arguments[0].IsRegister()) { var reg = Arguments[0].AsRegister(); VMType type = VMType.None; if (Arguments.Length == 3) { if (!Enum.TryParse(Arguments[2], out type)) { throw new CompilerException(LineNumber, ERR_INVALID_ARGUMENT); } } if (Arguments[1].IsBytes()) { sb.EmitLoad(reg, Arguments[1].AsBytes()); } else if (Arguments[1].IsBool()) { sb.EmitLoad(reg, Arguments[1].AsBool()); } else if (Arguments[1].IsString()) { sb.EmitLoad(reg, Arguments[1].AsString()); } else if (Arguments[1].IsNumber()) { if (type == VMType.Enum) { var num = (uint)Arguments[1].AsNumber(); using (var stream = new MemoryStream()) { using (var writer = new BinaryWriter(stream)) { writer.Write((byte)reg); writer.Write((byte)VMType.Enum); writer.Write((byte)4); var numBytes = BitConverter.GetBytes(num); writer.Write(numBytes); } var bytes = stream.ToArray(); sb.Emit(Opcode.LOAD, bytes); } } else if (type != VMType.None) { throw new CompilerException(LineNumber, ERR_INVALID_TYPE); } else { sb.EmitLoad(reg, Arguments[1].AsNumber()); } } else { throw new CompilerException(LineNumber, ERR_INVALID_ARGUMENT); } } else { throw new CompilerException(LineNumber, ERR_INVALID_ARGUMENT); } }
public VCallAnnotation(VMCalls vmCall, VMType returnType) { VMCall = vmCall; ReturnType = returnType; }
public VMObject SetValue(byte[] val, VMType type) { this.Type = type; this._localSize = val != null ? val.Length : 0; switch (type) { case VMType.Bytes: { this.Data = val; break; } case VMType.Number: { this.Data = (val == null || val.Length == 0) ? new BigInteger(0) : BigInteger.FromSignedArray(val); break; } case VMType.String: { this.Data = Encoding.UTF8.GetString(val); break; } case VMType.Enum: { // TODO this will fail if val is not exactly 4 bytes long. Add code here to autopad with zeros if necessary this.Data = BitConverter.ToUInt32(val, 0); break; } case VMType.Timestamp: { var temp = BitConverter.ToUInt32(val, 0); this.Data = new Timestamp(temp); break; } case VMType.Bool: { this.Data = BitConverter.ToBoolean(val, 0); break; } default: if (val is byte[]) { var bytes = (byte[])val; var len = bytes != null ? bytes.Length : 0; switch (len) { case Address.LengthInBytes: this.Data = Address.FromBytes(bytes); break; case Hash.Length: this.Data = Hash.FromBytes(bytes); break; default: try { this.UnserializeData(bytes); } catch (Exception e) { throw new Exception("Cannot decode interop object from bytes with length: " + len); } break; } break; } else { throw new Exception("Cannot set value for vmtype: " + type); } } return(this); }