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%2FCHRHashIndexCodeGenerator.java;fp=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Finternal%2Fcodegen%2Fchr%2FCHRHashIndexCodeGenerator.java;h=bafd83ec35776c530ac0fd7c3cdb357a64568cb6;hb=a2df536f7fc878982c6c960a79ed49f350cddc6f;hp=0000000000000000000000000000000000000000;hpb=5f0ad7a26810df602600c5eddad317588fce0ac4;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRHashIndexCodeGenerator.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRHashIndexCodeGenerator.java new file mode 100644 index 000000000..bafd83ec3 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/chr/CHRHashIndexCodeGenerator.java @@ -0,0 +1,120 @@ +package org.simantics.scl.compiler.internal.codegen.chr; + +import org.cojen.classfile.TypeDesc; +import org.objectweb.asm.Label; +import org.objectweb.asm.Opcodes; +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.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.MethodBuilderBase; +import org.simantics.scl.compiler.internal.codegen.utils.ModuleBuilder; + +public class CHRHashIndexCodeGenerator implements CHRCodeGenerationConstants { + + public static ClassBuilder generateHashIndex(ClassBuilder storeClassBuilder, CHRConstraint constraint, IndexInfo indexInfo, TypeDesc factClassTypeDesc, String factClassName) { + // new CHRHashIndex() { + // @Override + // protected boolean keyEquals(Object a, Object b) { + // return ((ExampleFact)a).c0 == ((ExampleFact)b).c0; + // } + // @Override + // protected int keyHashCode(Object key) { + // return ((ExampleFact)key).c0; + // } + // } + + ModuleBuilder moduleBuilder = storeClassBuilder.getModuleBuilder(); + JavaTypeTranslator jtt = moduleBuilder.getJavaTypeTranslator(); + + String hashIndexClassName = factClassName + "$" + indexInfo.indexName; + ClassBuilder hashIndexClassBuilder = new ClassBuilder(moduleBuilder, Opcodes.ACC_PUBLIC, hashIndexClassName, "org/simantics/scl/runtime/chr/CHRHashIndex"); + + // Method: keyEquals + + { + + // @Override + // protected boolean keyEquals(Object a, Object b) { + // return ((ExampleFact)a).c0 == ((ExampleFact)b).c0; + // } + + MethodBuilderBase mb = hashIndexClassBuilder.addMethodBase(Opcodes.ACC_PROTECTED, "keyEquals", TypeDesc.BOOLEAN, Constants.OBJECTS[2]); + mb.loadLocal(mb.getParameter(0)); + mb.checkCast(factClassTypeDesc); + LocalVariable aVar = mb.createLocalVariable("a", factClassTypeDesc); + mb.storeLocal(aVar); + + mb.loadLocal(mb.getParameter(1)); + mb.checkCast(factClassTypeDesc); + LocalVariable bVar = mb.createLocalVariable("b", factClassTypeDesc); + mb.storeLocal(bVar); + + Label failure = mb.createLabel(); + + int curMask = indexInfo.indexMask; + for(int i=0;i>=1) + if((curMask&1) == 1) { + TypeDesc fieldTypeDesc = jtt.toTypeDesc(constraint.parameterTypes[i]); + if(fieldTypeDesc.equals(TypeDesc.VOID)) + continue; + mb.loadLocal(aVar); + mb.loadField(factClassName, CHRCodeGenerationConstants.fieldName(i), fieldTypeDesc); + + mb.loadLocal(bVar); + mb.loadField(factClassName, CHRCodeGenerationConstants.fieldName(i), fieldTypeDesc); + + CodeBuilderUtils.equals(mb, fieldTypeDesc, failure); + } + mb.loadConstant(true); + mb.returnValue(TypeDesc.BOOLEAN); + + mb.setLocation(failure); + mb.loadConstant(false); + mb.returnValue(TypeDesc.BOOLEAN); + mb.finish(); + } + + // Method: keyHashCode + + { + // @Override + // protected int keyHashCode(Object key) { + // return (0x811C9DC5^((ExampleFact)key).c0)*16777619; + // } + + MethodBuilderBase mb = hashIndexClassBuilder.addMethodBase(Opcodes.ACC_PROTECTED, "keyHashCode", TypeDesc.INT, Constants.OBJECTS[1]); + mb.loadLocal(mb.getParameter(0)); + mb.checkCast(factClassTypeDesc); + LocalVariable factVar = mb.createLocalVariable("fact", factClassTypeDesc); + mb.storeLocal(factVar); + + mb.loadConstant(0x811C9DC5); + + int curMask = indexInfo.indexMask; + for(int i=0;i>=1) + if((curMask&1) == 1) { + TypeDesc fieldTypeDesc = jtt.toTypeDesc(constraint.parameterTypes[i]); + if(fieldTypeDesc.equals(TypeDesc.VOID)) + continue; + mb.loadLocal(factVar); + mb.loadField(factClassName, CHRCodeGenerationConstants.fieldName(i), fieldTypeDesc); + CodeBuilderUtils.hashCode(mb, fieldTypeDesc); + mb.math(Opcodes.IXOR); + mb.loadConstant(16777619); + mb.math(Opcodes.IMUL); + + } + mb.returnValue(TypeDesc.INT); + mb.finish(); + } + + hashIndexClassBuilder.addDefaultConstructor(); + + return hashIndexClassBuilder; + } + +}