X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Finternal%2Fcodegen%2Fchr%2FCHRFactCodeGenerator.java;fp=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Finternal%2Fcodegen%2Fchr%2FCHRFactCodeGenerator.java;h=06725ec2b813dc4f0693a3b7a066d2f310a1dd4c;hb=2420f847edec02c27130709c8b333a72776f69c6;hp=0000000000000000000000000000000000000000;hpb=c8cce62f9952ab3f6db451d2f22d969b4e777eaa;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRFactCodeGenerator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRFactCodeGenerator.java new file mode 100644 index 000000000..06725ec2b --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRFactCodeGenerator.java @@ -0,0 +1,602 @@ +package org.simantics.scl.compiler.internal.codegen.chr; + +import java.util.ArrayList; + +import org.cojen.classfile.TypeDesc; +import org.objectweb.asm.Label; +import org.objectweb.asm.Opcodes; +import org.simantics.scl.compiler.elaboration.chr.CHRRuleset; +import org.simantics.scl.compiler.elaboration.chr.plan.PrioritizedPlan; +import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint; +import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint.IndexInfo; +import org.simantics.scl.compiler.internal.codegen.references.BoundVar; +import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator; +import org.simantics.scl.compiler.internal.codegen.utils.ClassBuilder; +import org.simantics.scl.compiler.internal.codegen.utils.CodeBuilderUtils; +import org.simantics.scl.compiler.internal.codegen.utils.Constants; +import org.simantics.scl.compiler.internal.codegen.utils.LocalVariable; +import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder; +import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilderBase; +import org.simantics.scl.compiler.internal.codegen.utils.ModuleBuilder; + +import gnu.trove.list.array.TIntArrayList; +import gnu.trove.set.hash.THashSet; + +public class CHRFactCodeGenerator { + private static final TypeDesc FACT_ID_TYPE = TypeDesc.INT; + private static final String CHRHashIndex_name = "org/simantics/scl/runtime/chr/CHRHashIndex"; + private static final TypeDesc CHRHashIndex = TypeDesc.forClass(CHRHashIndex_name); + private static final String FactActivationQueue_name = "org/simantics/scl/runtime/chr/FactActivationQueue"; + private static final TypeDesc FactActivationQueue = TypeDesc.forClass(FactActivationQueue_name); + private static final String Fact_name = "org/simantics/scl/runtime/chr/Fact"; + private static final TypeDesc Fact = TypeDesc.forClass(Fact_name); + private static final String QUEUE = "queue"; + + private ModuleBuilder moduleBuilder; + private JavaTypeTranslator jtt; + private CHRRuleset ruleset; + + private ClassBuilder storeClassBuilder; + private CHRConstraint constraint; + + private String factClassName; + private TypeDesc factTypeDesc; + private ClassBuilder factClassBuilder; + + private TypeDesc storeTypeDesc; + private TypeDesc[] storeTypeDescArray; + + private TypeDesc[] parameterTypeDescs; + private boolean supportsRemoval; + + CHRFactCodeGenerator(ClassBuilder storeClassBuilder, CHRConstraint constraint) { + this.storeClassBuilder = storeClassBuilder; + this.constraint = constraint; + this.ruleset = constraint.parentRuleset; + + this.moduleBuilder = storeClassBuilder.getModuleBuilder(); + this.jtt = moduleBuilder.getJavaTypeTranslator(); + this.storeTypeDesc = storeClassBuilder.getType(); + this.storeTypeDescArray = new TypeDesc[] { storeTypeDesc }; + + this.factClassName = storeClassBuilder.getClassName() + "$" + constraint.name; + this.factTypeDesc = TypeDesc.forClass(factClassName); + this.factClassBuilder = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, factClassName, "java/lang/Object", Fact_name); + + this.parameterTypeDescs = jtt.toTypeDescs(constraint.parameterTypes); + this.supportsRemoval = constraint.mayBeRemoved(); + } + + public void generate(ArrayList hashIndexInitializations) { + generateFields(hashIndexInitializations); + hashIndexInitializations.add(new StoreInitialization(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, constraint.name + "$temp", factTypeDesc, factClassName)); + + generateIndices(); + generateAdd(); + + if(supportsRemoval) + generateRemove(); + + generateIsAlive(); + + for(int i=0;i getParameterTypeDescs = new ArrayList(constraint.parameterTypes.length); + for(int i=0;i>i)&1)==1) + getParameterTypeDescs.add(parameterTypeDescs[i]); + MethodBuilderBase mb = storeClassBuilder.addMethodBase(Opcodes.ACC_PUBLIC, constraint.name + "$" + indexInfo.indexName, factTypeDesc, + getParameterTypeDescs.toArray(new TypeDesc[getParameterTypeDescs.size()])); + + // ExampleFact$temp.c0 = c0; + mb.loadThis(); + mb.loadField(storeClassBuilder.getClassName(), constraint.name + "$temp", factTypeDesc); + LocalVariable tempFactVar = mb.createLocalVariable("temp", factTypeDesc); + mb.storeLocal(tempFactVar); + int parameterId=0; + for(int i=0;i>i)&1)==1) { + TypeDesc typeDesc = parameterTypeDescs[i]; + if(!typeDesc.equals(TypeDesc.VOID)) { + mb.loadLocal(tempFactVar); + mb.loadLocal(mb.getParameter(parameterId)); + mb.storeField(factClassName, fieldName(i), typeDesc); + } + ++parameterId; + } + + // return (ExampleFact)ExampleFact_bfIndex.getEqual(ExampleFact$temp); + mb.loadThis(); + mb.loadField(storeClassBuilder.getClassName(), constraint.name + "$" + indexInfo.indexName, CHRHashIndex); + mb.loadLocal(tempFactVar); + mb.invokeVirtual(CHRHashIndex_name, supportsRemoval ? "getEqual" : "getEqualNoRemovals", TypeDesc.OBJECT, Constants.OBJECTS[1]); + mb.checkCast(factTypeDesc); + mb.returnValue(factTypeDesc); + mb.finish(); + } + } + } + + private THashSet usedParameters = new THashSet(); + + private void generateActivateI(int i) { + PrioritizedPlan plan = constraint.plans.get(i); + MethodBuilder mb = factClassBuilder.addMethod(Opcodes.ACC_PUBLIC, "activate" + i, TypeDesc.BOOLEAN, storeTypeDescArray); + LocalVariable storeVar = mb.getParameter(0); + LocalVariable factVar = new LocalVariable(0, factTypeDesc); + mb.setLocalVariable(ruleset.this_, storeVar); + mb.setLocalVariable(plan.implementation.getParameters()[0], factVar); + + // Set closure parameters + usedParameters.clear(); + plan.implementation.forValRefs(valRef -> { + if(valRef.getBinding() instanceof BoundVar) + usedParameters.add((BoundVar)valRef.getBinding()); + }); + for(int j=0;j labels = new ArrayList