Esempio n. 1
0
        /// <summary>
        /// Emits code to load variable onto the evaluation stack. Supports operators chaining.
        /// </summary>
        /// <param name="codeGenerator">A geenrator.</param>
        /// <param name="itemGetterKind">Whether to load for "get", "isset", or "empty".</param>
        private PhpTypeCode EmitNodeRead(CodeGenerator /*!*/ codeGenerator, Operators.GetItemKinds itemGetterKind)
        {
            ChainBuilder chain = codeGenerator.ChainBuilder;
            PhpTypeCode  result;

            if (chain.IsArrayItem)
            {
                // we are in the array subchain //

                // 3: a_[x]_[x]
                chain.Lengthen();                 // for []
                result = chain.EmitGetItem(array, index, itemGetterKind);
                return(result);
            }

            // 1,2,4,5,6,7
            if (chain.IsMember)
            {
                // we are in the field chain //

                // 4, 5
                if (this.isMemberOf != null)
                {
                    // we are in the middle of the field chain //

                    // 5: ...->a[]->...

                    // Lengthen chain for isMemberOf
                    chain.Lengthen();                     // for hop over ->

                    isMemberOf.Emit(codeGenerator);

                    // Lengthen chain for own []
                    chain.Lengthen();

                    chain.IsArrayItem  = true;
                    chain.IsLastMember = false;

                    result = chain.EmitGetItem(array, index, itemGetterKind);

                    chain.IsArrayItem = false;
                    return(result);
                }
                else
                {
                    // we are at the beginning of the field chain //

                    // 4: a[x]->...
                    // Lengthen chain for itself
                    chain.Lengthen();                     // for own []
                    chain.IsArrayItem  = true;
                    chain.IsLastMember = true;

                    result = chain.EmitGetItem(array, index, itemGetterKind);

                    chain.IsArrayItem = false;
                    return(result);
                }
            }

            // 1, 2, 6, 7
            if (this.isMemberOf != null)
            {
                // last node of the field chain //

                // 6 , 7: ...->a[]_[]_ , ...->a_[]_
                bool quiet_read = chain.QuietRead;
                chain.Create();
                chain.Begin();
                chain.QuietRead = quiet_read;
                chain.Lengthen();                 // for hop over ->

                isMemberOf.Emit(codeGenerator);

                // let's emit the array subchain followed by the GetItem:
                chain.IsArrayItem  = true;
                chain.IsLastMember = false;
                result             = chain.EmitGetItem(array, index, itemGetterKind);
                chain.IsArrayItem  = false;
                chain.End();
                return(result);
            }

            // 1, 2
            if (array is ItemUse || array is DirectStFldUse || array is IndirectStFldUse)
            {
                // we are at the beginning of the field chain //

                // 2: a[]_[]_
                bool quiet_read = chain.QuietRead;
                chain.Create();
                chain.Begin();
                chain.QuietRead    = quiet_read;
                chain.IsArrayItem  = true;
                chain.IsLastMember = true;

                result = chain.EmitGetItem(array, index, itemGetterKind);

                chain.IsArrayItem = false;
                chain.End();
                return(result);
            }

            // no chains //

            // 1: a_[x]_
            chain.IsArrayItem  = true;
            chain.IsLastMember = true;
            result             = chain.EmitGetItem(array, index, itemGetterKind);
            chain.IsArrayItem  = false;
            return(result);
        }