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