Пример #1
0
        internal override PhpTypeCode Emit(CodeGenerator /*!*/ codeGenerator)
        {
            // emit tuple value
            foreach (OrderingClause clause in OrderingItems)
            {
                clause.Expression.Emit(codeGenerator);
            }
            LastItem.Emit(codeGenerator);

            // emit tuple creation
            ILEmitter il = codeGenerator.IL;

            for (int indirection = 0; indirection < OrderingItems.Count; indirection++)
            {
                il.Emit(OpCodes.Newobj, LinqExterns.GetTupleInfo(indirection).Constructor);
            }
            return(PhpTypeCode.Object);
        }
Пример #2
0
        internal override PhpTypeCode Emit(CodeGenerator /*!*/ codeGenerator)
        {
            ILEmitter il    = codeGenerator.IL;
            int       indir = this.count - 2;

            // cast object to correct tuple type:
            //   Tuple<Tuple<...Tuple<object, object>, .. >, object>, object>
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Castclass, LinqExterns.GetTupleInfo(indir).Type);

            // Find value at specified index (tup.First.First....First/Second);
            int timesFirst = index - ((index == count - 1) ? 1 : 0);

            for (int i = 0; i < timesFirst; i++)
            {
                il.Emit(OpCodes.Call, LinqExterns.GetTupleInfo(indir - i).SecondGetter);
            }

            // The last value is stored in Second, other values are stored in First
            il.Emit(OpCodes.Call, (index == count - 1)?
                    LinqExterns.GetTupleInfo(indir - timesFirst).SecondGetter:
                    LinqExterns.GetTupleInfo(indir - timesFirst).FirstGetter);
            return(PhpTypeCode.Object);
        }