示例#1
0
        private void WriteAnonType(ModuleWriter writer)
        {
            AnonTypeHeader header = new AnonTypeHeader();

            foreach(IChelaType anonType in anonymousTypes)
            {
                if(anonType.IsReference())
                {
                    // Write the header.
                    ReferenceType refType = (ReferenceType) anonType;
                    header.typeKind = (byte) TypeKind.Reference;
                    header.recordSize = 6;
                    header.Write(writer);

                    // Write the referenced type.
                    writer.Write((uint)RegisterType(refType.GetReferencedType()));
                    writer.Write((byte)refType.GetReferenceFlow());
                    writer.Write((byte)(refType.IsStreamReference() ? 1 : 0));
                }
                else if(anonType.IsPointer())
                {
                    // Write the header.
                    PointerType pointerType = (PointerType) anonType;
                    header.typeKind = (byte) TypeKind.Pointer;
                    header.recordSize = 4;
                    header.Write(writer);

                    // Write the referenced type.
                    writer.Write((uint)RegisterType(pointerType.GetPointedType()));

                }
                else if(anonType.IsConstant())
                {
                    // Write the header.
                    ConstantType constantType = (ConstantType) anonType;
                    header.typeKind = (byte) TypeKind.Constant;
                    header.recordSize = 4;
                    header.Write(writer);

                    // Write the value type.
                    writer.Write((uint)RegisterType(constantType.GetValueType()));
                }
                else if(anonType.IsArray())
                {
                    // Write the header.
                    ArrayType arrayType = (ArrayType) anonType;
                    header.typeKind = (byte) TypeKind.Array;
                    header.recordSize = 6;
                    header.Write(writer);

                    // Write the value type.
                    writer.Write((uint)RegisterType(arrayType.GetValueType()));
                    writer.Write((byte)arrayType.GetDimensions());
                    writer.Write((byte)(arrayType.IsReadOnly() ? 1 : 0));
                }
                else if(anonType.IsVector())
                {
                    // Write the header.
                    VectorType vectorType = (VectorType)anonType;
                    header.typeKind = (byte)TypeKind.Vector;
                    header.recordSize = 5;
                    header.Write(writer);

                    // Write the primitive type.
                    writer.Write((uint)RegisterType(vectorType.GetPrimitiveType()));

                    // Write the number of components.
                    writer.Write((byte)vectorType.GetNumComponents());
                }
                else if(anonType.IsMatrix())
                {
                    // Write the header.
                    MatrixType matrixType = (MatrixType)anonType;
                    header.typeKind = (byte)TypeKind.Matrix;
                    header.recordSize = 6;
                    header.Write(writer);

                    // Write the primitive type.
                    writer.Write((uint)RegisterType(matrixType.GetPrimitiveType()));

                    // Write the number of rows and columns.
                    writer.Write((byte)matrixType.GetNumRows());
                    writer.Write((byte)matrixType.GetNumColumns());
                }
                else if(anonType.IsFunction())
                {
                    // Get the type.
                    FunctionType functionType = (FunctionType) anonType;

                    // Write the header.
                    header.typeKind =(byte) TypeKind.Function;
                    header.recordSize = (uint)(functionType.GetArgumentCount()*4 + 8);
                    header.Write(writer);

                    // Write the flags.
                    int flags = (int)functionType.GetFunctionFlags();
                    flags |= functionType.HasVariableArgument() ? 1 : 0;
                    writer.Write((uint)flags);

                    // Write the return type.
                    writer.Write((uint)RegisterType(functionType.GetReturnType()));

                    // Write the arguments.
                    foreach(IChelaType arg in functionType.GetArguments())
                        writer.Write((uint)RegisterType(arg));
                }
                else if(anonType.IsPlaceHolderType())
                {
                    // Cast the type.
                    PlaceHolderType placeholder = (PlaceHolderType)anonType;

                    // Write the header.
                    header.typeKind =(byte) TypeKind.PlaceHolder;
                    header.recordSize = (uint)(placeholder.GetBaseCount()*4 + 10);
                    header.Write(writer);

                    // Write the name.
                    writer.Write((uint)RegisterString(placeholder.GetName()));

                    // Write the id.
                    writer.Write((uint)placeholder.GetPlaceHolderId());

                    // Write the value type flag.
                    writer.Write((byte) (placeholder.IsValueType() ? 1 : 0));

                    // Write the number of bases.
                    writer.Write((byte) placeholder.GetBaseCount());

                    // Write the bases.
                    for(int i = 0; i < placeholder.GetBaseCount(); ++i)
                        writer.Write((uint) RegisterMember(placeholder.GetBase(i)));
                }
                else
                {
                    throw new ModuleException("Trying to write an invalid anon type.");
                }
            }
        }
