protected internal override void VisitLdElema(LdElema inst) { base.VisitLdElema(inst); CleanUpArrayIndices(inst.Indices); if (IndexRangeTransform.HandleLdElema(inst, context)) { return; } }
/// <summary> /// Called by expression transforms. /// Handles the `array[System.Index]` cases. /// </summary> public static bool HandleLdElema(LdElema ldelema, ILTransformContext context) { if (!context.Settings.Ranges) { return(false); } if (!ldelema.Array.MatchLdLoc(out ILVariable array)) { return(false); } if (ldelema.Indices.Count != 1) { return(false); // the index/range feature doesn't support multi-dimensional arrays } var index = ldelema.Indices[0]; if (index is CallInstruction call && call.Method.Name == "GetOffset" && call.Method.DeclaringType.IsKnownType(KnownTypeCode.Index)) { // ldelema T(ldloc array, call GetOffset(..., ldlen.i4(ldloc array))) // -> withsystemindex.ldelema T(ldloc array, ...) if (call.Arguments.Count != 2) { return(false); } if (!(call.Arguments[1].MatchLdLen(StackType.I4, out var arrayLoad) && arrayLoad.MatchLdLoc(array))) { return(false); } context.Step("ldelema with System.Index", ldelema); foreach (var node in call.Arguments[1].Descendants) { ldelema.AddILRange(node); } ldelema.AddILRange(call); ldelema.WithSystemIndex = true; // The method call had a `ref System.Index` argument for the this pointer, but we want a `System.Index` by-value. ldelema.Indices[0] = new LdObj(call.Arguments[0], call.Method.DeclaringType); return(true); }
protected internal override void VisitLdElema(LdElema inst) { base.VisitLdElema(inst); CleanUpArrayIndices(inst.Indices); }