public void AddPrefix(AstExpressionPrefix prefix) { var arr = Prefixes; if (arr == null) { arr = new AstExpressionPrefix[1]; } else { Array.Resize(ref arr, arr.Length + 1); } arr[arr.Length - 1] = prefix; Prefixes = arr; }
private List<AstNode> ConvertToAst(IEnumerable<ByteCode> body) { var ast = new List<AstNode>(); // Convert stack-based IL code to ILAst tree foreach (var byteCode in body) { var ilRange = new InstructionRange(byteCode.Offset, byteCode.EndOffset); if (byteCode.StackBefore == null) { // Unreachable code continue; } var expr = new AstExpression(byteCode.SequencePoint, byteCode.Code, byteCode.Operand); expr.ILRanges.Add(ilRange); if (byteCode.Prefixes != null && byteCode.Prefixes.Length > 0) { var prefixes = new AstExpressionPrefix[byteCode.Prefixes.Length]; for (var i = 0; i < prefixes.Length; i++) { var operand = byteCode.Prefixes[i].Operand; if (operand is FieldReference) { operand = XBuilder.AsFieldReference(module, (FieldReference) operand); } else if (operand is MethodReference) { operand = XBuilder.AsMethodReference(module, (MethodReference)operand); } else if (operand is TypeReference) { operand = XBuilder.AsTypeReference(module, (TypeReference) operand); } prefixes[i] = new AstExpressionPrefix((AstCode)byteCode.Prefixes[i].OpCode.Code, operand); } expr.Prefixes = prefixes; } // Label for this instruction if (byteCode.Label != null) { ast.Add(byteCode.Label); } // Reference arguments using temporary variables var popCount = byteCode.PopCount ?? byteCode.StackBefore.Length; for (var i = byteCode.StackBefore.Length - popCount; i < byteCode.StackBefore.Length; i++) { var slot = byteCode.StackBefore[i]; expr.Arguments.Add(new AstExpression(byteCode.SequencePoint, AstCode.Ldloc, slot.LoadFrom)); } // Store the result to temporary variable(s) if needed if (byteCode.StoreTo == null || byteCode.StoreTo.Count == 0) { ast.Add(expr); } else if (byteCode.StoreTo.Count == 1) { ast.Add(new AstExpression(byteCode.SequencePoint, AstCode.Stloc, byteCode.StoreTo[0], expr)); } else { var tmpVar = new AstGeneratedVariable("expr_" + byteCode.Offset.ToString("X2"), byteCode.StoreTo.Select(x => x.OriginalName).FirstOrDefault()); ast.Add(new AstExpression(byteCode.SequencePoint, AstCode.Stloc, tmpVar, expr)); foreach (var storeTo in byteCode.StoreTo.AsEnumerable().Reverse()) { ast.Add(new AstExpression(byteCode.SequencePoint, AstCode.Stloc, storeTo, new AstExpression(byteCode.SequencePoint, AstCode.Ldloc, tmpVar))); } } } return ast; }