]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/JavaStaticField.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / constants / JavaStaticField.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/JavaStaticField.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/JavaStaticField.java
new file mode 100644 (file)
index 0000000..77d50fd
--- /dev/null
@@ -0,0 +1,96 @@
+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 +")";
+    }
+}