| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- //
- // Author:
- // Jb Evain (jbevain@gmail.com)
- //
- // Copyright (c) 2008 - 2015 Jb Evain
- // Copyright (c) 2008 - 2011 Novell, Inc.
- //
- // Licensed under the MIT/X11 license.
- //
- using System;
- using System.Threading;
- using Mono.Collections.Generic;
- namespace Mono.Cecil.Cil {
- public sealed class MethodBody {
- readonly internal MethodDefinition method;
- internal ParameterDefinition this_parameter;
- internal int max_stack_size;
- internal int code_size;
- internal bool init_locals;
- internal MetadataToken local_var_token;
- internal Collection<Instruction> instructions;
- internal Collection<ExceptionHandler> exceptions;
- internal Collection<VariableDefinition> variables;
- public MethodDefinition Method {
- get { return method; }
- }
- public int MaxStackSize {
- get { return max_stack_size; }
- set { max_stack_size = value; }
- }
- public int CodeSize {
- get { return code_size; }
- }
- public bool InitLocals {
- get { return init_locals; }
- set { init_locals = value; }
- }
- public MetadataToken LocalVarToken {
- get { return local_var_token; }
- set { local_var_token = value; }
- }
- public Collection<Instruction> Instructions {
- get { return instructions ?? (instructions = new InstructionCollection (method)); }
- }
- public bool HasExceptionHandlers {
- get { return !exceptions.IsNullOrEmpty (); }
- }
- public Collection<ExceptionHandler> ExceptionHandlers {
- get { return exceptions ?? (exceptions = new Collection<ExceptionHandler> ()); }
- }
- public bool HasVariables {
- get { return !variables.IsNullOrEmpty (); }
- }
- public Collection<VariableDefinition> Variables {
- get { return variables ?? (variables = new VariableDefinitionCollection ()); }
- }
- public ParameterDefinition ThisParameter {
- get {
- if (method == null || method.DeclaringType == null)
- throw new NotSupportedException ();
- if (!method.HasThis)
- return null;
- if (this_parameter == null)
- Interlocked.CompareExchange (ref this_parameter, CreateThisParameter (method), null);
- return this_parameter;
- }
- }
- static ParameterDefinition CreateThisParameter (MethodDefinition method)
- {
- var parameter_type = method.DeclaringType as TypeReference;
- if (parameter_type.HasGenericParameters) {
- var instance = new GenericInstanceType (parameter_type);
- for (int i = 0; i < parameter_type.GenericParameters.Count; i++)
- instance.GenericArguments.Add (parameter_type.GenericParameters [i]);
- parameter_type = instance;
- }
- if (parameter_type.IsValueType || parameter_type.IsPrimitive)
- parameter_type = new ByReferenceType (parameter_type);
- return new ParameterDefinition (parameter_type, method);
- }
- public MethodBody (MethodDefinition method)
- {
- this.method = method;
- }
- public ILProcessor GetILProcessor ()
- {
- return new ILProcessor (this);
- }
- }
- sealed class VariableDefinitionCollection : Collection<VariableDefinition> {
- internal VariableDefinitionCollection ()
- {
- }
- internal VariableDefinitionCollection (int capacity)
- : base (capacity)
- {
- }
- protected override void OnAdd (VariableDefinition item, int index)
- {
- item.index = index;
- }
- protected override void OnInsert (VariableDefinition item, int index)
- {
- item.index = index;
- for (int i = index; i < size; i++)
- items [i].index = i + 1;
- }
- protected override void OnSet (VariableDefinition item, int index)
- {
- item.index = index;
- }
- protected override void OnRemove (VariableDefinition item, int index)
- {
- item.index = -1;
- for (int i = index + 1; i < size; i++)
- items [i].index = i - 1;
- }
- }
- class InstructionCollection : Collection<Instruction> {
- readonly MethodDefinition method;
- internal InstructionCollection (MethodDefinition method)
- {
- this.method = method;
- }
- internal InstructionCollection (MethodDefinition method, int capacity)
- : base (capacity)
- {
- this.method = method;
- }
- protected override void OnAdd (Instruction item, int index)
- {
- if (index == 0)
- return;
- var previous = items [index - 1];
- previous.next = item;
- item.previous = previous;
- }
- protected override void OnInsert (Instruction item, int index)
- {
- if (size == 0)
- return;
- var current = items [index];
- if (current == null) {
- var last = items [index - 1];
- last.next = item;
- item.previous = last;
- return;
- }
- var previous = current.previous;
- if (previous != null) {
- previous.next = item;
- item.previous = previous;
- }
- current.previous = item;
- item.next = current;
- }
- protected override void OnSet (Instruction item, int index)
- {
- var current = items [index];
- item.previous = current.previous;
- item.next = current.next;
- current.previous = null;
- current.next = null;
- }
- protected override void OnRemove (Instruction item, int index)
- {
- var previous = item.previous;
- if (previous != null)
- previous.next = item.next;
- var next = item.next;
- if (next != null)
- next.previous = item.previous;
- RemoveSequencePoint (item);
- item.previous = null;
- item.next = null;
- }
- void RemoveSequencePoint (Instruction instruction)
- {
- var debug_info = method.debug_info;
- if (debug_info == null || !debug_info.HasSequencePoints)
- return;
- var sequence_points = debug_info.sequence_points;
- for (int i = 0; i < sequence_points.Count; i++) {
- if (sequence_points [i].Offset == instruction.offset) {
- sequence_points.RemoveAt (i);
- return;
- }
- }
- }
- }
- }
|