Esempio n. 1
0
        /// <summary>
        /// Reads a single CIL instruction from a given data stream.
        /// </summary>
        /// <param name="stream">The source data stream.</param>
        /// <param name="instruction">The instruction that was read, undefined if the method returns zero.</param>
        /// <returns>A value indicating if an instruction was read, <c>false</c> if the end of the stream was reached.</returns>
        public static bool ReadInstruction(Stream stream, out RawInstruction instruction)
        {
            Contract.Requires(stream != null && stream.CanRead);

            int firstOpcodeByte = stream.ReadByte();

            if (unchecked ((byte)firstOpcodeByte) != firstOpcodeByte)
            {
                instruction = default(RawInstruction);
                return(false);
            }

            OpcodeValue opcodeValue;

            if (OpcodeValueEnum.IsFirstOfTwoBytes((byte)firstOpcodeByte))
            {
                opcodeValue = (OpcodeValue)((firstOpcodeByte << 8) | stream.ReadUInt8());
            }
            else
            {
                opcodeValue = (OpcodeValue)firstOpcodeByte;
            }

            var opcode = Opcode.FromValue(opcodeValue);

            if (opcode == Opcode.Switch)
            {
                // Read jump table
                int[] jumpTable = new int[stream.ReadUInt32()];
                for (int i = 0; i < jumpTable.Length; ++i)
                {
                    jumpTable[i] = stream.ReadInt32();
                }
                instruction = RawInstruction.CreateSwitch(jumpTable);
            }
            else
            {
                NumericalOperand operand;
                switch ((int)opcode.OperandKind.GetSizeInBytes())
                {
                case 0: operand = default(NumericalOperand); break;

                case 1: operand = stream.ReadInt8(); break;

                case 2: operand = stream.ReadInt16(); break;

                case 4: operand = stream.ReadInt32(); break;

                case 8: operand = stream.ReadInt64(); break;

                default: throw new NotSupportedException("Unexpected opcode operand size");
                }
                instruction = new RawInstruction(opcode, operand);
            }

            return(true);
        }
Esempio n. 2
0
 private static void compile(TextWriter output, RawInstruction[] instructions, string[] _)
 {
     foreach (var _i in instructions)
     {
         var i = _i;
         if (i.Command.Length == 1)
         {
             i = new RawInstruction(CommandByShort[i.Command[0]], i.Arguments);
         }
         output.WriteLine(i);
     }
 }
Esempio n. 3
0
        public void arguments()
        {
            Assert.AreEqual(0, new RawInstruction("a").Arguments.Length);

            var args1 = new RawInstruction("a.abc").Arguments;

            Assert.AreEqual(1, args1.Length);
            Assert.AreEqual("abc", args1[0]);

            var args2 = new RawInstruction("a.\"def\\\"\\\\\\n\".abc").Arguments;

            Assert.AreEqual(2, args2.Length);
            Assert.AreEqual("def\"\\\n", args2[0]);
            Assert.AreEqual("abc", args2[1]);
        }
Esempio n. 4
0
        public override void Instruction(RawInstruction instruction)
        {
            if (instruction.IsSwitch)
            {
                throw RequiresSymbolicOverload(Opcode.Switch);
            }

            var param = new VisitorParam(this, instruction.NumericalOperand);

            instruction.Opcode.Accept(Visitor.Instance, param);

            if (sink != null)
            {
                sink.Instruction(instruction);
            }
        }
Esempio n. 5
0
        private static void decompile(TextWriter output, RawInstruction[] instructions, string[] _)
        {
            int prefixLength = 4;
            int prefixTabs   = 0;

            foreach (var _i in instructions)
            {
                var i = _i;
                if (i.Command.Length == 1)
                {
                    i = new RawInstruction(CommandByShort[i.Command[0]], i.Arguments);
                }
                if (SectionEndCommands.Contains(i.Command))
                {
                    prefixTabs = Math.Max(0, prefixTabs - 1);
                }
                output.Write(string.Join("", Enumerable.Repeat(" ", prefixTabs * prefixLength)));
                output.WriteLine(i);
                if (SectionStartCommands.Contains(i.Command))
                {
                    prefixTabs++;
                }
            }
        }
