]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRRuntimeRulesetCodeGenerator.java
(refs #7250) Refactoring CHR implementation
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / chr / CHRRuntimeRulesetCodeGenerator.java
@@ -4,6 +4,7 @@ import java.util.ArrayList;
 
 import org.cojen.classfile.TypeDesc;
 import org.objectweb.asm.Opcodes;
+import org.simantics.scl.compiler.elaboration.chr.CHRRule;
 import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
 import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
 import org.simantics.scl.compiler.internal.codegen.references.BoundVar;
@@ -12,34 +13,32 @@ import org.simantics.scl.compiler.internal.codegen.utils.Constants;
 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilderBase;
 import org.simantics.scl.compiler.internal.codegen.utils.ModuleBuilder;
 
-public class CHRCodeGenerator {
+public class CHRRuntimeRulesetCodeGenerator implements CHRCodeGenerationConstants {
 
-    public static final TypeDesc FACT_ID_TYPE = TypeDesc.INT;
-    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 QUEUE = "queue";
-
-    public static void generateStore(ModuleBuilder moduleBuilder, CHRRuleset ruleset) {
-        ClassBuilder storeClassBuilder = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, ruleset.storeClassName, "java/lang/Object");
+    public static void generateRuntimeRuleset(ModuleBuilder moduleBuilder, CHRRuleset ruleset) {
+        ClassBuilder storeClassBuilder = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, ruleset.runtimeRulesetName, CHRRuntimeRuleset_name);
         if(ruleset.parameters == null)
             ruleset.parameters = new BoundVar[0];
         ruleset.parameterTypeDescs = moduleBuilder.getJavaTypeTranslator().getTypeDescs(ruleset.parameters); 
 
-        ArrayList<StoreInitialization> hashIndexInitializations = new ArrayList<>();
+        ArrayList<StoreInitialization> hashIndexInitializations = new ArrayList<StoreInitialization>();
         for(CHRConstraint constraint : ruleset.constraints)
             generateFact(storeClassBuilder, constraint, hashIndexInitializations);
+        
+        for(int i=ruleset.rules.size()-1;i>=0;--i)
+            generateFactContainer(storeClassBuilder, ruleset, ruleset.rules.get(i));
 
         // Fields
         for(int i=0;i<ruleset.parameterTypeDescs.length;++i) {
             TypeDesc typeDesc = ruleset.parameterTypeDescs[i];
             if(typeDesc.equals(TypeDesc.VOID))
                 continue;
-            storeClassBuilder.addField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "p" + i, typeDesc);
+            storeClassBuilder.addField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, CHRCodeGenerationConstants.parameterName(i), typeDesc);
         }
-        storeClassBuilder.addField(Opcodes.ACC_PUBLIC, "currentId", FACT_ID_TYPE);
         for(StoreInitialization ini : hashIndexInitializations)
             storeClassBuilder.addField(ini.access, ini.fieldName, ini.fieldType);
-        storeClassBuilder.addField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, QUEUE, FactActivationQueue);
+        for(CHRRule rule : ruleset.rules)
+            storeClassBuilder.addField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, CHRCodeGenerationConstants.priorityName(rule.priority), CHRPriorityFactContainer);
 
         // Constructors
 
@@ -53,43 +52,28 @@ public class CHRCodeGenerator {
                     continue;
                 mb.loadThis();
                 mb.loadLocal(mb.getParameter(i));
-                mb.storeField(ruleset.storeClassName, "p" + i, ruleset.parameterTypeDescs[i]);
+                mb.storeField(ruleset.runtimeRulesetName, CHRCodeGenerationConstants.parameterName(i), ruleset.parameterTypeDescs[i]);
             }
-            mb.loadThis();
-            mb.loadConstant(1);
-            mb.storeField(storeClassBuilder.getClassName(), "currentId", TypeDesc.INT);
             for(StoreInitialization ini : hashIndexInitializations) {
                 mb.loadThis();
                 mb.newObject(ini.className);
                 mb.dup();
                 mb.invokeConstructor(ini.className, Constants.EMPTY_TYPEDESC_ARRAY);
-                mb.storeField(ruleset.storeClassName, ini.fieldName, ini.fieldType);
+                mb.storeField(ruleset.runtimeRulesetName, ini.fieldName, ini.fieldType);
             }
-            {
+            TypeDesc[] runtimeRulesetTypeDescArray = new TypeDesc[] {TypeDesc.forClass(storeClassBuilder.getClassName())};
+            for(CHRRule rule : ruleset.rules) {
                 mb.loadThis();
-                mb.newObject(FactActivationQueue_name);
+                mb.newObject(rule.containerClassName);
                 mb.dup();
-                mb.loadConstant(ruleset.priorityCount);
-                mb.invokeConstructor(FactActivationQueue_name, new TypeDesc[] {TypeDesc.INT});
-                mb.storeField(ruleset.storeClassName, QUEUE, FactActivationQueue);
+                mb.loadThis();
+                mb.invokeConstructor(rule.containerClassName, runtimeRulesetTypeDescArray);
+                mb.storeField(ruleset.runtimeRulesetName, CHRCodeGenerationConstants.priorityName(rule.priority), CHRPriorityFactContainer);
             }
             mb.returnVoid();
             mb.finish();
         }
 
-        // Activate
-
-        {
-            MethodBuilderBase mb = storeClassBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "activate", TypeDesc.VOID, new TypeDesc[] {TypeDesc.INT});
-            mb.loadThis();
-            mb.loadField(ruleset.storeClassName, QUEUE, FactActivationQueue);
-            mb.loadThis();
-            mb.loadLocal(mb.getParameter(0));
-            mb.invokeVirtual(FactActivationQueue_name, "activate", TypeDesc.VOID, new TypeDesc[] {TypeDesc.OBJECT, TypeDesc.INT});
-            mb.returnVoid();
-            mb.finish();
-        }
-
         moduleBuilder.addClass(storeClassBuilder);
     }
 
@@ -97,4 +81,10 @@ public class CHRCodeGenerator {
         CHRFactCodeGenerator generator = new CHRFactCodeGenerator(storeClassBuilder, constraint);
         generator.generate(hashIndexInitializations);
     }
+
+    private static void generateFactContainer(ClassBuilder storeClassBuilder, CHRRuleset ruleset, CHRRule rule) {
+        CHRPriorityFactContainerCodeGenerator generator = new CHRPriorityFactContainerCodeGenerator(storeClassBuilder, ruleset, rule); 
+        generator.generate();
+        rule.containerClassName = generator.containerClassName;
+    }
 }