Ejemplo n.º 1
0
 /// <summary>
 /// Pops the value from the top of the stack and stores it in the given local variable.
 /// </summary>
 /// <param name="variable"> The variable to store the value. </param>
 public override void StoreVariable(ILLocalVariable variable)
 {
     if (variable as ReflectionEmitILLocalVariable == null)
     {
         throw new ArgumentNullException("variable");
     }
     this.generator.Emit(OpCodes.Stloc, ((ReflectionEmitILLocalVariable)variable).UnderlyingLocal);
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Outputs an instruction and a variable to the log.
 /// </summary>
 /// <param name="instruction"> The instruction to output. </param>
 /// <param name="variable"> The variable to output. </param>
 private void Log(string instruction, ILLocalVariable variable)
 {
     if (variable.Name == null)
     {
         LogInstruction(instruction, string.Format("V{0}", variable.Index));
     }
     else
     {
         LogInstruction(instruction, string.Format("V{0} ({1})", variable.Index, variable.Name));
     }
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Indicates that the given temporary variable is no longer needed.
 /// </summary>
 /// <param name="temporaryVariable"> The temporary variable created using CreateTemporaryVariable(). </param>
 public void ReleaseTemporaryVariable(ILLocalVariable temporaryVariable)
 {
     if (temporaryVariable == null)
     {
         throw new ArgumentNullException("temporaryVariable");
     }
     if (this.temporaryVariables == null)
     {
         this.temporaryVariables = new List <ILLocalVariable>();
     }
     this.temporaryVariables.Add(temporaryVariable);
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Pops the value from the top of the stack and stores it in the given local variable.
 /// </summary>
 /// <param name="variable"> The variable to store the value. </param>
 public override void StoreVariable(ILLocalVariable variable)
 {
     Log("stloc", variable);
     this.generator.StoreVariable(variable);
 }
Ejemplo n.º 5
0
 /// <summary>
 /// Pushes the address of the given variable onto the stack.
 /// </summary>
 /// <param name="variable"> The variable whose address will be pushed. </param>
 public override void LoadAddressOfVariable(ILLocalVariable variable)
 {
     Log("ldloca", variable);
     this.generator.LoadAddressOfVariable(variable);
 }
Ejemplo n.º 6
0
 public TemporaryVariableExpression(ILLocalVariable variable)
 {
     this.variable = variable;
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Stores the value on the top of the stack in the reference.
        /// </summary>
        /// <param name="generator"> The generator to output the CIL to. </param>
        /// <param name="optimizationInfo"> Information about any optimizations that should be performed. </param>
        /// <param name="valueType"> The primitive type of the value that is on the top of the stack. </param>
        /// <param name="throwIfUnresolvable"> <c>true</c> to throw a ReferenceError exception if
        /// the name is unresolvable; <c>false</c> to create a new property instead. </param>
        public void GenerateSet(ILGenerator generator, OptimizationInfo optimizationInfo, bool rIU, Type valueType, SetValueMethod value, bool throwIfUnresolvable)
        {
            if (ResolvedProperty == null)
            {
                // Dynamic property access
                // -----------------------
                // xxx = object.Set(x)

                // Load the left-hand side:
                var lhs = this.GetOperand(0);

                // -- Begin args for Prototype.SetPropertyValue --

                // Script engine (engine):
                EmitHelpers.LoadEngine(generator);

                // Put LHS object onto stack now (thisObj):
                lhs.GenerateCode(generator, optimizationInfo);

                // What type have we now got on the stack? Typically expected to be 'object'.
                Type lhsType = lhs.GetResultType(optimizationInfo);

                // Ensure it's boxed (still thisObj):
                EmitConversion.ToAny(generator, lhsType);

                // Load the property name and convert to a string.
                var rhs = this.GetOperand(1);
                rhs.GenerateCode(generator, optimizationInfo);
                EmitConversion.ToString(generator, rhs.GetResultType(optimizationInfo));

                if (rIU)
                {
                    // Output the value now (twice):
                    value(true);

                    // We now have [obj][value][value] on the stack.
                    // Calling the set method would fail (as it'll operate on the duplicated value).
                    // So, we have to pop one off and re-add it after.

                    // In order for SetValue to work, we need to shove the 2nd copy into a temp variable.
                    ILLocalVariable localVar = generator.DeclareVariable(valueType);

                    // Store into the local:
                    generator.StoreVariable(localVar);

                    // Set the value:
                    generator.Call(ReflectionHelpers.Object_SetPropertyValue);

                    // Load from the local:
                    generator.LoadVariable(localVar);
                }
                else
                {
                    // Output the value now:
                    value(false);

                    // Set the value:
                    generator.Call(ReflectionHelpers.Object_SetPropertyValue);
                }
            }
            else if (isArrayIndex)
            {
                // Array indexer
                // -------------
                // object[index] = x

                // Load the left-hand side and convert to an object instance.
                var lhs = this.GetOperand(0);
                lhs.GenerateCode(generator, optimizationInfo);

                // Load the right-hand side and convert to int32/uint32/whatever the indexer function wants.
                var rhs = this.GetOperand(1);
                rhs.GenerateCode(generator, optimizationInfo);

                // Convert the index:
                EmitConversion.Convert(generator, rhs.GetResultType(optimizationInfo), ResolvedProperty.FirstIndexType);

                // Call set:
                ResolvedProperty.Set(generator, optimizationInfo, rIU, valueType, value);
            }
            else
            {
                // Named property modification (e.g. x.property = y)
                // -------------------------------------------------

                if (ResolvedProperty.HasEngine)
                {
                    // Emit the engine ref:
                    EmitHelpers.LoadEngine(generator);
                }

                if (ResolvedProperty.HasAccessor)
                {
                    // Load the left-hand side:
                    var lhs = GetOperand(0);
                    lhs.GenerateCode(generator, optimizationInfo);
                }

                // Target object is now on the stack.

                // Set it:
                ResolvedProperty.Set(generator, optimizationInfo, rIU, valueType, value);
            }
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Pops the value from the top of the stack and stores it in the given local variable.
 /// </summary>
 /// <param name="variable"> The variable to store the value. </param>
 public abstract void StoreVariable(ILLocalVariable variable);
Ejemplo n.º 9
0
 /// <summary>
 /// Pushes the address of the given variable onto the stack.
 /// </summary>
 /// <param name="variable"> The variable whose address will be pushed. </param>
 public abstract void LoadAddressOfVariable(ILLocalVariable variable);
Ejemplo n.º 10
0
 /// <summary>
 /// Pushes the value of the given variable onto the stack.
 /// </summary>
 /// <param name="variable"> The variable whose value will be pushed. </param>
 public abstract void LoadVariable(ILLocalVariable variable);