diff options
author | jfrijters <jfrijters> | 2009-05-12 08:00:01 +0400 |
---|---|---|
committer | jfrijters <jfrijters> | 2009-05-12 08:00:01 +0400 |
commit | c1553b7f1acf44c4cef0dceb24c9689c948b7120 (patch) | |
tree | 5264f7f9247657ebdb1e01ced56d22fcd2d111de /ikvmc/AotTypeWrapper.cs | |
parent | 7cb468fbecaa7aee251b3ae2b0c3f460787aad65 (diff) |
Refactored method call replacement to allow it to be used by others than xml mapping stuff.
Diffstat (limited to 'ikvmc/AotTypeWrapper.cs')
-rw-r--r-- | ikvmc/AotTypeWrapper.cs | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/ikvmc/AotTypeWrapper.cs b/ikvmc/AotTypeWrapper.cs index ddac8fab..1a9160c0 100644 --- a/ikvmc/AotTypeWrapper.cs +++ b/ikvmc/AotTypeWrapper.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2008 Jeroen Frijters + Copyright (C) 2002-2009 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 @@ -46,6 +46,7 @@ namespace IKVM.Internal private MethodBuilder ghostCastArrayMethod; private TypeBuilder typeBuilderGhostInterface; private Annotation annotation; + private MethodWrapper[] replacedMethods; internal AotTypeWrapper(ClassFile f, CompilerClassLoader loader) : base(f, loader) @@ -1011,5 +1012,68 @@ namespace IKVM.Internal return annotation; } } + + private sealed class ReplacedMethodWrapper : MethodWrapper + { + private IKVM.Internal.MapXml.InstructionList code; + + internal ReplacedMethodWrapper(TypeWrapper tw, string name, string sig, IKVM.Internal.MapXml.InstructionList code) + : base(tw, name, sig, null, null, null, Modifiers.Public, MemberFlags.None) + { + this.code = code; + } + + internal ReplacedMethodWrapper(ClassFile.ConstantPoolItemMI cpi, IKVM.Internal.MapXml.InstructionList code) + : base(cpi.GetClassType(), cpi.Name, cpi.Signature, null, cpi.GetRetType(), cpi.GetArgTypes(), Modifiers.Public, MemberFlags.None) + { + this.code = code; + } + + protected override void DoLinkMethod() + { + } + + internal override void EmitCall(CodeEmitter ilgen) + { + code.Emit(DeclaringType.GetClassLoader(), ilgen); + } + + internal override void EmitCallvirt(CodeEmitter ilgen) + { + code.Emit(DeclaringType.GetClassLoader(), ilgen); + } + + internal override void EmitNewobj(CodeEmitter ilgen, MethodAnalyzer ma, int opcodeIndex) + { + code.Emit(DeclaringType.GetClassLoader(), ilgen); + } + } + + internal override MethodWrapper[] GetReplacedMethodsFor(MethodWrapper mw) + { + IKVM.Internal.MapXml.ReplaceMethodCall[] replacedMethods = ((CompilerClassLoader)GetClassLoader()).GetReplacedMethodsFor(mw); + MethodWrapper[] baseReplacedMethodWrappers = base.GetReplacedMethodsFor(mw); + if (replacedMethods != null || baseReplacedMethodWrappers != null || this.replacedMethods != null) + { + List<MethodWrapper> list = new List<MethodWrapper>(); + if (replacedMethods != null) + { + for (int i = 0; i < replacedMethods.Length; i++) + { + list.Add(new ReplacedMethodWrapper(GetClassLoader().LoadClassByDottedName(replacedMethods[i].Class), replacedMethods[i].Name, replacedMethods[i].Sig, replacedMethods[i].code)); + } + } + if (baseReplacedMethodWrappers != null) + { + list.AddRange(baseReplacedMethodWrappers); + } + if (this.replacedMethods != null) + { + list.AddRange(this.replacedMethods); + } + return list.ToArray(); + } + return null; + } } } |