Esempio n. 6
0
        public override void Instruction(RawInstruction instruction)
        {
            var opcode = instruction.Opcode;

            OpCode emitOpCode;

            opcode.GetReflectionEmitOpCode(out emitOpCode);

            switch (emitOpCode.OperandType)
            {
            case OperandType.InlineNone: generator.Emit(emitOpCode); break;

            case OperandType.InlineI8: generator.Emit(emitOpCode, instruction.Int64Operand); break;

            case OperandType.InlineR: generator.Emit(emitOpCode, instruction.Float64Operand); break;

            case OperandType.InlineVar: generator.Emit(emitOpCode, (ushort)instruction.UIntOperand); break;

            case OperandType.ShortInlineR: generator.Emit(emitOpCode, instruction.Float32Operand); break;

            case OperandType.ShortInlineVar: generator.Emit(emitOpCode, (byte)instruction.UIntOperand); break;

            case OperandType.ShortInlineBrTarget:
            case OperandType.ShortInlineI:
                generator.Emit(emitOpCode, (sbyte)instruction.IntOperand);
                break;

            case OperandType.InlineBrTarget:
            case OperandType.InlineI:
                generator.Emit(emitOpCode, instruction.IntOperand);
                break;

            default:
                throw new NotSupportedException();                         // Phi, tokens, jump tables
            }
        }
Esempio n. 7
0
        // TODO: Replace ScriptExecution ctor with actual compiler

        private static RawInstruction Compile(RawInstruction raw) => LongToShortCommand.TryGetValue(raw.Command, out var shortCommand) ?
        new RawInstruction(shortCommand, raw.Arguments)
            : raw;
Esempio n. 8
0
        public override void Instruction(RawInstruction instruction)
        {
            var opcode = instruction.Opcode;

            stringBuilder.Append(opcode.Name);
            if (opcode.OperandKind == OperandKind.None)
            {
                stringBuilder.AppendLine();
                return;
            }

            stringBuilder.Append(' ');
            switch (opcode.OperandKind)
            {
            case OperandKind.VariableIndex8:
            case OperandKind.VariableIndex16:
            {
                // TODO: Use index if variable has no name
                int  variableIndex = instruction.IntOperand;
                bool isLocal       = ((VariableReferenceOpcode)opcode).VariableKind == VariableKind.Local;
                stringBuilder.Append(isLocal ? locals[variableIndex].Name : argumentNames[variableIndex]);
                break;
            }

            case OperandKind.Int8:
            case OperandKind.Int32:
            case OperandKind.BranchTarget8:
            case OperandKind.BranchTarget32:
                stringBuilder.Append(instruction.IntOperand);
                break;

            case OperandKind.Int64:
                stringBuilder.Append(instruction.Int64Operand);
                break;

            case OperandKind.Float64:
                stringBuilder.Append(instruction.Float64Operand);
                break;

            case OperandKind.Float32:
                stringBuilder.Append(instruction.Float32Operand);
                break;

            case OperandKind.JumpTable:
            {
                var jumpTable = instruction.JumpTable;
                stringBuilder.Append("(");
                for (int i = 0; i < jumpTable.Length; ++i)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append(", ");
                    }
                    stringBuilder.Append(jumpTable[i].ToString(CultureInfo.InvariantCulture));
                }
                stringBuilder.AppendLine(")");
                break;
            }

            default:
                throw new NotSupportedException();
            }

            stringBuilder.AppendLine();
        }
Esempio n. 9
0
 /// <summary>
 /// Writes a <c>switch</c> CIL instruction to this sink.
 /// </summary>
 /// <param name="jumpTable">The switch's jump table.</param>
 public void Switch(int[] jumpTable)
 {
     Instruction(RawInstruction.CreateSwitch(jumpTable));
 }
Esempio n. 10
0
 /// <summary>
 /// Writes a given CIL instruction to this sink.
 /// </summary>
 /// <param name="instruction">The instruction to be written.</param>
 public abstract void Instruction(RawInstruction instruction);