提取 UdonModuleInfo.json
Udon VM - 执行过程和 Udon VM - 外部函数中解释了 Udon VM 如何调用外部函数. 为了正常识别外部函数调用, 并重建更高级的语义信息, 本反编译器也需要知道每个 externSignatureexternSignature 所对应函数的参数数量, 原始名字, 具体类型(methodmethod, ctorctor, opop, fieldfield), 是否有返回值, 是否为静态函数等信息.
这一提取工作通过编辑器脚本 UdonModuleInfoExtractor.csUdonModuleInfoExtractor.cs 完成, 其大致运行逻辑如下
- 使用
UdonVMUdonVM所使用的 API 获取所有实现了IUdonWrapperModuleIUdonWrapperModule的类 - 对于每一个类, 读取它们的
NameName(externSignatureexternSignature中的ModuleNameModuleName) 和_parameterCounts_parameterCounts(Dictionary<string, int>Dictionary<string, int>) 字段. 从而获得每个externSignatureexternSignature对应的参数数量 - 使用
NodeRegistriesNodeRegistries相关 API 获取每个externSignatureexternSignature对应的UdonNodeDefinitionUdonNodeDefinition -
对于每个类中的每个函数, 使用其函数签名和
UdonNodeDefinitionUdonNodeDefinition中的参数列表信息推断我们需要的所有信息, 具体而言- 推断类的原始名字: 使用该类中任一函数的
UdonNodeDefinition.typeUdonNodeDefinition.type即可获得该类的TypeType -
推断类型: 根据函数签名的开头和参数数量的不同
__op___op_开头的, 是opop类型__ctor____ctor__开头的, 是ctorctor类型__get___get_或__set___set_开头的且参数数量不小于 1, 不大于 2 的, 是fieldfield类型(签名符合特征但是参数数量不正确的那部分函数是数组成员访问. 截至目前, 这种类型的函数还没有被正确反编译, 相关工作在 todo 列表中)- 其它的是
methodmethod类型
-
推断原始名字
- 对于
fieldfield类型: 将函数签名去掉开头的__get___get_或__set___set_即为原始名字 - 对于
methodmethod类型: 将对应UdonNodeDefinition.nameUdonNodeDefinition.name用空格rsplitrsplit, 最后一段即为原始名字
- 对于
- 推断是否为静态函数: 检查
UdonNodeDefinition.parameters.First()UdonNodeDefinition.parameters.First()的namename是否为instanceinstance且类型是否与该类相同 - 推断是否有返回值: 检查
UdonNodeDefinition.parameters.Last()UdonNodeDefinition.parameters.Last()的parameterTypeparameterType是否为UdonNodeParameter.ParameterType.OUTUdonNodeParameter.ParameterType.OUT
- 推断类的原始名字: 使用该类中任一函数的
- 将所有信息输出到
UdonModuleInfo.jsonUdonModuleInfo.json中