/// <summary> /// Decodes the specified CIL instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="decoder">The instruction decoder, which holds the code stream.</param> /// <remarks> /// This method is used by instructions to retrieve immediate operands /// From the instruction stream. /// </remarks> public override void Decode(InstructionNode ctx, IInstructionDecoder decoder) { // Decode base classes first base.Decode(ctx, decoder); int index; // Opcode specific handling switch (opcode) { case OpCode.Ldarg: case OpCode.Ldarg_s: index = (int)decoder.Instruction.Operand; break; case OpCode.Ldarg_0: index = 0; break; case OpCode.Ldarg_1: index = 1; break; case OpCode.Ldarg_2: index = 2; break; case OpCode.Ldarg_3: index = 3; break; default: throw new System.NotImplementedException(); } // Push the loaded value onto the evaluation stack var parameterOperand = decoder.Compiler.GetParameterOperand(index); var result = LoadInstruction.CreateResultOperand(decoder, parameterOperand.Type); ctx.Operand1 = parameterOperand; ctx.Result = result; }
public override void Visit(LoadInstruction instruction) { base.Visit(instruction); // method argument is assigned // thus violating corral's requirements if (methodBody.Parameters.Contains(instruction.Result)) { // check if it was processed already if (argumentToNewVariable.ContainsKey(instruction.Result)) { return; } // creates new copy of the assigned argument // creates a load instruction for to set original argument value to the new local copy // the new local copy will replace the use of the argument var newVar = AddNewLocalVariable(instruction.Result); var newLoad = new LoadInstruction(0, newVar, instruction.Result); newLoad.Label = String.Empty; newLoads.Add(newLoad); argumentToNewVariable.Add(instruction.Result, newVar); } }
public LoadJob Load(LoadInstruction instruction) { // do load via adaptor var loadJob = (LoadJob)InvokeAdaptor("Load", instruction); this.EnqueueJob(loadJob); return loadJob; }
public Form1() { InitializeComponent(); string[] args = Environment.GetCommandLineArgs(); ReadXls.onSheetChoise += this.getXlsSheet; loadInstruction = new LoadInstruction(this); }
public LoadJob Load(LoadInstruction instruction) { // do load via adaptor var loadJob = (LoadJob)InvokeAdaptor("Load", instruction); this.EnqueueJob(loadJob); return(loadJob); }
public override void Visit(LoadInstruction instruction) { if (instruction.Operand is Constant) { var value = ExtractConstant(instruction.Operand as Constant); this.State.SetValue(instruction.Result, value); } if (instruction.Operand is IVariable) { this.State.SetValue(instruction.Result, this.State.GetValue(instruction.Operand as IVariable)); } }
private bool HandleLoadWithOperand(LoadInstruction load, IValue operand) { var result = true; if (operand is Constant) { var constant = operand as Constant; if (constant.Value == null) { ptAnalysis.ProcessNull(State, load.Result); } } if (operand is IVariable) { var variable = operand as IVariable; ptAnalysis.ProcessCopy(State, load.Result, variable); } else if (operand is InstanceFieldAccess) { var access = operand as InstanceFieldAccess; ptAnalysis.ProcessLoad(State, load.Offset, load.Result, access.Instance, access.Field); } else if (operand is StaticFieldAccess) { var access = operand as StaticFieldAccess; ptAnalysis.ProcessLoad(State, load.Offset, load.Result, IteratorPointsToAnalysis.GlobalVariable, access.Field); } else if (operand is ArrayElementAccess) { var arrayAccess = operand as ArrayElementAccess; var baseArray = arrayAccess.Array; ptAnalysis.ProcessLoad(State, load.Offset, load.Result, baseArray, new FieldReference("[]", operand.Type, this.ptAnalysis.method.ContainingType)); } else if (operand is VirtualMethodReference) { var loadDelegateStmt = operand as VirtualMethodReference; var methodRef = loadDelegateStmt.Method; var instance = loadDelegateStmt.Instance; ptAnalysis.ProcessDelegateAddr(State, load.Offset, load.Result, methodRef, instance); } else if (operand is StaticMethodReference) { var loadDelegateStmt = operand as StaticMethodReference; var methodRef = loadDelegateStmt.Method; ptAnalysis.ProcessDelegateAddr(State, load.Offset, load.Result, methodRef, null); } else { result = false; } return(result); }
public override void Visit(LoadInstruction instruction) { if (instruction.Operand is Reference reference) { // Reference object is an expression of the form &<...> // <...> is the pointedObj IReferenceable pointedObj = reference.Value; if (pointedObj is InstanceFieldAccess || pointedObj is StaticFieldAccess) { return; } ReferenceFinder.AddReference(pointedObj); } }
public override void Visit(LoadInstruction instruction) { if (instruction.Operand is Reference reference) { // Reference object is an expression of the form &<...> // <...> is the pointedObj IReferenceable pointedObj = reference.Value; if (pointedObj is StaticFieldAccess staticFieldAccess) { FieldReferencedSet.Add(staticFieldAccess.Field); } else if (pointedObj is InstanceFieldAccess instanceFieldAccess) { FieldReferencedSet.Add(instanceFieldAccess.Field); } } }
public override void Visit(LoadInstruction instruction) { SavePreState(instruction, FreshCurrent()); var nstate = FreshCurrent(); var operand = instruction.Operand; var result = instruction.Result; if (operand is Dereference || operand is Reference) { //TODO: make this more precise UpdateStateNotConstant(nstate); } else if (IsConstantType(result.Type)) { if (operand is Constant) { var c = operand as Constant; UpdateState(nstate, result, c); } else if (operand is IVariable) { var v = operand as IVariable; UpdateStateCopy(nstate, result, v); } else if (operand is InstanceFieldAccess) { var ifa = operand as InstanceFieldAccess; UpdateStateCopy(nstate, result, ifa.Field); } else if (operand is StaticFieldAccess) { var sfa = operand as StaticFieldAccess; UpdateStateCopy(nstate, result, sfa.Field); } else { UpdateStateNotConstant(nstate, result); } } SetCurrent(nstate); SavePostState(instruction, FreshCurrent()); }
public override void Visit(LoadInstruction instruction) { var operand = instruction.Operand; if (operand is VirtualMethodReference) { // DIEGO TODO: Maybe I will need to add the instance var loadDelegateStmt = operand as VirtualMethodReference; var methodRef = loadDelegateStmt.Method; var instance = loadDelegateStmt.Instance; methodVisitor.Delegates.Add(methodRef); } else if (operand is StaticMethodReference) { var loadDelegateStmt = operand as StaticMethodReference; var methodRef = loadDelegateStmt.Method; methodVisitor.Delegates.Add(methodRef); } }
public override void Visit(LoadInstruction instruction) { if (instruction.Operand is StaticFieldAccess) { var fieldAccess = (instruction.Operand as StaticFieldAccess); var field = fieldAccess.Field.ResolvedField; if (field != null) { RangeDomain value; if (RangeAnalysis.GlobalVariables.TryGetValue(field, out value)) { this.State.SetValue(instruction.Result, value); } } } var source = instruction.Operand; var dest = instruction.Result; Copy(source, dest); }
public override void Visit(LoadInstruction instruction) { var load = instruction as LoadInstruction; if (load.Operand is Constant) { } else if (load.Operand is IVariable) { var variable = load.Operand as IVariable; var lastDefs = depAnalysis.LastDefGet(variable); depAnalysis.SetDataDependency((int)load.Offset, lastDefs); } else if (load.Operand is InstanceFieldAccess) { var fieldAccess = load.Operand as InstanceFieldAccess; var lastDefs = depAnalysis.LastDefGet(fieldAccess.Instance, fieldAccess.Field, ptg); depAnalysis.SetDataDependency((int)load.Offset, lastDefs); } depAnalysis.LastDefSet(load.Result, (int)load.Offset); }
public override void Visit(LoadInstruction instruction) { var load = instruction as LoadInstruction; var operand = load.Operand; HandleLoadWithOperand(load, operand); if (operand is Reference) { var referencedValue = (operand as Reference).Value; var isHandled = HandleLoadWithOperand(load, referencedValue); if (!(referencedValue is IVariable)) { } addressMap[instruction.Result] = referencedValue; } else if (operand is Dereference) { var reference = (operand as Dereference).Reference; var isHandled = HandleLoadWithOperand(load, reference); } }
// shortcut public static UnityLoadJob Load(LoadInstruction instruction) { return (UnityLoadJob)Module.Find<SinozeAssetLoader>().Load(instruction); }
public void Visit(LoadInstruction instruction) { lines.Add($"{label}\tLOAD {instruction.Destination.GetAssemblySymbol()},{instruction.MemoryAddress.GetAssemblySymbol()}"); }
public LoadJob(LoadInstruction instruction) { this.Instruction = instruction; }
public override void Visit(LoadInstruction instruction) { instruction.Result.Type = instruction.Operand.Type; }
public virtual void Visit(LoadInstruction instruction) { Default(instruction); }
public override void Visit(LoadInstruction instruction) { var operandAsConstant = instruction.Operand as Constant; var operandAsVariable = instruction.Operand as IVariable; // Null is a polymorphic value so we handle it specially. We don't set the // corresponding variable's type yet. We postpone it to usage of the variable // or set it to System.Object if it is never used. if (operandAsConstant != null) { if (operandAsConstant.Value == null) { instruction.Result.Type = Types.Instance.PlatformType.SystemObject; } else if (instruction.Result.Type != null && instruction.Result.Type.TypeCode == PrimitiveTypeCode.Boolean) { // If the result of the load has type Boolean, // then we are actually loading a Boolean constant. if (operandAsConstant.Value.Equals(0)) { operandAsConstant.Value = false; operandAsConstant.Type = Types.Instance.PlatformType.SystemBoolean; } else if (operandAsConstant.Value.Equals(1)) { operandAsConstant.Value = true; operandAsConstant.Type = Types.Instance.PlatformType.SystemBoolean; } } } // If we have variable to variable assignment where the result was assigned // a type but the operand was not, then we set the operand type accordingly. else if (operandAsVariable != null && instruction.Result.Type != null && (operandAsVariable.Type == null || operandAsVariable.Type == Types.Instance.PlatformType.SystemObject || instruction.Result.Type.TypeCode == PrimitiveTypeCode.Boolean)) { operandAsVariable.Type = instruction.Result.Type; } if (instruction.Result.Type == null) { instruction.Result.Type = instruction.Operand.Type; } if (instruction.Operand is Dereference) { var deref = instruction.Operand as Dereference; // SRK (4th Oct 2019) instruction.Result.Type = deref.Reference.Type; if (deref.Reference.Type.TypeCode == PrimitiveTypeCode.Reference && deref.Type != null) { instruction.Result.Type = deref.Type; } else { instruction.Result.Type = deref.Reference.Type; } } if (instruction.Operand.Type != null && // we can be in the middle of the type inference analysis instruction.Operand.Type is IManagedPointerType) { instruction.Result.Type = instruction.Operand.Type; } }
public override void Visit(LoadInstruction instruction) { base.Visit(instruction); string name = instruction.Operand.ToString(); var v = instruction.Operand as IVariable; /* * // we want to detect code like this * // and use in the method call i and j * // in boogie the method will overwrite their values * * local Int32 i; * local Int32 j; * local Int32* $r2; * local Int32* $r3; * * $r2 = &i; * $r3 = &j; * RefKeyword::Ref($r2, $r3); * * // expected boogie (bct works like this) * call i, j := RefKeyword::Ref(i, j); * // we copy their values and then return a new value */ if (instruction.Operand.Type is IManagedPointerType && instruction.Operand is Reference && IsInMethodCallAsRef(instruction.Result)) { var r = instruction.Operand as Reference; instruction.Result.Type = r.Value.Type; instruction.Operand = r.Value; //variableToParameter.Add(instruction.Result, r.Variables.First()); } /* * this check is used to detect ref/out parameters * * parameter Int32* a; * parameter Int32* b; * * local Int32* $r0; * local Int32 $r1; * local Int32* $r2; * local Int32 $r3; * * LABEL_0: * $r0 = a; * $r1 = 10; *$r0 = $r1; * LABEL_1: * $r2 = b; * $r3 = 11; *$r2 = $r3; * return; * * // we will ignore pointers and use them as their target types * // that's why the aliasing in LABEL_0 and LABEL_1 wont work * // we need to replace every use of $r0 by a and $r2 by b * * // in boogie we return the new values of a and b (read previous comment) */ if (instruction.HasResult && v != null && methodBody.Parameters.Contains(instruction.Operand) && IsRefArgument(v)) { variableToParameter.Add(instruction.Result, v); } }
// some field initialization can be missing in constructors // example: /* * class Foo{ * int x; // this initialization is not added by the compiler * int y = y; * } */ // therefore we are adding the initialization for each field at the top of every constructor. public void Transform() { // these variables hold the default value IDictionary <Helpers.BoogieType, LocalVariable> boogieTypeToLocalVariable = new Dictionary <Helpers.BoogieType, LocalVariable>(); // they are the same stored in boogieTypeToLocalVariable IList <LocalVariable> variables = new List <LocalVariable>(); // assignment of constants IList <Instruction> instructions = new List <Instruction>(); CreateLocalVariablesWithDefaultValues(boogieTypeToLocalVariable, variables, instructions); // we need to initialize local variables. foreach (var lv in methodBody.Variables) { if (lv.IsParameter || // in the delegate handling this type of variables are not used // calling get boogie type will crash lv.Type is Microsoft.Cci.Immutable.FunctionPointerType) { continue; } var varBoogieType = Helpers.GetBoogieType(lv); IVariable initialValue = boogieTypeToLocalVariable[varBoogieType]; var storeInstruction = new LoadInstruction(0, lv, initialValue); storeInstruction.Label = String.Empty; instructions.Add(storeInstruction); } var fields = methodBody.MethodDefinition.ContainingTypeDefinition.Fields; if (methodBody.MethodDefinition.IsStaticConstructor) { foreach (IFieldDefinition field in fields.Where(f => f.IsStatic)) { var fieldBoogieType = Helpers.GetBoogieType(field); IVariable initialValue = boogieTypeToLocalVariable[fieldBoogieType]; var staticAccess = new StaticFieldAccess(field); var storeInstruction = new StoreInstruction(0, staticAccess, initialValue); storeInstruction.Label = String.Empty; instructions.Add(storeInstruction); } } else if (methodBody.MethodDefinition.IsConstructor) { var thisVariable = methodBody.Parameters[0]; foreach (IFieldDefinition field in fields.Where(f => !f.IsStatic)) { var fieldBoogieType = Helpers.GetBoogieType(field); IVariable initialValue = boogieTypeToLocalVariable[fieldBoogieType]; var instanceAccess = new InstanceFieldAccess(thisVariable, field); var storeInstruction = new StoreInstruction(0, instanceAccess, initialValue); storeInstruction.Label = String.Empty; instructions.Add(storeInstruction); } } methodBody.Variables.UnionWith(variables); int idx = 0; foreach (var i in instructions) { methodBody.Instructions.Insert(idx, i); idx++; } }
// some field initialization can be missing in constructors // example: /* * class Foo{ * int x; // this initialization is not added by the compiler * int y = y; * } */ // therefore we are adding the initialization for each field at the top of every constructor. public void Transform() { // these variables hold the default value IDictionary <Helpers.BoogieType, LocalVariable> boogieTypeToLocalVariable = new Dictionary <Helpers.BoogieType, LocalVariable>(); // they are the same stored in boogieTypeToLocalVariable IList <LocalVariable> variables = new List <LocalVariable>(); // assignment of constants IList <Instruction> instructions = new List <Instruction>(); CreateLocalVariablesWithDefaultValues(boogieTypeToLocalVariable, variables, instructions); // we need to initialize local variables. foreach (var lv in methodBody.Variables) { if (lv.IsParameter || // in the delegate handling this type of variables are not used // calling get boogie type will crash lv.Type is Microsoft.Cci.Immutable.FunctionPointerType || (lv.Type is IManagedPointerType && Settings.AddressesEnabled())) { continue; } var varBoogieType = Helpers.GetBoogieType(lv.Type); IVariable initialValue = boogieTypeToLocalVariable[varBoogieType]; var storeInstruction = new LoadInstruction(0, lv, initialValue); storeInstruction.Label = String.Empty; instructions.Add(storeInstruction); } if (methodBody.MethodDefinition.IsConstructor) { IEnumerable <IFieldDefinition> fields = null; if (methodBody.MethodDefinition.ContainingTypeDefinition.IsGeneric) { /* * This solves the issue of having a generic class (ie. class A<T>) and mismatches between field names. * If we just use ContaingTypeDefinition.Fields we have have a different IFieldDefinition than the ones found in the method bodies * Here, I want to be sure that we use A<T>.field as a field definition and not A.field * However, this could not be the ultimate solution and there could be a better way to tackle it. */ var instanceOrSpecialized = TypeHelper.GetInstanceOrSpecializedNestedType(methodBody.MethodDefinition.ContainingTypeDefinition); fields = instanceOrSpecialized.Fields; } else { fields = methodBody.MethodDefinition.ContainingTypeDefinition.Fields; } var thisVariable = methodBody.Parameters[0]; foreach (IFieldDefinition field in fields.Where(f => !f.IsStatic)) { var fieldBoogieType = Helpers.GetBoogieType(field.Type); IVariable initialValue = boogieTypeToLocalVariable[fieldBoogieType]; var instanceAccess = new InstanceFieldAccess(thisVariable, field); var storeInstruction = new StoreInstruction(0, instanceAccess, initialValue); storeInstruction.Label = String.Empty; instructions.Add(storeInstruction); } } methodBody.Variables.UnionWith(variables); int idx = 0; foreach (var i in instructions) { methodBody.Instructions.Insert(idx, i); idx++; } }
public virtual void Visit(LoadInstruction instruction) { }
public UnityLoadJob Load(LoadInstruction instruction) { return new UnityLoadJob(instruction); }
public void VisitMethod(MethodBody mBody, ControlFlowGraph cfg) { VisitLocals(mBody); // Going through the instructions via cfg nodes instead of directly iterating over the instructions // of the methodBody becuase Phi instructions may not have been inserted in the insts of the methodBody. foreach (var node in cfg.Nodes) { foreach (var instruction in node.Instructions) { // System.Console.WriteLine("{0}", instruction.ToString()); // System.Console.WriteLine("{0}", instruction.GetType().FullName()); // System.Console.WriteLine(); if (instruction is LoadInstruction) { LoadInstruction lInst = instruction as LoadInstruction; IValue rhsOperand = lInst.Operand; if (rhsOperand is StaticFieldAccess) { StaticFieldAccess rhsAcc = rhsOperand as StaticFieldAccess; IFieldReference fld = rhsAcc.Field; ITypeDefinition fldType = fld.ContainingType.ResolvedType; Stubber.CheckAndAdd(fldType); } // Note: calls to static methods and instance methods appear as a StaticMethodReference else if (rhsOperand is StaticMethodReference) { StaticMethodReference sMethAddr = rhsOperand as StaticMethodReference; IMethodDefinition tgtMeth = sMethAddr.Method.ResolvedMethod; ITypeDefinition containingTy = tgtMeth.ContainingTypeDefinition; Stubber.CheckAndAdd(containingTy); IMethodDefinition addedMeth = Stubber.CheckAndAdd(tgtMeth); // addrTakenMethods do not contain templates. if (addedMeth != null) { addrTakenMethods.Add(addedMeth); } } //Note: calls to virtual, abstract or interface methods appear as VirtualMethodReference else if (rhsOperand is VirtualMethodReference) { VirtualMethodReference sMethAddr = rhsOperand as VirtualMethodReference; IMethodDefinition tgtMeth = sMethAddr.Method.ResolvedMethod; ITypeDefinition containingTy = tgtMeth.ContainingTypeDefinition; ITypeDefinition addedTy = Stubber.CheckAndAdd(containingTy); IMethodDefinition addedMeth = Stubber.CheckAndAdd(tgtMeth); if (addedTy != null && addedMeth != null) { // addrTakenMethods do not contain templates. addrTakenMethods.Add(addedMeth); ProcessVirtualInvoke(addedMeth, addedTy, true); } } else if (rhsOperand is Reference) { Reference rhsRef = rhsOperand as Reference; IReferenceable refOf = rhsRef.Value; if (refOf is StaticFieldAccess) { StaticFieldAccess refAcc = refOf as StaticFieldAccess; IFieldDefinition fld = refAcc.Field.ResolvedField; ITypeDefinition fldType = fld.ContainingType.ResolvedType; Stubber.CheckAndAdd(fldType); addrTakenStatFlds.Add(fld); } else if (refOf is IVariable) { IVariable refVar = refOf as IVariable; if (!refVar.Type.IsValueType || refVar.Type.ResolvedType.IsStruct) { addrTakenLocals.Add(refVar); } } else if (refOf is InstanceFieldAccess) { InstanceFieldAccess refAcc = refOf as InstanceFieldAccess; IFieldDefinition fld = refAcc.Field.ResolvedField; addrTakenInstFlds.Add(fld); } else if (refOf is ArrayElementAccess) { // All arrays will be added into domX as potential address taken. } } } else if (instruction is StoreInstruction) { StoreInstruction sInst = instruction as StoreInstruction; IAssignableValue lhs = sInst.Result; if (lhs is StaticFieldAccess) { StaticFieldAccess lhsAcc = lhs as StaticFieldAccess; IFieldReference fld = lhsAcc.Field; ITypeDefinition fldType = fld.ContainingType.ResolvedType; Stubber.CheckAndAdd(fldType); } } else if (instruction is CreateObjectInstruction) { CreateObjectInstruction newObjInst = instruction as CreateObjectInstruction; ITypeReference objType = newObjInst.AllocationType; ITypeDefinition objTypeDef = objType.ResolvedType; if (objTypeDef is IGenericTypeInstance) { objTypeDef = objTypeDef.ResolvedType; } ITypeDefinition addedTy = Stubber.CheckAndAdd(objTypeDef); if (addedTy != null && !allocClasses.Contains(addedTy)) { allocClasses.Add(addedTy); } } else if (instruction is CreateArrayInstruction) { CreateArrayInstruction newArrInst = instruction as CreateArrayInstruction; ITypeReference elemType = newArrInst.ElementType; ITypeDefinition elemTypeDef = elemType.ResolvedType; ITypeDefinition addedTy = Stubber.CheckAndAdd(elemTypeDef); if (addedTy != null && !allocClasses.Contains(addedTy)) { allocClasses.Add(addedTy); } } else if (instruction is MethodCallInstruction) { MethodCallInstruction invkInst = instruction as MethodCallInstruction; IMethodReference callTgt = invkInst.Method; ITypeReference containingType = callTgt.ContainingType; ITypeDefinition declType = containingType.ResolvedType; IMethodDefinition callTgtDef = callTgt.ResolvedMethod; ITypeDefinition addedType = Stubber.CheckAndAdd(declType); IMethodDefinition addedMeth = Stubber.CheckAndAdd(callTgtDef); MethodCallOperation callType = invkInst.Operation; if (callType == MethodCallOperation.Virtual && addedType != null && addedMeth != null) { ProcessVirtualInvoke(addedMeth, addedType, false); } } else { // System.Console.WriteLine("{0}", instruction.ToString()); // System.Console.WriteLine("Not currently handled: {0}", instruction.GetType().ToString()); // System.Console.WriteLine(); } } } }
public static void Inline(this MethodBody callerBody, MethodCallInstruction methodCall, MethodBody calleeBody) { // TODO: Fix local variables (and parameters) name clashing var index = callerBody.Instructions.IndexOf(methodCall); callerBody.Instructions.RemoveAt(index); Instruction nextInstruction = null; if (callerBody.Instructions.Count > index) { // The caller method has more instructions after the method call nextInstruction = callerBody.Instructions[index]; } for (var i = 0; i < calleeBody.Parameters.Count; ++i) { var parameter = calleeBody.Parameters[i]; var argument = methodCall.Arguments[i]; var copy = new LoadInstruction(methodCall.Offset, parameter, argument); copy.Label = string.Format("{0}_{1}", methodCall.Label, copy.Label); callerBody.Instructions.Insert(index, copy); index++; } var lastCalleeInstructionIndex = calleeBody.Instructions.Count - 1; for (var i = 0; i < calleeBody.Instructions.Count; ++i) { var instruction = calleeBody.Instructions[i]; if (instruction is ReturnInstruction) { var ret = instruction as ReturnInstruction; if (ret.HasOperand && methodCall.HasResult) { // Copy the return value of the callee to the result variable of the method call var copy = new LoadInstruction(ret.Offset, methodCall.Result, ret.Operand); copy.Label = string.Format("{0}_{1}", methodCall.Label, copy.Label); callerBody.Instructions.Insert(index, copy); index++; } if (nextInstruction != null && i < lastCalleeInstructionIndex) { // Jump to the instruction after the method call var branch = new UnconditionalBranchInstruction(ret.Offset, nextInstruction.Offset); branch.Label = string.Format("{0}_{1}", methodCall.Label, branch.Label); callerBody.Instructions.Insert(index, branch); index++; } } else { // TODO: Fix! We should clone the instruction // so the original is not modified // and calleeBody remain intacted if (instruction is BranchInstruction) { var branch = instruction as BranchInstruction; branch.Target = string.Format("{0}_{1}", methodCall.Label, branch.Target); } else if (instruction is SwitchInstruction) { var branch = instruction as SwitchInstruction; for (var j = 0; j < branch.Targets.Count; ++j) { var target = branch.Targets[j]; branch.Targets[j] = string.Format("{0}_{1}", methodCall.Label, target); } } instruction.Label = string.Format("{0}_{1}", methodCall.Label, instruction.Label); callerBody.Instructions.Insert(index, instruction); index++; } } }
private void ReadLoop(PHINode phi, BasicBlock oldBlock, BasicBlock testBlock) { // parse the input file and generate code for it Symbol currentSymbol = Symbol.None; Symbol nextSymbol = Symbol.None; Int32 currentValue = 0, nextValue = 0; Char c; Int32 direction; while (currentSymbol != Symbol.EOF && currentSymbol != Symbol.EndLoop) { switch (currentSymbol) { case Symbol.None: break; case Symbol.Read: { CallInstruction getCharCall = this.builder.CreateCall(this.getcharFunction, "tape"); getCharCall.TailCall = false; Value tape0 = (Value)getCharCall; Value tape1 = this.builder.CreateTrunc(tape0, Type.GetInteger8Type(this.context), "tape"); builder.CreateStore(tape1, this.currentHead); } break; case Symbol.Write: { LoadInstruction tape0 = this.builder.CreateLoad(this.currentHead, "tape"); Value tape1 = this.builder.CreateSignExtend(tape0, Type.GetInteger32Type(this.context), "tape"); CallInstruction putcharCall = this.builder.CreateCall(this.putcharFunction, tape1); putcharCall.TailCall = false; } break; case Symbol.Move: this.currentHead = this.builder.CreateGEP( this.currentHead, new Constant(this.context, 32, (UInt64)currentValue), "head"); break; case Symbol.Change: { LoadInstruction tape0 = this.builder.CreateLoad(this.currentHead, "tape"); Value tape1 = this.builder.CreateAdd(tape0, new Constant(this.context, 8, (UInt64)currentValue), "tape"); this.builder.CreateStore(tape1, this.currentHead); } break; case Symbol.Loop: BasicBlock testbb = new BasicBlock(this.context, this.brainfFunction, "brainf"); this.builder.CreateBranch(testbb); BasicBlock bb0 = this.builder.GetInsertBlock(); BasicBlock bb1 = new BasicBlock(this.context, this.brainfFunction, "brainf"); this.builder.SetInsertPoint(bb1); PHINode phi0 = new PHINode(PointerType.GetUnqualified(Type.GetInteger8Type(this.context)), 2, "head", testbb); phi0.AddIncomding(this.currentHead, bb0); this.currentHead = phi0; this.ReadLoop(phi0, bb1, testbb); break; default: throw new Exception("Unknown symbol."); } currentSymbol = nextSymbol; currentValue = nextValue; nextSymbol = Symbol.None; bool loop = currentSymbol == Symbol.None || currentSymbol == Symbol.Move || currentSymbol == Symbol.Change; while (loop) { if (this.reader.EndOfStream) { if (currentSymbol == Symbol.None) currentSymbol = Symbol.EOF; else nextSymbol = Symbol.EOF; loop = false; } else { c = (Char)this.reader.Read(); direction = 1; switch (c) { case '-': direction = -1; goto case '+'; case '+': if (currentSymbol == Symbol.Change) { currentValue += direction; } else { if (currentSymbol == Symbol.None) { currentSymbol = Symbol.Change; currentValue = direction; } else { nextSymbol = Symbol.Change; nextValue = direction; loop = false; } } break; case '<': direction = -1; goto case '>'; case '>': if (currentSymbol == Symbol.Move) { currentValue += direction; } else { if (currentSymbol == Symbol.None) { currentSymbol = Symbol.Move; currentValue = direction; } else { nextSymbol = Symbol.Move; nextValue = direction; loop = false; } } break; case ',': if (currentSymbol == Symbol.None) currentSymbol = Symbol.Read; else nextSymbol = Symbol.Read; loop = false; break; case '.': if (currentSymbol == Symbol.None) currentSymbol = Symbol.Write; else nextSymbol = Symbol.Write; loop = false; break; case '[': if (currentSymbol == Symbol.None) currentSymbol = Symbol.Loop; else nextSymbol = Symbol.Loop; loop = false; break; case ']': if (currentSymbol == Symbol.None) currentSymbol = Symbol.EndLoop; else nextSymbol = Symbol.EndLoop; loop = false; break; default: break; } } } } if (currentSymbol == Symbol.EndLoop) { if(phi == null) throw new Exception("Unexpected ]"); this.builder.CreateBranch(testBlock); phi.AddIncomding(this.currentHead, this.builder.GetInsertBlock()); Value head0 = phi; LoadInstruction tape0 = new LoadInstruction(head0, "tape", testBlock); IntegerCompareInstruction test0 = new IntegerCompareInstruction( testBlock, Predicate.Equal, tape0, new Constant(this.context, 8, 0), "test"); BasicBlock bb0 = new BasicBlock(this.context, this.brainfFunction, "brainf"); BranchInstruction.Create(bb0, oldBlock, test0, testBlock); this.builder.SetInsertPoint(bb0); PHINode phi1 = this.builder.CreatePHI(Type.GetInteger8PointerType(this.context), 1, "head"); phi1.AddIncomding(head0, testBlock); this.currentHead = phi1; return; } this.builder.CreateBranch(this.endBlock); if (phi != null) throw new Exception("Missing ]"); }
private void CreateLocalVariablesWithDefaultValues(IDictionary <Helpers.BoogieType, LocalVariable> boogieTypeToLocalVariable, IList <LocalVariable> variables, IList <Instruction> instructions) { // int var defaultInt = new LocalVariable("$defaultIntValue", false, methodBody.MethodDefinition); defaultInt.Type = Types.Instance.PlatformType.SystemInt32; Contract.Assert(Helpers.GetBoogieType(defaultInt).Equals(Helpers.BoogieType.Int)); var intAssign = new LoadInstruction(0, defaultInt, new Constant(0) { Type = defaultInt.Type }); intAssign.Label = String.Empty; variables.Add(defaultInt); instructions.Add(intAssign); boogieTypeToLocalVariable.Add(Helpers.BoogieType.Int, defaultInt); // real var defaultReal = new LocalVariable("$defaultRealValue", false, methodBody.MethodDefinition); defaultReal.Type = Types.Instance.PlatformType.SystemFloat32; Contract.Assert(Helpers.GetBoogieType(defaultReal).Equals(Helpers.BoogieType.Real)); var realAssing = new LoadInstruction(0, defaultReal, new Constant(0F) { Type = defaultReal.Type }); realAssing.Label = String.Empty; variables.Add(defaultReal); instructions.Add(realAssing); boogieTypeToLocalVariable.Add(Helpers.BoogieType.Real, defaultReal); // bool var defaultBool = new LocalVariable("$defaultBoolValue", false, methodBody.MethodDefinition); defaultBool.Type = Types.Instance.PlatformType.SystemBoolean; Contract.Assert(Helpers.GetBoogieType(defaultBool).Equals(Helpers.BoogieType.Bool)); var boolAssign = new LoadInstruction(0, defaultBool, new Constant(false) { Type = defaultBool.Type }); boolAssign.Label = String.Empty; variables.Add(defaultBool); instructions.Add(boolAssign); boogieTypeToLocalVariable.Add(Helpers.BoogieType.Bool, defaultBool); // Ref var defaultRef = new LocalVariable("$defaultRef", false, methodBody.MethodDefinition); defaultRef.Type = Types.Instance.PlatformType.SystemObject; Contract.Assert(Helpers.GetBoogieType(defaultRef).Equals(Helpers.BoogieType.Ref)); var refAssign = new LoadInstruction(0, defaultRef, new Constant(null) { Type = defaultRef.Type }); refAssign.Label = String.Empty; variables.Add(defaultRef); instructions.Add(refAssign); boogieTypeToLocalVariable.Add(Helpers.BoogieType.Ref, defaultRef); }