1 package org.simantics.scl.compiler.elaboration.chr;
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;
17 import gnu.trove.map.hash.TObjectIntHashMap;
18 import gnu.trove.procedure.TIntProcedure;
19 import gnu.trove.set.hash.TIntHashSet;
21 public class CHRRulesetObject extends SSAObject {
24 public BoundVar this_;
25 public BoundVar[] parameters;
26 public TObjectIntHashMap<BoundVar> parameterIndexMap;
27 public TypeDesc[] parameterTypeDescs;
29 public CHRRulesetObject(BoundVar target, CHRRuleset ruleset) {
30 super(ruleset.runtimeRulesetType);
31 this.setTarget(target);
32 this.ruleset = ruleset;
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));
47 public void generateCode(ModuleBuilder moduleBuilder) {
48 CHRRuntimeRulesetCodeGenerator.generateRuntimeRuleset(moduleBuilder, ruleset);
52 public interface ParameterDefiner {
53 public void defineParameter(int index, BoundVar var);
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]);
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));
71 usedParameterIndices.forEach(new TIntProcedure() {
73 public boolean execute(int i) {
74 loader.defineParameter(i, parameters[i]);
80 function.markGenerateOnFly();
81 function.generateCodeWithAlreadyPreparedParameters(mb);