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."); } } }
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; }