/// <summary> /// 因为在生成raw的时候并不知道要访问函数还是域(函数和域允许同名) /// 所以生成raw的时候仅作信息检索不生成字节码 /// 在这里做决定,生成field的相关字节码 /// </summary> /// <param name="pass"></param> /// <param name="raw"></param> /// <returns></returns> private static VariableType ExpectLocalOrField(CodeGenPass pass, VariableType raw) { if (raw is MemberType memberType) { if (memberType.IsField) { FieldConstantInfo fieldConstantInfo = pass.Constructor.FieldPool.Get(memberType.FieldPoolIndex); AccessFlag flag = new AccessFlag() { Flag = fieldConstantInfo.Flag }; if (flag.IsStatic) { if (memberType.FromObject) { // 多余的object地址要pop pass.Constructor.AddPop(new ObjectType(memberType.ClassType)); } pass.Constructor.AddLoadStatic(memberType.FieldPoolIndex); } else { if (memberType.FromThis) { // 隐式的this.bar pass.Constructor.AddLocal(pass.Constructor.CurrentMethod.Params[0].Offset); pass.Constructor.AddLoadT(pass.Constructor.CurrentMethod.Params[0].Type); } pass.Constructor.AddLoadNonStatic(memberType.FieldPoolIndex); } VariableType ret = VariableType.GetType( pass.Constructor.StringPool.Get(fieldConstantInfo.Descriptor)); return(ret); } else { throw new XiLangError($"{memberType} is not a variable"); } } return(raw); }
private static void ExternalSymbolResolution(VMModule module) { uint moduleNameAddress, nameAddress, classNameAddress; VMModule importedModule; VMClass outerClass; // 外部类 for (int i = 0; i < module.ClassPool.Length; ++i) { if (module.ClassPoolLink[i] != null) { continue; } ClassConstantInfo classInfo = module.ClassPool[i]; moduleNameAddress = module.StringPoolLink[classInfo.Module - 1]; Modules.TryGetValue(moduleNameAddress, out importedModule); nameAddress = module.StringPoolLink[classInfo.Name - 1]; if (!importedModule.Classes.TryGetValue(nameAddress, out outerClass)) { throw new XiVMError($"Outer class not found"); } module.ClassPoolLink[i] = outerClass; } // 外部域 for (int i = 0; i < module.FieldPool.Length; ++i) { if (module.FieldPoolLink[i] != null) { continue; } FieldConstantInfo fieldInfo = module.FieldPool[i]; moduleNameAddress = module.StringPoolLink[module.ClassPool[fieldInfo.Class - 1].Module - 1]; Modules.TryGetValue(moduleNameAddress, out importedModule); // TODO 可以将VMModule.Classes的结构化信息补全,这样直接在结构化信息中查找效率更高一些 // 外部函数符号也可以这样优化 classNameAddress = module.StringPoolLink[module.ClassPool[fieldInfo.Class - 1].Name - 1]; nameAddress = module.StringPoolLink[fieldInfo.Name - 1]; uint descriptorAddress = module.StringPoolLink[fieldInfo.Descriptor - 1]; foreach ((FieldConstantInfo candidateFieldInfo, VMField vmField) in importedModule.FieldPool.Zip(importedModule.FieldPoolLink)) { // 模块名类名函数名描述符匹配,未比较flag if (moduleNameAddress == importedModule.StringPoolLink[importedModule.ClassPool[candidateFieldInfo.Class - 1].Module - 1] && classNameAddress == importedModule.StringPoolLink[importedModule.ClassPool[candidateFieldInfo.Class - 1].Name - 1] && nameAddress == importedModule.StringPoolLink[candidateFieldInfo.Name - 1] && descriptorAddress == importedModule.StringPoolLink[candidateFieldInfo.Descriptor - 1]) { // 建立Link module.FieldPoolLink[i] = vmField; break; } } } // 外部函数符号 for (int i = 0; i < module.MethodPool.Length; ++i) { if (module.MethodPoolLink[i] != null) { // 已经填上了 continue; } MethodConstantInfo methodInfo = module.MethodPool[i]; moduleNameAddress = module.StringPoolLink[module.ClassPool[methodInfo.Class - 1].Module - 1]; Modules.TryGetValue(moduleNameAddress, out importedModule); classNameAddress = module.StringPoolLink[module.ClassPool[methodInfo.Class - 1].Name - 1]; nameAddress = module.StringPoolLink[methodInfo.Name - 1]; uint descriptorAddress = module.StringPoolLink[methodInfo.Descriptor - 1]; foreach ((MethodConstantInfo candidateMethodInfo, VMMethod vmMethod) in importedModule.MethodPool.Zip(importedModule.MethodPoolLink)) { // 模块名类名函数名描述符匹配,未比较flag if (moduleNameAddress == importedModule.StringPoolLink[importedModule.ClassPool[candidateMethodInfo.Class - 1].Module - 1] && classNameAddress == importedModule.StringPoolLink[importedModule.ClassPool[candidateMethodInfo.Class - 1].Name - 1] && nameAddress == importedModule.StringPoolLink[candidateMethodInfo.Name - 1] && descriptorAddress == importedModule.StringPoolLink[candidateMethodInfo.Descriptor - 1]) { // 建立Link module.MethodPoolLink[i] = vmMethod; break; } } } }