package org.simantics.scl.compiler.constants; import java.lang.reflect.Field; import org.cojen.classfile.TypeDesc; import org.objectweb.asm.Label; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.internal.codegen.continuations.Cont; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator; import org.simantics.scl.compiler.internal.codegen.utils.Constants; import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder; import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder; import org.simantics.scl.compiler.runtime.MutableClassLoader; import org.simantics.scl.compiler.types.Type; public class JavaStaticField extends Constant { String className; String fieldName; TypeDesc fieldType; Type effect; int constructorTag; public JavaStaticField(String className, String fieldName, Type effect, TypeDesc fieldType, Type type, int constructorTag) { super(type); this.className = className; this.fieldName = fieldName; this.fieldType = fieldType; this.effect = effect; this.constructorTag = constructorTag; } public JavaStaticField(String className, String fieldName, Type type, int constructorTag) { this(className, fieldName, null, null, type, constructorTag); } @Override public void push(MethodBuilder mb) { if(fieldType == null) { JavaTypeTranslator tt = mb.getJavaTypeTranslator(); fieldType = tt.toTypeDesc(getType()); } mb.loadStaticField(className, fieldName, fieldType); } public String getClassName() { return className; } public String getFieldName() { return fieldName; } @Override public Object realizeValue(TransientClassBuilder classBuilder) { MutableClassLoader classLoader = classBuilder.classLoader; try { Class clazz = classLoader.loadClass(className.replace('/', '.')); Field field = clazz.getDeclaredField(fieldName); return field.get(null); } catch (IllegalArgumentException e) { throw new InternalCompilerError(e); } catch (IllegalAccessException e) { throw new InternalCompilerError(e); } catch (ClassNotFoundException e) { throw new InternalCompilerError(e); } catch (SecurityException e) { throw new InternalCompilerError(e); } catch (NoSuchFieldException e) { throw new InternalCompilerError(e); } } @Override public void deconstruct(MethodBuilder mb, IVal parameter, Cont success, Label failure) { push(mb); mb.push(parameter, getType()); mb.invokeVirtual(TypeDesc.OBJECT, "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]); mb.ifZeroComparisonBranch(failure, "=="); mb.jump(success); } public int constructorTag() { return constructorTag; } @Override public String toString() { return "JavaStaticField(" + className + "." + fieldName +")"; } }