using System;
using System.Collections;
using System.Diagnostics.SymbolStore;
using System.Runtime.InteropServices;
namespace System.Reflection.Emit
{
/// Generates Microsoft intermediate language (MSIL) instructions.
// Token: 0x020001FC RID: 508
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
[ComDefaultInterface(typeof(_ILGenerator))]
public class ILGenerator : _ILGenerator
{
// Token: 0x06001A9F RID: 6815 RVA: 0x00063580 File Offset: 0x00061780
internal ILGenerator(Module m, TokenGenerator token_gen, int size)
{
if (size < 0)
{
size = 128;
}
this.code = new byte[size];
this.token_fixups = new ILTokenInfo[8];
this.module = m;
this.token_gen = token_gen;
}
/// Maps a set of names to a corresponding set of dispatch identifiers.
/// Reserved for future use. Must be IID_NULL.
/// Passed-in array of names to be mapped.
/// Count of the names to be mapped.
/// The locale context in which to interpret the names.
/// Caller-allocated array that receives the IDs corresponding to the names.
/// The method is called late-bound using the COM IDispatch interface.
// Token: 0x06001AA1 RID: 6817 RVA: 0x000635DC File Offset: 0x000617DC
void _ILGenerator.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
{
throw new NotImplementedException();
}
/// Retrieves the type information for an object, which can then be used to get the type information for an interface.
/// The type information to return.
/// The locale identifier for the type information.
/// Receives a pointer to the requested type information object.
/// The method is called late-bound using the COM IDispatch interface.
// Token: 0x06001AA2 RID: 6818 RVA: 0x000635E4 File Offset: 0x000617E4
void _ILGenerator.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
{
throw new NotImplementedException();
}
/// Retrieves the number of type information interfaces that an object provides (either 0 or 1).
/// Points to a location that receives the number of type information interfaces provided by the object.
/// The method is called late-bound using the COM IDispatch interface.
// Token: 0x06001AA3 RID: 6819 RVA: 0x000635EC File Offset: 0x000617EC
void _ILGenerator.GetTypeInfoCount(out uint pcTInfo)
{
throw new NotImplementedException();
}
/// Provides access to properties and methods exposed by an object.
/// Identifies the member.
/// Reserved for future use. Must be IID_NULL.
/// The locale context in which to interpret arguments.
/// Flags describing the context of the call.
/// Pointer to a structure containing an array of arguments, an array of argument DISPIDs for named arguments, and counts for the number of elements in the arrays.
/// Pointer to the location where the result is to be stored.
/// Pointer to a structure that contains exception information.
/// The index of the first argument that has an error.
/// The method is called late-bound using the COM IDispatch interface.
// Token: 0x06001AA4 RID: 6820 RVA: 0x000635F4 File Offset: 0x000617F4
void _ILGenerator.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
{
throw new NotImplementedException();
}
// Token: 0x06001AA5 RID: 6821 RVA: 0x000635FC File Offset: 0x000617FC
private void add_token_fixup(MemberInfo mi)
{
if (this.num_token_fixups == this.token_fixups.Length)
{
ILTokenInfo[] array = new ILTokenInfo[this.num_token_fixups * 2];
this.token_fixups.CopyTo(array, 0);
this.token_fixups = array;
}
this.token_fixups[this.num_token_fixups].member = mi;
this.token_fixups[this.num_token_fixups++].code_pos = this.code_len;
}
// Token: 0x06001AA6 RID: 6822 RVA: 0x0006367C File Offset: 0x0006187C
private void make_room(int nbytes)
{
if (this.code_len + nbytes < this.code.Length)
{
return;
}
byte[] array = new byte[(this.code_len + nbytes) * 2 + 128];
Array.Copy(this.code, 0, array, 0, this.code.Length);
this.code = array;
}
// Token: 0x06001AA7 RID: 6823 RVA: 0x000636D4 File Offset: 0x000618D4
private void emit_int(int val)
{
this.code[this.code_len++] = (byte)(val & 255);
this.code[this.code_len++] = (byte)((val >> 8) & 255);
this.code[this.code_len++] = (byte)((val >> 16) & 255);
this.code[this.code_len++] = (byte)((val >> 24) & 255);
}
// Token: 0x06001AA8 RID: 6824 RVA: 0x0006376C File Offset: 0x0006196C
private void ll_emit(OpCode opcode)
{
if (opcode.Size == 2)
{
this.code[this.code_len++] = opcode.op1;
}
this.code[this.code_len++] = opcode.op2;
switch (opcode.StackBehaviourPush)
{
case StackBehaviour.Push1:
case StackBehaviour.Pushi:
case StackBehaviour.Pushi8:
case StackBehaviour.Pushr4:
case StackBehaviour.Pushr8:
case StackBehaviour.Pushref:
case StackBehaviour.Varpush:
this.cur_stack++;
break;
case StackBehaviour.Push1_push1:
this.cur_stack += 2;
break;
}
if (this.max_stack < this.cur_stack)
{
this.max_stack = this.cur_stack;
}
switch (opcode.StackBehaviourPop)
{
case StackBehaviour.Pop1:
case StackBehaviour.Popi:
case StackBehaviour.Popref:
this.cur_stack--;
break;
case StackBehaviour.Pop1_pop1:
case StackBehaviour.Popi_pop1:
case StackBehaviour.Popi_popi:
case StackBehaviour.Popi_popi8:
case StackBehaviour.Popi_popr4:
case StackBehaviour.Popi_popr8:
case StackBehaviour.Popref_pop1:
case StackBehaviour.Popref_popi:
this.cur_stack -= 2;
break;
case StackBehaviour.Popi_popi_popi:
case StackBehaviour.Popref_popi_popi:
case StackBehaviour.Popref_popi_popi8:
case StackBehaviour.Popref_popi_popr4:
case StackBehaviour.Popref_popi_popr8:
case StackBehaviour.Popref_popi_popref:
this.cur_stack -= 3;
break;
}
}
// Token: 0x06001AA9 RID: 6825 RVA: 0x000638FC File Offset: 0x00061AFC
private static int target_len(OpCode opcode)
{
if (opcode.OperandType == OperandType.InlineBrTarget)
{
return 4;
}
return 1;
}
// Token: 0x06001AAA RID: 6826 RVA: 0x00063910 File Offset: 0x00061B10
private void InternalEndClause()
{
int num = this.ex_handlers[this.cur_block].LastClauseType();
switch (num + 1)
{
case 0:
case 1:
case 2:
this.Emit(OpCodes.Leave, this.ex_handlers[this.cur_block].end);
break;
case 3:
case 5:
this.Emit(OpCodes.Endfinally);
break;
}
}
/// Begins a catch block.
/// The object that represents the exception.
/// The catch block is within a filtered exception.
///
/// is null, and the exception filter block has not returned a value that indicates that finally blocks should be run until this catch block is located.
/// The Microsoft intermediate language (MSIL) being generated is not currently in an exception block.
// Token: 0x06001AAB RID: 6827 RVA: 0x00063990 File Offset: 0x00061B90
public virtual void BeginCatchBlock(Type exceptionType)
{
if (this.open_blocks == null)
{
this.open_blocks = new Stack(2);
}
if (this.open_blocks.Count <= 0)
{
throw new NotSupportedException("Not in an exception block");
}
if (exceptionType != null && exceptionType.IsUserType)
{
throw new NotSupportedException("User defined subclasses of System.Type are not yet supported.");
}
if (this.ex_handlers[this.cur_block].LastClauseType() == -1)
{
if (exceptionType != null)
{
throw new ArgumentException("Do not supply an exception type for filter clause");
}
this.Emit(OpCodes.Endfilter);
this.ex_handlers[this.cur_block].PatchFilterClause(this.code_len);
}
else
{
this.InternalEndClause();
this.ex_handlers[this.cur_block].AddCatch(exceptionType, this.code_len);
}
this.cur_stack = 1;
if (this.max_stack < this.cur_stack)
{
this.max_stack = this.cur_stack;
}
}
/// Begins an exception block for a filtered exception.
/// The Microsoft intermediate language (MSIL) being generated is not currently in an exception block. -or-This belongs to a .
// Token: 0x06001AAC RID: 6828 RVA: 0x00063A8C File Offset: 0x00061C8C
public virtual void BeginExceptFilterBlock()
{
if (this.open_blocks == null)
{
this.open_blocks = new Stack(2);
}
if (this.open_blocks.Count <= 0)
{
throw new NotSupportedException("Not in an exception block");
}
this.InternalEndClause();
this.ex_handlers[this.cur_block].AddFilter(this.code_len);
}
/// Begins an exception block for a non-filtered exception.
/// The label for the end of the block. This will leave you in the correct place to execute finally blocks or to finish the try.
// Token: 0x06001AAD RID: 6829 RVA: 0x00063AF0 File Offset: 0x00061CF0
public virtual Label BeginExceptionBlock()
{
if (this.open_blocks == null)
{
this.open_blocks = new Stack(2);
}
if (this.ex_handlers != null)
{
this.cur_block = this.ex_handlers.Length;
ILExceptionInfo[] array = new ILExceptionInfo[this.cur_block + 1];
Array.Copy(this.ex_handlers, array, this.cur_block);
this.ex_handlers = array;
}
else
{
this.ex_handlers = new ILExceptionInfo[1];
this.cur_block = 0;
}
this.open_blocks.Push(this.cur_block);
this.ex_handlers[this.cur_block].start = this.code_len;
return this.ex_handlers[this.cur_block].end = this.DefineLabel();
}
/// Begins an exception fault block in the Microsoft intermediate language (MSIL) stream.
/// The MSIL being generated is not currently in an exception block. -or-This belongs to a .
// Token: 0x06001AAE RID: 6830 RVA: 0x00063BC0 File Offset: 0x00061DC0
public virtual void BeginFaultBlock()
{
if (this.open_blocks == null)
{
this.open_blocks = new Stack(2);
}
if (this.open_blocks.Count <= 0)
{
throw new NotSupportedException("Not in an exception block");
}
if (this.ex_handlers[this.cur_block].LastClauseType() == -1)
{
this.Emit(OpCodes.Leave, this.ex_handlers[this.cur_block].end);
this.ex_handlers[this.cur_block].PatchFilterClause(this.code_len);
}
this.InternalEndClause();
this.ex_handlers[this.cur_block].AddFault(this.code_len);
}
/// Begins a finally block in the Microsoft intermediate language (MSIL) instruction stream.
/// The MSIL being generated is not currently in an exception block.
// Token: 0x06001AAF RID: 6831 RVA: 0x00063C7C File Offset: 0x00061E7C
public virtual void BeginFinallyBlock()
{
if (this.open_blocks == null)
{
this.open_blocks = new Stack(2);
}
if (this.open_blocks.Count <= 0)
{
throw new NotSupportedException("Not in an exception block");
}
this.InternalEndClause();
if (this.ex_handlers[this.cur_block].LastClauseType() == -1)
{
this.Emit(OpCodes.Leave, this.ex_handlers[this.cur_block].end);
this.ex_handlers[this.cur_block].PatchFilterClause(this.code_len);
}
this.ex_handlers[this.cur_block].AddFinally(this.code_len);
}
/// Begins a lexical scope.
/// This belongs to a .
// Token: 0x06001AB0 RID: 6832 RVA: 0x00063D38 File Offset: 0x00061F38
public virtual void BeginScope()
{
}
/// Declares a local variable of the specified type.
/// The declared local variable.
/// A object that represents the type of the local variable.
///
/// is null.
/// The containing type has been created by the method.
// Token: 0x06001AB1 RID: 6833 RVA: 0x00063D3C File Offset: 0x00061F3C
public virtual LocalBuilder DeclareLocal(Type localType)
{
return this.DeclareLocal(localType, false);
}
/// Declares a local variable of the specified type, optionally pinning the object referred to by the variable.
/// A object that represents the local variable.
/// A object that represents the type of the local variable.
/// true to pin the object in memory; otherwise, false.
///
/// is null.
/// The containing type has been created by the method.-or-The method body of the enclosing method has been created by the method.
/// The method with which this is associated is not represented by a .
// Token: 0x06001AB2 RID: 6834 RVA: 0x00063D48 File Offset: 0x00061F48
public virtual LocalBuilder DeclareLocal(Type localType, bool pinned)
{
if (localType == null)
{
throw new ArgumentNullException("localType");
}
if (localType.IsUserType)
{
throw new NotSupportedException("User defined subclasses of System.Type are not yet supported.");
}
LocalBuilder localBuilder = new LocalBuilder(localType, this);
localBuilder.is_pinned = pinned;
if (this.locals != null)
{
LocalBuilder[] array = new LocalBuilder[this.locals.Length + 1];
Array.Copy(this.locals, array, this.locals.Length);
array[this.locals.Length] = localBuilder;
this.locals = array;
}
else
{
this.locals = new LocalBuilder[1];
this.locals[0] = localBuilder;
}
localBuilder.position = (ushort)(this.locals.Length - 1);
return localBuilder;
}
/// Declares a new label.
/// Returns a new label that can be used as a token for branching.
// Token: 0x06001AB3 RID: 6835 RVA: 0x00063DF8 File Offset: 0x00061FF8
public virtual Label DefineLabel()
{
if (this.labels == null)
{
this.labels = new ILGenerator.LabelData[4];
}
else if (this.num_labels >= this.labels.Length)
{
ILGenerator.LabelData[] array = new ILGenerator.LabelData[this.labels.Length * 2];
Array.Copy(this.labels, array, this.labels.Length);
this.labels = array;
}
this.labels[this.num_labels] = new ILGenerator.LabelData(-1, 0);
return new Label(this.num_labels++);
}
/// Puts the specified instruction onto the stream of instructions.
/// The Microsoft Intermediate Language (MSIL) instruction to be put onto the stream.
// Token: 0x06001AB4 RID: 6836 RVA: 0x00063E94 File Offset: 0x00062094
public virtual void Emit(OpCode opcode)
{
this.make_room(2);
this.ll_emit(opcode);
}
/// Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions.
/// The MSIL instruction to be put onto the stream.
/// The character argument pushed onto the stream immediately after the instruction.
// Token: 0x06001AB5 RID: 6837 RVA: 0x00063EA4 File Offset: 0x000620A4
public virtual void Emit(OpCode opcode, byte arg)
{
this.make_room(3);
this.ll_emit(opcode);
this.code[this.code_len++] = arg;
}
/// Puts the specified instruction and metadata token for the specified constructor onto the Microsoft intermediate language (MSIL) stream of instructions.
/// The MSIL instruction to be emitted onto the stream.
/// A ConstructorInfo representing a constructor.
// Token: 0x06001AB6 RID: 6838 RVA: 0x00063ED8 File Offset: 0x000620D8
[ComVisible(true)]
public virtual void Emit(OpCode opcode, ConstructorInfo con)
{
int token = this.token_gen.GetToken(con);
this.make_room(6);
this.ll_emit(opcode);
if (con.DeclaringType.Module == this.module)
{
this.add_token_fixup(con);
}
this.emit_int(token);
if (opcode.StackBehaviourPop == StackBehaviour.Varpop)
{
this.cur_stack -= con.GetParameterCount();
}
}
/// Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.
/// The MSIL instruction to be put onto the stream. Defined in the OpCodes enumeration.
/// The numerical argument pushed onto the stream immediately after the instruction.
// Token: 0x06001AB7 RID: 6839 RVA: 0x00063F48 File Offset: 0x00062148
public virtual void Emit(OpCode opcode, double arg)
{
byte[] bytes = BitConverter.GetBytes(arg);
this.make_room(10);
this.ll_emit(opcode);
if (BitConverter.IsLittleEndian)
{
Array.Copy(bytes, 0, this.code, this.code_len, 8);
this.code_len += 8;
}
else
{
this.code[this.code_len++] = bytes[7];
this.code[this.code_len++] = bytes[6];
this.code[this.code_len++] = bytes[5];
this.code[this.code_len++] = bytes[4];
this.code[this.code_len++] = bytes[3];
this.code[this.code_len++] = bytes[2];
this.code[this.code_len++] = bytes[1];
this.code[this.code_len++] = bytes[0];
}
}
/// Puts the specified instruction and metadata token for the specified field onto the Microsoft intermediate language (MSIL) stream of instructions.
/// The MSIL instruction to be emitted onto the stream.
/// A FieldInfo representing a field.
// Token: 0x06001AB8 RID: 6840 RVA: 0x00064074 File Offset: 0x00062274
public virtual void Emit(OpCode opcode, FieldInfo field)
{
int token = this.token_gen.GetToken(field);
this.make_room(6);
this.ll_emit(opcode);
if (field.DeclaringType.Module == this.module)
{
this.add_token_fixup(field);
}
this.emit_int(token);
}
/// Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.
/// The MSIL instruction to be emitted onto the stream.
/// The Int argument pushed onto the stream immediately after the instruction.
// Token: 0x06001AB9 RID: 6841 RVA: 0x000640C0 File Offset: 0x000622C0
public virtual void Emit(OpCode opcode, short arg)
{
this.make_room(4);
this.ll_emit(opcode);
this.code[this.code_len++] = (byte)(arg & 255);
this.code[this.code_len++] = (byte)((arg >> 8) & 255);
}
/// Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.
/// The MSIL instruction to be put onto the stream.
/// The numerical argument pushed onto the stream immediately after the instruction.
// Token: 0x06001ABA RID: 6842 RVA: 0x00064120 File Offset: 0x00062320
public virtual void Emit(OpCode opcode, int arg)
{
this.make_room(6);
this.ll_emit(opcode);
this.emit_int(arg);
}
/// Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.
/// The MSIL instruction to be put onto the stream.
/// The numerical argument pushed onto the stream immediately after the instruction.
// Token: 0x06001ABB RID: 6843 RVA: 0x00064144 File Offset: 0x00062344
public virtual void Emit(OpCode opcode, long arg)
{
this.make_room(10);
this.ll_emit(opcode);
this.code[this.code_len++] = (byte)(arg & 255L);
this.code[this.code_len++] = (byte)((arg >> 8) & 255L);
this.code[this.code_len++] = (byte)((arg >> 16) & 255L);
this.code[this.code_len++] = (byte)((arg >> 24) & 255L);
this.code[this.code_len++] = (byte)((arg >> 32) & 255L);
this.code[this.code_len++] = (byte)((arg >> 40) & 255L);
this.code[this.code_len++] = (byte)((arg >> 48) & 255L);
this.code[this.code_len++] = (byte)((arg >> 56) & 255L);
}
/// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done.
/// The MSIL instruction to be emitted onto the stream.
/// The label to which to branch from this location.
// Token: 0x06001ABC RID: 6844 RVA: 0x0006427C File Offset: 0x0006247C
public virtual void Emit(OpCode opcode, Label label)
{
int num = ILGenerator.target_len(opcode);
this.make_room(6);
this.ll_emit(opcode);
if (this.cur_stack > this.labels[label.label].maxStack)
{
this.labels[label.label].maxStack = this.cur_stack;
}
if (this.fixups == null)
{
this.fixups = new ILGenerator.LabelFixup[4];
}
else if (this.num_fixups >= this.fixups.Length)
{
ILGenerator.LabelFixup[] array = new ILGenerator.LabelFixup[this.fixups.Length * 2];
Array.Copy(this.fixups, array, this.fixups.Length);
this.fixups = array;
}
this.fixups[this.num_fixups].offset = num;
this.fixups[this.num_fixups].pos = this.code_len;
this.fixups[this.num_fixups].label_idx = label.label;
this.num_fixups++;
this.code_len += num;
}
/// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done.
/// The MSIL instruction to be emitted onto the stream.
/// The array of label objects to which to branch from this location. All of the labels will be used.
// Token: 0x06001ABD RID: 6845 RVA: 0x000643A4 File Offset: 0x000625A4
public virtual void Emit(OpCode opcode, Label[] labels)
{
if (labels == null)
{
throw new ArgumentNullException("labels");
}
int num = labels.Length;
this.make_room(6 + num * 4);
this.ll_emit(opcode);
for (int i = 0; i < num; i++)
{
if (this.cur_stack > this.labels[labels[i].label].maxStack)
{
this.labels[labels[i].label].maxStack = this.cur_stack;
}
}
this.emit_int(num);
if (this.fixups == null)
{
this.fixups = new ILGenerator.LabelFixup[4 + num];
}
else if (this.num_fixups + num >= this.fixups.Length)
{
ILGenerator.LabelFixup[] array = new ILGenerator.LabelFixup[num + this.fixups.Length * 2];
Array.Copy(this.fixups, array, this.fixups.Length);
this.fixups = array;
}
int j = 0;
int num2 = num * 4;
while (j < num)
{
this.fixups[this.num_fixups].offset = num2;
this.fixups[this.num_fixups].pos = this.code_len;
this.fixups[this.num_fixups].label_idx = labels[j].label;
this.num_fixups++;
this.code_len += 4;
j++;
num2 -= 4;
}
}
/// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the index of the given local variable.
/// The MSIL instruction to be emitted onto the stream.
/// A local variable.
/// The parent method of the parameter does not match the method associated with this .
///
/// is null.
///
/// is a single-byte instruction, and represents a local variable with an index greater than Byte.MaxValue.
// Token: 0x06001ABE RID: 6846 RVA: 0x0006452C File Offset: 0x0006272C
public virtual void Emit(OpCode opcode, LocalBuilder local)
{
if (local == null)
{
throw new ArgumentNullException("local");
}
uint position = (uint)local.position;
bool flag = false;
bool flag2 = false;
this.make_room(6);
if (local.ilgen != this)
{
throw new ArgumentException("Trying to emit a local from a different ILGenerator.");
}
if (opcode.StackBehaviourPop == StackBehaviour.Pop1)
{
this.cur_stack--;
flag2 = true;
}
else
{
this.cur_stack++;
if (this.cur_stack > this.max_stack)
{
this.max_stack = this.cur_stack;
}
flag = opcode.StackBehaviourPush == StackBehaviour.Pushi;
}
if (flag)
{
if (position < 256U)
{
this.code[this.code_len++] = 18;
this.code[this.code_len++] = (byte)position;
}
else
{
this.code[this.code_len++] = 254;
this.code[this.code_len++] = 13;
this.code[this.code_len++] = (byte)(position & 255U);
this.code[this.code_len++] = (byte)((position >> 8) & 255U);
}
}
else if (flag2)
{
if (position < 4U)
{
this.code[this.code_len++] = (byte)(10U + position);
}
else if (position < 256U)
{
this.code[this.code_len++] = 19;
this.code[this.code_len++] = (byte)position;
}
else
{
this.code[this.code_len++] = 254;
this.code[this.code_len++] = 14;
this.code[this.code_len++] = (byte)(position & 255U);
this.code[this.code_len++] = (byte)((position >> 8) & 255U);
}
}
else if (position < 4U)
{
this.code[this.code_len++] = (byte)(6U + position);
}
else if (position < 256U)
{
this.code[this.code_len++] = 17;
this.code[this.code_len++] = (byte)position;
}
else
{
this.code[this.code_len++] = 254;
this.code[this.code_len++] = 12;
this.code[this.code_len++] = (byte)(position & 255U);
this.code[this.code_len++] = (byte)((position >> 8) & 255U);
}
}
/// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given method.
/// The MSIL instruction to be emitted onto the stream.
/// A MethodInfo representing a method.
///
/// is null.
///
/// is a generic method for which the property is false.
// Token: 0x06001ABF RID: 6847 RVA: 0x0006486C File Offset: 0x00062A6C
public virtual void Emit(OpCode opcode, MethodInfo meth)
{
if (meth == null)
{
throw new ArgumentNullException("meth");
}
if (meth is DynamicMethod && (opcode == OpCodes.Ldftn || opcode == OpCodes.Ldvirtftn || opcode == OpCodes.Ldtoken))
{
throw new ArgumentException("Ldtoken, Ldftn and Ldvirtftn OpCodes cannot target DynamicMethods.");
}
int token = this.token_gen.GetToken(meth);
this.make_room(6);
this.ll_emit(opcode);
Type declaringType = meth.DeclaringType;
if (declaringType != null && declaringType.Module == this.module)
{
this.add_token_fixup(meth);
}
this.emit_int(token);
if (meth.ReturnType != ILGenerator.void_type)
{
this.cur_stack++;
}
if (opcode.StackBehaviourPop == StackBehaviour.Varpop)
{
this.cur_stack -= meth.GetParameterCount();
}
}
// Token: 0x06001AC0 RID: 6848 RVA: 0x00064958 File Offset: 0x00062B58
private void Emit(OpCode opcode, MethodInfo method, int token)
{
this.make_room(6);
this.ll_emit(opcode);
Type declaringType = method.DeclaringType;
if (declaringType != null && declaringType.Module == this.module)
{
this.add_token_fixup(method);
}
this.emit_int(token);
if (method.ReturnType != ILGenerator.void_type)
{
this.cur_stack++;
}
if (opcode.StackBehaviourPop == StackBehaviour.Varpop)
{
this.cur_stack -= method.GetParameterCount();
}
}
/// Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions.
/// The MSIL instruction to be put onto the stream.
/// The character argument pushed onto the stream immediately after the instruction.
// Token: 0x06001AC1 RID: 6849 RVA: 0x000649E0 File Offset: 0x00062BE0
[CLSCompliant(false)]
public void Emit(OpCode opcode, sbyte arg)
{
this.make_room(3);
this.ll_emit(opcode);
this.code[this.code_len++] = (byte)arg;
}
/// Puts the specified instruction and a signature token onto the Microsoft intermediate language (MSIL) stream of instructions.
/// The MSIL instruction to be emitted onto the stream.
/// A helper for constructing a signature token.
///
/// is null.
// Token: 0x06001AC2 RID: 6850 RVA: 0x00064A18 File Offset: 0x00062C18
public virtual void Emit(OpCode opcode, SignatureHelper signature)
{
int token = this.token_gen.GetToken(signature);
this.make_room(6);
this.ll_emit(opcode);
this.emit_int(token);
}
/// Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.
/// The MSIL instruction to be put onto the stream.
/// The Single argument pushed onto the stream immediately after the instruction.
// Token: 0x06001AC3 RID: 6851 RVA: 0x00064A48 File Offset: 0x00062C48
public virtual void Emit(OpCode opcode, float arg)
{
byte[] bytes = BitConverter.GetBytes(arg);
this.make_room(6);
this.ll_emit(opcode);
if (BitConverter.IsLittleEndian)
{
Array.Copy(bytes, 0, this.code, this.code_len, 4);
this.code_len += 4;
}
else
{
this.code[this.code_len++] = bytes[3];
this.code[this.code_len++] = bytes[2];
this.code[this.code_len++] = bytes[1];
this.code[this.code_len++] = bytes[0];
}
}
/// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given string.
/// The MSIL instruction to be emitted onto the stream.
/// The String to be emitted.
// Token: 0x06001AC4 RID: 6852 RVA: 0x00064B08 File Offset: 0x00062D08
public virtual void Emit(OpCode opcode, string str)
{
int token = this.token_gen.GetToken(str);
this.make_room(6);
this.ll_emit(opcode);
this.emit_int(token);
}
/// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given type.
/// The MSIL instruction to be put onto the stream.
/// A Type.
///
/// is null.
// Token: 0x06001AC5 RID: 6853 RVA: 0x00064B38 File Offset: 0x00062D38
public virtual void Emit(OpCode opcode, Type cls)
{
this.make_room(6);
this.ll_emit(opcode);
this.emit_int(this.token_gen.GetToken(cls));
}
/// Puts a call or callvirt instruction onto the Microsoft intermediate language (MSIL) stream to call a varargs method.
/// The MSIL instruction to be emitted onto the stream. Must be , , or .
/// The varargs method to be called.
/// The types of the optional arguments if the method is a varargs method; otherwise, null.
///
/// is null.
/// The calling convention for the method is not varargs, but optional parameter types are supplied. This exception is thrown in the .NET Framework versions 1.0 and 1.1, In subsequent versions, no exception is thrown.
// Token: 0x06001AC6 RID: 6854 RVA: 0x00064B68 File Offset: 0x00062D68
[MonoLimitation("vararg methods are not supported")]
public virtual void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes)
{
if (methodInfo == null)
{
throw new ArgumentNullException("methodInfo");
}
short value = opcode.Value;
if (value != OpCodes.Call.Value && value != OpCodes.Callvirt.Value)
{
throw new NotSupportedException("Only Call and CallVirt are allowed");
}
if ((methodInfo.CallingConvention & CallingConventions.VarArgs) == (CallingConventions)0)
{
optionalParameterTypes = null;
}
if (optionalParameterTypes == null)
{
this.Emit(opcode, methodInfo);
return;
}
if ((methodInfo.CallingConvention & CallingConventions.VarArgs) == (CallingConventions)0)
{
throw new InvalidOperationException("Method is not VarArgs method and optional types were passed");
}
int token = this.token_gen.GetToken(methodInfo, optionalParameterTypes);
this.Emit(opcode, methodInfo, token);
}
/// Puts a instruction onto the Microsoft intermediate language (MSIL) stream, specifying an unmanaged calling convention for the indirect call.
/// The MSIL instruction to be emitted onto the stream. Must be .
/// The unmanaged calling convention to be used.
/// The of the result.
/// The types of the required arguments to the instruction.
// Token: 0x06001AC7 RID: 6855 RVA: 0x00064C10 File Offset: 0x00062E10
public virtual void EmitCalli(OpCode opcode, CallingConvention unmanagedCallConv, Type returnType, Type[] parameterTypes)
{
SignatureHelper methodSigHelper = SignatureHelper.GetMethodSigHelper(this.module, (CallingConventions)0, unmanagedCallConv, returnType, parameterTypes);
this.Emit(opcode, methodSigHelper);
}
/// Puts a instruction onto the Microsoft intermediate language (MSIL) stream, specifying a managed calling convention for the indirect call.
/// The MSIL instruction to be emitted onto the stream. Must be .
/// The managed calling convention to be used.
/// The of the result.
/// The types of the required arguments to the instruction.
/// The types of the optional arguments for varargs calls.
///
/// is not null, but does not include the flag.
// Token: 0x06001AC8 RID: 6856 RVA: 0x00064C38 File Offset: 0x00062E38
public virtual void EmitCalli(OpCode opcode, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes)
{
if (optionalParameterTypes != null)
{
throw new NotImplementedException();
}
SignatureHelper methodSigHelper = SignatureHelper.GetMethodSigHelper(this.module, callingConvention, (CallingConvention)0, returnType, parameterTypes);
this.Emit(opcode, methodSigHelper);
}
/// Emits the Microsoft intermediate language (MSIL) necessary to call with the given field.
/// The field whose value is to be written to the console.
/// There is no overload of the method that accepts the type of the specified field.
///
/// is null.
/// The type of the field is or , which are not supported.
// Token: 0x06001AC9 RID: 6857 RVA: 0x00064C6C File Offset: 0x00062E6C
public virtual void EmitWriteLine(FieldInfo fld)
{
if (fld == null)
{
throw new ArgumentNullException("fld");
}
if (fld.IsStatic)
{
this.Emit(OpCodes.Ldsfld, fld);
}
else
{
this.Emit(OpCodes.Ldarg_0);
this.Emit(OpCodes.Ldfld, fld);
}
this.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { fld.FieldType }));
}
/// Emits the Microsoft intermediate language (MSIL) necessary to call with the given local variable.
/// The local variable whose value is to be written to the console.
/// The type of is or , which are not supported. -or-There is no overload of that accepts the type of .
///
/// is null.
// Token: 0x06001ACA RID: 6858 RVA: 0x00064CEC File Offset: 0x00062EEC
public virtual void EmitWriteLine(LocalBuilder localBuilder)
{
if (localBuilder == null)
{
throw new ArgumentNullException("localBuilder");
}
if (localBuilder.LocalType is TypeBuilder)
{
throw new ArgumentException("Output streams do not support TypeBuilders.");
}
this.Emit(OpCodes.Ldloc, localBuilder);
this.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { localBuilder.LocalType }));
}
/// Emits the Microsoft intermediate language (MSIL) to call with a string.
/// The string to be printed.
// Token: 0x06001ACB RID: 6859 RVA: 0x00064D60 File Offset: 0x00062F60
public virtual void EmitWriteLine(string value)
{
this.Emit(OpCodes.Ldstr, value);
this.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
}
/// Ends an exception block.
/// The end exception block occurs in an unexpected place in the code stream.
/// The Microsoft intermediate language (MSIL) being generated is not currently in an exception block.
// Token: 0x06001ACC RID: 6860 RVA: 0x00064DAC File Offset: 0x00062FAC
public virtual void EndExceptionBlock()
{
if (this.open_blocks == null)
{
this.open_blocks = new Stack(2);
}
if (this.open_blocks.Count <= 0)
{
throw new NotSupportedException("Not in an exception block");
}
if (this.ex_handlers[this.cur_block].LastClauseType() == -1)
{
throw new InvalidOperationException("Incorrect code generation for exception block.");
}
this.InternalEndClause();
this.MarkLabel(this.ex_handlers[this.cur_block].end);
this.ex_handlers[this.cur_block].End(this.code_len);
this.ex_handlers[this.cur_block].Debug(this.cur_block);
this.open_blocks.Pop();
if (this.open_blocks.Count > 0)
{
this.cur_block = (int)this.open_blocks.Peek();
}
}
/// Ends a lexical scope.
/// This belongs to a .
// Token: 0x06001ACD RID: 6861 RVA: 0x00064EA0 File Offset: 0x000630A0
public virtual void EndScope()
{
}
/// Marks the Microsoft intermediate language (MSIL) stream's current position with the given label.
/// The label for which to set an index.
///
/// represents an invalid index into the label array.-or- An index for has already been defined.
// Token: 0x06001ACE RID: 6862 RVA: 0x00064EA4 File Offset: 0x000630A4
public virtual void MarkLabel(Label loc)
{
if (loc.label < 0 || loc.label >= this.num_labels)
{
throw new ArgumentException("The label is not valid");
}
if (this.labels[loc.label].addr >= 0)
{
throw new ArgumentException("The label was already defined");
}
this.labels[loc.label].addr = this.code_len;
if (this.labels[loc.label].maxStack > this.cur_stack)
{
this.cur_stack = this.labels[loc.label].maxStack;
}
}
/// Marks a sequence point in the Microsoft intermediate language (MSIL) stream.
/// The document for which the sequence point is being defined.
/// The line where the sequence point begins.
/// The column in the line where the sequence point begins.
/// The line where the sequence point ends.
/// The column in the line where the sequence point ends.
///
/// or is <= 0.
/// This belongs to a .
// Token: 0x06001ACF RID: 6863 RVA: 0x00064F60 File Offset: 0x00063160
public virtual void MarkSequencePoint(ISymbolDocumentWriter document, int startLine, int startColumn, int endLine, int endColumn)
{
if (this.currentSequence == null || this.currentSequence.Document != document)
{
if (this.sequencePointLists == null)
{
this.sequencePointLists = new ArrayList();
}
this.currentSequence = new SequencePointList(document);
this.sequencePointLists.Add(this.currentSequence);
}
this.currentSequence.AddSequencePoint(this.code_len, startLine, startColumn, endLine, endColumn);
}
// Token: 0x06001AD0 RID: 6864 RVA: 0x00064FD4 File Offset: 0x000631D4
internal void GenerateDebugInfo(ISymbolWriter symbolWriter)
{
if (this.sequencePointLists != null)
{
SequencePointList sequencePointList = (SequencePointList)this.sequencePointLists[0];
SequencePointList sequencePointList2 = (SequencePointList)this.sequencePointLists[this.sequencePointLists.Count - 1];
symbolWriter.SetMethodSourceRange(sequencePointList.Document, sequencePointList.StartLine, sequencePointList.StartColumn, sequencePointList2.Document, sequencePointList2.EndLine, sequencePointList2.EndColumn);
foreach (object obj in this.sequencePointLists)
{
SequencePointList sequencePointList3 = (SequencePointList)obj;
symbolWriter.DefineSequencePoints(sequencePointList3.Document, sequencePointList3.GetOffsets(), sequencePointList3.GetLines(), sequencePointList3.GetColumns(), sequencePointList3.GetEndLines(), sequencePointList3.GetEndColumns());
}
if (this.locals != null)
{
foreach (LocalBuilder localBuilder in this.locals)
{
if (localBuilder.Name != null && localBuilder.Name.Length > 0)
{
SignatureHelper localVarSigHelper = SignatureHelper.GetLocalVarSigHelper(this.module);
localVarSigHelper.AddArgument(localBuilder.LocalType);
byte[] signature = localVarSigHelper.GetSignature();
symbolWriter.DefineLocalVariable(localBuilder.Name, FieldAttributes.Public, signature, SymAddressKind.ILOffset, (int)localBuilder.position, 0, 0, localBuilder.StartOffset, localBuilder.EndOffset);
}
}
}
this.sequencePointLists = null;
}
}
// Token: 0x170004BD RID: 1213
// (get) Token: 0x06001AD1 RID: 6865 RVA: 0x00065174 File Offset: 0x00063374
internal bool HasDebugInfo
{
get
{
return this.sequencePointLists != null;
}
}
/// Emits an instruction to throw an exception.
/// The class of the type of exception to throw.
///
/// is not the class or a derived class of .-or- The type does not have a default constructor.
///
/// is null.
// Token: 0x06001AD2 RID: 6866 RVA: 0x00065184 File Offset: 0x00063384
public virtual void ThrowException(Type excType)
{
if (excType == null)
{
throw new ArgumentNullException("excType");
}
if (excType != typeof(Exception) && !excType.IsSubclassOf(typeof(Exception)))
{
throw new ArgumentException("Type should be an exception type", "excType");
}
ConstructorInfo constructor = excType.GetConstructor(Type.EmptyTypes);
if (constructor == null)
{
throw new ArgumentException("Type should have a default constructor", "excType");
}
this.Emit(OpCodes.Newobj, constructor);
this.Emit(OpCodes.Throw);
}
/// Specifies the namespace to be used in evaluating locals and watches for the current active lexical scope.
/// The namespace to be used in evaluating locals and watches for the current active lexical scope
/// Length of is zero.
///
/// is null.
/// This belongs to a .
// Token: 0x06001AD3 RID: 6867 RVA: 0x00065210 File Offset: 0x00063410
[MonoTODO("Not implemented")]
public virtual void UsingNamespace(string usingNamespace)
{
throw new NotImplementedException();
}
// Token: 0x06001AD4 RID: 6868 RVA: 0x00065218 File Offset: 0x00063418
internal void label_fixup()
{
for (int i = 0; i < this.num_fixups; i++)
{
if (this.labels[this.fixups[i].label_idx].addr < 0)
{
throw new ArgumentException("Label not marked");
}
int num = this.labels[this.fixups[i].label_idx].addr - (this.fixups[i].pos + this.fixups[i].offset);
if (this.fixups[i].offset == 1)
{
this.code[this.fixups[i].pos] = (byte)((sbyte)num);
}
else
{
int num2 = this.code_len;
this.code_len = this.fixups[i].pos;
this.emit_int(num);
this.code_len = num2;
}
}
}
// Token: 0x06001AD5 RID: 6869 RVA: 0x00065318 File Offset: 0x00063518
[Obsolete("Use ILOffset")]
internal static int Mono_GetCurrentOffset(ILGenerator ig)
{
return ig.code_len;
}
// Token: 0x040007E5 RID: 2021
private const int defaultFixupSize = 4;
// Token: 0x040007E6 RID: 2022
private const int defaultLabelsSize = 4;
// Token: 0x040007E7 RID: 2023
private const int defaultExceptionStackSize = 2;
// Token: 0x040007E8 RID: 2024
private static readonly Type void_type = typeof(void);
// Token: 0x040007E9 RID: 2025
private byte[] code;
// Token: 0x040007EA RID: 2026
private int code_len;
// Token: 0x040007EB RID: 2027
private int max_stack;
// Token: 0x040007EC RID: 2028
private int cur_stack;
// Token: 0x040007ED RID: 2029
private LocalBuilder[] locals;
// Token: 0x040007EE RID: 2030
private ILExceptionInfo[] ex_handlers;
// Token: 0x040007EF RID: 2031
private int num_token_fixups;
// Token: 0x040007F0 RID: 2032
private ILTokenInfo[] token_fixups;
// Token: 0x040007F1 RID: 2033
private ILGenerator.LabelData[] labels;
// Token: 0x040007F2 RID: 2034
private int num_labels;
// Token: 0x040007F3 RID: 2035
private ILGenerator.LabelFixup[] fixups;
// Token: 0x040007F4 RID: 2036
private int num_fixups;
// Token: 0x040007F5 RID: 2037
internal Module module;
// Token: 0x040007F6 RID: 2038
private int cur_block;
// Token: 0x040007F7 RID: 2039
private Stack open_blocks;
// Token: 0x040007F8 RID: 2040
private TokenGenerator token_gen;
// Token: 0x040007F9 RID: 2041
private ArrayList sequencePointLists;
// Token: 0x040007FA RID: 2042
private SequencePointList currentSequence;
// Token: 0x020001FD RID: 509
private struct LabelFixup
{
// Token: 0x040007FB RID: 2043
public int offset;
// Token: 0x040007FC RID: 2044
public int pos;
// Token: 0x040007FD RID: 2045
public int label_idx;
}
// Token: 0x020001FE RID: 510
private struct LabelData
{
// Token: 0x06001AD6 RID: 6870 RVA: 0x00065320 File Offset: 0x00063520
public LabelData(int addr, int maxStack)
{
this.addr = addr;
this.maxStack = maxStack;
}
// Token: 0x040007FE RID: 2046
public int addr;
// Token: 0x040007FF RID: 2047
public int maxStack;
}
}
}