private void InitializeTypeForwarder(ForwarderKey key, TypeForwarder record) { Cts.Ecma.EcmaModule module = key.Module; Ecma.MetadataReader reader = module.MetadataReader; Ecma.ExportedType exportedType = reader.GetExportedType(key.ExportedType); record.Name = HandleString(reader.GetString(exportedType.Name)); switch (exportedType.Implementation.Kind) { case Ecma.HandleKind.AssemblyReference: { string ns = reader.GetString(exportedType.Namespace); NamespaceDefinition namespaceDefinition = HandleNamespaceDefinition(module, ns); Ecma.AssemblyReference assemblyRef = reader.GetAssemblyReference((Ecma.AssemblyReferenceHandle)exportedType.Implementation); AssemblyName refName = new AssemblyName { ContentType = (AssemblyContentType)((int)(assemblyRef.Flags & AssemblyFlags.ContentTypeMask) >> 9), Flags = (AssemblyNameFlags)(assemblyRef.Flags & ~AssemblyFlags.ContentTypeMask), CultureName = reader.GetString(assemblyRef.Culture), Name = reader.GetString(assemblyRef.Name), Version = assemblyRef.Version, }; if ((assemblyRef.Flags & AssemblyFlags.PublicKey) != 0) { refName.SetPublicKey(reader.GetBlobBytes(assemblyRef.PublicKeyOrToken)); } else { refName.SetPublicKeyToken(reader.GetBlobBytes(assemblyRef.PublicKeyOrToken)); } record.Scope = HandleScopeReference(refName); namespaceDefinition.TypeForwarders.Add(record); } break; case Ecma.HandleKind.ExportedType: { TypeForwarder scope = HandleTypeForwarder(module, (Ecma.ExportedTypeHandle)exportedType.Implementation); record.Scope = scope.Scope; scope.NestedTypes.Add(record); } break; default: throw new BadImageFormatException(); } }
internal sealed override RuntimeTypeInfo UncachedGetTypeCoreCaseSensitive(string fullName) { string[] parts = fullName.Split('.'); int numNamespaceParts = parts.Length - 1; string[] namespaceParts = new string[numNamespaceParts]; for (int i = 0; i < numNamespaceParts; i++) { namespaceParts[numNamespaceParts - i - 1] = parts[i]; } string name = parts[numNamespaceParts]; foreach (QScopeDefinition scopeDefinition in AllScopes) { MetadataReader reader = scopeDefinition.Reader; ScopeDefinitionHandle scopeDefinitionHandle = scopeDefinition.Handle; NamespaceDefinition namespaceDefinition; if (!TryResolveNamespaceDefinitionCaseSensitive(reader, namespaceParts, scopeDefinitionHandle, out namespaceDefinition)) { continue; } // We've successfully drilled down the namespace chain. Now look for a top-level type matching the type name. TypeDefinitionHandleCollection candidateTypes = namespaceDefinition.TypeDefinitions; foreach (TypeDefinitionHandle candidateType in candidateTypes) { TypeDefinition typeDefinition = candidateType.GetTypeDefinition(reader); if (typeDefinition.Name.StringEquals(name, reader)) { return(candidateType.ResolveTypeDefinition(reader)); } } // No match found in this assembly - see if there's a matching type forwarder. TypeForwarderHandleCollection candidateTypeForwarders = namespaceDefinition.TypeForwarders; foreach (TypeForwarderHandle typeForwarderHandle in candidateTypeForwarders) { TypeForwarder typeForwarder = typeForwarderHandle.GetTypeForwarder(reader); if (typeForwarder.Name.StringEquals(name, reader)) { RuntimeAssemblyName redirectedAssemblyName = typeForwarder.Scope.ToRuntimeAssemblyName(reader); RuntimeAssemblyInfo redirectedAssembly = RuntimeAssemblyInfo.GetRuntimeAssemblyIfExists(redirectedAssemblyName); if (redirectedAssembly == null) { return(null); } return(redirectedAssembly.GetTypeCoreCaseSensitive(fullName)); } } } return(null); }
private TypeForwarder HandleTypeForwarder(Cts.Ecma.EcmaModule module, Ecma.ExportedType exportedType) { Ecma.MetadataReader reader = module.MetadataReader; string name = reader.GetString(exportedType.Name); TypeForwarder result; switch (exportedType.Implementation.Kind) { case Ecma.HandleKind.AssemblyReference: { string ns = reader.GetString(exportedType.Namespace); NamespaceDefinition namespaceDefinition = HandleNamespaceDefinition(module, ns); Ecma.AssemblyReference assemblyRef = reader.GetAssemblyReference((Ecma.AssemblyReferenceHandle)exportedType.Implementation); AssemblyName refName = new AssemblyName { ContentType = (AssemblyContentType)((int)(assemblyRef.Flags & AssemblyFlags.ContentTypeMask) >> 9), Flags = (AssemblyNameFlags)(assemblyRef.Flags & ~AssemblyFlags.ContentTypeMask), CultureName = reader.GetString(assemblyRef.Culture), Name = reader.GetString(assemblyRef.Name), Version = assemblyRef.Version, }; result = new TypeForwarder { Name = HandleString(name), Scope = HandleScopeReference(refName), }; namespaceDefinition.TypeForwarders.Add(result); } break; case Ecma.HandleKind.ExportedType: { TypeForwarder scope = HandleTypeForwarder(module, reader.GetExportedType((Ecma.ExportedTypeHandle)exportedType.Implementation)); result = new TypeForwarder { Name = HandleString(name), Scope = scope.Scope, }; scope.NestedTypes.Add(result); } break; default: throw new BadImageFormatException(); } return(result); }
private Exception UncachedTryResolveCaseSensitive(ReflectionDomain reflectionDomain, RuntimeAssembly currentAssembly, out RuntimeType result) { result = null; foreach (QScopeDefinition scopeDefinition in currentAssembly.AllScopes) { MetadataReader reader = scopeDefinition.Reader; ScopeDefinitionHandle scopeDefinitionHandle = scopeDefinition.Handle; NamespaceDefinition namespaceDefinition; if (!TryResolveNamespaceDefinitionCaseSensitive(reader, scopeDefinitionHandle, out namespaceDefinition)) { continue; } // We've successfully drilled down the namespace chain. Now look for a top-level type matching the type name. IEnumerable <TypeDefinitionHandle> candidateTypes = namespaceDefinition.TypeDefinitions; foreach (TypeDefinitionHandle candidateType in candidateTypes) { TypeDefinition typeDefinition = candidateType.GetTypeDefinition(reader); if (typeDefinition.Name.StringEquals(_name, reader)) { result = reflectionDomain.ResolveTypeDefinition(reader, candidateType); return(null); } } // No match found in this assembly - see if there's a matching type forwarder. IEnumerable <TypeForwarderHandle> candidateTypeForwarders = namespaceDefinition.TypeForwarders; foreach (TypeForwarderHandle typeForwarderHandle in candidateTypeForwarders) { TypeForwarder typeForwarder = typeForwarderHandle.GetTypeForwarder(reader); if (typeForwarder.Name.StringEquals(_name, reader)) { RuntimeAssemblyName redirectedAssemblyName = typeForwarder.Scope.ToRuntimeAssemblyName(reader); AssemblyQualifiedTypeName redirectedTypeName = new AssemblyQualifiedTypeName(this, redirectedAssemblyName); return(redirectedTypeName.TryResolve(reflectionDomain, null, /*ignoreCase: */ false, out result)); } } } { String typeName = this.ToString(); String message = SR.Format(SR.TypeLoad_TypeNotFound, typeName, currentAssembly.FullName); return(ReflectionCoreNonPortable.CreateTypeLoadException(message, typeName)); } }
private Exception TryResolveCaseInsensitive(ReflectionDomain reflectionDomain, RuntimeAssembly currentAssembly, out RuntimeType result) { String fullName = this.ToString().ToLower(); LowLevelDictionary <String, QHandle> dict = GetCaseInsensitiveTypeDictionary(currentAssembly); QHandle qualifiedHandle; if (!dict.TryGetValue(fullName, out qualifiedHandle)) { result = null; return(new TypeLoadException(SR.Format(SR.TypeLoad_TypeNotFound, this.ToString(), currentAssembly.FullName))); } MetadataReader reader = qualifiedHandle.Reader; Handle typeDefOrForwarderHandle = qualifiedHandle.Handle; HandleType handleType = typeDefOrForwarderHandle.HandleType; switch (handleType) { case HandleType.TypeDefinition: { TypeDefinitionHandle typeDefinitionHandle = typeDefOrForwarderHandle.ToTypeDefinitionHandle(reader); result = reflectionDomain.ResolveTypeDefinition(reader, typeDefinitionHandle); return(null); } case HandleType.TypeForwarder: { TypeForwarder typeForwarder = typeDefOrForwarderHandle.ToTypeForwarderHandle(reader).GetTypeForwarder(reader); ScopeReferenceHandle destinationScope = typeForwarder.Scope; RuntimeAssemblyName destinationAssemblyName = destinationScope.ToRuntimeAssemblyName(reader); RuntimeAssembly destinationAssembly; Exception exception = RuntimeAssembly.TryGetRuntimeAssembly(reflectionDomain, destinationAssemblyName, out destinationAssembly); if (exception != null) { result = null; return(exception); } return(TryResolveCaseInsensitive(reflectionDomain, destinationAssembly, out result)); } default: throw new InvalidOperationException(); } }
private MetadataType ResolveExportedType(TypeForwarderHandle handle) { TypeForwarder typeForwarder = _metadataReader.GetTypeForwarder(handle); var module = GetModule(typeForwarder.Scope); string fullname = _metadataReader.GetString(typeForwarder.Name); int lastDotIndex = fullname.LastIndexOf('.'); string nameSpace = null; string name = fullname; if (lastDotIndex != -1) { nameSpace = fullname.Substring(0, lastDotIndex); name = fullname.Substring(lastDotIndex + 1); } return(module.GetType(nameSpace, name)); }
internal sealed override RuntimeTypeInfo GetTypeCoreCaseInsensitive(string fullName) { LowLevelDictionary <string, QHandle> dict = CaseInsensitiveTypeDictionary; QHandle qualifiedHandle; if (!dict.TryGetValue(fullName.ToLowerInvariant(), out qualifiedHandle)) { return(null); } MetadataReader reader = qualifiedHandle.Reader; Handle typeDefOrForwarderHandle = qualifiedHandle.Handle; HandleType handleType = typeDefOrForwarderHandle.HandleType; switch (handleType) { case HandleType.TypeDefinition: { TypeDefinitionHandle typeDefinitionHandle = typeDefOrForwarderHandle.ToTypeDefinitionHandle(reader); return(typeDefinitionHandle.ResolveTypeDefinition(reader)); } case HandleType.TypeForwarder: { TypeForwarder typeForwarder = typeDefOrForwarderHandle.ToTypeForwarderHandle(reader).GetTypeForwarder(reader); ScopeReferenceHandle destinationScope = typeForwarder.Scope; RuntimeAssemblyName destinationAssemblyName = destinationScope.ToRuntimeAssemblyName(reader); RuntimeAssemblyInfo destinationAssembly = RuntimeAssemblyInfo.GetRuntimeAssemblyIfExists(destinationAssemblyName); if (destinationAssembly == null) { return(null); } return(destinationAssembly.GetTypeCoreCaseInsensitive(fullName)); } default: throw new InvalidOperationException(); } }
public static RuntimeIshtarModule Read(AppVault vault, byte[] arr, IReadOnlyList <VeinModule> deps, Func <string, Version, VeinModule> resolver) { var module = new RuntimeIshtarModule(vault); using var mem = new MemoryStream(arr); using var reader = new BinaryReader(mem); module.Deps.AddRange(deps); var idx = reader.ReadInt32(); // name index var vdx = reader.ReadInt32(); // version index var ilVersion = reader.ReadInt32(); if (ilVersion != OpCodes.SetVersion) { var exp = new ILCompatibleException(ilVersion, OpCodes.SetVersion); VM.FastFail(WNE.ASSEMBLY_COULD_NOT_LOAD, $"Unable to load assembly: '{exp.Message}'.", sys_frame); VM.ValidateLastError(); return(null); } // read strings table foreach (var _ in..reader.ReadInt32()) { var key = reader.ReadInt32(); var value = reader.ReadIshtarString(); module.strings_table.Add(key, value); } // read types table foreach (var _ in..reader.ReadInt32()) { var key = reader.ReadInt32(); var asmName = reader.ReadIshtarString(); var ns = reader.ReadIshtarString(); var name = reader.ReadIshtarString(); module.types_table.Add(key, new QualityTypeName(asmName, name, ns)); } // read fields table foreach (var _ in..reader.ReadInt32()) { var key = reader.ReadInt32(); var name = reader.ReadIshtarString(); var clazz = reader.ReadIshtarString(); module.fields_table.Add(key, new FieldName(name, clazz)); } // read deps refs foreach (var _ in..reader.ReadInt32()) { var name = reader.ReadIshtarString(); var ver = Version.Parse(reader.ReadIshtarString()); if (module.Deps.Any(x => x.Version.Equals(ver) && x.Name.Equals(name))) { continue; } var dep = resolver(name, ver); module.Deps.Add(dep); } // read class storage foreach (var _ in..reader.ReadInt32()) { var body = reader.ReadBytes(reader.ReadInt32()); var @class = DecodeClass(body, module); module.class_table.Add(@class); if (@class.IsSpecial) { if (VeinCore.All.Any(x => x.FullName == @class.FullName)) { TypeForwarder.Indicate(@class); } } } // restore unresolved types foreach (var @class in module.class_table) { for (var index = 0; index < @class.Parents.Count; index++) { var parent = @class.Parents[index]; if (parent is not UnresolvedVeinClass) { continue; } @class.Parents[index] = parent.FullName != @class.FullName ? module.FindType(parent.FullName, true) : null; } } // restore unresolved types foreach (var @class in module.class_table) { foreach (var method in @class.Methods) { if (method.ReturnType is not UnresolvedVeinClass) { continue; } method.ReturnType = module.FindType(method.ReturnType.FullName, true); } foreach (var method in @class.Methods) { foreach (var argument in method.Arguments) { if (argument.Type is not UnresolvedVeinClass) { continue; } argument.Type = module.FindType(argument.Type.FullName, true); } } foreach (var field in @class.Fields) { if (field.FieldType is not UnresolvedVeinClass) { continue; } field.FieldType = module.FindType(field.FieldType.FullName, true); } } var const_body_len = reader.ReadInt32(); var const_body = reader.ReadBytes(const_body_len); module.const_table = const_body.ToConstStorage(); module.Name = module.GetConstStringByIndex(idx); module.Version = Version.Parse(module.GetConstStringByIndex(vdx)); module.aspects.AddRange(Aspect.Deconstruct(module.const_table.storage)); module.SetupBootstraper(vault); DistributionAspects(module); ValidateRuntimeTokens(module); LinkFFIMethods(module); InitVTables(module); return(module); }