public override void Visit(BinaryInstruction instruction)
            {
                var left     = instruction.LeftOperand.Type;
                var right    = instruction.RightOperand.Type;
                var unsigned = instruction.UnsignedOperands;

                switch (instruction.Operation)
                {
                case BinaryOperation.Add:
                case BinaryOperation.Div:
                case BinaryOperation.Mul:
                case BinaryOperation.Rem:
                case BinaryOperation.Sub:
                    instruction.Result.Type = Types.Instance.BinaryNumericOperationType(left, right, unsigned);
                    break;

                case BinaryOperation.And:
                case BinaryOperation.Or:
                case BinaryOperation.Xor:
                    instruction.Result.Type = Types.Instance.BinaryLogicalOperationType(left, right);
                    break;

                case BinaryOperation.Shl:
                case BinaryOperation.Shr:
                    instruction.Result.Type = left;
                    break;

                case BinaryOperation.Eq:
                case BinaryOperation.Gt:
                case BinaryOperation.Lt:
                    instruction.Result.Type = Types.Instance.PlatformType.SystemBoolean;
                    break;
                }
            }
Exemplo n.º 2
0
            public override void Visit(BinaryInstruction instruction)
            {
                var left     = instruction.LeftOperand.Type;
                var right    = instruction.RightOperand.Type;
                var unsigned = instruction.UnsignedOperands;

                switch (instruction.Operation)
                {
                case BinaryOperation.Add:
                case BinaryOperation.Div:
                case BinaryOperation.Mul:
                case BinaryOperation.Rem:
                case BinaryOperation.Sub:
                    instruction.Result.Type = Types.Instance.BinaryNumericOperationType(left, right, unsigned);
                    break;

                case BinaryOperation.And:
                case BinaryOperation.Or:
                case BinaryOperation.Xor:
                    instruction.Result.Type = Types.Instance.BinaryLogicalOperationType(left, right);
                    break;

                case BinaryOperation.Shl:
                case BinaryOperation.Shr:
                    instruction.Result.Type = left;
                    break;

                case BinaryOperation.Eq:
                case BinaryOperation.Neq:
                    // If one of the operands has type Boolean,
                    // then the other operand must also have type Boolean.
                    if (left != null && left.TypeCode == PrimitiveTypeCode.Boolean)
                    {
                        instruction.RightOperand.Type = Types.Instance.PlatformType.SystemBoolean;
                    }
                    else if (right != null && right.TypeCode == PrimitiveTypeCode.Boolean)
                    {
                        instruction.LeftOperand.Type = Types.Instance.PlatformType.SystemBoolean;
                    }

                    instruction.Result.Type = Types.Instance.PlatformType.SystemBoolean;
                    break;

                case BinaryOperation.Gt:
                case BinaryOperation.Ge:
                case BinaryOperation.Lt:
                case BinaryOperation.Le:
                    // If one of the operands has a reference type,
                    // then the operator must be != instead of >.
                    if ((left != null && !left.IsValueType) ||
                        (right != null && !right.IsValueType))
                    {
                        instruction.Operation = BinaryOperation.Neq;
                    }

                    instruction.Result.Type = Types.Instance.PlatformType.SystemBoolean;
                    break;
                }
            }
Exemplo n.º 3
0
        public static string DisassembleInstructionWithLabelReferenceOperand(BinaryInstruction instruction, IList <BinaryLabel> labels)
        {
            if (instruction.OperandShort >= labels.Count)
            {
                throw new ArgumentOutOfRangeException(nameof(instruction.OperandShort), $"No label for label reference id {instruction.OperandShort} present in {nameof( labels )}");
            }

            return($"{instruction.Opcode}\t\t{labels[instruction.OperandShort].Name}");
        }
Exemplo n.º 4
0
        public static string DisassembleInstructionWithNoOperand(BinaryInstruction instruction)
        {
            if (instruction.OperandShort != 0)
            {
                throw new ArgumentOutOfRangeException(nameof(instruction.OperandShort), $"{instruction.Opcode} should not have any operands");
            }

            return($"{instruction.Opcode}");
        }
