private void WriteResources(ModuleWriter writer) { // Compute the initial offsets. int numresources = resources.Count; int headerSize = numresources*12; int nextOffset = (int)writer.GetPosition() + headerSize + /*numresources*/4; // Sort the resources by name. resources.Sort(delegate(ResourceData r1, ResourceData r2) { return string.Compare(r1.Name, r2.Name); }); // Write the number of resources. writer.Write(numresources); // Write the resource headers. foreach(ResourceData resource in resources) { // Writer the resource metadata. uint name = RegisterString(resource.Name); int offset = nextOffset; int length = resource.Length; writer.Write(name); writer.Write(offset); writer.Write(length); // Increase the next offset. nextOffset += length; } // Write the resource data. foreach(ResourceData resource in resources) writer.Write(resource.File); }
public void Write(ModuleWriter writer) { // Create the header. ModuleHeader header = new ModuleHeader(); // Populate it. // Store the module type. header.moduleType = (uint)moduleType; // Write the header. header.Write(writer); // Prepare the members. globalNamespace.PrepareSerialization(); foreach(ScopeMember instance in genericInstances) instance.PrepareSerialization(); // Prepare type referemnces. PrepareTypeReferences(); // Prepare resource writing. PrepareResources(); // Prepare debug information. DebugEmitter debugEmitter = null; if(debugBuild) { debugEmitter = new DebugEmitter(this); debugEmitter.Prepare(); globalNamespace.PrepareDebug(debugEmitter); } // Don't allow registering members. writingModule = true; // Write the members. header.memberTableOffset = writer.GetPosition(); foreach(ScopeMember member in memberTable) { // Write local members, and a pointer for the externals. ChelaModule memberModule = member.GetModule(); if(memberModule == this) { member.Write(writer); } else { // Don't write external generic instances. if(member.GetGenericInstance() != null) throw new ModuleException("Write external generic instance."); // Create the member reference header. MemberHeader mheader = new MemberHeader(); mheader.memberSize = 1; mheader.memberName = RegisterString(member.GetFullName()); // TODO: Use mangled name. mheader.memberType = (byte)MemberHeaderType.Reference; // Write the reference header and module id. mheader.Write(writer); writer.Write((byte)AddReference(memberModule)); } } header.memberTableSize = writer.GetPosition() - header.memberTableOffset; // Write module references. header.moduleRefTableOffset = writer.GetPosition(); header.moduleRefTableEntries = (uint) (referencedModules.Count + 1); // Write myself. ModuleReference modRef = new ModuleReference(); modRef.moduleName = RegisterString(GetName()); modRef.Write(writer); // Write module references. foreach(ChelaModule mod in referencedModules) { modRef.moduleName = RegisterString(mod.GetName()); modRef.Write(writer); } // Write the libraries table. header.libTableOffset = writer.GetPosition(); header.libTableEntries = (uint)nativeLibraries.Count; foreach(string libname in nativeLibraries) writer.Write(RegisterString(libname)); // Write the anonymous types. header.anonTypeTableOffset = writer.GetPosition(); WriteAnonType(writer); header.anonTypeTableSize = writer.GetPosition() - header.anonTypeTableOffset; // Write the type table. header.typeTableOffset = writer.GetPosition(); header.typeTableEntries = (uint)typeTable.Count; TypeReference typeRef = new TypeReference(); foreach(IChelaType type in typeTable) { // Write the type kind. if(type.IsTypeInstance()) typeRef.typeKind = (byte)TypeKind.Instance; else if(type.IsStructure()) typeRef.typeKind = (byte)TypeKind.Structure; else if(type.IsClass()) typeRef.typeKind = (byte)TypeKind.Class; else if(type.IsInterface()) typeRef.typeKind = (byte)TypeKind.Interface; else if(type.IsFunction()) typeRef.typeKind = (byte)TypeKind.Function; else if(type.IsReference()) typeRef.typeKind = (byte)TypeKind.Reference; else if(type.IsPointer()) typeRef.typeKind = (byte)TypeKind.Pointer; else if(type.IsConstant()) typeRef.typeKind = (byte)TypeKind.Constant; else if(type.IsArray()) typeRef.typeKind = (byte)TypeKind.Array; else if(type.IsVector()) typeRef.typeKind = (byte)TypeKind.Vector; else if(type.IsMatrix()) typeRef.typeKind = (byte)TypeKind.Matrix; else if(type.IsPlaceHolderType()) typeRef.typeKind = (byte)TypeKind.PlaceHolder; if(!type.IsStructure() && !type.IsClass() && !type.IsInterface() && !type.IsTypeInstance()) { // Write a reference into the anonymous types. typeRef.memberId = (uint)anonymousTypeMap[type]; typeRef.typeName = 0;//RegisterString(type.GetName()); } else { // Write the type member reference. ScopeMember member = (ScopeMember)type; typeRef.memberId = RegisterMember(member); typeRef.typeName = 0;//RegisterString(type.GetName()); } // Write the type reference. typeRef.Write(writer); } // Write the string table. header.stringTableOffset = writer.GetPosition(); header.stringTableEntries = (uint)stringTable.Count; foreach(string s in stringTable) writer.Write(s); // Write the debug info if(debugBuild) { header.debugInfoOffset = writer.GetPosition(); debugEmitter.Write(writer); header.debugInfoSize = writer.GetPosition() - header.debugInfoOffset; } // Write the resources. header.resourceDataOffset = writer.GetPosition(); WriteResources(writer); header.resourceDataSize = writer.GetPosition() - header.resourceDataOffset; // Store the module size. header.moduleSize = writer.GetPosition(); // Store the entry point. if(mainFunction != null) header.entryPoint = mainFunction.GetSerialId(); // Write the header again. writer.MoveBegin(); header.Write(writer); // Allow more modifications from here. writingModule = false; }