internal DirectCommand(int globals, ReplyParser <TReply> replyParser, BytecodeObject obj) { if (globals < 0 || globals > maxGlobals) { throw new ArgumentOutOfRangeException($"Cannot be < 0 or exceed {maxGlobals}", nameof(globals)); } if (obj == null) { throw new ArgumentNullException(nameof(obj)); } if (obj.Type != BytecodeObjectType.VMThread) { throw new ArgumentOutOfRangeException("Only vmthread objects are supported", nameof(obj)); } // TODO: could do a check here to see if we exceed maxBytecodes instead of waiting until ToBytes() is called. if (obj.Locals > maxLocals) { throw new ArgumentOutOfRangeException("Exceeds max local size", nameof(obj)); } this.globals = globals; this.replyParser = replyParser ?? throw new ArgumentNullException(nameof(replyParser)); this.obj = obj; }
/// <summary> /// Creates a new empty direct command with one global variable. /// </summary> /// <typeparam name="T0">The VM variable type of <paramref name="gv0"/></typeparam> /// <param name="gv0">Object representing a global variable.</param> /// <param name="size0">The number of bytes to allocate for <paramref name="gv0"/></param> /// <returns>Object representing the direct command.</returns> /// <exception cref="ArgumentOutOfRangeException"> /// Thrown if <paramref name="size0"/> is negative or if <typeparamref name="T0"/> is a fixed /// size type such as <see cref="Data8"/> and <paramref name="size0"/> is not the correct size. /// (Tip: You can use <see cref="Data8.FixedSize"/> to get the correct size.) /// </exception> public static DirectCommand <T0> DirectCommand <T0>( out IExpression <T0> gv0, int size0) where T0 : VMDataType { int offset = 0; gv0 = new GlobalVariable <T0>(size0, ref offset); ReplyParser <T0> parser = ((GlobalVariable <T0>)gv0).Parse; return(new DirectCommand <T0>(offset, parser, new BytecodeObject(BytecodeObjectType.VMThread, 0, new Opcodes.Opcode[0]))); }
/// <summary> /// Creates a new empty direct command with no global variables. /// </summary> /// <returns>Object representing the direct command.</returns> /// <remarks> /// <see cref="Unit"/> basically just means a <c>void</c> return type (we can't /// use <see cref="Void"/> as a type parameter for technical reasons). /// </remarks> public static DirectCommand <Unit> DirectCommand() { ReplyParser <Unit> parser = (r) => Unit.Value; return(new DirectCommand <Unit>(0, parser, new BytecodeObject(BytecodeObjectType.VMThread, 0, new Opcodes.Opcode[0]))); }
/// <summary> /// Creates a new command. /// </summary> /// <param name="message"></param> /// <param name="replyRequirement"></param> /// <param name="replyParser"></param> public Command(ReadOnlyMemory <byte> message, RequestTypes replyRequirement, ReplyParser replyParser) { Message = message; RequestTypes = replyRequirement; this.replyParser = replyParser ?? throw new ArgumentNullException(nameof(replyParser)); }
internal Command(ReadOnlyMemory <byte> payload, int replySize, ReplyParser replyParser) { Payload = payload; ReplySize = replySize; this.replyParser = replyParser; }