implements PR-O1.1

This commit is contained in:
bQUARKz 2026-03-07 17:41:02 +00:00
parent bfa5f06fb6
commit b5c372efb2
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
7 changed files with 63 additions and 14 deletions

View File

@ -26,12 +26,16 @@ public class EmitBytecodePipelineStage implements PipelineStage {
return BuildingIssueSink.empty() return BuildingIssueSink.empty()
.report(builder -> builder .report(builder -> builder
.error(true) .error(true)
.phase("BACKEND_EMIT_BYTECODE")
.code("MARSHAL_FORMAT_STAGE_INPUT_MISSING")
.message("[BUILD]: optimized IRVM is missing before EmitBytecode stage")); .message("[BUILD]: optimized IRVM is missing before EmitBytecode stage"));
} }
if (ctx.optimizedIrvm.hasInternalOpcodes()) { if (ctx.optimizedIrvm.hasInternalOpcodes()) {
return BuildingIssueSink.empty() return BuildingIssueSink.empty()
.report(builder -> builder .report(builder -> builder
.error(true) .error(true)
.phase("BACKEND_EMIT_BYTECODE")
.code("MARSHAL_VERIFY_PRECHECK_INTERNAL_OPCODE_RESIDUAL")
.message("[BUILD]: optimized IRVM still contains internal opcodes")); .message("[BUILD]: optimized IRVM still contains internal opcodes"));
} }
try { try {
@ -41,8 +45,9 @@ public class EmitBytecodePipelineStage implements PipelineStage {
return BuildingIssueSink.empty() return BuildingIssueSink.empty()
.report(builder -> builder .report(builder -> builder
.error(true) .error(true)
.message("[BUILD]: bytecode marshaling failed (%s): %s" .phase("BACKEND_EMIT_BYTECODE")
.formatted(e.code().name(), e.getMessage())) .code(e.code().name())
.message("[BUILD]: bytecode marshaling failed: " + e.getMessage())
.exception(e)); .exception(e));
} }
return BuildingIssueSink.empty(); return BuildingIssueSink.empty();

View File

@ -27,6 +27,8 @@ public class LowerToIRVMPipelineStage implements PipelineStage {
return BuildingIssueSink.empty() return BuildingIssueSink.empty()
.report(builder -> builder .report(builder -> builder
.error(true) .error(true)
.phase("BACKEND_LOWER_TO_IRVM")
.code("MARSHAL_FORMAT_STAGE_INPUT_MISSING")
.message("[BUILD]: IRBackend is missing before LowerToIRVM stage")); .message("[BUILD]: IRBackend is missing before LowerToIRVM stage"));
} }
try { try {
@ -35,15 +37,19 @@ public class LowerToIRVMPipelineStage implements PipelineStage {
return BuildingIssueSink.empty() return BuildingIssueSink.empty()
.report(builder -> builder .report(builder -> builder
.error(true) .error(true)
.message("[BUILD]: lower to irvm failed (%s): %s" .phase("BACKEND_LOWER_TO_IRVM")
.formatted(e.code().name(), e.getMessage())) .code(e.code().name())
.message("[BUILD]: lower to irvm failed: " + e.getMessage())
.exception(e)); .exception(e));
} catch (IRVMValidationException e) { } catch (IRVMValidationException e) {
return BuildingIssueSink.empty() return BuildingIssueSink.empty()
.report(builder -> builder .report(builder -> builder
.error(true) .error(true)
.message("[BUILD]: lower to irvm validation failed (%s): %s" .phase("BACKEND_LOWER_TO_IRVM")
.formatted(e.code().name(), e.getMessage())) .code(e.code().name())
.functionIndex(e.functionIndex())
.pc(e.pc())
.message("[BUILD]: lower to irvm validation failed: " + e.getMessage())
.exception(e)); .exception(e));
} }
return BuildingIssueSink.empty(); return BuildingIssueSink.empty();

View File

@ -26,6 +26,8 @@ public class OptimizeIRVMPipelineStage implements PipelineStage {
return BuildingIssueSink.empty() return BuildingIssueSink.empty()
.report(builder -> builder .report(builder -> builder
.error(true) .error(true)
.phase("BACKEND_OPTIMIZE_IRVM")
.code("MARSHAL_FORMAT_STAGE_INPUT_MISSING")
.message("[BUILD]: IRVM is missing before OptimizeIRVM stage")); .message("[BUILD]: IRVM is missing before OptimizeIRVM stage"));
} }
try { try {
@ -34,13 +36,18 @@ public class OptimizeIRVMPipelineStage implements PipelineStage {
return BuildingIssueSink.empty() return BuildingIssueSink.empty()
.report(builder -> builder .report(builder -> builder
.error(true) .error(true)
.message("[BUILD]: optimize irvm validation failed (%s): %s" .phase("BACKEND_OPTIMIZE_IRVM")
.formatted(e.code().name(), e.getMessage())) .code(e.code().name())
.functionIndex(e.functionIndex())
.pc(e.pc())
.message("[BUILD]: optimize irvm validation failed: " + e.getMessage())
.exception(e)); .exception(e));
} catch (RuntimeException e) { } catch (RuntimeException e) {
return BuildingIssueSink.empty() return BuildingIssueSink.empty()
.report(builder -> builder .report(builder -> builder
.error(true) .error(true)
.phase("BACKEND_OPTIMIZE_IRVM")
.code("MARSHAL_VERIFY_PRECHECK_OPTIMIZE_RUNTIME_FAILURE")
.message("[BUILD]: optimize irvm failed: " + e.getMessage()) .message("[BUILD]: optimize irvm failed: " + e.getMessage())
.exception(e)); .exception(e));
} }

View File

@ -21,9 +21,12 @@ class EmitBytecodePipelineStageTest {
final var stage = new EmitBytecodePipelineStage(); final var stage = new EmitBytecodePipelineStage();
final var issues = stage.run(ctx, LogAggregator.empty()); final var issues = stage.run(ctx, LogAggregator.empty());
final var firstIssue = issues.asCollection().iterator().next();
assertTrue(issues.hasErrors()); assertTrue(issues.hasErrors());
assertEquals(1, issues.size()); assertEquals(1, issues.size());
assertEquals("BACKEND_EMIT_BYTECODE", firstIssue.getPhase());
assertEquals("MARSHAL_FORMAT_STAGE_INPUT_MISSING", firstIssue.getCode());
} }
@Test @Test
@ -33,9 +36,11 @@ class EmitBytecodePipelineStageTest {
final var stage = new EmitBytecodePipelineStage(); final var stage = new EmitBytecodePipelineStage();
final var issues = stage.run(ctx, LogAggregator.empty()); final var issues = stage.run(ctx, LogAggregator.empty());
final var firstIssue = issues.asCollection().iterator().next();
assertTrue(issues.hasErrors()); assertTrue(issues.hasErrors());
assertEquals(1, issues.size()); assertEquals(1, issues.size());
assertEquals("MARSHAL_VERIFY_PRECHECK_INTERNAL_OPCODE_RESIDUAL", firstIssue.getCode());
} }
@Test @Test
@ -66,4 +71,3 @@ class EmitBytecodePipelineStageTest {
assertEquals(0, ctx.bytecodeModule.syscalls().size()); assertEquals(0, ctx.bytecodeModule.syscalls().size());
} }
} }