Exemplo n.º 5
0
        private void ExecuteBinaryInstruction(BinaryInstruction instruction)
        {
            string  name  = instruction.Name;
            Operand left  = instruction.LeftOperand;
            Operand right = instruction.RightOperand;

            StorageBase leftStorage  = GetStorageForOperand(left);
            StorageBase rightStorage = GetStorageForOperand(right);

            if (leftStorage == null)
            {
                throw new Exception(string.Format("Bad args, {0}", instruction.Name));
            }

            string leftVal  = GetStorageValue(leftStorage);
            string rightVal = rightStorage != null?GetStorageValue(rightStorage) : right.Value;

            int leftInt  = BinaryToIntegerUtility.LoadSignedInt(leftVal);
            int rightInt = BinaryToIntegerUtility.LoadSignedInt(rightVal);

            switch (name)
            {
            case "mov":
            {
                leftStorage.Data = GetDataForBitString(rightVal);
            } break;

            case "add":
            {
                int sum = leftInt + rightInt;
                leftStorage.Data = IntToData(sum);
            } break;

            case "sub":
            {
                int diff = leftInt - rightInt;
                leftStorage.Data = IntToData(diff);
            } break;

            case "mul":
            {
                int prod = leftInt * rightInt;
                leftStorage.Data = IntToData(prod);
            } break;

            case "div":
            {
                int quot = leftInt / rightInt;
                leftStorage.Data = IntToData(quot);
            } break;

            default:
                throw new ArgumentException(string.Format("Instruction without implementation: {0}", instruction.Name));
            }
        }
Exemplo n.º 6
0
        public static string DisassembleInstructionWithStringReferenceOperand(BinaryInstruction instruction, IList <byte> stringTable)
        {
            string value = string.Empty;

            for (int i = instruction.OperandShort; i < stringTable.Count; i++)
            {
                if (stringTable[i] == 0)
                {
                    break;
                }

                value += ( char )stringTable[i];
            }

            return($"{instruction.Opcode}\t\"{value}\"");
        }
Exemplo n.º 7
0
        public InstructionViewModel(IInstruction instruction)
        {
            m_instruction = instruction;
            instruction.IsCurrentChanged += new EventHandler(IsCurrentChanged);
            m_name = instruction.Name;

            UnaryInstruction  unary  = instruction as UnaryInstruction;
            BinaryInstruction binary = instruction as BinaryInstruction;

            if (binary != null)
            {
                m_leftOperand  = binary.LeftOperand;
                m_rightOperand = binary.RightOperand;
            }
            else if (unary != null)
            {
                m_leftOperand = unary.Operand;
            }
        }
Exemplo n.º 8
0
            public override void Visit(BinaryInstruction instruction)
            {
                var op1 = this.State.GetValue(instruction.LeftOperand);
                var op2 = this.State.GetValue(instruction.RightOperand);

                switch (instruction.Operation)
                {
                case BinaryOperation.Add:
                    this.State.AssignValue(instruction.Result, op1.Sum(op2));
                    break;

                case BinaryOperation.Sub:
                    this.State.AssignValue(instruction.Result, op1.Sub(op2));
                    break;

                default:
                    this.State.AssignValue(instruction.Result, RangeDomain.TOP);
                    break;
                }
            }
Exemplo n.º 9
0
        private void ExecuteInstruction(IInstruction instruction)
        {
            string            name    = instruction.Name;
            Instruction       regular = instruction as Instruction;
            UnaryInstruction  unary   = instruction as UnaryInstruction;
            BinaryInstruction binary  = instruction as BinaryInstruction;

            if (binary != null)
            {
                ExecuteBinaryInstruction(binary);
            }
            else if (unary != null)
            {
            }
            else if (regular != null)
            {
            }
            else
            {
                throw new Exception("Bad instruction.");
            }
        }
Exemplo n.º 10
0
 public override void Visit(BinaryInstruction instruction)
 {
     //TODO: very imprecise, can we do it better?
     DefaultVarTop(instruction, instruction.Result);
 }
