X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Finternal%2Fcodegen%2Fchr%2FCHRRuntimeRulesetCodeGenerator.java;h=341ba34a796b18ebdd7dbd0850e7649b1328f60f;hp=003086704522773d11ebaa0e43bf4b659e00c28d;hb=f5c5f79bf2a62515c8c81103a4c8932fc0dcf79d;hpb=a2df536f7fc878982c6c960a79ed49f350cddc6f diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRRuntimeRulesetCodeGenerator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRRuntimeRulesetCodeGenerator.java index 003086704..341ba34a7 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRRuntimeRulesetCodeGenerator.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRRuntimeRulesetCodeGenerator.java @@ -7,30 +7,33 @@ 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.elaboration.expressions.block.IncludeStatement; import org.simantics.scl.compiler.internal.codegen.references.BoundVar; import org.simantics.scl.compiler.internal.codegen.utils.ClassBuilder; 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; public class CHRRuntimeRulesetCodeGenerator implements CHRCodeGenerationConstants { 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); + ClassBuilder storeClassBuilder = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, ruleset.runtimeRulesetClassName, CHRRuntimeRuleset_name); + if(ruleset.rulesetObject.parameters == null) + ruleset.rulesetObject.parameters = new BoundVar[0]; + TypeDesc[] parameterTypeDescs = ruleset.rulesetObject.parameterTypeDescs = moduleBuilder.getJavaTypeTranslator().getTypeDescs(ruleset.rulesetObject.parameters); ArrayList hashIndexInitializations = new ArrayList(); for(CHRConstraint constraint : ruleset.constraints) - generateFact(storeClassBuilder, constraint, hashIndexInitializations); + generateFact(storeClassBuilder, ruleset, 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 list = ruleset.inverseActiveConstraintSourceMap.get(include); + if(list != null) + for(CHRConstraint constraint : list) { + int minimumPriority = ruleset.getMinimumPriority(constraint); + if(minimumPriority == Integer.MAX_VALUE) + continue; + mb.loadLocal(importedStore); + mb.loadThis(); + mb.loadField(storeClassBuilder.getClassName(), CHRCodeGenerationConstants.priorityName(minimumPriority), CHRPriorityFactContainer); + mb.storeField(include.ruleset.runtimeRulesetClassName, CHRCodeGenerationConstants.nextContainerName(constraint.name), CHRPriorityFactContainer); + } + + // update context id + mb.loadLocal(importedStore); + mb.loadLocal(contextVar); + mb.invokeVirtual("org/simantics/scl/runtime/chr/CHRRuntimeRuleset", "register", TypeDesc.VOID, new TypeDesc[] {CHRContext}); + /*mb.loadLocal(contextVar); + mb.loadLocal(contextVar); + mb.loadField(CHRContext_name, "currentId", FACT_ID_TYPE); + mb.loadLocal(importedStore); + mb.loadField(include.ruleset.runtimeRulesetClassName, "currentId", FACT_ID_TYPE); + mb.invokeStatic("java/lang/Math", "max", FACT_ID_TYPE, new TypeDesc[] {FACT_ID_TYPE, FACT_ID_TYPE}); + mb.storeField(CHRContext_name, "currentId", FACT_ID_TYPE);*/ + + mb.returnVoid(); + mb.finish(); + } + + { + MethodBuilderBase mb = storeClassBuilder.addMethodBase(Opcodes.ACC_PUBLIC, "unregister", TypeDesc.VOID, + new TypeDesc[] {CHRContext, include.ruleset.runtimeRulesetTypeDesc}); + LocalVariable contextVar = mb.getParameter(0); + LocalVariable importedStore = mb.getParameter(1); + ArrayList list = ruleset.inverseActiveConstraintSourceMap.get(include); + if(list != null) + for(CHRConstraint constraint : list) { + int minimumPriority = ruleset.getMinimumPriority(constraint); + if(minimumPriority == Integer.MAX_VALUE) + continue; + mb.loadLocal(importedStore); + mb.loadNull(); + mb.storeField(include.ruleset.runtimeRulesetClassName, CHRCodeGenerationConstants.nextContainerName(constraint.name), CHRPriorityFactContainer); + } + + // store context id + mb.loadLocal(importedStore); + mb.loadLocal(contextVar); + mb.invokeVirtual("org/simantics/scl/runtime/chr/CHRRuntimeRuleset", "unregister", TypeDesc.VOID, new TypeDesc[] {CHRContext}); + /*mb.loadLocal(importedStore); + mb.loadLocal(contextVar); + mb.loadField(CHRContext_name, "currentId", FACT_ID_TYPE); + mb.storeField(include.ruleset.runtimeRulesetClassName, "currentId", FACT_ID_TYPE);*/ + + mb.returnVoid(); + mb.finish(); + } + } + + if(ruleset.initializer != null) { + MethodBuilder mb = storeClassBuilder.addMethod(Opcodes.ACC_PUBLIC, "initialize", TypeDesc.VOID, new TypeDesc[] {CHRContext}); + ruleset.rulesetObject.realizeMethod(mb, + (i, target) -> { + mb.loadThis(); + mb.loadField(ruleset.runtimeRulesetClassName, CHRCodeGenerationConstants.parameterName(i), parameterTypeDescs[i]); + mb.store(target); + }, + ruleset.initializer, mb.getThis(ruleset.runtimeRulesetTypeDesc), mb.getParameter(0)); + mb.finish(); + } + if(ruleset.deinitializer != null) { + MethodBuilder mb = storeClassBuilder.addMethod(Opcodes.ACC_PUBLIC, "deinitialize", TypeDesc.VOID, new TypeDesc[] {CHRContext}); + ruleset.rulesetObject.realizeMethod(mb, + (i, target) -> { + mb.loadThis(); + mb.loadField(ruleset.runtimeRulesetClassName, CHRCodeGenerationConstants.parameterName(i), parameterTypeDescs[i]); + mb.store(target); + }, + ruleset.deinitializer, mb.getThis(ruleset.runtimeRulesetTypeDesc), mb.getParameter(0)); + mb.finish(); + } moduleBuilder.addClass(storeClassBuilder); } - private static void generateFact(ClassBuilder storeClassBuilder, CHRConstraint constraint, ArrayList hashIndexInitializations) { - CHRFactCodeGenerator generator = new CHRFactCodeGenerator(storeClassBuilder, constraint); + private static void generateFact(ClassBuilder storeClassBuilder, CHRRuleset ruleset, CHRConstraint constraint, ArrayList hashIndexInitializations) { + CHRFactCodeGenerator generator = new CHRFactCodeGenerator(storeClassBuilder, ruleset, constraint); generator.generate(hashIndexInitializations); }