X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Fconstants%2Fgeneric%2FThreadLocalStackItem.java;fp=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Fconstants%2Fgeneric%2FThreadLocalStackItem.java;h=fe8959f64d44362ca19fdf1f742e704330667248;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/ThreadLocalStackItem.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/ThreadLocalStackItem.java new file mode 100644 index 000000000..fe8959f64 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/generic/ThreadLocalStackItem.java @@ -0,0 +1,81 @@ +package org.simantics.scl.compiler.constants.generic; + +import org.cojen.classfile.TypeDesc; +import org.objectweb.asm.Label; +import org.simantics.scl.compiler.internal.codegen.references.Val; +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.PreparationStep; +import org.simantics.scl.compiler.internal.codegen.utils.SCLContextPreparationStep; +import org.simantics.scl.compiler.top.SCLCompilerConfiguration; + +public class ThreadLocalStackItem implements StackItem, PreparationStep { + + private static final TypeDesc THREAD_LOCAL = + TypeDesc.forClass(ThreadLocal.class); + + String variableName; + TypeDesc type; + + public ThreadLocalStackItem(String variableName, TypeDesc type) { + this.variableName = variableName; + this.type = type; + } + + @Override + public void push(MethodBuilder mb, Val[] parameters) { + mb.loadLocal(mb.getPreparation(this)); + } + + @Override + public void prepare(MethodBuilder mb) { + LocalVariable var = mb.getPreparation(this); + if(var == null) { + var = mb.createLocalVariable("context", type); + LocalVariable sclContext = SCLContextPreparationStep.getCurrent(mb); + mb.loadLocal(sclContext); + mb.loadConstant(variableName); + mb.invokeVirtual("gnu/trove/map/hash/THashMap", "get", + TypeDesc.OBJECT, new TypeDesc[] {TypeDesc.OBJECT}); + mb.checkCast(type); + mb.storeLocal(var); + + if(SCLCompilerConfiguration.NULL_CHECK_THREAD_LOCAL_VARIABLES) { + Label exit = mb.createLabel(); + mb.loadLocal(var); + mb.ifNullBranch(exit, false); + + // This code should me redundant because of static type caughts the problem + mb.newObject(TypeDesc.forClass(IllegalStateException.class)); + mb.dup(); + mb.loadConstant("Thread local variable missing"); + mb.invokeConstructor(TypeDesc.forClass(IllegalStateException.class), + new TypeDesc[] {TypeDesc.STRING}); + mb.throwObject(); + + mb.setLocation(exit); + } + + mb.addPreparation(this, var); + } + } + + @Override + public int hashCode() { + return 234234 + type.hashCode() + 31*variableName.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ThreadLocalStackItem other = (ThreadLocalStackItem) obj; + return variableName.equals(other.variableName) + && type.equals(other.type); + } + +}