Exemplo n.º 11
0
        /// <summary>
        /// Converts a binary instruction to its simplified representation.
        /// This method is only valid for instructions that don't take up 2 instructions.
        /// </summary>
        /// <param name="binary">The binary instruction.</param>
        /// <returns>A <see cref="Instruction"/> instance.</returns>
        public static Instruction FromBinaryInstruction(BinaryInstruction binary)
        {
            switch (binary.Opcode)
            {
            case Opcode.PUSHIX:
                return(PUSHIX(binary.OperandShort));

            case Opcode.PUSHIF:
                return(PUSHIF(binary.OperandShort));

            case Opcode.PUSHREG:
                return(PUSHREG());

            case Opcode.POPIX:
                return(POPIX(binary.OperandShort));

            case Opcode.POPFX:
                return(POPFX(binary.OperandShort));

            case Opcode.PROC:
                return(PROC(binary.OperandShort));

            case Opcode.COMM:
                return(COMM(binary.OperandShort));

            case Opcode.END:
                return(END());

            case Opcode.JUMP:
                return(JUMP(binary.OperandShort));

            case Opcode.CALL:
                return(CALL(binary.OperandShort));

            case Opcode.RUN:
                return(RUN());

            case Opcode.GOTO:
                return(GOTO(binary.OperandShort));

            case Opcode.ADD:
                return(ADD());

            case Opcode.SUB:
                return(SUB());

            case Opcode.MUL:
                return(MUL());

            case Opcode.DIV:
                return(DIV());

            case Opcode.MINUS:
                return(MINUS());

            case Opcode.NOT:
                return(NOT());

            case Opcode.OR:
                return(OR());

            case Opcode.AND:
                return(AND());

            case Opcode.EQ:
                return(EQ());

            case Opcode.NEQ:
                return(NEQ());

            case Opcode.S:
                return(S());

            case Opcode.L:
                return(L());

            case Opcode.SE:
                return(SE());

            case Opcode.LE:
                return(LE());

            case Opcode.IF:
                return(IF(binary.OperandShort));

            case Opcode.PUSHIS:
                return(PUSHIS(binary.OperandShort));

            case Opcode.PUSHLIX:
                return(PUSHLIX(binary.OperandShort));

            case Opcode.PUSHLFX:
                return(PUSHLFX(binary.OperandShort));

            case Opcode.POPLIX:
                return(POPLIX(binary.OperandShort));

            case Opcode.POPLFX:
                return(POPLFX(binary.OperandShort));

            default:
                throw new Exception("Opcode not supported");
            }
        }
Exemplo n.º 12
0
 public override void Visit(BinaryInstruction instruction)
 {
     base.Visit(instruction);
 }
Exemplo n.º 13
0
 public virtual void Visit(BinaryInstruction instruction)
 {
 }
Exemplo n.º 14
0
        /// <summary>
        /// Converts the <see cref="FlowScript"/> to a <see cref="FlowScriptBinary"/> instance.
        /// </summary>
        /// <returns>A <see cref="FlowScriptBinary"/> instance.</returns>
        public FlowScriptBinary ToBinary()
        {
            var builder = new FlowScriptBinaryBuilder((BinaryFormatVersion)mFormatVersion);

            builder.SetUserId(mUserId);

            // Skip the labels until after the instructions have been converted, as we need to fix up
            // the instruction indices

            // Convert string table before the instructions so we can fix up string instructions later
            // by building an index remap table
            // TODO: optimize instructions usage
            var stringIndexToBinaryStringIndexMap = new Dictionary <short, short>();
            var strings = EnumerateInstructions()
                          .Where(x => x.Opcode == Opcode.PUSHSTR)
                          .Select(x => x.Operand.StringValue)
                          .Distinct()
                          .ToList();

            for (short stringIndex = 0; stringIndex < strings.Count; stringIndex++)
            {
                builder.AddString(strings[stringIndex], out int binaryIndex);
                stringIndexToBinaryStringIndexMap[stringIndex] = ( short )binaryIndex;
            }

            // Convert procedures
            int instructionBinaryIndex = 0;
            int nextBinaryLabelIndex   = 0;

            foreach (var procedure in mProcedures)
            {
                int procedureInstructionStartBinaryIndex          = instructionBinaryIndex;
                var procedureInstructionListIndexToBinaryIndexMap = new Dictionary <int, int>();
                var procedureIndexRemap = new Dictionary <int, int>();

                // Convert instructions in procedure
                for (int instructionIndex = 0; instructionIndex < procedure.Instructions.Count; instructionIndex++)
                {
                    procedureInstructionListIndexToBinaryIndexMap[instructionIndex] = instructionBinaryIndex;

                    var instruction = procedure.Instructions[instructionIndex];

                    if (!instruction.UsesTwoBinaryInstructions)
                    {
                        var binaryInstruction = new BinaryInstruction
                        {
                            Opcode = instruction.Opcode
                        };

                        if (instruction.Opcode == Opcode.PUSHSTR)
                        {
                            // Handle PUSHSTR seperately due to difference in string index usage
                            short stringIndex = ( short )strings.IndexOf(instruction.Operand.StringValue);
                            if (stringIndex == -1)
                            {
                                throw new InvalidDataException("String could not be found??");
                            }

                            binaryInstruction.OperandShort = stringIndexToBinaryStringIndexMap[stringIndex];
                        }
                        else if (instruction.Opcode == Opcode.GOTO || instruction.Opcode == Opcode.IF)
                        {
                            // Convert procedure-local label index to global label index
                            int oldIndex = instruction.Operand.Int16Value;
                            if (!procedureIndexRemap.ContainsKey(oldIndex))
                            {
                                procedureIndexRemap[oldIndex] = nextBinaryLabelIndex++;
                            }

                            binaryInstruction.OperandShort = (short)procedureIndexRemap[oldIndex];
                        }
                        else
                        {
                            // Handle regular instruction
                            if (instruction.Operand != null)
                            {
                                binaryInstruction.OperandShort = instruction.Operand.Int16Value;
                            }
                        }

                        builder.AddInstruction(binaryInstruction);
                        instructionBinaryIndex += 1;
                    }
                    else
                    {
                        // Handle instruction that uses the next instruction as its operand
                        var binaryInstruction = new BinaryInstruction {
                            Opcode = instruction.Opcode
                        };
                        var binaryInstruction2 = new BinaryInstruction();

                        switch (instruction.Operand.Kind)
                        {
                        case Operand.ValueKind.Int32:
                            binaryInstruction2.OperandInt = instruction.Operand.Int32Value;
                            break;

                        case Operand.ValueKind.Single:
                            binaryInstruction2.OperandFloat = instruction.Operand.SingleValue;
                            break;

                        default:
                            throw new InvalidOperationException();
                        }

                        builder.AddInstruction(binaryInstruction);
                        builder.AddInstruction(binaryInstruction2);
                        instructionBinaryIndex += 2;
                    }
                }

                // Convert labels in procedure after the instructions to remap the instruction indices
                foreach (var key in procedureIndexRemap.Keys)
                {
                    var label = procedure.Labels[key];
                    builder.AddJumpLabel(new BinaryLabel {
                        InstructionIndex = procedureInstructionListIndexToBinaryIndexMap[label.InstructionIndex], Name = label.Name, Reserved = 0
                    });
                }

                // Add procedure to builder
                builder.AddProcedureLabel(new BinaryLabel {
                    InstructionIndex = procedureInstructionStartBinaryIndex, Name = procedure.Name, Reserved = 0
                });
            }

            // Convert message script
            if (mMessageScript != null)
            {
                builder.SetMessageScriptSection(mMessageScript);
            }

            return(builder.Build());
        }
