예제 #1
0
        /// <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=>&amp;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));
        }
예제 #2
0
        /// <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);
        }