/// <summary> /// Emit IL instructions that load the value of array item at the stack and make a copy /// of it if necessary. /// </summary> /// <param name="codeGenerator"></param> /// <returns></returns> /// <remarks>This node represents the item x=>&y in PHP notation. See <see cref="PHP.Core.AST.ArrayEx"/> /// for more details.</remarks> internal override PhpTypeCode EmitValue(CodeGenerator codeGenerator) { Debug.Assert(refToGet != null); Statistics.AST.AddNode("Array.RefItem"); // Emit refToGet return(refToGet.Emit(codeGenerator)); }
/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/> internal override PhpTypeCode Emit(CodeGenerator codeGenerator) { Statistics.AST.AddNode("IncDecEx"); Debug.Assert(access == AccessType.Read || access == AccessType.None); AccessType old_selector = codeGenerator.AccessSelector; PhpTypeCode returned_typecode = PhpTypeCode.Void; codeGenerator.AccessSelector = AccessType.Write; codeGenerator.ChainBuilder.Create(); variable.Emit(codeGenerator); codeGenerator.AccessSelector = AccessType.Read; codeGenerator.ChainBuilder.Create(); variable.Emit(codeGenerator); codeGenerator.ChainBuilder.End(); LocalBuilder old_value = null; if (access == AccessType.Read && post) { old_value = codeGenerator.IL.DeclareLocal(Types.Object[0]); // Save variable's value for later use codeGenerator.IL.Emit(OpCodes.Dup); codeGenerator.IL.Stloc(old_value); } if (this.inc) { // Increment codeGenerator.IL.Emit(OpCodes.Call, Methods.Operators.Increment); } else { // Decrement codeGenerator.IL.Emit(OpCodes.Call, Methods.Operators.Decrement); } codeGenerator.AccessSelector = AccessType.Write; if (access == AccessType.Read) { if (post) { variable.EmitAssign(codeGenerator); // Load original value (as was before operation) codeGenerator.IL.Ldloc(old_value); } else { old_value = codeGenerator.IL.DeclareLocal(Types.Object[0]); // pre-incrementation // Load variable's value after operation codeGenerator.IL.Emit(OpCodes.Dup); codeGenerator.IL.Stloc(old_value); variable.EmitAssign(codeGenerator); codeGenerator.IL.Ldloc(old_value); } returned_typecode = PhpTypeCode.Object; } else { variable.EmitAssign(codeGenerator); } codeGenerator.AccessSelector = old_selector; codeGenerator.ChainBuilder.End(); return(returned_typecode); }