예제 #1
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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));
            }
        }
예제 #5
0
        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();
            }
        }
예제 #6
0
        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();
            }
        }
예제 #8
0
        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);
        }