Exemplo n.º 1
0
 /// <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);
 }
Exemplo n.º 2
0
        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;
                    }
                }
            }
        }