/// <summary> /// Releases the specified temporary variable for reuse. /// </summary> /// <param name="temp">A local descriptor for the temporary variable</param> public void ReleaseTemporary(LocalDescriptor temp) { if (temp == null) { throw new ArgumentNullException("temp"); } temp.InUse = false; }
// Emit the code that computes the number of iterations that the // loop requires. void GenerateLoopCount(CodeGenerator cg, Symbol sym, LocalDescriptor stepVar) { cg.GenerateExpression(sym.Type, EndExpression); if (StartExpression.IsConstant && StartExpression.Value.IntValue == 0) { // Start index is zero so no initial subtraction required. cg.GenerateExpression(sym.Type, StartExpression); cg.Emitter.StoreLocal(sym.Index); } else { cg.GenerateExpression(sym.Type, StartExpression); cg.Emitter.Dup(); cg.Emitter.StoreLocal(sym.Index); cg.Emitter.Sub(sym.Type); } if (StepExpression.IsConstant) { int stepValue = StepExpression.Value.IntValue; cg.Emitter.LoadInteger(stepValue); cg.Emitter.Add(sym.Type); if (stepValue != 1) { cg.Emitter.LoadInteger(stepValue); cg.Emitter.Div(sym.Type); } } else { cg.GenerateExpression(sym.Type, StepExpression); cg.Emitter.Dup(); cg.Emitter.StoreLocal(stepVar); cg.Emitter.Add(sym.Type); cg.Emitter.LoadLocal(stepVar); cg.Emitter.Div(sym.Type); } cg.Emitter.ConvertType(sym.Type, SymType.INTEGER); }
// Emit an opcode with an local variable void Emit0(OpCode op, LocalDescriptor value) { _code.Add(new InstructionLocal(op, value)); }
/// <summary> /// Emit the code to load the address of a local variable. /// </summary> /// <param name="value">The local variable reference</param> public void LoadLocalAddress(LocalDescriptor value) { if (value == null) { throw new ArgumentNullException("value"); } Emit0(OpCodes.Ldloca, value); }
// Create a local descriptor for a local variable at the // given index and with the given type. LocalDescriptor AssignLocal(Type type, int index) { LocalDescriptor newTemp = new LocalDescriptor(); newTemp.Type = type; newTemp.Index = index; newTemp.InUse = true; _temp.Add(newTemp); return newTemp; }
/// <summary> /// Emit the appropriate store local index opcode. /// </summary> /// <param name="value">The local variable reference</param> public void StoreLocal(LocalDescriptor value) { Emit0(OpCodes.Stloc, value); }
/// <summary> /// Initialises a new Lifetime object using the specified local /// variable and the start index in the code.. /// </summary> /// <param name="localVar">Local variable.</param> /// <param name="startIndex">Start index.</param> public Lifetime(LocalDescriptor localVar, int startIndex) { LocalVar = localVar; StartIndex = startIndex; }
/// <summary> /// Create an InstructionInt object with the given opcode /// and integer value. /// </summary> /// <param name="op">Opcode</param> /// <param name="value">An integer value</param> public InstructionLocal(OpCode op, LocalDescriptor value) : base(op) { if (value == null) { throw new ArgumentNullException("value"); } Value = value; }
/// <summary> /// Creates a local parse node with the specified local index. /// </summary> /// <param name="local">The local identifier index</param> public LocalParseNode(LocalDescriptor local) { _local = local; }