Exemplo n.º 15
0
 public static string DisassembleInstructionWithCommReferenceOperand(BinaryInstruction instruction)
 {
     return($"{instruction.Opcode}\t\t{instruction.OperandShort:X4}");
 }
Exemplo n.º 16
0
        private void ExecuteBinaryInstruction(BinaryInstruction instruction)
        {
            string name = instruction.Name;
            Operand left = instruction.LeftOperand;
            Operand right = instruction.RightOperand;

            StorageBase leftStorage = GetStorageForOperand(left);
            StorageBase rightStorage = GetStorageForOperand(right);

            if (leftStorage == null)
                throw new Exception(string.Format("Bad args, {0}", instruction.Name));

            string leftVal = GetStorageValue(leftStorage);
            string rightVal = rightStorage != null ? GetStorageValue(rightStorage) : right.Value;

            int leftInt = BinaryToIntegerUtility.LoadSignedInt(leftVal);
            int rightInt = BinaryToIntegerUtility.LoadSignedInt(rightVal);

            switch (name)
            {
                case "mov":
                    {
                        leftStorage.Data = GetDataForBitString(rightVal);
                    } break;

                case "add":
                    {
                        int sum = leftInt + rightInt;
                        leftStorage.Data = IntToData(sum);
                    } break;

                case "sub":
                    {
                        int diff = leftInt - rightInt;
                        leftStorage.Data = IntToData(diff);
                    } break;

                case "mul":
                    {
                        int prod = leftInt * rightInt;
                        leftStorage.Data = IntToData(prod);
                    } break;

                case "div":
                    {
                        int quot = leftInt / rightInt;
                        leftStorage.Data = IntToData(quot);
                    } break;

                default:
                    throw new ArgumentException(string.Format("Instruction without implementation: {0}", instruction.Name));
            }
        }
Exemplo n.º 17
0
        }                                                                        // { Default(instruction); }

        public virtual void Visit(BinaryInstruction instruction)
        {
            Default(instruction);
        }
Exemplo n.º 18
0
 public static string DisassembleInstructionWithFloatOperand(BinaryInstruction instruction, BinaryInstruction operand)
 {
     return($"{instruction.Opcode}\t\t{operand.OperandFloat.ToString( "0.00#####", CultureInfo.InvariantCulture )}f");
 }
Exemplo n.º 19
0
 public static string DisassembleInstructionWithIntOperand(BinaryInstruction instruction, BinaryInstruction operand)
 {
     return($"{instruction.Opcode}\t{operand.OperandInt:X8}");
 }