mirror of
https://github.com/GTNewHorizons/ForgeMultipart.git
synced 2026-11-13 17:04:25 +00:00
refactor: port ASM super lookup to Java
This commit is contained in:
1 parent
c0df2e0229
commit
fa008b80bb
4 files changed
+80
-29
No files matched your search
@@ -1459,3 +1459,23 @@ generated-trait compatibility work. Scala-runtime removal remains a later projec
|
||||
and the clean jar repeats the API/disassembly/dump matches above. The forced Scala-compilation version guard is
|
||||
retained; all five `@Mod` annotations match both packaged jar versions. External Scala-trait coverage remains green
|
||||
and the existing manual client checks and Java-source bridge limitations remain outstanding.
|
||||
- Added six Forge characterization cases for `ASMMixinCompiler.getSuper`, passing on untouched Scala and committed
|
||||
separately as `c0df2e0`: owner/name filter short-circuiting, greedy Scala super-name stripping, exact inherited
|
||||
signature selection and visibility, receiver recognition, argument indexing, failure paths, stack preservation,
|
||||
virtual getter/callback order, returned option identity and descriptor rereads. Baseline: 326 JVM / 141 Forge.
|
||||
The compiler singleton requires Forge initialization, so these behavior tests use its existing harness.
|
||||
- Moved only `getSuper` into the existing Java `ClassInfoLookup`, retaining the public Scala entry point and
|
||||
`Option.flatMap` callback dispatch. The current argument-count/stack-slot mismatch for wide arguments remains,
|
||||
as do the lack of invocation-opcode and `This.owner` validation and the limited target-owner check. The caller's
|
||||
`INVOKESPECIAL` guard, all trait rewrites and metadata/model behavior remain unchanged; algorithm fixes are separate.
|
||||
- Saved reference source/jar, reports and 40 generated dumps in ignored `run/migration-super-reference/`. All 16 named
|
||||
compiler APIs retain their names/descriptors/modifiers/generic signatures and private fields; 14 named classfiles
|
||||
are byte-identical. All 218 other named compiler methods, 34 algorithm closures, 17 existing metadata-helper methods
|
||||
and 143 other ASM/generator disassemblies match. All dump names/hashes match. One private Scala closure becomes a
|
||||
Java callback, leaving 450 packaged classes and no new divergence entry. Sources total 209 Java files and 9 Scala
|
||||
files / 1,675 nonblank Scala lines. Next: `ASMMixinCompiler.listSideOnly` annotation filtering, characterized first.
|
||||
- Formatting/checkstyle/build and Forge pass, including clean verification after stopping Gradle: 326 JVM / 141 Forge,
|
||||
zero failures/errors/skips. Characterization tests remain unchanged. The clean jar repeats the API/disassembly/dump
|
||||
matches, the local dev config is unchanged, and all five `@Mod` versions match both packaged jar versions with the
|
||||
forced Scala-compilation guard retained. External Scala-trait tests remain green; existing manual client checks and
|
||||
Java-source model-bridge limitations remain outstanding.
|
||||
+34
-10
@@ -12,8 +12,8 @@ what breaks, and what is left. The other documents hold the reasoning.
|
||||
| `JAVA_MIGRATION_MANUAL_CHECKS.md` | What no automated test can cover, and must be checked by hand in a client |
|
||||
| `JAVA_MIGRATION_PROFILE.md` | The focused baseline, first measured result, findings, and exact rerun command |
|
||||
|
||||
Branch: `algent/java`. Base: `master`. 178 commits including the API-cleanup plan, divergence-log cleanup, ports
|
||||
through the ASM descriptor/bridge helper extraction, and the ASM characterization backfill and review fixes.
|
||||
Branch: `algent/java`. Base: `master`. 180 commits including the API-cleanup plan, divergence-log cleanup, ports
|
||||
through ASM super-call lookup, and the ASM characterization backfill and review fixes.
|
||||
|
||||
## The one rule that matters
|
||||
|
||||
@@ -74,7 +74,7 @@ awk -F'"' '/<testsuite /{t+=$4;f+=$8;e+=$10} END{print "tests="t" failures="f" e
|
||||
grep -o 'tests="[0-9]*" skipped="[0-9]*" failures="[0-9]*" errors="[0-9]*"' run/server/junit-out/TEST-*.xml
|
||||
```
|
||||
|
||||
Current baseline: **326 plain-JVM tests and 135 Java 8 Forge dedicated-server tests passing.** The ignored local server
|
||||
Current baseline: **326 plain-JVM tests and 141 Java 8 Forge dedicated-server tests passing.** The ignored local server
|
||||
EULA is accepted in this checkout. GitHub Actions runs the same self-validating Forge suite in a dependent job after
|
||||
the shared GTNH build; keep both jobs required.
|
||||
|
||||
@@ -280,7 +280,7 @@ across the port. It is also where the two shim constraints in the gotchas list w
|
||||
`rayTraceAll`'s index production is now characterized, closing the gap the read-path cleanup left: the index written
|
||||
into `ExtendedMOP.data` is what `reduceMOP` hands back to every click, activate, harvest and pick block.
|
||||
|
||||
209 Java files, 9 Scala files, 1,689 Scala lines left (non-blank; that is the metric this figure has always used).
|
||||
209 Java files, 9 Scala files, 1,675 Scala lines left (non-blank; that is the metric this figure has always used).
|
||||
|
||||
## What is left, and in what order
|
||||
|
||||
@@ -704,12 +704,36 @@ match. The dev config and forced Scala-compilation version guard remain unchange
|
||||
both packaged jar versions. External Scala-trait tests stay green. Existing manual client checks and the documented
|
||||
Java-source limitations in the retained Scala model bridges are still outstanding.
|
||||
|
||||
**Next: `multipart/asm/ASMMixinCompiler.getSuper`, bounded to super-call recognition and lookup.** Characterize the
|
||||
owner/name filters, Scala super-name pattern, stack receiver checks, argument indexing and inherited implementation
|
||||
selection before extracting it. Use Forge for compiler initialization and preserve the current algorithm, including
|
||||
any quirks exposed by tests. Keep composition/trait registration and rewriting separate, along with external Scala
|
||||
trait support, retained metadata/stack models and `ScalaSignature` primitive/erased bridges. Save a fresh reference
|
||||
and compare generated dumps before expanding scope.
|
||||
`ASMMixinCompiler.getSuper` now delegates to the existing Java `ClassInfoLookup`. Six Forge characterization cases
|
||||
passed on untouched Scala and were committed separately as `c0df2e0`. They cover filter short-circuiting and failures,
|
||||
the greedy Scala super-name pattern, exact inherited signature selection, private/abstract exclusion, `Load(This)`
|
||||
recognition, argument indexing, unchanged stack state, virtual getter/callback order, returned option identity and
|
||||
descriptor rereads after callbacks. All tests pass unchanged after extraction. Forge is necessary for the original
|
||||
compiler singleton's `LaunchClassLoader` initialization.
|
||||
|
||||
The existing algorithm intentionally remains: argument count is used as a stack-slot index, so a wide argument can
|
||||
prevent super-call recognition; the helper does not validate the invocation opcode, target owner beyond its initial
|
||||
same-owner exclusion, or `This.owner`. Its caller still applies the `INVOKESPECIAL` guard. These are characterized
|
||||
existing behaviors, not new divergences or fixes. No trait rewrite or metadata/model algorithm changed.
|
||||
|
||||
Reference source/jar, reports, dumps and comparisons are under ignored `run/migration-super-reference/`. All 16 named
|
||||
compiler APIs match, including generic signatures, modifiers and private fields; 14 named classfiles are byte-identical.
|
||||
All 218 other named compiler methods, 34 algorithm closures, 17 existing metadata-helper methods and 143 other
|
||||
ASM/generator disassemblies match. All 40 generated dump names/hashes match. A private Scala closure becomes a Java
|
||||
callback, keeping 450 packaged classes; no new divergence entry is needed. Sources total 209 Java files and 9 Scala
|
||||
files / 1,675 nonblank Scala lines.
|
||||
|
||||
Formatting/checkstyle/build and Forge pass after stopping Gradle and building clean: 326 JVM / 141 Forge, zero
|
||||
failures/errors/skips. Tests are unchanged after the port; clean APIs and dumps match the reference. The dev config
|
||||
and forced Scala-compilation guard remain unchanged, and all five `@Mod` annotations match both packaged jar versions.
|
||||
External Scala-trait tests stay green; existing Java-source model-bridge limitations and manual client checks remain.
|
||||
|
||||
**Next: `multipart/asm/ASMMixinCompiler.listSideOnly`, bounded to annotation filtering.** Characterize annotation
|
||||
selection, enum-side comparison, owner-name collection/deduplication and malformed/missing annotation values before
|
||||
extracting it. Use Forge where side/singleton initialization requires it and preserve the current decoder behavior.
|
||||
Keep composition/trait registration and rewriting separate, along with external Scala-trait support, retained
|
||||
metadata/stack models and `ScalaSignature` primitive/erased bridges. Save a fresh reference and compare generated
|
||||
dumps before expanding scope.
|
||||
The remaining generated microblock traits still need the Phase 7 abstract-Java-mixin and side-only-member support
|
||||
before their Java mixin inputs are safe; do not bypass those prerequisites by flattening their inheritance.
|
||||
|
||||
|
||||
@@ -435,25 +435,7 @@ object ASMMixinCompiler {
|
||||
def getSuper(
|
||||
minsn: MethodInsnNode,
|
||||
stack: StackAnalyser
|
||||
): Option[MethodInfo] = {
|
||||
import StackAnalyser._
|
||||
|
||||
if (minsn.owner == stack.owner.getInternalName)
|
||||
return None // not a super call
|
||||
|
||||
// super calls are either to methods with the same name or contain a pattern 'target$$super$name' from the scala compiler
|
||||
val methodName = stack.m.name.replaceAll(".+\\Q$$super$\\E", "")
|
||||
if (minsn.name != methodName)
|
||||
return None
|
||||
|
||||
stack.peek(Type.getType(minsn.desc).getArgumentTypes.length) match {
|
||||
case Load(This(o)) =>
|
||||
case _ => return None // have to be invoked on this
|
||||
}
|
||||
|
||||
getClassInfo(stack.owner.getInternalName).superClass
|
||||
.flatMap(_.findPublicImpl(methodName, minsn.desc))
|
||||
}
|
||||
): Option[MethodInfo] = ClassInfoLookup.getSuper(minsn, stack)
|
||||
|
||||
def getAndRegisterParentTraits(cnode: ClassNode) =
|
||||
cnode.interfaces.map(getClassInfo).collect {
|
||||
|
||||
@@ -3,13 +3,18 @@ package codechicken.multipart.asm;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.AnnotationNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import codechicken.multipart.asm.ASMMixinCompiler.ClassInfo;
|
||||
import codechicken.multipart.asm.ASMMixinCompiler.ClassInfo$;
|
||||
import codechicken.multipart.asm.ASMMixinCompiler.MethodInfo;
|
||||
import codechicken.multipart.asm.StackAnalyser.Load;
|
||||
import codechicken.multipart.asm.StackAnalyser.StackEntry;
|
||||
import codechicken.multipart.asm.StackAnalyser.This;
|
||||
import scala.Array$;
|
||||
import scala.Function1;
|
||||
import scala.Function3;
|
||||
@@ -173,4 +178,24 @@ final class ClassInfoLookup {
|
||||
private static <R, E extends Throwable> R throwUnchecked(Throwable throwable) throws E {
|
||||
throw (E) throwable;
|
||||
}
|
||||
|
||||
static Option<MethodInfo> getSuper(final MethodInsnNode call, StackAnalyser stack) {
|
||||
if (Objects.equals(call.owner, stack.owner().getInternalName())) return Option.empty();
|
||||
|
||||
final String methodName = stack.m().name.replaceAll(".+\\Q$$super$\\E", "");
|
||||
if (!Objects.equals(call.name, methodName)) return Option.empty();
|
||||
|
||||
// Preserve the compiler's argument-count indexing, including its behavior for wide stack values.
|
||||
StackEntry receiver = stack.peek(Type.getType(call.desc).getArgumentTypes().length);
|
||||
if (!(receiver instanceof Load) || !(((Load) receiver).e() instanceof This)) return Option.empty();
|
||||
|
||||
return ASMMixinCompiler$.MODULE$.getClassInfo(stack.owner().getInternalName()).superClass()
|
||||
.flatMap(new AbstractFunction1<ClassInfo, Option<MethodInfo>>() {
|
||||
|
||||
@Override
|
||||
public Option<MethodInfo> apply(ClassInfo parent) {
|
||||
return parent.findPublicImpl(methodName, call.desc);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user