/// <summary> /// Pushes the value of the reference onto the stack. /// </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="throwIfUnresolvable"> <c>true</c> to throw a ReferenceError exception if /// the name is unresolvable; <c>false</c> to output <c>null</c> instead. </param> public void GenerateGet(ILGenerator generator, OptimizationInfo optimizationInfo, bool throwIfUnresolvable) { string propertyName = null; TypeOfMemberAccess memberAccessType = DetermineTypeOfMemberAccess(optimizationInfo, out propertyName); if (memberAccessType == TypeOfMemberAccess.ArrayIndex) { // Array indexer // ------------- // xxx = object[index] // Call the indexer. generator.Call(ReflectionHelpers.ObjectInstance_Indexer_UInt); } else if (memberAccessType == TypeOfMemberAccess.Static) { // Named property access (e.g. x = y.property) // ------------------------------------------- // Use a PropertyReference to speed up access if we are inside a loop. if (optimizationInfo.InsideLoop) { // C# // if (propertyReference != null) // propertyReference = new PropertyReference("property"); // value = object.GetPropertyValue(propertyReference) ILLocalVariable propertyReference = optimizationInfo.GetPropertyReferenceVariable(generator, propertyName); generator.LoadVariable(propertyReference); generator.Duplicate(); var afterIf = generator.CreateLabel(); generator.BranchIfNotNull(afterIf); generator.Pop(); generator.LoadString(propertyName); generator.NewObject(ReflectionHelpers.PropertyName_Constructor); generator.Duplicate(); generator.StoreVariable(propertyReference); generator.DefineLabelPosition(afterIf); generator.Call(ReflectionHelpers.ObjectInstance_GetPropertyValue_PropertyReference); } else { // C# // value = object.GetPropertyValue("property") generator.LoadString(propertyName); generator.Call(ReflectionHelpers.ObjectInstance_Indexer_Object); } } else { // Dynamic property access // ----------------------- // x = y.GetPropertyValue("property") generator.Call(ReflectionHelpers.ObjectInstance_Indexer_Object); } }
/// <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> public void GenerateSet(ILGenerator generator, OptimizationInfo optimizationInfo, PrimitiveType valueType) { string propertyName = null; TypeOfMemberAccess memberAccessType = DetermineTypeOfMemberAccess(optimizationInfo, out propertyName); if (memberAccessType == TypeOfMemberAccess.ArrayIndex) { // Array indexer // ------------- // xxx = object[index] // Call the indexer. EmitConversion.ToAny(generator, valueType); generator.LoadBoolean(optimizationInfo.StrictMode); generator.Call(ReflectionHelpers.ObjectInstance_SetPropertyValue_Int); generator.Pop(); } else if (memberAccessType == TypeOfMemberAccess.Static) { // Named property modification (e.g. object.property = value) // ---------------------------------------------------------- // object.SetPropertyValue(property, value, strictMode) // Convert the value to an object and store it in a temporary variable. var value = generator.CreateTemporaryVariable(typeof(object)); EmitConversion.ToAny(generator, valueType); generator.StoreVariable(value); // Use a PropertyReference to speed up access if we are inside a loop. if (optimizationInfo.InsideLoop) { ILLocalVariable propertyReference = optimizationInfo.GetPropertyReferenceVariable(generator, propertyName); generator.LoadVariable(propertyReference); generator.Duplicate(); var afterIf = generator.CreateLabel(); generator.BranchIfNotNull(afterIf); generator.Pop(); generator.LoadString(propertyName); generator.NewObject(ReflectionHelpers.PropertyName_Constructor); generator.Duplicate(); generator.StoreVariable(propertyReference); generator.DefineLabelPosition(afterIf); generator.LoadVariable(value); generator.LoadBoolean(optimizationInfo.StrictMode); generator.Call(ReflectionHelpers.ObjectInstance_SetPropertyValue_PropertyReference); generator.Pop(); } else { generator.LoadString(propertyName); generator.LoadVariable(value); generator.LoadBoolean(optimizationInfo.StrictMode); generator.Call(ReflectionHelpers.ObjectInstance_SetPropertyValue_Object); generator.Pop(); } generator.ReleaseTemporaryVariable(value); } else { // Dynamic property access // ----------------------- // object.SetPropertyValue(property, value, strictMode) EmitConversion.ToAny(generator, valueType); generator.LoadBoolean(optimizationInfo.StrictMode); generator.Call(ReflectionHelpers.ObjectInstance_SetPropertyValue_Object); generator.Pop(); } }