| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- //
- // MethodBody.cs
- //
- // Author:
- // Jb Evain (jbevain@gmail.com)
- //
- // Copyright (c) 2008 - 2011 Jb Evain
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- using System;
- using System.Threading;
- using Mono.Collections.Generic;
- namespace Mono.Cecil.Cil
- {
- public sealed class MethodBody : IVariableDefinitionProvider
- {
- 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;
- Scope scope;
- 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()); }
- }
- public bool HasExceptionHandlers
- {
- get { return !Mixin.IsNullOrEmpty(exceptions); }
- }
- public Collection<ExceptionHandler> ExceptionHandlers
- {
- get { return exceptions ?? (exceptions = new Collection<ExceptionHandler>()); }
- }
- public bool HasVariables
- {
- get { return !Mixin.IsNullOrEmpty(variables); }
- }
- public Collection<VariableDefinition> Variables
- {
- get { return variables ?? (variables = new VariableDefinitionCollection()); }
- }
- public Scope Scope
- {
- get { return scope; }
- set { scope = value; }
- }
- public ParameterDefinition ThisParameter
- {
- get
- {
- if (method == null || method.DeclaringType == null)
- throw new NotSupportedException();
- if (!method.HasThis)
- return null;
- if (this_parameter == null)
- this_parameter = ThisParameterFor(method);
- return this_parameter;
- }
- }
- static ParameterDefinition ThisParameterFor(MethodDefinition method)
- {
- var declaring_type = method.DeclaringType;
- var type = declaring_type.IsValueType || declaring_type.IsPrimitive
- ? new PointerType(declaring_type)
- : declaring_type as TypeReference;
- return new ParameterDefinition(type, method);
- }
- public MethodBody(MethodDefinition method)
- {
- this.method = method;
- }
- public ILProcessor GetILProcessor()
- {
- return new ILProcessor(this);
- }
- }
- public interface IVariableDefinitionProvider
- {
- bool HasVariables { get; }
- Collection<VariableDefinition> Variables { get; }
- }
- 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>
- {
- internal InstructionCollection()
- {
- }
- internal InstructionCollection(int capacity)
- : base(capacity)
- {
- }
- 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;
- item.previous = null;
- item.next = null;
- }
- }
- }
|