ikvm-fork/runtime/remapper.cs

813 строки
17 KiB
C#
Исходник Обычный вид История

2004-04-23 18:21:43 +04:00
/*
Copyright (C) 2002, 2003, 2004 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
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jeroen Frijters
jeroen@frijters.net
*/
2002-12-18 19:00:25 +03:00
using System;
using System.Xml.Serialization;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
2003-04-14 13:41:58 +04:00
using System.Diagnostics;
2002-12-18 19:00:25 +03:00
namespace MapXml
{
public abstract class Instruction
{
internal abstract void Generate(Hashtable context, ILGenerator ilgen);
}
[XmlType("ldstr")]
public sealed class Ldstr : Instruction
{
[XmlAttribute("value")]
public string Value;
internal override void Generate(Hashtable context, ILGenerator ilgen)
{
ilgen.Emit(OpCodes.Ldstr, Value);
}
}
2003-11-17 15:01:50 +03:00
[XmlType("ldnull")]
public sealed class Ldnull : Simple
{
public Ldnull() : base(OpCodes.Ldnull)
{
}
}
2002-12-18 19:00:25 +03:00
[XmlType("call")]
public class Call : Instruction
{
public Call() : this(OpCodes.Call)
{
}
internal Call(OpCode opcode)
{
this.opcode = opcode;
}
[XmlAttribute("class")]
public string Class;
2003-04-14 13:41:58 +04:00
[XmlAttribute("type")]
public string type;
2002-12-18 19:00:25 +03:00
[XmlAttribute("name")]
public string Name;
[XmlAttribute("sig")]
public string Sig;
2003-04-14 13:41:58 +04:00
private CodeEmitter emitter;
2002-12-18 19:00:25 +03:00
private OpCode opcode;
internal sealed override void Generate(Hashtable context, ILGenerator ilgen)
{
2003-04-14 13:41:58 +04:00
if(emitter == null)
2002-12-18 19:00:25 +03:00
{
2003-04-14 13:41:58 +04:00
Debug.Assert(Name != null);
if(Name == ".ctor")
2002-12-18 19:00:25 +03:00
{
2003-04-14 13:41:58 +04:00
Debug.Assert(Class == null && type != null);
Type[] argTypes = ClassLoaderWrapper.GetBootstrapClassLoader().ArgTypeListFromSig(Sig);
2003-08-21 14:06:34 +04:00
emitter = CodeEmitter.Create(opcode, Type.GetType(type, true).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard, argTypes, null));
2002-12-18 19:00:25 +03:00
}
else
{
2003-04-14 13:41:58 +04:00
Debug.Assert(Class == null ^ type == null);
if(Class != null)
2003-01-02 16:46:16 +03:00
{
2003-04-14 13:41:58 +04:00
Debug.Assert(Sig != null);
2003-08-13 19:00:41 +04:00
MethodWrapper method = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(Class).GetMethodWrapper(MethodDescriptor.FromNameSig(ClassLoaderWrapper.GetBootstrapClassLoader(), Name, Sig), false);
2004-04-23 18:21:43 +04:00
if(method == null)
2003-01-02 16:46:16 +03:00
{
2004-04-23 18:21:43 +04:00
throw new InvalidOperationException("method not found: " + Class + "." + Name + Sig);
}
if(opcode.Value == OpCodes.Call.Value)
{
emitter = method.EmitCall;
}
else if(opcode.Value == OpCodes.Callvirt.Value)
{
emitter = method.EmitCallvirt;
}
else if(opcode.Value == OpCodes.Newobj.Value)
{
emitter = method.EmitNewobj;
}
else
{
throw new InvalidOperationException();
2003-01-02 16:46:16 +03:00
}
2004-03-16 20:10:09 +03:00
// TODO this code is part of what Compiler.CastInterfaceArgs (in compiler.cs) does,
// it would be nice if we could avoid this duplication...
TypeWrapper[] argTypeWrappers = method.Descriptor.ArgTypeWrappers;
for(int i = 0; i < argTypeWrappers.Length; i++)
{
if(argTypeWrappers[i].IsGhost)
{
LocalBuilder[] temps = new LocalBuilder[argTypeWrappers.Length + (method.IsStatic ? 0 : 1)];
for(int j = temps.Length - 1; j >= 0; j--)
{
TypeWrapper tw;
if(method.IsStatic)
{
tw = argTypeWrappers[j];
}
else
{
if(j == 0)
{
tw = method.DeclaringType;
}
else
{
tw = argTypeWrappers[j - 1];
}
}
if(tw.IsGhost)
{
tw.EmitConvStackToParameterType(ilgen, tw);
}
temps[j] = ilgen.DeclareLocal(tw.TypeAsParameterType);
ilgen.Emit(OpCodes.Stloc, temps[j]);
}
for(int j = 0; j < temps.Length; j++)
{
ilgen.Emit(OpCodes.Ldloc, temps[j]);
}
break;
}
}
2003-01-02 16:46:16 +03:00
}
else
{
2003-04-14 13:41:58 +04:00
if(Sig != null)
{
Type[] argTypes = ClassLoaderWrapper.GetBootstrapClassLoader().ArgTypeListFromSig(Sig);
2003-08-21 14:06:34 +04:00
emitter = CodeEmitter.Create(opcode, Type.GetType(type, true).GetMethod(Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null, argTypes, null));
2003-04-14 13:41:58 +04:00
}
else
{
2003-08-21 14:06:34 +04:00
emitter = CodeEmitter.Create(opcode, Type.GetType(type, true).GetMethod(Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static));
2003-04-14 13:41:58 +04:00
}
2003-01-02 16:46:16 +03:00
}
2002-12-18 19:00:25 +03:00
}
2003-04-14 13:41:58 +04:00
if(emitter == null)
2002-12-18 19:00:25 +03:00
{
2004-01-11 16:14:42 +03:00
// TODO better error handling
2003-04-14 13:41:58 +04:00
throw new InvalidOperationException("method not found: " + Name);
2002-12-18 19:00:25 +03:00
}
}
2003-04-14 13:41:58 +04:00
emitter.Emit(ilgen);
2002-12-18 19:00:25 +03:00
}
}
[XmlType("callvirt")]
public sealed class Callvirt : Call
{
public Callvirt() : base(OpCodes.Callvirt)
{
}
}
[XmlType("newobj")]
public sealed class NewObj : Call
{
public NewObj() : base(OpCodes.Newobj)
{
}
}
public abstract class Simple : Instruction
{
private OpCode opcode;
public Simple(OpCode opcode)
{
this.opcode = opcode;
}
internal sealed override void Generate(Hashtable context, ILGenerator ilgen)
{
ilgen.Emit(opcode);
}
}
[XmlType("dup")]
public sealed class Dup : Simple
{
public Dup() : base(OpCodes.Dup)
{
}
}
[XmlType("pop")]
public sealed class Pop : Simple
{
public Pop() : base(OpCodes.Pop)
{
}
}
2004-01-11 16:14:42 +03:00
public abstract class TypeOrTypeWrapperInstruction : Instruction
2002-12-18 19:00:25 +03:00
{
[XmlAttribute("class")]
public string Class;
2003-04-14 13:41:58 +04:00
[XmlAttribute("type")]
public string type;
2004-01-11 16:14:42 +03:00
internal TypeWrapper typeWrapper;
internal Type typeType;
2002-12-18 19:00:25 +03:00
internal override void Generate(Hashtable context, ILGenerator ilgen)
{
2003-04-14 13:41:58 +04:00
if(typeWrapper == null && typeType == null)
2002-12-18 19:00:25 +03:00
{
2003-04-14 13:41:58 +04:00
Debug.Assert(Class == null ^ type == null);
if(Class != null)
{
typeWrapper = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(Class);
}
else
{
2003-08-21 14:06:34 +04:00
typeType = Type.GetType(type, true);
2003-04-14 13:41:58 +04:00
}
2002-12-18 19:00:25 +03:00
}
2003-04-14 13:41:58 +04:00
}
}
[XmlType("isinst")]
2004-01-11 16:14:42 +03:00
public sealed class IsInst : TypeOrTypeWrapperInstruction
2003-04-14 13:41:58 +04:00
{
2004-01-11 16:14:42 +03:00
public IsInst()
2003-04-14 13:41:58 +04:00
{
}
2004-01-11 16:14:42 +03:00
2004-03-08 18:18:47 +03:00
// TODO isinst is broken, because for Java types it returns true/false while for
// .NET types it returns null/reference.
2004-01-11 16:14:42 +03:00
internal override void Generate(Hashtable context, ILGenerator ilgen)
{
base.Generate(context, ilgen);
if(typeType != null)
{
ilgen.Emit(OpCodes.Isinst, typeType);
}
else
{
// NOTE we pass a null context, but that shouldn't be a problem, because
// typeWrapper should never be an UnloadableTypeWrapper
typeWrapper.EmitInstanceOf(null, ilgen);
}
}
2003-04-14 13:41:58 +04:00
}
[XmlType("castclass")]
2004-01-11 16:14:42 +03:00
public sealed class Castclass : TypeOrTypeWrapperInstruction
{
public Castclass()
{
}
internal override void Generate(Hashtable context, ILGenerator ilgen)
{
base.Generate(context, ilgen);
if(typeType != null)
{
ilgen.Emit(OpCodes.Castclass, typeType);
}
else
{
// NOTE we pass a null context, but that shouldn't be a problem, because
// typeWrapper should never be an UnloadableTypeWrapper
typeWrapper.EmitCheckcast(null, ilgen);
}
}
}
public abstract class TypeInstruction : Instruction
2003-04-14 13:41:58 +04:00
{
2004-01-11 16:14:42 +03:00
[XmlAttribute("type")]
public string type;
private OpCode opcode;
private Type typeType;
internal TypeInstruction(OpCode opcode)
2003-04-14 13:41:58 +04:00
{
2004-01-11 16:14:42 +03:00
this.opcode = opcode;
}
internal override void Generate(Hashtable context, ILGenerator ilgen)
{
if(typeType == null)
{
2004-02-10 20:16:35 +03:00
Debug.Assert(type != null);
2004-01-11 16:14:42 +03:00
typeType = Type.GetType(type, true);
}
ilgen.Emit(opcode, typeType);
2002-12-18 19:00:25 +03:00
}
}
2003-08-08 16:37:14 +04:00
[XmlType("unbox")]
public sealed class Unbox : TypeInstruction
{
public Unbox() : base(OpCodes.Unbox)
{
}
}
2003-11-17 15:01:50 +03:00
[XmlType("box")]
public sealed class Box : TypeInstruction
{
public Box() : base(OpCodes.Box)
{
}
}
2002-12-18 19:00:25 +03:00
public abstract class Branch : Instruction
{
private OpCode opcode;
public Branch(OpCode opcode)
{
this.opcode = opcode;
}
internal sealed override void Generate(Hashtable context, ILGenerator ilgen)
{
Label l;
if(context[Name] == null)
{
l = ilgen.DefineLabel();
context[Name] = l;
}
else
{
l = (Label)context[Name];
}
ilgen.Emit(opcode, l);
}
[XmlAttribute("name")]
public string Name;
}
[XmlType("brfalse")]
public sealed class BrFalse : Branch
{
public BrFalse() : base(OpCodes.Brfalse)
{
}
}
2003-04-14 13:41:58 +04:00
[XmlType("brtrue")]
public sealed class BrTrue : Branch
{
public BrTrue() : base(OpCodes.Brtrue)
{
}
}
2002-12-18 19:00:25 +03:00
[XmlType("br")]
public sealed class Br : Branch
{
public Br() : base(OpCodes.Br)
{
}
}
[XmlType("label")]
public sealed class BrLabel : Instruction
{
[XmlAttribute("name")]
public string Name;
internal override void Generate(Hashtable context, ILGenerator ilgen)
{
Label l;
if(context[Name] == null)
{
l = ilgen.DefineLabel();
context[Name] = l;
}
else
{
l = (Label)context[Name];
}
ilgen.MarkLabel(l);
}
}
[XmlType("stloc")]
public sealed class StLoc : Instruction
{
[XmlAttribute("name")]
public string Name;
[XmlAttribute("class")]
public string Class;
2003-04-14 13:41:58 +04:00
[XmlAttribute("type")]
public string type;
private TypeWrapper typeWrapper;
private Type typeType;
2002-12-18 19:00:25 +03:00
internal override void Generate(Hashtable context, ILGenerator ilgen)
{
LocalBuilder lb = (LocalBuilder)context[Name];
if(lb == null)
{
2003-04-14 13:41:58 +04:00
if(typeWrapper == null && typeType == null)
2002-12-18 19:00:25 +03:00
{
2003-04-14 13:41:58 +04:00
Debug.Assert(Class == null ^ type == null);
if(type != null)
{
2003-08-21 14:06:34 +04:00
typeType = Type.GetType(type, true);
2003-04-14 13:41:58 +04:00
}
else
{
typeWrapper = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(Class);
}
2002-12-18 19:00:25 +03:00
}
2004-01-11 16:14:42 +03:00
lb = ilgen.DeclareLocal(typeType != null ? typeType : typeWrapper.TypeAsTBD);
2002-12-18 19:00:25 +03:00
context[Name] = lb;
}
ilgen.Emit(OpCodes.Stloc, lb);
}
}
[XmlType("ldloc")]
public sealed class LdLoc : Instruction
{
[XmlAttribute("name")]
public string Name;
internal override void Generate(Hashtable context, ILGenerator ilgen)
{
ilgen.Emit(OpCodes.Ldloc, (LocalBuilder)context[Name]);
}
}
[XmlType("ldarg_0")]
public sealed class LdArg_0 : Simple
{
public LdArg_0() : base(OpCodes.Ldarg_0)
{
}
}
2003-01-02 16:46:16 +03:00
[XmlType("ldarg_1")]
public sealed class LdArg_1 : Simple
{
public LdArg_1() : base(OpCodes.Ldarg_1)
{
}
}
[XmlType("ldarg_2")]
public sealed class LdArg_2 : Simple
{
public LdArg_2() : base(OpCodes.Ldarg_2)
{
}
}
[XmlType("ldarg_3")]
public sealed class LdArg_3 : Simple
{
public LdArg_3() : base(OpCodes.Ldarg_3)
{
}
}
2004-06-14 14:36:38 +04:00
[XmlType("ldind_i1")]
public sealed class Ldind_i1 : Simple
{
public Ldind_i1() : base(OpCodes.Ldind_I1)
{
}
}
[XmlType("ldind_i2")]
public sealed class Ldind_i2 : Simple
{
public Ldind_i2() : base(OpCodes.Ldind_I2)
{
}
}
2003-08-08 16:37:14 +04:00
[XmlType("ldind_i4")]
public sealed class Ldind_i4 : Simple
{
public Ldind_i4() : base(OpCodes.Ldind_I4)
{
}
}
2004-06-14 14:36:38 +04:00
[XmlType("ldind_i8")]
public sealed class Ldind_i8 : Simple
{
public Ldind_i8() : base(OpCodes.Ldind_I8)
{
}
}
[XmlType("ldind_r4")]
public sealed class Ldind_r4 : Simple
{
public Ldind_r4() : base(OpCodes.Ldind_R4)
{
}
}
[XmlType("ldind_r8")]
public sealed class Ldind_r8 : Simple
{
public Ldind_r8() : base(OpCodes.Ldind_R8)
{
}
}
2002-12-18 19:00:25 +03:00
[XmlType("ret")]
public sealed class Ret : Simple
{
public Ret() : base(OpCodes.Ret)
{
}
}
2003-04-14 13:41:58 +04:00
[XmlType("throw")]
public sealed class Throw : Simple
{
public Throw() : base(OpCodes.Throw)
{
}
}
2004-03-08 18:18:47 +03:00
[XmlType("stsfld")]
public sealed class Stsfld : Instruction
{
[XmlAttribute("class")]
public string Class;
[XmlAttribute("name")]
public string Name;
[XmlAttribute("sig")]
public string Sig;
internal override void Generate(Hashtable context, ILGenerator ilgen)
{
2004-03-16 20:10:09 +03:00
ClassLoaderWrapper.LoadClassCritical(Class).GetFieldWrapper(Name, ClassLoaderWrapper.GetBootstrapClassLoader().FieldTypeWrapperFromSig(Sig)).EmitSet.Emit(ilgen);
2004-03-08 18:18:47 +03:00
}
}
[XmlType("ldc_i4_0")]
public sealed class Ldc_I4_0 : Simple
{
public Ldc_I4_0() : base(OpCodes.Ldc_I4_0)
{
}
}
2004-06-14 14:36:38 +04:00
[XmlType("conv_u1")]
public sealed class Conv_U1 : Simple
{
public Conv_U1() : base(OpCodes.Conv_U1)
{
}
}
[XmlType("conv_u2")]
public sealed class Conv_U2 : Simple
{
public Conv_U2() : base(OpCodes.Conv_U2)
{
}
}
[XmlType("conv_u4")]
public sealed class Conv_U4 : Simple
{
public Conv_U4() : base(OpCodes.Conv_U4)
{
}
}
[XmlType("conv_u8")]
public sealed class Conv_U8 : Simple
{
public Conv_U8() : base(OpCodes.Conv_U8)
{
}
}
2002-12-18 19:00:25 +03:00
public class InstructionList : CodeEmitter
{
[XmlElement(typeof(Ldstr))]
[XmlElement(typeof(Call))]
[XmlElement(typeof(Callvirt))]
[XmlElement(typeof(Dup))]
[XmlElement(typeof(Pop))]
[XmlElement(typeof(IsInst))]
2003-04-14 13:41:58 +04:00
[XmlElement(typeof(Castclass))]
2003-08-08 16:37:14 +04:00
[XmlElement(typeof(Unbox))]
2003-11-17 15:01:50 +03:00
[XmlElement(typeof(Box))]
2002-12-18 19:00:25 +03:00
[XmlElement(typeof(BrFalse))]
2003-04-14 13:41:58 +04:00
[XmlElement(typeof(BrTrue))]
2002-12-18 19:00:25 +03:00
[XmlElement(typeof(Br))]
[XmlElement(typeof(BrLabel))]
[XmlElement(typeof(NewObj))]
[XmlElement(typeof(StLoc))]
[XmlElement(typeof(LdLoc))]
[XmlElement(typeof(LdArg_0))]
2003-01-02 16:46:16 +03:00
[XmlElement(typeof(LdArg_1))]
[XmlElement(typeof(LdArg_2))]
[XmlElement(typeof(LdArg_3))]
2004-06-14 14:36:38 +04:00
[XmlElement(typeof(Ldind_i1))]
[XmlElement(typeof(Ldind_i2))]
2003-08-08 16:37:14 +04:00
[XmlElement(typeof(Ldind_i4))]
2004-06-14 14:36:38 +04:00
[XmlElement(typeof(Ldind_i8))]
[XmlElement(typeof(Ldind_r4))]
[XmlElement(typeof(Ldind_r8))]
2002-12-18 19:00:25 +03:00
[XmlElement(typeof(Ret))]
2003-04-14 13:41:58 +04:00
[XmlElement(typeof(Throw))]
2003-11-17 15:01:50 +03:00
[XmlElement(typeof(Ldnull))]
2004-03-08 18:18:47 +03:00
[XmlElement(typeof(Stsfld))]
[XmlElement(typeof(Ldc_I4_0))]
2004-06-14 14:36:38 +04:00
[XmlElement(typeof(Conv_U1))]
[XmlElement(typeof(Conv_U2))]
[XmlElement(typeof(Conv_U4))]
[XmlElement(typeof(Conv_U8))]
2002-12-18 19:00:25 +03:00
public Instruction[] invoke;
internal sealed override void Emit(ILGenerator ilgen)
{
Hashtable context = new Hashtable();
for(int i = 0; i < invoke.Length; i++)
{
invoke[i].Generate(context, ilgen);
}
}
}
2003-11-17 15:01:50 +03:00
public class Throws
{
[XmlAttribute("class")]
public string Class;
}
2002-12-18 19:00:25 +03:00
public class Constructor
{
[XmlAttribute("sig")]
public string Sig;
[XmlAttribute("modifiers")]
public MapModifiers Modifiers;
2004-03-08 18:18:47 +03:00
public InstructionList body;
public InstructionList alternateBody;
2002-12-18 19:00:25 +03:00
public Redirect redirect;
2003-11-17 15:01:50 +03:00
[XmlElement("throws", typeof(Throws))]
public Throws[] throws;
2002-12-18 19:00:25 +03:00
}
public class Redirect
{
[XmlAttribute("class")]
public string Class;
[XmlAttribute("name")]
public string Name;
[XmlAttribute("sig")]
public string Sig;
[XmlAttribute("type")]
public string Type;
}
public class Override
{
[XmlAttribute("name")]
public string Name;
}
2004-03-08 18:18:47 +03:00
public class Method
2002-12-18 19:00:25 +03:00
{
[XmlAttribute("name")]
public string Name;
[XmlAttribute("sig")]
public string Sig;
[XmlAttribute("modifiers")]
public MapModifiers Modifiers;
[XmlAttribute("type")]
public string Type;
2004-03-08 18:18:47 +03:00
public InstructionList body;
public InstructionList alternateBody;
2002-12-18 19:00:25 +03:00
public Redirect redirect;
public Override @override;
2003-11-17 15:01:50 +03:00
[XmlElement("throws", typeof(Throws))]
public Throws[] throws;
2002-12-18 19:00:25 +03:00
}
public class Field
{
[XmlAttribute("name")]
public string Name;
[XmlAttribute("sig")]
public string Sig;
[XmlAttribute("modifiers")]
public MapModifiers Modifiers;
2003-11-17 15:01:50 +03:00
[XmlAttribute("constant")]
public string Constant;
2002-12-18 19:00:25 +03:00
public Redirect redirect;
}
2002-12-27 12:01:16 +03:00
public class Interface
{
[XmlAttribute("class")]
public string Name;
}
2002-12-18 19:00:25 +03:00
[Flags]
public enum MapModifiers
{
[XmlEnum("public")]
Public = Modifiers.Public,
[XmlEnum("protected")]
Protected = Modifiers.Protected,
2003-11-17 15:01:50 +03:00
[XmlEnum("private")]
Private = Modifiers.Private,
2002-12-18 19:00:25 +03:00
[XmlEnum("final")]
Final = Modifiers.Final,
[XmlEnum("interface")]
Interface = Modifiers.Interface,
[XmlEnum("static")]
2003-10-17 12:08:31 +04:00
Static = Modifiers.Static,
[XmlEnum("abstract")]
Abstract = Modifiers.Abstract
2002-12-18 19:00:25 +03:00
}
2004-04-23 18:21:43 +04:00
public enum Scope
{
[XmlEnum("public")]
Public = 0,
[XmlEnum("private")]
Private = 1
}
2002-12-18 19:00:25 +03:00
[XmlType("class")]
public class Class
{
[XmlAttribute("name")]
public string Name;
2004-04-23 18:21:43 +04:00
[XmlAttribute("shadows")]
public string Shadows;
2002-12-18 19:00:25 +03:00
[XmlAttribute("modifiers")]
public MapModifiers Modifiers;
2004-04-23 18:21:43 +04:00
[XmlAttribute("scope")]
public Scope scope;
2002-12-18 19:00:25 +03:00
[XmlElement("constructor")]
public Constructor[] Constructors;
[XmlElement("method")]
public Method[] Methods;
[XmlElement("field")]
public Field[] Fields;
2002-12-27 12:01:16 +03:00
[XmlElement("implements")]
public Interface[] Interfaces;
2003-11-17 15:01:50 +03:00
[XmlElement("box")]
public InstructionList Box;
2004-03-08 18:18:47 +03:00
[XmlElement("clinit")]
public Method Clinit;
2002-12-18 19:00:25 +03:00
}
2003-12-20 01:19:18 +03:00
[XmlType("exception")]
public class ExceptionMapping
{
[XmlAttribute]
public string src;
[XmlAttribute]
public string dst;
public InstructionList code;
}
2002-12-18 19:00:25 +03:00
[XmlRoot("root")]
public class Root
{
2004-04-23 18:21:43 +04:00
public Class[] assembly;
2003-12-20 01:19:18 +03:00
public ExceptionMapping[] exceptionMappings;
2002-12-18 19:00:25 +03:00
}
}