]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRulesetObject.java
(refs #7250) Merging master, minor CHR bugfixes
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / chr / CHRRulesetObject.java
1 package org.simantics.scl.compiler.elaboration.chr;
2
3 import org.cojen.classfile.TypeDesc;
4 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
5 import org.simantics.scl.compiler.constants.Constant;
6 import org.simantics.scl.compiler.constants.JavaConstructor;
7 import org.simantics.scl.compiler.internal.codegen.chr.CHRRuntimeRulesetCodeGenerator;
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.ssa.SSAFunction;
11 import org.simantics.scl.compiler.internal.codegen.ssa.SSAObject;
12 import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable;
13 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
14 import org.simantics.scl.compiler.internal.codegen.utils.ModuleBuilder;
15 import org.simantics.scl.compiler.types.Types;
16
17 import gnu.trove.map.hash.TObjectIntHashMap;
18 import gnu.trove.procedure.TIntProcedure;
19 import gnu.trove.set.hash.TIntHashSet;
20
21 public class CHRRulesetObject extends SSAObject {
22     CHRRuleset ruleset;
23
24     public BoundVar this_;
25     public BoundVar[] parameters;
26     public TObjectIntHashMap<BoundVar> parameterIndexMap; 
27     public TypeDesc[] parameterTypeDescs;
28     
29     public CHRRulesetObject(BoundVar target, CHRRuleset ruleset) {
30         super(ruleset.runtimeRulesetType);
31         this.setTarget(target);
32         this.ruleset = ruleset;
33     }
34     
35     @Override
36     public Constant liftClosure(BoundVar newTarget, BoundVar[] parameters) {
37         ruleset.rulesetObject = this;
38         this.this_ = newTarget;
39         this.parameters = parameters;
40         this.parameterIndexMap = new TObjectIntHashMap<>(parameters.length);
41         for(int i=0;i<parameters.length;++i)
42             this.parameterIndexMap.put(parameters[i], i);
43         return new JavaConstructor(ruleset.runtimeRulesetClassName, Types.PROC, ruleset.runtimeRulesetType, Types.getTypes(parameters));
44     }
45     
46     @Override
47     public void generateCode(ModuleBuilder moduleBuilder) {
48         CHRRuntimeRulesetCodeGenerator.generateRuntimeRuleset(moduleBuilder, ruleset);
49     }
50     
51     @FunctionalInterface
52     public interface ParameterDefiner {
53         public void defineParameter(int index, BoundVar var);
54     }
55     
56     public void realizeMethod(MethodBuilder mb, ParameterDefiner loader, SSAFunction function, LocalVariable this_, LocalVariable ... callParameters) {
57         mb.setLocalVariable(this.this_, this_);
58         BoundVar[] functionParameters = function.getParameters();
59         if(functionParameters.length != callParameters.length)
60             throw new InternalCompilerError();
61         for(int i=0;i<callParameters.length;++i)
62             mb.setLocalVariable(functionParameters[i], callParameters[i]);
63
64         // Set closure parameters
65         TIntHashSet usedParameterIndices = new TIntHashSet(parameters.length);
66         function.forValRefs(valRef -> {
67             Val binding = valRef.getBinding();
68             if(parameterIndexMap.containsKey(binding))
69                 usedParameterIndices.add(parameterIndexMap.get((BoundVar)binding));
70         });
71         usedParameterIndices.forEach(new TIntProcedure() {
72             @Override
73             public boolean execute(int i) {
74                 loader.defineParameter(i, parameters[i]);
75                 return true;
76             }
77         });
78
79         // Generate code
80         function.markGenerateOnFly();
81         function.generateCodeWithAlreadyPreparedParameters(mb);
82     }
83 }