]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/utils/SSAValidationContext.java
923acdba26115c6cd18d2a95d3bc15267a9a5536
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / utils / SSAValidationContext.java
1 package org.simantics.scl.compiler.internal.codegen.utils;
2
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
16 import gnu.trove.map.hash.TObjectIntHashMap;
17 import gnu.trove.procedure.TObjectIntProcedure;
18 import gnu.trove.set.hash.THashSet;
19
20 public class SSAValidationContext {
21
22     public THashSet<BoundVar> validBoundVariables = new THashSet<BoundVar>();
23     public THashSet<Cont> validContinuations = new THashSet<Cont>();
24     public THashSet<TVar> validTypeVariables = new THashSet<TVar>();
25     public TObjectIntHashMap<Val> refCount = new TObjectIntHashMap<Val>(); 
26     public Object errorMarker = null;
27     
28     public void assertEquals(Object loc, Type a, Type b) {
29         if(!Types.equals(a, b)) {
30             TypeUnparsingContext tuc = new TypeUnparsingContext();
31             System.err.println(a.toString(tuc) + " != " + b.toString(tuc));
32             setErrorMarker(loc);
33             throw new InternalCompilerError();
34         }
35     }
36     
37     public void assertSubsumes(Object loc, Type a, Type b) {
38         if(!Types.subsumes(a, b)) {
39             TypeUnparsingContext tuc = new TypeUnparsingContext();
40             /*System.err.println(a.toString(tuc) + " <! " + b.toString(tuc));*/
41             setErrorMarker(loc);
42             throw new InternalCompilerError(a.toString(tuc) + " <! " + b.toString(tuc));
43         }
44     }
45
46     public void assertEqualsEffect(Object loc, Type a, Type b) {
47         if(!Types.equalsEffect(a, b)) {
48             TypeUnparsingContext tuc = new TypeUnparsingContext();
49             System.err.println(a.toString(tuc) + " != " + b.toString(tuc));
50             setErrorMarker(loc);
51             throw new InternalCompilerError();
52         }
53     }
54     
55     public void assertEquals(int a, int b) {
56         if(a != b)
57             throw new InternalCompilerError();
58     }
59
60     public void reset() {
61         validContinuations.clear();
62         validTypeVariables.clear();
63     }
64
65     public void validate(Cont cont) {
66         for(int i=0;i<cont.getArity();++i)
67             validateType(cont.getParameterType(i));
68     }
69     
70     public void validate(Val val) {
71         validateType(val.getType());
72     }
73     
74     private static boolean hasOccurrence(Cont cont, ContRef occ) {
75         for(ContRef ref = cont.getOccurrence(); 
76                 ref != null; 
77                 ref = ref.getNext())
78             if(ref == occ)
79                 return true;
80         return false;
81     }
82     
83     public void validate(ContRef ref) {
84         if(!validContinuations.contains(ref.getBinding()))
85             throw new InternalCompilerError();
86         if(!hasOccurrence(ref.getBinding(), ref))
87             throw new InternalCompilerError();
88         if(ref.getParent() == null)
89             throw new InternalCompilerError();
90     }
91     
92     boolean invalidReferenceCounts;
93     
94     public void checkReferences() {
95         invalidReferenceCounts = false;
96         refCount.forEachEntry(new TObjectIntProcedure<Val>() {            
97             @Override
98             public boolean execute(Val val, int count) {
99                 if(val instanceof Constant) {
100                     if(!(val instanceof SCLConstant))
101                         return true;
102                     if(!((SCLConstant)val).getName().module.equals("Composition"))
103                         return true;
104                 }
105                 
106                 int realCount = val.occurrenceCount();
107                 if(realCount != count) {
108                     System.out.println(val + ": " + realCount + " != " + count);
109                     invalidReferenceCounts = true;                    
110                 }
111                 return true;
112             }
113         });
114         if(invalidReferenceCounts)
115             throw new InternalCompilerError();
116     }
117     
118     public void validate(ValRef ref) {
119         refCount.adjustOrPutValue(ref.getBinding(), 1, 1);
120         
121         Val val = ref.getBinding();
122         if(val == null)
123             throw new InternalCompilerError();
124         if(val instanceof Constant)
125             return;
126         if(!validBoundVariables.contains(val))
127             throw new InternalCompilerError();
128         
129         if(ref.getParent() == null)
130             throw new InternalCompilerError();
131     }
132
133     public void validateType(Type type) {
134         // PROBLEM: code involving existential data types do not pass this test
135         /*for(TVar var : Types.freeVars(type))
136             if(!validTypeVariables.contains(var))
137                 throw new InternalCompilerError();*/
138     }
139     
140     public void setErrorMarker(Object errorMarker) {
141         this.errorMarker = errorMarker;
142     }
143     
144 }