implements PR-O3.3
This commit is contained in:
parent
0df936e36f
commit
a79a19cd4f
@ -0,0 +1,44 @@
|
||||
package p.studio.compiler.backend.irvm;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public final class IRVMProfileFeatureGate {
|
||||
private final Map<String, Set<IRVMOp>> allowedByProfile;
|
||||
|
||||
public IRVMProfileFeatureGate() {
|
||||
this(Map.of(
|
||||
"core-v1", Set.of(
|
||||
IRVMOp.HALT,
|
||||
IRVMOp.RET,
|
||||
IRVMOp.CALL,
|
||||
IRVMOp.JMP,
|
||||
IRVMOp.JMP_IF_TRUE,
|
||||
IRVMOp.JMP_IF_FALSE,
|
||||
IRVMOp.HOSTCALL,
|
||||
IRVMOp.INTRINSIC,
|
||||
IRVMOp.PUSH_I32),
|
||||
"experimental-v1", Set.of(
|
||||
IRVMOp.HALT,
|
||||
IRVMOp.RET,
|
||||
IRVMOp.CALL,
|
||||
IRVMOp.JMP,
|
||||
IRVMOp.JMP_IF_TRUE,
|
||||
IRVMOp.JMP_IF_FALSE,
|
||||
IRVMOp.HOSTCALL,
|
||||
IRVMOp.INTRINSIC,
|
||||
IRVMOp.PUSH_I32,
|
||||
IRVMOp.INTERNAL_EXT)));
|
||||
}
|
||||
|
||||
IRVMProfileFeatureGate(final Map<String, Set<IRVMOp>> allowedByProfile) {
|
||||
this.allowedByProfile = allowedByProfile == null ? Map.of() : Map.copyOf(allowedByProfile);
|
||||
}
|
||||
|
||||
public boolean isAllowed(
|
||||
final String profile,
|
||||
final IRVMOp op) {
|
||||
final var allowed = allowedByProfile.get(profile == null || profile.isBlank() ? "core-v1" : profile);
|
||||
return allowed != null && allowed.contains(op);
|
||||
}
|
||||
}
|
||||
@ -9,5 +9,5 @@ public enum IRVMValidationErrorCode {
|
||||
MARSHAL_VERIFY_PRECHECK_INVALID_FUNC_ID,
|
||||
MARSHAL_VERIFY_PRECHECK_UNTERMINATED_PATH,
|
||||
MARSHAL_VERIFY_PRECHECK_INTERNAL_OPCODE_RESIDUAL,
|
||||
MARSHAL_VERIFY_PRECHECK_OPCODE_NOT_ALLOWED_FOR_PROFILE,
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,15 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class IRVMValidator {
|
||||
private final IRVMProfileFeatureGate profileFeatureGate;
|
||||
|
||||
public IRVMValidator() {
|
||||
this(new IRVMProfileFeatureGate());
|
||||
}
|
||||
|
||||
IRVMValidator(final IRVMProfileFeatureGate profileFeatureGate) {
|
||||
this.profileFeatureGate = profileFeatureGate;
|
||||
}
|
||||
|
||||
public void validate(
|
||||
final IRVMModule module,
|
||||
@ -40,6 +49,13 @@ public class IRVMValidator {
|
||||
functionIndex,
|
||||
pcByIndex[i]);
|
||||
}
|
||||
if (!profileFeatureGate.isAllowed(module.vmProfile(), instr.op())) {
|
||||
throw new IRVMValidationException(
|
||||
IRVMValidationErrorCode.MARSHAL_VERIFY_PRECHECK_OPCODE_NOT_ALLOWED_FOR_PROFILE,
|
||||
"opcode '%s' is not allowed for vm profile '%s'".formatted(instr.op().name(), module.vmProfile()),
|
||||
functionIndex,
|
||||
pcByIndex[i]);
|
||||
}
|
||||
}
|
||||
|
||||
final var worklist = new ArrayDeque<Integer>();
|
||||
@ -222,4 +238,3 @@ public class IRVMValidator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test;
|
||||
import p.studio.utilities.structures.ReadOnlyList;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
class IRVMValidatorTest {
|
||||
@ -84,5 +85,41 @@ class IRVMValidatorTest {
|
||||
final var thrown = assertThrows(IRVMValidationException.class, () -> validator.validate(module, true));
|
||||
assertEquals(IRVMValidationErrorCode.MARSHAL_VERIFY_PRECHECK_INTERNAL_OPCODE_RESIDUAL, thrown.code());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateMustRejectOpcodeOutsideProfileFeatureGate() {
|
||||
final var module = new IRVMModule(
|
||||
"core-v1",
|
||||
ReadOnlyList.from(
|
||||
new IRVMFunction(
|
||||
"main",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
ReadOnlyList.from(
|
||||
new IRVMInstruction(IRVMOp.INTERNAL_EXT, null),
|
||||
new IRVMInstruction(IRVMOp.HALT, null)))));
|
||||
|
||||
final var thrown = assertThrows(IRVMValidationException.class, () -> validator.validate(module, false));
|
||||
assertEquals(IRVMValidationErrorCode.MARSHAL_VERIFY_PRECHECK_OPCODE_NOT_ALLOWED_FOR_PROFILE, thrown.code());
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateMayAllowProfileSpecificOpcodeWhenProfileSupportsIt() {
|
||||
final var module = new IRVMModule(
|
||||
"experimental-v1",
|
||||
ReadOnlyList.from(
|
||||
new IRVMFunction(
|
||||
"main",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
ReadOnlyList.from(
|
||||
new IRVMInstruction(IRVMOp.INTERNAL_EXT, null),
|
||||
new IRVMInstruction(IRVMOp.HALT, null)))));
|
||||
|
||||
assertDoesNotThrow(() -> validator.validate(module, false));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user