From 58b69bab3b91ded13425457ea0ddcdc05866d77e Mon Sep 17 00:00:00 2001 From: jfrijters Date: Thu, 19 Apr 2012 12:14:51 +0000 Subject: [PATCH] - Added ModuleBuilder.__GetAssemblyToken() API. - Changed assembly refs to use general pseudo mechanism, instead of its own special case. --- reflect/Emit/ModuleBuilder.cs | 40 ++++++++++++++--------------------- reflect/Metadata/Tables.cs | 24 +++++++++++++++++++++ reflect/Writer/TextSection.cs | 3 +++ 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/reflect/Emit/ModuleBuilder.cs b/reflect/Emit/ModuleBuilder.cs index 41ebeffc..945d2392 100644 --- a/reflect/Emit/ModuleBuilder.cs +++ b/reflect/Emit/ModuleBuilder.cs @@ -499,6 +499,11 @@ namespace IKVM.Reflection.Emit return symbolWriter.DefineDocument(url, language, languageVendor, documentType); } + public int __GetAssemblyToken(Assembly assembly) + { + return ImportAssemblyRef(assembly); + } + public TypeToken GetTypeToken(string name) { return new TypeToken(GetType(name, true, false).MetadataToken); @@ -687,9 +692,7 @@ namespace IKVM.Reflection.Emit { // We can't write the AssemblyRef record here yet, because the identity of the assembly can still change // (if it's an AssemblyBuilder). - // We set the high bit of rid in the token to make sure we emit obviously broken metadata, - // if we forget to patch up the token somewhere. - token = 0x23800001 + referencedAssemblies.Count; + token = AllocPseudoToken(); referencedAssemblies.Add(asm, token); } return token; @@ -697,30 +700,11 @@ namespace IKVM.Reflection.Emit internal void FillAssemblyRefTable() { - int[] realtokens = new int[referencedAssemblies.Count]; foreach (KeyValuePair kv in referencedAssemblies) { - if ((kv.Value & 0x7F800000) == 0x23800000) + if (IsPseudoToken(kv.Value)) { - realtokens[(kv.Value & 0x7FFFFF) - 1] = FindOrAddAssemblyRef(kv.Key.GetName(), false); - } - } - // now fixup the resolution scopes in TypeRef - for (int i = 0; i < this.TypeRef.records.Length; i++) - { - int resolutionScope = this.TypeRef.records[i].ResolutionScope; - if ((resolutionScope & 0x7F800000) == 0x23800000) - { - this.TypeRef.records[i].ResolutionScope = realtokens[(resolutionScope & 0x7FFFFF) - 1]; - } - } - // and implementation in ExportedType - for (int i = 0; i < this.ExportedType.records.Length; i++) - { - int implementation = this.ExportedType.records[i].Implementation; - if ((implementation & 0x7F800000) == 0x23800000) - { - this.ExportedType.records[i].Implementation = realtokens[(implementation & 0x7FFFFF) - 1]; + RegisterTokenFixup(kv.Value, FindOrAddAssemblyRef(kv.Key.GetName(), false)); } } } @@ -1582,6 +1566,14 @@ namespace IKVM.Reflection.Emit } } } + + internal void FixupPseudoToken(ref int token) + { + if (IsPseudoToken(token)) + { + token = ResolvePseudoToken(token); + } + } } struct UnmanagedExport diff --git a/reflect/Metadata/Tables.cs b/reflect/Metadata/Tables.cs index d39e9f65..13207951 100644 --- a/reflect/Metadata/Tables.cs +++ b/reflect/Metadata/Tables.cs @@ -670,6 +670,14 @@ namespace IKVM.Reflection.Metadata .WriteStringIndex() .Value; } + + internal void Fixup(ModuleBuilder moduleBuilder) + { + for (int i = 0; i < rowCount; i++) + { + moduleBuilder.FixupPseudoToken(ref records[i].ResolutionScope); + } + } } sealed class TypeDefTable : Table @@ -2423,6 +2431,14 @@ namespace IKVM.Reflection.Metadata } return AddRecord(rec); } + + internal void Fixup(ModuleBuilder moduleBuilder) + { + for (int i = 0; i < rowCount; i++) + { + moduleBuilder.FixupPseudoToken(ref records[i].Implementation); + } + } } sealed class ManifestResourceTable : Table @@ -2467,6 +2483,14 @@ namespace IKVM.Reflection.Metadata .WriteImplementation() .Value; } + + internal void Fixup(ModuleBuilder moduleBuilder) + { + for (int i = 0; i < rowCount; i++) + { + moduleBuilder.FixupPseudoToken(ref records[i].Implementation); + } + } } sealed class NestedClassTable : SortedTable diff --git a/reflect/Writer/TextSection.cs b/reflect/Writer/TextSection.cs index 2cb91efd..5462b3be 100644 --- a/reflect/Writer/TextSection.cs +++ b/reflect/Writer/TextSection.cs @@ -299,6 +299,7 @@ namespace IKVM.Reflection.Writer internal void Write(MetadataWriter mw, uint sdataRVA) { // Now that we're ready to start writing, we need to do some fix ups + moduleBuilder.TypeRef.Fixup(moduleBuilder); moduleBuilder.MethodDef.Fixup(this); moduleBuilder.MethodImpl.Fixup(moduleBuilder); moduleBuilder.MethodSemantics.Fixup(moduleBuilder); @@ -313,6 +314,8 @@ namespace IKVM.Reflection.Writer moduleBuilder.FieldLayout.Fixup(moduleBuilder); moduleBuilder.FieldRVA.Fixup(moduleBuilder, (int)sdataRVA, (int)this.MethodBodiesRVA); moduleBuilder.ImplMap.Fixup(moduleBuilder); + moduleBuilder.ExportedType.Fixup(moduleBuilder); + moduleBuilder.ManifestResource.Fixup(moduleBuilder); moduleBuilder.MethodSpec.Fixup(moduleBuilder); moduleBuilder.GenericParamConstraint.Fixup(moduleBuilder);