View File

@ -22,9 +22,12 @@ class LowerToIRVMPipelineStageTest {
final var stage = new LowerToIRVMPipelineStage(); final var stage = new LowerToIRVMPipelineStage();
final var issues = stage.run(ctx, LogAggregator.empty()); final var issues = stage.run(ctx, LogAggregator.empty());
final var firstIssue = issues.asCollection().iterator().next();
assertTrue(issues.hasErrors()); assertTrue(issues.hasErrors());
assertEquals(1, issues.size()); assertEquals(1, issues.size());
assertEquals("BACKEND_LOWER_TO_IRVM", firstIssue.getPhase());
assertEquals("MARSHAL_FORMAT_STAGE_INPUT_MISSING", firstIssue.getCode());
} }
@Test @Test
@ -59,4 +62,3 @@ class LowerToIRVMPipelineStageTest {
assertEquals(1, ctx.irvm.module().functions().size()); assertEquals(1, ctx.irvm.module().functions().size());
} }
} }

View File

@ -24,9 +24,12 @@ class OptimizeIRVMPipelineStageTest {
final var stage = new OptimizeIRVMPipelineStage(); final var stage = new OptimizeIRVMPipelineStage();
final var issues = stage.run(ctx, LogAggregator.empty()); final var issues = stage.run(ctx, LogAggregator.empty());
final var firstIssue = issues.asCollection().iterator().next();
assertTrue(issues.hasErrors()); assertTrue(issues.hasErrors());
assertEquals(1, issues.size()); assertEquals(1, issues.size());
assertEquals("BACKEND_OPTIMIZE_IRVM", firstIssue.getPhase());
assertEquals("MARSHAL_FORMAT_STAGE_INPUT_MISSING", firstIssue.getCode());
} }
@Test @Test
@ -72,4 +75,3 @@ class OptimizeIRVMPipelineStageTest {
assertEquals(1, issues.size()); assertEquals(1, issues.size());
} }
} }

View File

@ -10,16 +10,39 @@ public class BuildingIssue {
private final boolean error; private final boolean error;
private final String message; private final String message;
private final Throwable exception; private final Throwable exception;
private final String phase;
private final String code;
private final Integer functionIndex;
private final Integer pc;
public void print(LogAggregator logs) { public void print(LogAggregator logs) {
final var composed = composeMessage();
if (error) { if (error) {
if (exception != null) { if (exception != null) {
logs.error(message, exception); logs.error(composed, exception);
} else { } else {
logs.error(message); logs.error(composed);
} }
} else { } else {
logs.warn(message); logs.warn(composed);
} }
} }
private String composeMessage() {
final var sb = new StringBuilder();
if (phase != null && !phase.isBlank()) {
sb.append('[').append(phase).append(']').append(' ');
}
if (code != null && !code.isBlank()) {
sb.append('(').append(code).append(')').append(' ');
}
sb.append(message == null ? "" : message);
if (functionIndex != null && functionIndex >= 0) {
sb.append(" [fn=").append(functionIndex).append(']');
}
if (pc != null && pc >= 0) {
sb.append(" [pc=").append(pc).append(']');
}
return sb.toString().trim();
}
} }