From ea27561e65bebd60e4e94d001ae93d9e7fc9c6ec Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Sat, 7 Mar 2026 18:23:09 +0000 Subject: [PATCH] implements PR-O2.4 --- .../BackendGateIIntegrationTest.java | 97 ++--------------- .../integration/CompatibilityError.java | 9 ++ .../integration/CompatibilityResult.java | 8 ++ .../LocalRuntimeCompatibilityAdapter.java | 101 ++++++++++++++++++ .../RuntimeCompatibilityAdapter.java | 7 ++ 5 files changed, 135 insertions(+), 87 deletions(-) create mode 100644 prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/CompatibilityError.java create mode 100644 prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/CompatibilityResult.java create mode 100644 prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/LocalRuntimeCompatibilityAdapter.java create mode 100644 prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/RuntimeCompatibilityAdapter.java diff --git a/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/BackendGateIIntegrationTest.java b/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/BackendGateIIntegrationTest.java index 423e0a4d..ece6ab61 100644 --- a/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/BackendGateIIntegrationTest.java +++ b/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/BackendGateIIntegrationTest.java @@ -20,7 +20,6 @@ import p.studio.utilities.structures.ReadOnlyList; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -31,6 +30,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertThrows; class BackendGateIIntegrationTest { + private final RuntimeCompatibilityAdapter compatibilityAdapter = new LocalRuntimeCompatibilityAdapter(); @Test void gateI_syscSectionPresentAndEmpty() { @@ -38,7 +38,7 @@ class BackendGateIIntegrationTest { fn("main", ReadOnlyList.from(ret())))); assertTrue(module.syscalls().isEmpty()); - assertEquals(CompatibilityError.NONE, new RuntimePreloadCompatibilityChecker().check(module).error()); + assertEquals(CompatibilityError.NONE, compatibilityAdapter.check(module).error()); } @Test @@ -48,9 +48,11 @@ class BackendGateIIntegrationTest { callHost("gfx", "draw_pixel", 1, 2, 0), ret())))); - final var check = new RuntimePreloadCompatibilityChecker().check(module); + final var check = compatibilityAdapter.check(module); assertEquals(CompatibilityError.NONE, check.error()); assertTrue(check.hostcallCount() > 0); + assertEquals("local", check.adapterMode()); + assertTrue(!check.runtimeLine().isBlank()); } @Test @@ -64,7 +66,7 @@ class BackendGateIIntegrationTest { ReadOnlyList.empty(), ReadOnlyList.from(new BytecodeModule.SyscallDecl("gfx", "draw_pixel", 1, 1, 0))); - final var check = new RuntimePreloadCompatibilityChecker().check(module); + final var check = compatibilityAdapter.check(module); assertEquals(CompatibilityError.HOSTCALL_INDEX_OUT_OF_BOUNDS, check.error()); } @@ -79,7 +81,7 @@ class BackendGateIIntegrationTest { ReadOnlyList.empty(), ReadOnlyList.from(new BytecodeModule.SyscallDecl("gfx", "draw_pixel", 1, 1, 0))); - final var check = new RuntimePreloadCompatibilityChecker().check(module); + final var check = compatibilityAdapter.check(module); assertEquals(CompatibilityError.UNUSED_SYSC_DECL, check.error()); } @@ -94,7 +96,7 @@ class BackendGateIIntegrationTest { ReadOnlyList.empty(), ReadOnlyList.empty()); - final var check = new RuntimePreloadCompatibilityChecker().check(module); + final var check = compatibilityAdapter.check(module); assertEquals(CompatibilityError.RAW_SYSCALL_IN_PRELOAD, check.error()); } @@ -131,7 +133,7 @@ class BackendGateIIntegrationTest { final var caps = Set.of("input"); final var required = new HashMap(); required.put("gfx::draw_pixel::1", "gfx"); - final var check = new RuntimePreloadCompatibilityChecker(caps, required).check(module); + final var check = new LocalRuntimeCompatibilityAdapter(caps, required).check(module); assertEquals(CompatibilityError.MISSING_CAPABILITY, check.error()); } @@ -142,7 +144,7 @@ class BackendGateIIntegrationTest { callIntrinsic("core.color.pack", 1, 0x2000), ret())))); - final var check = new RuntimePreloadCompatibilityChecker().check(module); + final var check = compatibilityAdapter.check(module); assertEquals(CompatibilityError.NONE, check.error()); assertTrue(module.syscalls().isEmpty()); } @@ -244,83 +246,4 @@ class BackendGateIIntegrationTest { out.putShort((short) 0x51); return out.array(); } - - private enum CompatibilityError { - NONE, - RAW_SYSCALL_IN_PRELOAD, - HOSTCALL_INDEX_OUT_OF_BOUNDS, - UNUSED_SYSC_DECL, - MISSING_CAPABILITY, - } - - private record CompatibilityResult( - CompatibilityError error, - int hostcallCount) { - } - - private static final class RuntimePreloadCompatibilityChecker { - private final Set capabilities; - private final Map requiredCapabilityBySyscallIdentity; - - private RuntimePreloadCompatibilityChecker() { - this(Set.of("gfx", "input", "audio", "system"), Map.of()); - } - - private RuntimePreloadCompatibilityChecker( - final Set capabilities, - final Map requiredCapabilityBySyscallIdentity) { - this.capabilities = capabilities == null ? Set.of() : new HashSet<>(capabilities); - this.requiredCapabilityBySyscallIdentity = requiredCapabilityBySyscallIdentity == null - ? Map.of() - : new HashMap<>(requiredCapabilityBySyscallIdentity); - } - - CompatibilityResult check(final BytecodeModule module) { - final var used = new boolean[module.syscalls().size()]; - var hostcallCount = 0; - var pc = 0; - while (pc < module.code().length) { - final var opcode = readU16(module.code(), pc); - switch (opcode) { - case 0x70 -> { - return new CompatibilityResult(CompatibilityError.RAW_SYSCALL_IN_PRELOAD, hostcallCount); - } - case 0x71 -> { - final var syscIndex = readU32(module.code(), pc + 2); - if (syscIndex < 0 || syscIndex >= module.syscalls().size()) { - return new CompatibilityResult(CompatibilityError.HOSTCALL_INDEX_OUT_OF_BOUNDS, hostcallCount); - } - used[syscIndex] = true; - hostcallCount++; - final var decl = module.syscalls().get(syscIndex); - final var identity = decl.module() + "::" + decl.name() + "::" + decl.version(); - final var requiredCap = requiredCapabilityBySyscallIdentity.get(identity); - if (requiredCap != null && !capabilities.contains(requiredCap)) { - return new CompatibilityResult(CompatibilityError.MISSING_CAPABILITY, hostcallCount); - } - pc += 6; - } - case 0x50, 0x72, 0x02, 0x03, 0x04, 0x10, 0x18, 0x40, 0x41, 0x42, 0x43, 0x56 -> pc += 6; - case 0x14, 0x15, 0x52, 0x54 -> pc += 10; - case 0x16 -> pc += 3; - default -> pc += 2; - } - } - for (var i = 0; i < used.length; i++) { - if (!used[i]) { - return new CompatibilityResult(CompatibilityError.UNUSED_SYSC_DECL, hostcallCount); - } - } - return new CompatibilityResult(CompatibilityError.NONE, hostcallCount); - } - - private int readU16(final byte[] code, final int offset) { - return ByteBuffer.wrap(code, offset, 2).order(ByteOrder.LITTLE_ENDIAN).getShort() & 0xFFFF; - } - - private int readU32(final byte[] code, final int offset) { - return ByteBuffer.wrap(code, offset, 4).order(ByteOrder.LITTLE_ENDIAN).getInt(); - } - } } - diff --git a/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/CompatibilityError.java b/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/CompatibilityError.java new file mode 100644 index 00000000..2d1fce23 --- /dev/null +++ b/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/CompatibilityError.java @@ -0,0 +1,9 @@ +package p.studio.compiler.integration; + +enum CompatibilityError { + NONE, + RAW_SYSCALL_IN_PRELOAD, + HOSTCALL_INDEX_OUT_OF_BOUNDS, + UNUSED_SYSC_DECL, + MISSING_CAPABILITY, +} diff --git a/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/CompatibilityResult.java b/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/CompatibilityResult.java new file mode 100644 index 00000000..6406f7a0 --- /dev/null +++ b/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/CompatibilityResult.java @@ -0,0 +1,8 @@ +package p.studio.compiler.integration; + +record CompatibilityResult( + CompatibilityError error, + int hostcallCount, + String runtimeLine, + String adapterMode) { +} diff --git a/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/LocalRuntimeCompatibilityAdapter.java b/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/LocalRuntimeCompatibilityAdapter.java new file mode 100644 index 00000000..2d7d52e3 --- /dev/null +++ b/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/LocalRuntimeCompatibilityAdapter.java @@ -0,0 +1,101 @@ +package p.studio.compiler.integration; + +import p.studio.compiler.backend.bytecode.BytecodeModule; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +final class LocalRuntimeCompatibilityAdapter implements RuntimeCompatibilityAdapter { + private final Set capabilities; + private final Map requiredCapabilityBySyscallIdentity; + private final String runtimeLine; + + LocalRuntimeCompatibilityAdapter() { + this(Set.of("gfx", "input", "audio", "system"), Map.of(), "runtime-local-sim-v1"); + } + + LocalRuntimeCompatibilityAdapter( + final Set capabilities, + final Map requiredCapabilityBySyscallIdentity) { + this(capabilities, requiredCapabilityBySyscallIdentity, "runtime-local-sim-v1"); + } + + LocalRuntimeCompatibilityAdapter( + final Set capabilities, + final Map requiredCapabilityBySyscallIdentity, + final String runtimeLine) { + this.capabilities = capabilities == null ? Set.of() : new HashSet<>(capabilities); + this.requiredCapabilityBySyscallIdentity = requiredCapabilityBySyscallIdentity == null + ? Map.of() + : new HashMap<>(requiredCapabilityBySyscallIdentity); + this.runtimeLine = runtimeLine == null || runtimeLine.isBlank() ? "runtime-local-sim-v1" : runtimeLine; + } + + @Override + public CompatibilityResult check(final BytecodeModule module) { + final var used = new boolean[module.syscalls().size()]; + var hostcallCount = 0; + var pc = 0; + while (pc < module.code().length) { + final var opcode = readU16(module.code(), pc); + switch (opcode) { + case 0x70 -> { + return new CompatibilityResult( + CompatibilityError.RAW_SYSCALL_IN_PRELOAD, + hostcallCount, + runtimeLine, + "local"); + } + case 0x71 -> { + final var syscIndex = readU32(module.code(), pc + 2); + if (syscIndex < 0 || syscIndex >= module.syscalls().size()) { + return new CompatibilityResult( + CompatibilityError.HOSTCALL_INDEX_OUT_OF_BOUNDS, + hostcallCount, + runtimeLine, + "local"); + } + used[syscIndex] = true; + hostcallCount++; + final var decl = module.syscalls().get(syscIndex); + final var identity = decl.module() + "::" + decl.name() + "::" + decl.version(); + final var requiredCap = requiredCapabilityBySyscallIdentity.get(identity); + if (requiredCap != null && !capabilities.contains(requiredCap)) { + return new CompatibilityResult( + CompatibilityError.MISSING_CAPABILITY, + hostcallCount, + runtimeLine, + "local"); + } + pc += 6; + } + case 0x50, 0x72, 0x02, 0x03, 0x04, 0x10, 0x18, 0x40, 0x41, 0x42, 0x43, 0x56 -> pc += 6; + case 0x14, 0x15, 0x52, 0x54 -> pc += 10; + case 0x16 -> pc += 3; + default -> pc += 2; + } + } + for (var i = 0; i < used.length; i++) { + if (!used[i]) { + return new CompatibilityResult( + CompatibilityError.UNUSED_SYSC_DECL, + hostcallCount, + runtimeLine, + "local"); + } + } + return new CompatibilityResult(CompatibilityError.NONE, hostcallCount, runtimeLine, "local"); + } + + private int readU16(final byte[] code, final int offset) { + return ByteBuffer.wrap(code, offset, 2).order(ByteOrder.LITTLE_ENDIAN).getShort() & 0xFFFF; + } + + private int readU32(final byte[] code, final int offset) { + return ByteBuffer.wrap(code, offset, 4).order(ByteOrder.LITTLE_ENDIAN).getInt(); + } +} diff --git a/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/RuntimeCompatibilityAdapter.java b/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/RuntimeCompatibilityAdapter.java new file mode 100644 index 00000000..dcd77ae6 --- /dev/null +++ b/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/RuntimeCompatibilityAdapter.java @@ -0,0 +1,7 @@ +package p.studio.compiler.integration; + +import p.studio.compiler.backend.bytecode.BytecodeModule; + +interface RuntimeCompatibilityAdapter { + CompatibilityResult check(BytecodeModule module); +}