public static void SaveInt32(BinaryModule module, int offset, int val) { //module.DataSection.Blob[offset] = (byte) ((val) & 0xFF); //module.DataSection.Blob[offset + 1] = (byte) ((val >> 8) & 0xFF); //module.DataSection.Blob[offset + 2] = (byte) ((val >> 16) & 0xFF); //module.DataSection.Blob[offset + 3] = (byte) ((val >> 24) & 0xFF); }
public static void Import(string moduleName) { if (!ModuleHeaders.ContainsKey(moduleName)) { // 避免重复导入 if (File.Exists(Path.Combine(DirName, moduleName + ".xibc"))) { ModuleHeaders.Add(moduleName, BinaryModule.Load(Path.Combine(DirName, moduleName + ".xibc"))); } else if (File.Exists(Path.Combine(DirName, moduleName + ".xi"))) { // 可能需要共同编译,因为也许互相有依赖 // 一个可能的想法是层序遍历,先声明所有的class,再声明所有的类成员,再定义所有的类成员 throw new NotImplementedException(); } else { throw new XiLangError($"{moduleName} not found"); } } }
public void Dump(string dirName, bool dumpXir = true) { if (string.IsNullOrEmpty(dirName)) { dirName = "."; } BinaryModule binaryModule = Module.ToBinary(); using (FileStream fs = new FileStream(Path.Combine(dirName, $"{Name}.xibc"), FileMode.Create)) { BinaryFormatter binaryFormatter = new BinaryFormatter(); binaryFormatter.Serialize(fs, binaryModule); } if (dumpXir) { using (StreamWriter sw = new StreamWriter(Path.Combine(dirName, $"{Name}.xir"))) { sw.WriteLine($".Module {Name}"); sw.WriteLine($"\n.StringPool"); for (int i = 0; i < binaryModule.StringPool.Length; ++i) { sw.WriteLine("{0, 8}{1}", $"#{i + 1}: ", binaryModule.StringPool[i]); } sw.WriteLine($"\n.ClassPool"); for (int i = 0; i < binaryModule.ClassPool.Length; ++i) { sw.WriteLine("{0, 8}{1} {2}", $"#{i + 1}: ", binaryModule.ClassPool[i].Module, binaryModule.ClassPool[i].Name); } sw.WriteLine($"\n.MethodPool"); for (int i = 0; i < binaryModule.MethodPool.Length; ++i) { sw.WriteLine("{0, 8}{1} {2} {3} {4}", $"#{i + 1}: ", binaryModule.MethodPool[i].Class, binaryModule.MethodPool[i].Name, binaryModule.MethodPool[i].Descriptor, binaryModule.MethodPool[i].Flag); } sw.WriteLine($"\n.FieldPool"); for (int i = 0; i < binaryModule.FieldPool.Length; ++i) { sw.WriteLine("{0, 8}{1} {2} {3} {4}", $"#{i + 1}: ", binaryModule.FieldPool[i].Class, binaryModule.FieldPool[i].Name, binaryModule.FieldPool[i].Descriptor, binaryModule.FieldPool[i].Flag); } foreach (Class classType in Classes) { sw.WriteLine($"\n.Class {classType.Name} {{"); sw.WriteLine($" # ClassPoolIndex {classType.ConstantPoolIndex}"); foreach (KeyValuePair <string, List <Method> > methodGroup in classType.Methods) { foreach (Method method in methodGroup.Value) { sw.WriteLine($"\n .Method {method.Name} {method.Descriptor} {{"); sw.WriteLine($" # MethodPoolIndex {method.ConstantPoolIndex}"); sw.WriteLine($" # LocalTypeIndexTable: "); foreach (var localInfo in binaryModule.Methods[method.ConstantPoolIndex - 1].LocalDescriptorIndex) { sw.WriteLine($" # {localInfo}"); } int pc = 0; foreach (BasicBlock bb in method.BasicBlocks) { foreach (Instruction inst in bb.Instructions) { sw.WriteLine("{0, 8}{1}", $"{pc}: ", inst); pc += 1; if (inst.Params != null) { pc += inst.Params.Length; } } } sw.WriteLine($" }} \t// {method.Name}"); } } sw.WriteLine($"}} \t// {classType.Name}"); } } } }
/// <summary> /// 加载模块 /// </summary> /// <param name="binaryModule"></param> /// <param name="isDependency">是执行模块还是依赖模块</param> /// <returns></returns> public static VMModule AddModule(BinaryModule binaryModule, bool isDependency) { if (!isDependency) { LoadWatch.Start(); } VMModule module = new VMModule() { StringPoolLink = new List <uint>(), Classes = new Dictionary <uint, VMClass>(), ClassPool = binaryModule.ClassPool, ClassPoolLink = new List <VMClass>(), FieldPool = binaryModule.FieldPool, FieldPoolLink = new List <VMField>(), MethodPool = binaryModule.MethodPool, MethodPoolLink = new List <VMMethod>() }; HashSet <int> externalModuleNameIndexes = new HashSet <int>(); // 字符串常量 foreach (string stringConstant in binaryModule.StringPool) { // 建立映射 module.StringPoolLink.Add(MethodArea.Singleton.AddConstantString(stringConstant)); } Modules.Add(module.StringPoolLink[binaryModule.ModuleNameIndex - 1], module); // 类 foreach (ClassConstantInfo classInfo in module.ClassPool) { int moduleNameIndex = classInfo.Module; if (moduleNameIndex != binaryModule.ModuleNameIndex) { // 外部域 externalModuleNameIndexes.Add(moduleNameIndex); // 占位 module.ClassPoolLink.Add(null); } else { VMClass vmClass = new VMClass() { Parent = module, Methods = new Dictionary <uint, List <VMMethod> >(), StaticFields = new List <VMField>(), StaticFieldSize = HeapData.MiscDataSize, // 头部信息 Fields = new List <VMField>(), FieldSize = HeapData.MiscDataSize // 头部信息 }; module.Classes.Add(module.StringPoolLink[classInfo.Name - 1], vmClass); module.ClassPoolLink.Add(vmClass); } } // Field AccessFlag accessFlag = new AccessFlag(); foreach (FieldConstantInfo fieldInfo in module.FieldPool) { int moduleNameIndex = module.ClassPool[fieldInfo.Class - 1].Module; if (moduleNameIndex != binaryModule.ModuleNameIndex) { // 外部域 externalModuleNameIndexes.Add(moduleNameIndex); // 占位 module.FieldPoolLink.Add(null); } else { module.Classes.TryGetValue(module.StringPoolLink[module.ClassPool[fieldInfo.Class - 1].Name - 1], out VMClass vmClass); // 分配方法区空间并且链接地址 accessFlag.Flag = fieldInfo.Flag; VariableType fieldType = VariableType.GetType(binaryModule.StringPool[fieldInfo.Descriptor - 1]); VMField vmField; if (accessFlag.IsStatic) { vmField = new VMField(fieldInfo.Flag, fieldType, fieldInfo.Class, vmClass.StaticFieldSize); module.FieldPoolLink.Add(vmField); vmClass.StaticFields.Add(vmField); vmClass.StaticFieldSize += fieldType.Size; } else { vmField = new VMField(fieldInfo.Flag, fieldType, fieldInfo.Class, vmClass.FieldSize); module.FieldPoolLink.Add(vmField); vmClass.Fields.Add(vmField); vmClass.FieldSize += fieldType.Size; } } } // 完成静态空间分配 foreach (var vmClass in module.ClassPoolLink) { if (vmClass != null) { vmClass.StaticFieldAddress = StaticArea.Singleton.MallocClassStaticArea(vmClass); Classes.Add(vmClass.StaticFieldAddress, vmClass); } } // Method foreach ((MethodConstantInfo methodInfo, BinaryMethod binaryMethod) in module.MethodPool.Zip(binaryModule.Methods)) { int moduleNameIndex = module.ClassPool[methodInfo.Class - 1].Module; if (moduleNameIndex != binaryModule.ModuleNameIndex) { // 外部方法 externalModuleNameIndexes.Add(moduleNameIndex); // 占位 module.MethodPoolLink.Add(null); } else { module.Classes.TryGetValue(module.StringPoolLink[module.ClassPool[methodInfo.Class - 1].Name - 1], out VMClass vmClass); // 构造VMMethod VMMethod vmMethod = new VMMethod() { Parent = vmClass, Flag = new AccessFlag() { Flag = methodInfo.Flag }, DescriptorAddress = module.StringPoolLink[methodInfo.Descriptor - 1], LocalDescriptorAddress = binaryMethod.LocalDescriptorIndex.Select(i => module.StringPoolLink[i - 1]).ToList(), CodeBlock = MethodArea.Singleton.Malloc(binaryMethod.Instructions) }; Methods.Add(vmMethod.CodeAddress, vmMethod); // 将VMMethod添加到Class中 uint methodNameAddr = module.StringPoolLink[methodInfo.Name - 1]; if (vmClass.Methods.TryGetValue(methodNameAddr, out List <VMMethod> methodGroup)) { methodGroup.Add(vmMethod); } else { vmClass.Methods.Add(methodNameAddr, new List <VMMethod>() { vmMethod }); } // 建立Link module.MethodPoolLink.Add(vmMethod); } } if (!isDependency) { DependencyLoadWatch.Start(); } // 导入外部模块 foreach (int externalModuleNameIndex in externalModuleNameIndexes) { if (!Modules.ContainsKey(module.StringPoolLink[externalModuleNameIndex - 1])) { // 导入未导入的模块,图的广度优先遍历 AddModule(Program.LoadModule(binaryModule.StringPool[externalModuleNameIndex - 1]), true); } } if (!isDependency) { DependencyLoadWatch.Stop(); } // 链接外部符号 ExternalSymbolResolution(module); if (!isDependency) { LoadWatch.Stop(); } return(module); }