implements PR-O1.6
This commit is contained in:
parent
b5622bd9df
commit
d915e39511
@ -0,0 +1,168 @@
|
||||
package p.studio.compiler.workspaces.stages;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import p.studio.compiler.backend.bytecode.BytecodeEmitter;
|
||||
import p.studio.compiler.backend.irvm.IRVMFunction;
|
||||
import p.studio.compiler.backend.irvm.IRVMInstruction;
|
||||
import p.studio.compiler.backend.irvm.IRVMModule;
|
||||
import p.studio.compiler.backend.irvm.IRVMOp;
|
||||
import p.studio.compiler.backend.irvm.IRVMProgram;
|
||||
import p.studio.compiler.messages.BuilderPipelineConfig;
|
||||
import p.studio.compiler.models.BuilderPipelineContext;
|
||||
import p.studio.compiler.models.IRBackend;
|
||||
import p.studio.compiler.models.IRBackendExecutableFunction;
|
||||
import p.studio.compiler.source.Span;
|
||||
import p.studio.compiler.source.identifiers.FileId;
|
||||
import p.studio.utilities.logs.LogAggregator;
|
||||
import p.studio.utilities.structures.ReadOnlyList;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class BackendSafetyGateSUTest {
|
||||
|
||||
@Test
|
||||
void lowerStageMustExposeDeterministicFailureCodeForSameInvalidInput() {
|
||||
final var backend = IRBackend.builder()
|
||||
.executableFunctions(ReadOnlyList.from(new IRBackendExecutableFunction(
|
||||
new FileId(1),
|
||||
"app",
|
||||
"main",
|
||||
0,
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2,
|
||||
ReadOnlyList.from(
|
||||
new IRBackendExecutableFunction.Instruction(
|
||||
IRBackendExecutableFunction.InstructionKind.CALL_FUNC,
|
||||
"app",
|
||||
"missing",
|
||||
null,
|
||||
null,
|
||||
0,
|
||||
0,
|
||||
Span.none()),
|
||||
new IRBackendExecutableFunction.Instruction(
|
||||
IRBackendExecutableFunction.InstructionKind.RET,
|
||||
"",
|
||||
"",
|
||||
null,
|
||||
null,
|
||||
Span.none())),
|
||||
Span.none())))
|
||||
.build();
|
||||
|
||||
final var issueA = runLower(backend).asCollection().iterator().next();
|
||||
final var issueB = runLower(backend).asCollection().iterator().next();
|
||||
|
||||
assertEquals("LOWER_IRVM_MISSING_CALLEE", issueA.getCode());
|
||||
assertEquals(issueA.getCode(), issueB.getCode());
|
||||
assertEquals(issueA.getPhase(), issueB.getPhase());
|
||||
}
|
||||
|
||||
@Test
|
||||
void optimizeStageMustBeDeterministicForSameInputProgram() {
|
||||
final var program = new IRVMProgram(new IRVMModule(
|
||||
"core-v1",
|
||||
ReadOnlyList.from(new IRVMFunction(
|
||||
"main",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
ReadOnlyList.from(new IRVMInstruction(IRVMOp.HALT, null))))));
|
||||
|
||||
final var first = runOptimize(program);
|
||||
final var second = runOptimize(program);
|
||||
|
||||
assertTrue(!first.hasErrors());
|
||||
assertTrue(!second.hasErrors());
|
||||
assertEquals(first.size(), second.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void emitStageMustExposeMarshalingLinkageFailureDeterministically() {
|
||||
final var plan = new BytecodeEmitter.EmissionPlan(
|
||||
0,
|
||||
ReadOnlyList.empty(),
|
||||
ReadOnlyList.empty(),
|
||||
ReadOnlyList.from(new BytecodeEmitter.FunctionPlan(
|
||||
"main",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
ReadOnlyList.from(BytecodeEmitter.Operation.rawSyscall(0x1001)))));
|
||||
|
||||
final var issueA = runEmit(new IRVMProgram(false, plan)).asCollection().iterator().next();
|
||||
final var issueB = runEmit(new IRVMProgram(false, plan)).asCollection().iterator().next();
|
||||
|
||||
assertEquals("MARSHAL_LINKAGE_RAW_SYSCALL_IN_PRELOAD", issueA.getCode());
|
||||
assertEquals(issueA.getCode(), issueB.getCode());
|
||||
assertEquals(issueA.getPhase(), issueB.getPhase());
|
||||
}
|
||||
|
||||
@Test
|
||||
void fullPipelineMustProduceDeterministicBytecodeForSameInput() {
|
||||
final var backend = IRBackend.builder()
|
||||
.executableFunctions(ReadOnlyList.from(new IRBackendExecutableFunction(
|
||||
new FileId(1),
|
||||
"app",
|
||||
"main",
|
||||
0,
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
ReadOnlyList.from(new IRBackendExecutableFunction.Instruction(
|
||||
IRBackendExecutableFunction.InstructionKind.RET,
|
||||
"",
|
||||
"",
|
||||
null,
|
||||
null,
|
||||
Span.none())),
|
||||
Span.none())))
|
||||
.build();
|
||||
|
||||
final var first = emitBytes(backend);
|
||||
final var second = emitBytes(backend);
|
||||
|
||||
assertArrayEquals(first, second);
|
||||
}
|
||||
|
||||
private static p.studio.compiler.messages.BuildingIssueSink runLower(final IRBackend backend) {
|
||||
final var ctx = BuilderPipelineContext.compilerContext(new BuilderPipelineConfig(false, "."));
|
||||
ctx.irBackend = backend;
|
||||
return new LowerToIRVMPipelineStage().run(ctx, LogAggregator.empty());
|
||||
}
|
||||
|
||||
private static p.studio.compiler.messages.BuildingIssueSink runOptimize(final IRVMProgram program) {
|
||||
final var ctx = BuilderPipelineContext.compilerContext(new BuilderPipelineConfig(false, "."));
|
||||
ctx.irvm = program;
|
||||
return new OptimizeIRVMPipelineStage().run(ctx, LogAggregator.empty());
|
||||
}
|
||||
|
||||
private static p.studio.compiler.messages.BuildingIssueSink runEmit(final IRVMProgram program) {
|
||||
final var ctx = BuilderPipelineContext.compilerContext(new BuilderPipelineConfig(false, "."));
|
||||
ctx.optimizedIrvm = program;
|
||||
return new EmitBytecodePipelineStage().run(ctx, LogAggregator.empty());
|
||||
}
|
||||
|
||||
private static byte[] emitBytes(final IRBackend backend) {
|
||||
final var ctx = BuilderPipelineContext.compilerContext(new BuilderPipelineConfig(false, "."));
|
||||
ctx.irBackend = backend;
|
||||
|
||||
final var lowerIssues = new LowerToIRVMPipelineStage().run(ctx, LogAggregator.empty());
|
||||
final var optimizeIssues = new OptimizeIRVMPipelineStage().run(ctx, LogAggregator.empty());
|
||||
final var emitIssues = new EmitBytecodePipelineStage().run(ctx, LogAggregator.empty());
|
||||
|
||||
assertTrue(!lowerIssues.hasErrors());
|
||||
assertTrue(!optimizeIssues.hasErrors());
|
||||
assertTrue(!emitIssues.hasErrors());
|
||||
return ctx.bytecodeBytes;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user