TileEntityNullGuardTransformer

基本信息

属性 值
类 ...loading.fml.compat.transformers.generic.TileEntityNullGuardTransformer
路径 src/main/java/com/gtnewhorizons/angelica/loading/fml/compat/transformers/generic/TileEntityNullGuardTransformer.java
行数 94
类型 public class(:20),不实现 IClassTransformer
入口签名 public static void transform(ClassNode cn, List<String> patchMethods)(:22)
公开辅助 public static void injectGetTileEntityNullGuard(MethodNode mn)(:28)
数据来源 ICompatHandler.getTileEntityNullGuard()

它是什么 / 挂在哪个阶段

静态工具,被 GenericCompatTransformer :76-78 调用;该 transformer 由 CompatHandlers.getTransformers() 在 handler 非空时注册。跑在 LaunchWrapper 类加载期,RFB 路径不提供。

injectGetTileEntityNullGuard 是 public,是 4 个 generic/ transformer 里唯一一个把核心逻辑暴露为公开方法的(ThreadSafeISBRHAnnotationTransformer 等都是私有)。

它改写什么

:31-53 有一段完整的字节码模式注释,是理解本类最直接的文档:

匹配模式:
L0 { ... INVOKEINTERFACE IBlockAccess.getTileEntity(III)TileEntity; CHECKCAST *; ASTORE x }
L1 { ... }

注入后:
L0 { ASTORE x; ALOAD x; IFNONNULL L1; ICONST_0; IRETURN }
L1 { ... }

Java 层的等价:

MyTileEntity tile = (MyTileEntity) world.getTileEntity(x, y, z);
if (tile == null) { return false; } else { doSomethingWith(tile); }

匹配条件(:57-90,四层嵌套)

层 条件 行
1 INVOKEINTERFACE + owner == "net/minecraft/world/IBlockAccess" + name == obf("getTileEntity","func_147438_o") :58-61
2 下一条指令是 CHECKCAST :62-65
3 再下一条是 ASTORE :66-69

三条必须紧邻(getNext() 链式)。任何在 CHECKCAST 与 ASTORE 之间插入的指令(DUP、CHECKCAST 两次等)都会导致漏匹配。

返回类型分派(:71-79)

方法描述符结尾 注入
Z 或 I ICONST_0 + IRETURN
V RETURN
其他(对象/数组/J/F/D) 打 warn 日志并 return

已知问题(真实缺陷):

  1. return 而非 continue 会在遇到第一个未知返回类型的方法时放弃该方法的剩余全部指令(:76-79)。injectGetTileEntityNullGuard 是对 mn.instructions 的单趟 for 循环,一旦在循环体内 return,同一个方法里后续的 getTileEntity 调用点全部得不到补丁。同类问题也出现在 HUDCachingEarlyReturnTransformer(结构相同)。
  2. J/F/D/L 返回类型无解且无兜底:这四种返回类型下守卫被静默跳过,只有日志。对这些类型正确的做法是注入 0L/0.0f/aconst_null,但源码只实现了 Z/I/V。
  3. CHECKCAST 缺失即漏匹配:很多 ISBRH 写法是 TileEntity te = world.getTileEntity(...)(无 cast),本 transformer 不处理。
  4. 只守卫 IBlockAccess:IBlockAccessExtended(Angelica 自己的 API,见 API 层)派生的其他访问路径不在覆盖范围。

耦合点

数据提供方有 2 个 handler:ImmersiveEngineeringCompatHandler(6 个类)与 StacksOnStacksCompatHandler(1 个类)。

相关条目