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); }
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); }