/*
- Copyright (C) 2008-2010 Jeroen Frijters
+ Copyright (C) 2008-2012 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
using System.Collections.Generic;
using System.Diagnostics.SymbolStore;
using System.Diagnostics;
-using IKVM.Reflection.Metadata;
using IKVM.Reflection.Writer;
namespace IKVM.Reflection.Emit
}
}
- public sealed class LocalBuilder
+ public sealed class LocalBuilder : LocalVariableInfo
{
- private readonly Type localType;
- private readonly int index;
- private readonly bool pinned;
internal string name;
internal int startOffset;
internal int endOffset;
internal LocalBuilder(Type localType, int index, bool pinned)
+ : base(index, localType, pinned)
+ {
+ }
+
+ internal LocalBuilder(Type localType, int index, bool pinned, CustomModifiers customModifiers)
+ : base(index, localType, pinned, customModifiers)
{
- this.localType = localType;
- this.index = index;
- this.pinned = pinned;
}
public void SetLocalSymInfo(string name)
this.startOffset = startOffset;
this.endOffset = endOffset;
}
-
- public Type LocalType
- {
- get { return localType; }
- }
-
- public int LocalIndex
- {
- get { return index; }
- }
-
- public bool IsPinned
- {
- get { return pinned; }
- }
}
public sealed class ILGenerator
{
- private static readonly Type FAULT = new BakedType(null); // the type we use here doesn't matter, as long as it can never be used as a real exception type
private readonly ModuleBuilder moduleBuilder;
private readonly ByteBuffer code;
- private readonly List<LocalBuilder> locals = new List<LocalBuilder>();
+ private readonly SignatureHelper locals;
+ private int localsCount;
private readonly List<int> tokenFixups = new List<int>();
private readonly List<int> labels = new List<int>();
private readonly List<int> labelStackHeight = new List<int>();
private readonly List<ExceptionBlock> exceptions = new List<ExceptionBlock>();
private readonly Stack<ExceptionBlock> exceptionStack = new Stack<ExceptionBlock>();
private ushort maxStack;
+ private bool fatHeader;
private int stackHeight;
private Scope scope;
private byte exceptionBlockAssistanceMode = EBAM_COMPAT;
internal int offset;
}
- private sealed class ExceptionBlock : IComparer<ExceptionBlock>
+ internal sealed class ExceptionBlock : IComparer<ExceptionBlock>
{
internal readonly int ordinal;
internal Label labelEnd;
internal int tryLength;
internal int handlerOffset;
internal int handlerLength;
- internal Type exceptionType; // null = finally block or handler with filter, FAULT = fault block
- internal int filterOffset;
+ internal int filterOffsetOrExceptionTypeToken;
+ internal ExceptionHandlingClauseOptions kind;
internal ExceptionBlock(int ordinal)
{
this.ordinal = ordinal;
}
+ internal ExceptionBlock(ExceptionHandler h)
+ {
+ this.ordinal = -1;
+ this.tryOffset = h.TryOffset;
+ this.tryLength = h.TryLength;
+ this.handlerOffset = h.HandlerOffset;
+ this.handlerLength = h.HandlerLength;
+ this.kind = h.Kind;
+ this.filterOffsetOrExceptionTypeToken = kind == ExceptionHandlingClauseOptions.Filter ? h.FilterOffset : h.ExceptionTypeToken;
+ }
+
int IComparer<ExceptionBlock>.Compare(ExceptionBlock x, ExceptionBlock y)
{
// Mono's sort insists on doing unnecessary comparisons
{
return 0;
}
- if (x.tryOffset >= y.handlerOffset && x.tryOffset + x.tryLength <= y.handlerOffset + y.handlerLength)
- {
- return -1;
- }
- if (y.tryOffset >= x.handlerOffset && y.tryOffset + y.tryLength <= x.handlerOffset + x.handlerLength)
- {
- return 1;
- }
- if (x.tryOffset == y.tryOffset && x.tryLength == y.tryLength)
+ else if (x.tryOffset == y.tryOffset && x.tryLength == y.tryLength)
{
return x.ordinal < y.ordinal ? -1 : 1;
}
- if (x.tryOffset + x.tryLength <= y.tryOffset)
+ else if (x.tryOffset >= y.tryOffset && x.handlerOffset + x.handlerLength <= y.handlerOffset + y.handlerLength)
{
return -1;
}
- if (y.tryOffset + y.tryLength <= x.tryOffset)
+ else if (y.tryOffset >= x.tryOffset && y.handlerOffset + y.handlerLength <= x.handlerOffset + x.handlerLength)
{
return 1;
}
- if (x.tryOffset > y.tryOffset || (x.tryOffset == y.tryOffset && x.tryLength < y.tryLength))
- {
- return -1;
- }
else
{
- return 1;
+ return x.ordinal < y.ordinal ? -1 : 1;
}
}
}
{
this.code = new ByteBuffer(initialCapacity);
this.moduleBuilder = moduleBuilder;
+ this.locals = SignatureHelper.GetLocalVarSigHelper(moduleBuilder);
if (moduleBuilder.symbolWriter != null)
{
scope = new Scope(null);
}
}
- private bool IsLabelReachable(Label label)
- {
- return labelStackHeight[label.Index] != -1;
- }
-
// non-standard API
public void __DisableExceptionBlockAssistance()
{
exceptionBlockAssistanceMode = EBAM_CLEVER;
}
+ // non-standard API
+ public int __MaxStackSize
+ {
+ get { return maxStack; }
+ set
+ {
+ maxStack = (ushort)value;
+ fatHeader = true;
+ }
+ }
+
+ // non-standard API
+ // returns -1 if the current position is currently unreachable
+ public int __StackHeight
+ {
+ get { return stackHeight; }
+ }
+
// new in .NET 4.0
public int ILOffset
{
public void BeginCatchBlock(Type exceptionType)
{
- ExceptionBlock block = exceptionStack.Peek();
- if (exceptionBlockAssistanceMode == EBAM_COMPAT || (exceptionBlockAssistanceMode == EBAM_CLEVER && stackHeight != -1))
+ if (exceptionType == null)
{
- if (exceptionType == null)
+ // this must be a catch block after a filter
+ ExceptionBlock block = exceptionStack.Peek();
+ if (block.kind != ExceptionHandlingClauseOptions.Filter || block.handlerOffset != 0)
{
- Emit(OpCodes.Endfilter);
+ throw new ArgumentNullException("exceptionType");
}
- else
+ if (exceptionBlockAssistanceMode == EBAM_COMPAT || (exceptionBlockAssistanceMode == EBAM_CLEVER && stackHeight != -1))
{
- Emit(OpCodes.Leave, block.labelEnd);
+ Emit(OpCodes.Endfilter);
}
+ stackHeight = 0;
+ UpdateStack(1);
+ block.handlerOffset = code.Position;
+ }
+ else
+ {
+ ExceptionBlock block = BeginCatchOrFilterBlock();
+ block.kind = ExceptionHandlingClauseOptions.Clause;
+ block.filterOffsetOrExceptionTypeToken = moduleBuilder.GetTypeTokenForMemberRef(exceptionType);
+ block.handlerOffset = code.Position;
+ }
+ }
+
+ private ExceptionBlock BeginCatchOrFilterBlock()
+ {
+ ExceptionBlock block = exceptionStack.Peek();
+ if (exceptionBlockAssistanceMode == EBAM_COMPAT || (exceptionBlockAssistanceMode == EBAM_CLEVER && stackHeight != -1))
+ {
+ Emit(OpCodes.Leave, block.labelEnd);
}
stackHeight = 0;
UpdateStack(1);
{
block.tryLength = code.Position - block.tryOffset;
}
- else if (exceptionType != null)
+ else
{
block.handlerLength = code.Position - block.handlerOffset;
exceptionStack.Pop();
exceptions.Add(block);
exceptionStack.Push(block);
}
- block.handlerOffset = code.Position;
- block.exceptionType = exceptionType;
+ return block;
}
public Label BeginExceptionBlock()
block.tryOffset = code.Position;
exceptionStack.Push(block);
exceptions.Add(block);
+ stackHeight = 0;
return block.labelEnd;
}
public void BeginExceptFilterBlock()
{
- ExceptionBlock block = BeginFinallyFilterFaultBlock();
- block.filterOffset = code.Position;
- UpdateStack(1);
+ ExceptionBlock block = BeginCatchOrFilterBlock();
+ block.kind = ExceptionHandlingClauseOptions.Filter;
+ block.filterOffsetOrExceptionTypeToken = code.Position;
}
public void BeginFaultBlock()
{
- ExceptionBlock block = BeginFinallyFilterFaultBlock();
- block.handlerOffset = code.Position;
- block.exceptionType = FAULT;
+ BeginFinallyFaultBlock(ExceptionHandlingClauseOptions.Fault);
}
public void BeginFinallyBlock()
{
- ExceptionBlock block = BeginFinallyFilterFaultBlock();
- block.handlerOffset = code.Position;
+ BeginFinallyFaultBlock(ExceptionHandlingClauseOptions.Finally);
}
- private ExceptionBlock BeginFinallyFilterFaultBlock()
+ private void BeginFinallyFaultBlock(ExceptionHandlingClauseOptions kind)
{
ExceptionBlock block = exceptionStack.Peek();
if (exceptionBlockAssistanceMode == EBAM_COMPAT || (exceptionBlockAssistanceMode == EBAM_CLEVER && stackHeight != -1))
exceptions.Add(block);
exceptionStack.Push(block);
}
+ block.handlerOffset = code.Position;
+ block.kind = kind;
stackHeight = 0;
- return block;
}
public void EndExceptionBlock()
ExceptionBlock block = exceptionStack.Pop();
if (exceptionBlockAssistanceMode == EBAM_COMPAT || (exceptionBlockAssistanceMode == EBAM_CLEVER && stackHeight != -1))
{
- if (block.filterOffset != 0 || (block.exceptionType != null && block.exceptionType != FAULT))
+ if (block.kind != ExceptionHandlingClauseOptions.Finally && block.kind != ExceptionHandlingClauseOptions.Fault)
{
Emit(OpCodes.Leave, block.labelEnd);
}
public LocalBuilder DeclareLocal(Type localType, bool pinned)
{
- LocalBuilder local = new LocalBuilder(localType, locals.Count, pinned);
- locals.Add(local);
+ LocalBuilder local = new LocalBuilder(localType, localsCount++, pinned);
+ locals.AddArgument(localType, pinned);
+ if (scope != null)
+ {
+ scope.locals.Add(local);
+ }
+ return local;
+ }
+
+ public LocalBuilder __DeclareLocal(Type localType, bool pinned, CustomModifiers customModifiers)
+ {
+ LocalBuilder local = new LocalBuilder(localType, localsCount++, pinned, customModifiers);
+ locals.__AddArgument(localType, pinned, customModifiers);
if (scope != null)
{
scope.locals.Add(local);
public void Emit(OpCode opc, FieldInfo field)
{
Emit(opc);
- WriteToken(moduleBuilder.GetFieldToken(field));
+ WriteToken(moduleBuilder.GetFieldToken(field).Token);
}
public void Emit(OpCode opc, short arg)
}
}
- private void WriteToken(FieldToken token)
- {
- if (token.IsPseudoToken)
- {
- tokenFixups.Add(code.Position);
- }
- code.Write(token.Token);
- }
-
- private void WriteToken(MethodToken token)
+ private void WriteToken(int token)
{
- if (token.IsPseudoToken)
+ if (ModuleBuilder.IsPseudoToken(token))
{
tokenFixups.Add(code.Position);
}
- code.Write(token.Token);
+ code.Write(token);
}
private void UpdateStack(OpCode opc, bool hasthis, Type returnType, int parameterCount)
public void Emit(OpCode opc, MethodInfo method)
{
- Emit(opc);
- WriteToken(moduleBuilder.GetMethodTokenForIL(method));
UpdateStack(opc, method.HasThis, method.ReturnType, method.ParameterCount);
+ Emit(opc);
+ WriteToken(moduleBuilder.GetMethodTokenForIL(method).Token);
}
public void Emit(OpCode opc, ConstructorInfo constructor)
public void Emit(OpCode opc, string str)
{
Emit(opc);
- code.Write(0x70000000 | moduleBuilder.UserStrings.Add(str));
+ code.Write(moduleBuilder.GetStringConstant(str).Token);
}
public void Emit(OpCode opc, Type type)
{
Emit(opcode);
UpdateStack(opcode, signature.HasThis, signature.ReturnType, signature.ParameterCount);
- code.Write(0x11000000 | moduleBuilder.StandAloneSig.FindOrAddRecord(moduleBuilder.Blobs.Add(signature.GetSignature(moduleBuilder))));
+ code.Write(moduleBuilder.GetSignatureToken(signature).Token);
}
public void EmitCall(OpCode opc, MethodInfo method, Type[] optionalParameterTypes)
+ {
+ __EmitCall(opc, method, optionalParameterTypes, null);
+ }
+
+ public void __EmitCall(OpCode opc, MethodInfo method, Type[] optionalParameterTypes, CustomModifiers[] customModifiers)
{
if (optionalParameterTypes == null || optionalParameterTypes.Length == 0)
{
{
Emit(opc);
UpdateStack(opc, method.HasThis, method.ReturnType, method.ParameterCount + optionalParameterTypes.Length);
- ByteBuffer sig = new ByteBuffer(16);
- method.MethodSignature.WriteMethodRefSig(moduleBuilder, sig, optionalParameterTypes);
- MemberRefTable.Record record = new MemberRefTable.Record();
- if (method.Module == moduleBuilder)
- {
- record.Class = method.MetadataToken;
- }
- else
- {
- record.Class = moduleBuilder.GetTypeTokenForMemberRef(method.DeclaringType ?? method.Module.GetModuleType());
- }
- record.Name = moduleBuilder.Strings.Add(method.Name);
- record.Signature = moduleBuilder.Blobs.Add(sig);
- code.Write(0x0A000000 | moduleBuilder.MemberRef.FindOrAddRecord(record));
+ code.Write(moduleBuilder.__GetMethodToken(method, optionalParameterTypes, customModifiers).Token);
}
}
EmitCall(opc, constructor.GetMethodInfo(), optionalParameterTypes);
}
+ public void __EmitCall(OpCode opc, ConstructorInfo constructor, Type[] optionalParameterTypes, CustomModifiers[] customModifiers)
+ {
+ __EmitCall(opc, constructor.GetMethodInfo(), optionalParameterTypes, customModifiers);
+ }
+
public void EmitCalli(OpCode opc, CallingConvention callingConvention, Type returnType, Type[] parameterTypes)
{
- returnType = returnType ?? moduleBuilder.universe.System_Void;
- Emit(opc);
- UpdateStack(opc, false, returnType, parameterTypes.Length);
- ByteBuffer sig = new ByteBuffer(16);
- Signature.WriteStandAloneMethodSig(moduleBuilder, sig, callingConvention, returnType, parameterTypes);
- code.Write(0x11000000 | moduleBuilder.StandAloneSig.FindOrAddRecord(moduleBuilder.Blobs.Add(sig)));
+ SignatureHelper sig = SignatureHelper.GetMethodSigHelper(moduleBuilder, callingConvention, returnType);
+ sig.AddArguments(parameterTypes, null, null);
+ Emit(opc, sig);
}
public void EmitCalli(OpCode opc, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes)
{
- returnType = returnType ?? moduleBuilder.universe.System_Void;
- optionalParameterTypes = optionalParameterTypes ?? Type.EmptyTypes;
+ SignatureHelper sig = SignatureHelper.GetMethodSigHelper(moduleBuilder, callingConvention, returnType);
+ sig.AddArguments(parameterTypes, null, null);
+ sig.AddSentinel();
+ sig.AddArguments(optionalParameterTypes, null, null);
+ Emit(opc, sig);
+ }
+
+ public void __EmitCalli(OpCode opc, __StandAloneMethodSig sig)
+ {
Emit(opc);
- UpdateStack(opc, (callingConvention & CallingConventions.HasThis | CallingConventions.ExplicitThis) == CallingConventions.HasThis, returnType, parameterTypes.Length + optionalParameterTypes.Length);
- ByteBuffer sig = new ByteBuffer(16);
- Signature.WriteStandAloneMethodSig(moduleBuilder, sig, callingConvention, returnType, parameterTypes, optionalParameterTypes);
- code.Write(0x11000000 | moduleBuilder.StandAloneSig.FindOrAddRecord(moduleBuilder.Blobs.Add(sig)));
+ if (sig.IsUnmanaged)
+ {
+ UpdateStack(opc, false, sig.ReturnType, sig.ParameterCount);
+ }
+ else
+ {
+ CallingConventions callingConvention = sig.CallingConvention;
+ UpdateStack(opc, (callingConvention & CallingConventions.HasThis | CallingConventions.ExplicitThis) == CallingConventions.HasThis, sig.ReturnType, sig.ParameterCount);
+ }
+ ByteBuffer bb = new ByteBuffer(16);
+ Signature.WriteStandAloneMethodSig(moduleBuilder, bb, sig);
+ code.Write(0x11000000 | moduleBuilder.StandAloneSig.FindOrAddRecord(moduleBuilder.Blobs.Add(bb)));
}
public void EmitWriteLine(string text)
int localVarSigTok = 0;
int rva;
- if (locals.Count == 0 && exceptions.Count == 0 && maxStack <= 8 && code.Length < 64)
+ if (localsCount == 0 && exceptions.Count == 0 && maxStack <= 8 && code.Length < 64 && !fatHeader)
{
rva = WriteTinyHeaderAndCode(bb);
}
else
{
- rva = WriteFatHeaderAndCode(bb, ref localVarSigTok, initLocals);
+ if (localsCount != 0)
+ {
+ localVarSigTok = moduleBuilder.GetSignatureToken(locals).Token;
+ }
+ rva = WriteFatHeaderAndCode(bb, localVarSigTok, initLocals);
}
if (moduleBuilder.symbolWriter != null)
}
}
- private int WriteTinyHeaderAndCode(ByteBuffer bb)
+ internal static void WriteTinyHeader(ByteBuffer bb, int length)
{
- int rva = bb.Position;
const byte CorILMethod_TinyFormat = 0x2;
- bb.Write((byte)(CorILMethod_TinyFormat | (code.Length << 2)));
- WriteCode(bb);
- return rva;
+ bb.Write((byte)(CorILMethod_TinyFormat | (length << 2)));
}
- private int WriteFatHeaderAndCode(ByteBuffer bb, ref int localVarSigTok, bool initLocals)
+ private int WriteTinyHeaderAndCode(ByteBuffer bb)
{
- // fat headers require 4-byte alignment
- bb.Align(4);
int rva = bb.Position;
+ WriteTinyHeader(bb, code.Length);
+ AddTokenFixups(bb.Position, moduleBuilder.tokenFixupOffsets, tokenFixups);
+ bb.Write(code);
+ return rva;
+ }
- if (locals.Count != 0)
- {
- ByteBuffer localVarSig = new ByteBuffer(locals.Count + 2);
- Signature.WriteLocalVarSig(moduleBuilder, localVarSig, locals);
- localVarSigTok = 0x11000000 | moduleBuilder.StandAloneSig.FindOrAddRecord(moduleBuilder.Blobs.Add(localVarSig));
- }
-
+ internal static void WriteFatHeader(ByteBuffer bb, bool initLocals, bool exceptions, ushort maxStack, int codeLength, int localVarSigTok)
+ {
const byte CorILMethod_FatFormat = 0x03;
const byte CorILMethod_MoreSects = 0x08;
const byte CorILMethod_InitLocals = 0x10;
flagsAndSize |= CorILMethod_InitLocals;
}
- if (exceptions.Count > 0)
+ if (exceptions)
{
flagsAndSize |= CorILMethod_MoreSects;
}
bb.Write(flagsAndSize);
bb.Write(maxStack);
- bb.Write(code.Length);
+ bb.Write(codeLength);
bb.Write(localVarSigTok);
+ }
- WriteCode(bb);
-
+ private int WriteFatHeaderAndCode(ByteBuffer bb, int localVarSigTok, bool initLocals)
+ {
+ // fat headers require 4-byte alignment
+ bb.Align(4);
+ int rva = bb.Position;
+ WriteFatHeader(bb, initLocals, exceptions.Count > 0, maxStack, code.Length, localVarSigTok);
+ AddTokenFixups(bb.Position, moduleBuilder.tokenFixupOffsets, tokenFixups);
+ bb.Write(code);
if (exceptions.Count > 0)
{
- bb.Align(4);
+ exceptions.Sort(exceptions[0]);
+ WriteExceptionHandlers(bb, exceptions);
+ }
+ return rva;
+ }
- bool fat = false;
+ internal static void WriteExceptionHandlers(ByteBuffer bb, List<ExceptionBlock> exceptions)
+ {
+ bb.Align(4);
+
+ bool fat = false;
+ if (exceptions.Count * 12 + 4 > 255)
+ {
+ fat = true;
+ }
+ else
+ {
foreach (ExceptionBlock block in exceptions)
{
if (block.tryOffset > 65535 || block.tryLength > 255 || block.handlerOffset > 65535 || block.handlerLength > 255)
break;
}
}
- exceptions.Sort(exceptions[0]);
- if (exceptions.Count * 12 + 4 > 255)
- {
- fat = true;
- }
- const byte CorILMethod_Sect_EHTable = 0x1;
- const byte CorILMethod_Sect_FatFormat = 0x40;
- const short COR_ILEXCEPTION_CLAUSE_EXCEPTION = 0x0000;
- const short COR_ILEXCEPTION_CLAUSE_FILTER = 0x0001;
- const short COR_ILEXCEPTION_CLAUSE_FINALLY = 0x0002;
- const short COR_ILEXCEPTION_CLAUSE_FAULT = 0x0004;
-
- if (fat)
+ }
+
+ const byte CorILMethod_Sect_EHTable = 0x1;
+ const byte CorILMethod_Sect_FatFormat = 0x40;
+
+ if (fat)
+ {
+ bb.Write((byte)(CorILMethod_Sect_EHTable | CorILMethod_Sect_FatFormat));
+ int dataSize = exceptions.Count * 24 + 4;
+ bb.Write((byte)dataSize);
+ bb.Write((short)(dataSize >> 8));
+ foreach (ExceptionBlock block in exceptions)
{
- bb.Write((byte)(CorILMethod_Sect_EHTable | CorILMethod_Sect_FatFormat));
- int dataSize = exceptions.Count * 24 + 4;
- bb.Write((byte)dataSize);
- bb.Write((short)(dataSize >> 8));
- foreach (ExceptionBlock block in exceptions)
- {
- if (block.exceptionType == FAULT)
- {
- bb.Write((int)COR_ILEXCEPTION_CLAUSE_FAULT);
- }
- else if (block.filterOffset != 0)
- {
- bb.Write((int)COR_ILEXCEPTION_CLAUSE_FILTER);
- }
- else if (block.exceptionType != null)
- {
- bb.Write((int)COR_ILEXCEPTION_CLAUSE_EXCEPTION);
- }
- else
- {
- bb.Write((int)COR_ILEXCEPTION_CLAUSE_FINALLY);
- }
- bb.Write(block.tryOffset);
- bb.Write(block.tryLength);
- bb.Write(block.handlerOffset);
- bb.Write(block.handlerLength);
- if (block.exceptionType != null && block.exceptionType != FAULT)
- {
- bb.Write(moduleBuilder.GetTypeTokenForMemberRef(block.exceptionType));
- }
- else
- {
- bb.Write(block.filterOffset);
- }
- }
+ bb.Write((int)block.kind);
+ bb.Write(block.tryOffset);
+ bb.Write(block.tryLength);
+ bb.Write(block.handlerOffset);
+ bb.Write(block.handlerLength);
+ bb.Write(block.filterOffsetOrExceptionTypeToken);
}
- else
+ }
+ else
+ {
+ bb.Write(CorILMethod_Sect_EHTable);
+ bb.Write((byte)(exceptions.Count * 12 + 4));
+ bb.Write((short)0);
+ foreach (ExceptionBlock block in exceptions)
{
- bb.Write(CorILMethod_Sect_EHTable);
- bb.Write((byte)(exceptions.Count * 12 + 4));
- bb.Write((short)0);
- foreach (ExceptionBlock block in exceptions)
- {
- if (block.exceptionType == FAULT)
- {
- bb.Write(COR_ILEXCEPTION_CLAUSE_FAULT);
- }
- else if (block.filterOffset != 0)
- {
- bb.Write(COR_ILEXCEPTION_CLAUSE_FILTER);
- }
- else if (block.exceptionType != null)
- {
- bb.Write(COR_ILEXCEPTION_CLAUSE_EXCEPTION);
- }
- else
- {
- bb.Write(COR_ILEXCEPTION_CLAUSE_FINALLY);
- }
- bb.Write((short)block.tryOffset);
- bb.Write((byte)block.tryLength);
- bb.Write((short)block.handlerOffset);
- bb.Write((byte)block.handlerLength);
- if (block.exceptionType != null && block.exceptionType != FAULT)
- {
- bb.Write(moduleBuilder.GetTypeTokenForMemberRef(block.exceptionType));
- }
- else
- {
- bb.Write(block.filterOffset);
- }
- }
+ bb.Write((short)block.kind);
+ bb.Write((short)block.tryOffset);
+ bb.Write((byte)block.tryLength);
+ bb.Write((short)block.handlerOffset);
+ bb.Write((byte)block.handlerLength);
+ bb.Write(block.filterOffsetOrExceptionTypeToken);
}
}
- return rva;
}
- private void WriteCode(ByteBuffer bb)
+ internal static void AddTokenFixups(int codeOffset, List<int> tokenFixupOffsets, IEnumerable<int> tokenFixups)
{
- int codeOffset = bb.Position;
- foreach (int fixup in this.tokenFixups)
+ foreach (int fixup in tokenFixups)
{
- moduleBuilder.tokenFixupOffsets.Add(fixup + codeOffset);
+ tokenFixupOffsets.Add(fixup + codeOffset);
}
- bb.Write(code);
}
private void WriteScope(Scope scope, int localVarSigTok)