示例#2
0
        public static ChelaModule LoadModule(ModuleReader reader, bool fullLoad)
        {
            // Try to guess the file type.
            uint moduleStart = reader.GetPosition();
            byte[] signature;
            reader.Read(out signature, 8);

            // Check for elf file type.
            bool isElf = true;
            for(int i = 0; i < 4; ++i)
            {
                if(signature[i] != ElfFormat.ElfMagic[i])
                {
                    isElf = false;
                    break;
                }
            }

            // Check for PE.
            bool isPE = signature[0] == 'M' && signature[1] == 'Z';

            // Find the module content.
            reader.SetPosition(moduleStart);
            if(isElf)
            {
                // Move to the embedded module.
                ElfFormat.GetEmbeddedModule(reader);
                reader.FixBase();
            }
            else if(isPE)
            {
                // Move to the embedded module.
                PEFormat.GetEmbeddedModule(reader);
                reader.FixBase();
            }

            // Read the module header.
            ModuleHeader header = new ModuleHeader();
            header.Read(reader);

            // Create the output module.
            ChelaModule result = new ChelaModule();

            // Read the string table.
            reader.SetPosition(header.stringTableOffset);
            for(uint i = 0; i < header.stringTableEntries; ++i)
            {
                uint id = i+1u;
                string s = reader.ReadString();
                result.stringTable.Add(s);
                result.registeredStrings.Add(s, id);
            }

            // Read myself data.
            ModuleReference modref = new ModuleReference();
            reader.SetPosition(header.moduleRefTableOffset);
            modref.Read(reader);
            result.SetName(result.GetString(modref.moduleName));

            // Read the module type.
            result.moduleType = (ModuleType)header.moduleType;

            // Read the referenced modules.
            for(uint i = 1; i < header.moduleRefTableEntries; ++i)
            {
                // Read the referenced module.
                modref.Read(reader);

                // Load it.
                ChelaModule referencedModule = LoadNamedModule(result.GetString(modref.moduleName));
                result.referencedModules.Add(referencedModule);
            }

            // Preload the members.
            reader.SetPosition(header.memberTableOffset);
            uint end = header.memberTableOffset + header.memberTableSize;
            MemberHeader mheader = new MemberHeader();
            while(reader.GetPosition() < end)
            {
                // Read the member header.
                mheader.Read(reader);

                // Skip the attributes.
                SkipAttributes(reader, mheader.memberAttributes);

                // Preload the member.
                MemberHeaderType mtype = (MemberHeaderType)mheader.memberType;
                switch(mtype)
                {
                case MemberHeaderType.Namespace:
                    Namespace.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.Structure:
                    Structure.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.Class:
                    Class.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.Interface:
                    Interface.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.Function:
                    Function.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.Field:
                    FieldVariable.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.FunctionGroup:
                    FunctionGroup.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.TypeInstance:
                    StructureInstance.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.Property:
                    PropertyVariable.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.Event:
                    EventVariable.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.TypeName:
                    TypeNameMember.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.MemberInstance:
                case MemberHeaderType.FunctionInstance:
                    // Ignore the member instance.
                    result.memberTable.Add(null);
                    reader.Skip(mheader.memberSize);
                    break;
                case MemberHeaderType.TypeGroup:
                    TypeGroup.PreloadMember(result, reader, mheader);
                    break;
                case MemberHeaderType.Reference:
                    {
                        // Read the module id.
                        byte moduleId = reader.ReadByte();

                        // Get the referenced module.
                        ChelaModule refMod = result.GetReferenced(moduleId);

                        // Find the member there.
                        ScopeMember member = refMod.GetMember(result.GetString(mheader.memberName));
                        result.memberTable.Add(member);
                    }
                    break;
                default:
                    // Unknown member.
                    System.Console.WriteLine("add unknown member {0}", mtype);
                    result.memberTable.Add(null);
                    reader.Skip(mheader.memberSize);
                    break;
                }
            }

            // Read the type table.
            reader.SetPosition(header.typeTableOffset);
            for(uint i = 0; i < header.typeTableEntries; ++i)
            {
                // Read the type reference.
                TypeReference typeRef = new TypeReference();
                typeRef.Read(reader);

                // Try to load direct members.
                TypeKind kind = (ChelaModule.TypeKind)typeRef.typeKind;
                if(kind == TypeKind.Class || kind == TypeKind.Interface ||
                   kind == TypeKind.Structure || kind == TypeKind.Instance)
                {
                    // Store the actual type.
                    result.typeTable.Add(result.GetMember(typeRef.memberId));
                }
                else
                {
                    // Store the reference for delayed loading.
                    result.typeTable.Add(typeRef);
                }
            }

            // Read the anonymous types.
            reader.SetPosition(header.anonTypeTableOffset);
            end = header.anonTypeTableOffset + header.anonTypeTableSize;
            while(reader.GetPosition() < end)
            {
                // Read the anonymous type data.
                AnonTypeHeader anonType = new AnonTypeHeader();
                anonType.Read(reader);

                // Store it in the anonymous type table.
                result.anonymousTypes.Add(anonType);
            }

            // Now, read the actual members.
            reader.SetPosition(header.memberTableOffset);
            for(int i = 0; i < result.memberTable.Count; ++i)
            {
                // Get the preloaded member.
                ScopeMember member = result.memberTable[i];

                // Read his header.
                mheader.Read(reader);

                // Skip the attributes.
                SkipAttributes(reader, mheader.memberAttributes);

                // Read the member.
                if(member != null && mheader.memberType != (int)MemberHeaderType.Reference)
                    member.Read(reader, mheader);
                else
                    reader.Skip(mheader.memberSize); // Skip unknown members.
            }

            // The first member must be the global namespace.
            result.globalNamespace = (Namespace)result.GetMember(1);

            // Update the parent children relationship.
            result.globalNamespace.UpdateParent(null);

            // Now, perform second read pass, required by function groups.
            reader.SetPosition(header.memberTableOffset);
            for(int i = 0; i < result.memberTable.Count; ++i)
            {
                // Get the preloaded member.
                ScopeMember member = result.memberTable[i];

                // Read his header.
                mheader.Read(reader);

                // Skip the attributes.
                SkipAttributes(reader, mheader.memberAttributes);

                // Read the member.
                if(member != null && mheader.memberType != (int)MemberHeaderType.Reference)
                    member.Read2(reader, mheader);
                else
                    reader.Skip(mheader.memberSize); // Skip unknown members.
            }

            // Finish all of the loading.
            result.globalNamespace.FinishLoad();

            // Register the member names.
            for(int i = 0; i < result.memberTable.Count; ++i)
            {
                ScopeMember member = result.memberTable[i];
                if(member != null)
                    result.memberNameTable[member.GetFullName()] = member;
            }

            // Load the runtime classes.
            if(result.referencedModules.Count == 0)
                result.LoadRuntimeReferences(result);

            // Dump the readed module.
            //result.Dump();

            // Return the result module.
            return result;
        }