1 package org.simantics.scl.compiler.internal.codegen.utils;
3 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
4 import org.simantics.scl.compiler.constants.Constant;
5 import org.simantics.scl.compiler.constants.SCLConstant;
6 import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
7 import org.simantics.scl.compiler.internal.codegen.continuations.ContRef;
8 import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
9 import org.simantics.scl.compiler.internal.codegen.references.Val;
10 import org.simantics.scl.compiler.internal.codegen.references.ValRef;
11 import org.simantics.scl.compiler.types.TVar;
12 import org.simantics.scl.compiler.types.Type;
13 import org.simantics.scl.compiler.types.Types;
14 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
18 import gnu.trove.map.hash.TObjectIntHashMap;
19 import gnu.trove.procedure.TObjectIntProcedure;
20 import gnu.trove.set.hash.THashSet;
22 public class SSAValidationContext {
24 private static final Logger LOGGER = LoggerFactory.getLogger(SSAValidationContext.class);
26 public THashSet<BoundVar> validBoundVariables = new THashSet<BoundVar>();
27 public THashSet<Cont> validContinuations = new THashSet<Cont>();
28 public THashSet<TVar> validTypeVariables = new THashSet<TVar>();
29 public TObjectIntHashMap<Val> refCount = new TObjectIntHashMap<Val>();
30 public Object errorMarker = null;
32 public void assertEquals(Object loc, Type a, Type b) {
33 if(!Types.equals(a, b)) {
34 TypeUnparsingContext tuc = new TypeUnparsingContext();
35 String message = a.toString(tuc) + " != " + b.toString(tuc);
36 LOGGER.error(message);
38 throw new InternalCompilerError(message);
42 public void assertSubsumes(Object loc, Type a, Type b) {
43 if(!Types.subsumes(a, b)) {
44 TypeUnparsingContext tuc = new TypeUnparsingContext();
45 /*System.err.println(a.toString(tuc) + " <! " + b.toString(tuc));*/
47 throw new InternalCompilerError(a.toString(tuc) + " <! " + b.toString(tuc));
51 public void assertEqualsEffect(Object loc, Type a, Type b) {
52 if(!Types.equalsEffect(a, b)) {
53 TypeUnparsingContext tuc = new TypeUnparsingContext();
54 String message = a.toString(tuc) + " != " + b.toString(tuc);
55 LOGGER.error(message);
57 throw new InternalCompilerError(message);
61 public void assertEquals(int a, int b) {
63 throw new InternalCompilerError();
67 validContinuations.clear();
68 validTypeVariables.clear();
71 public void validate(Cont cont) {
72 for(int i=0;i<cont.getArity();++i)
73 validateType(cont.getParameterType(i));
76 public void validate(Val val) {
77 validateType(val.getType());
80 private static boolean hasOccurrence(Cont cont, ContRef occ) {
81 for(ContRef ref = cont.getOccurrence();
89 public void validate(ContRef ref) {
90 if(!validContinuations.contains(ref.getBinding()))
91 throw new InternalCompilerError();
92 if(!hasOccurrence(ref.getBinding(), ref))
93 throw new InternalCompilerError();
94 if(ref.getParent() == null)
95 throw new InternalCompilerError();
98 boolean invalidReferenceCounts;
100 public void checkReferences() {
101 invalidReferenceCounts = false;
102 refCount.forEachEntry(new TObjectIntProcedure<Val>() {
104 public boolean execute(Val val, int count) {
105 if(val instanceof Constant) {
106 if(!(val instanceof SCLConstant))
108 if(!((SCLConstant)val).getName().module.equals("Composition"))
112 int realCount = val.occurrenceCount();
113 if(realCount != count) {
114 LOGGER.warn(val + ": " + realCount + " != " + count);
115 invalidReferenceCounts = true;
120 if(invalidReferenceCounts)
121 throw new InternalCompilerError();
124 public void validate(ValRef ref) {
125 refCount.adjustOrPutValue(ref.getBinding(), 1, 1);
127 Val val = ref.getBinding();
129 throw new InternalCompilerError();
130 if(val instanceof Constant)
132 if(!validBoundVariables.contains(val))
133 throw new InternalCompilerError();
135 if(ref.getParent() == null)
136 throw new InternalCompilerError();
139 public void validateType(Type type) {
140 // PROBLEM: code involving existential data types do not pass this test
141 /*for(TVar var : Types.freeVars(type))
142 if(!validTypeVariables.contains(var))
143 throw new InternalCompilerError();*/
146 public void setErrorMarker(Object errorMarker) {
147 this.errorMarker = errorMarker;