Beispiel #1
0
        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;
        }
Beispiel #2
0
        /// <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])));
        }
Beispiel #3
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])));
        }
Beispiel #4
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));
 }
Beispiel #5
0
 internal Command(ReadOnlyMemory <byte> payload, int replySize, ReplyParser replyParser)
 {
     Payload          = payload;
     ReplySize        = replySize;
     this.replyParser = replyParser;
 }