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; } }
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; } }
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}"); }
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}"); }
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)); } }
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}\""); }
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; } }
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; } }
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."); } }
public override void Visit(BinaryInstruction instruction) { //TODO: very imprecise, can we do it better? DefaultVarTop(instruction, instruction.Result); }
/// <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"); } }
public override void Visit(BinaryInstruction instruction) { base.Visit(instruction); }
public virtual void Visit(BinaryInstruction instruction) { }
/// <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()); }
public static string DisassembleInstructionWithCommReferenceOperand(BinaryInstruction instruction) { return($"{instruction.Opcode}\t\t{instruction.OperandShort:X4}"); }
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)); } }
} // { Default(instruction); } public virtual void Visit(BinaryInstruction instruction) { Default(instruction); }
public static string DisassembleInstructionWithFloatOperand(BinaryInstruction instruction, BinaryInstruction operand) { return($"{instruction.Opcode}\t\t{operand.OperandFloat.ToString( "0.00#####", CultureInfo.InvariantCulture )}f"); }
public static string DisassembleInstructionWithIntOperand(BinaryInstruction instruction, BinaryInstruction operand) { return($"{instruction.Opcode}\t{operand.OperandInt:X8}"); }