]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/ValRef.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / codegen / references / ValRef.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/ValRef.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/references/ValRef.java
new file mode 100644 (file)
index 0000000..20a8eb1
--- /dev/null
@@ -0,0 +1,236 @@
+package org.simantics.scl.compiler.internal.codegen.references;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.binders.ValRefBinder;\r
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;\r
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;\r
+import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;\r
+import org.simantics.scl.compiler.internal.codegen.utils.TransientClassBuilder;\r
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;\r
+import org.simantics.scl.compiler.types.TVar;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+\r
+public final class ValRef implements IVal {\r
+    public static final ValRef[] EMPTY_ARRAY = new ValRef[0];\r
+\r
+    Val binding;\r
+    ValRef prev; // FreeVars with the same binding form a linked list\r
+    ValRef next;     \r
+    ValRefBinder parent;\r
+    Type[] parameters;\r
+    \r
+    /**\r
+     * Just for deserialization\r
+     */\r
+    public ValRef(Type[] parameters) {\r
+        this.parameters = parameters;\r
+    }\r
+    \r
+    ValRef(Val binding, Type[] parameters) {\r
+        //System.out.println("+ " + bindin g);\r
+        this.parameters = parameters;        \r
+        setBinding(binding);\r
+    }    \r
+    \r
+    public void setBinding(Val binding) {\r
+        this.binding = binding;\r
+        \r
+        ValRef head = binding.occurrence;\r
+        binding.occurrence = this;\r
+        this.next = head;\r
+        this.prev = null;\r
+        if(head != null)\r
+            head.prev = this;\r
+    }\r
+    \r
+    int removeModiId = -1;\r
+    public void remove() {\r
+        //System.out.println("- " + binding);\r
+        if(prev == null)\r
+            try {\r
+                binding.occurrence = next;\r
+            } catch(NullPointerException e) {\r
+                System.err.println("removeModiId = " + removeModiId);\r
+                System.err.println("current ModiId = " + SSASimplificationContext.modiId);\r
+                throw new InternalCompilerError("The ValRef has already been removed.");\r
+            }\r
+        else\r
+            prev.next = next;\r
+        if(next != null)\r
+            next.prev = prev;\r
+        if(SCLCompilerConfiguration.DEBUG) {\r
+            next = null;\r
+            prev = null;\r
+            binding = null;\r
+        }\r
+        removeModiId = SSASimplificationContext.modiId;\r
+    }\r
+    \r
+    public Val getBinding() {\r
+        return binding;\r
+    }\r
+    \r
+    public ValRef getNext() {\r
+        return next;\r
+    }\r
+    \r
+    public static Val[] getBindings(ValRef[] refs) {\r
+        Val[] result = new Val[refs.length];\r
+        for(int i=0;i<refs.length;++i)\r
+            result[i] = refs[i].getBinding();\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public ValRef createOccurrence() {\r
+        return binding.createOccurrence(parameters);\r
+    }\r
+\r
+    @Override\r
+    public ValRef createOccurrence(Type... otherParameters) {\r
+        return binding.createOccurrence(Types.concat(parameters, otherParameters));\r
+    }\r
+    \r
+    @Override\r
+    public IVal createSpecialization(Type... otherParameters) {\r
+        return new ValSpecialization(binding, Types.concat(parameters, otherParameters));\r
+    }\r
+\r
+    public void setParent(ValRefBinder parent) {\r
+        this.parent = parent;\r
+    }\r
+    \r
+    @Override\r
+    public Type getType() {\r
+        if(parameters.length == 0)\r
+            return binding.getType();\r
+        else\r
+            return Types.instantiate(binding.getType(), parameters); \r
+    }\r
+    \r
+    public static ValRef[] createOccurrences(IVal[] vals) {\r
+        ValRef[] result = new ValRef[vals.length];\r
+        for(int i=0;i<vals.length;++i)\r
+            result[i] = vals[i].createOccurrence();\r
+        return result;\r
+    }\r
+    \r
+    public static <T extends IVal> ValRef[] createOccurrences(List<T> vals) {\r
+        ValRef[] result = new ValRef[vals.size()];\r
+        for(int i=0;i<vals.size();++i)\r
+            result[i] = vals.get(i).createOccurrence();\r
+        return result;\r
+    }\r
+    \r
+    public Type[] getTypeParameters() {\r
+        return parameters;\r
+    }\r
+    \r
+    public Type getTypeParameter(int i) {\r
+        return parameters[i];\r
+    }\r
+\r
+    public static ValRef[] concat(ValRef[] refs1, ValRef[] refs2) {\r
+        ValRef[] result = new ValRef[refs1.length + refs2.length];\r
+        for(int i=0;i<refs1.length;++i)\r
+            result[i] = refs1[i];\r
+        for(int i=0;i<refs2.length;++i)\r
+            result[refs1.length + i] = refs2[i];\r
+        return result;\r
+    }\r
+    \r
+    @Override\r
+    public void push(MethodBuilder mb) {\r
+        binding.push(mb);\r
+    }\r
+    \r
+    public ValRefBinder getParent() {\r
+        return parent;\r
+    }\r
+    \r
+    public SSAFunction getParentFunction() {\r
+        return parent.getParentFunction();\r
+    }\r
+    \r
+    public void replace(TVar[] vars, Type[] replacements) {\r
+        for(int i=0;i<parameters.length;++i) {\r
+            Type oldType = parameters[i];\r
+            Type newType = parameters[i].replace(vars, replacements);\r
+            if(oldType != newType) {\r
+                Type[] newParameters = new Type[parameters.length];\r
+                for(int j=0;j<i;++j)\r
+                    newParameters[j] = parameters[j];\r
+                newParameters[i] = newType;\r
+                for(int j=i+1;j<parameters.length;++j)\r
+                    newParameters[j] = parameters[j].replace(vars, replacements);\r
+                this.parameters = newParameters;\r
+                return;\r
+            }\r
+            \r
+        }\r
+    }\r
+\r
+    public void setTypeParameters(Type[] parameters) {\r
+        this.parameters = parameters;\r
+    }\r
+    \r
+    public static ValRef[] copy(ValRef[] refs) {\r
+        ValRef[] result = new ValRef[refs.length];\r
+        for(int i=0;i<refs.length;++i)\r
+            result[i] = refs[i].copy();\r
+        return result;\r
+    }\r
+\r
+    public ValRef copy() {\r
+        return binding.createOccurrence(parameters);\r
+    }\r
+\r
+    public void collectFreeVariables(SSAFunction function,\r
+            ArrayList<ValRef> vars) {\r
+        if(binding instanceof BoundVar) {\r
+            BoundVar var = (BoundVar)binding;\r
+            if(var.getFunctionParent() != function)\r
+                vars.add(this);\r
+        }\r
+    }\r
+\r
+    public void replaceBy(Val binding) {\r
+        remove();\r
+        setBinding(binding);\r
+    }\r
+    \r
+    @Override\r
+    public Type apply(MethodBuilder mb, Type[] typeParameters,\r
+            Val... parameters) {\r
+        return binding.apply(mb, Types.concat(this.parameters, typeParameters), parameters);\r
+    }\r
+\r
+    /**\r
+     * Replaces this reference with an application\r
+     */\r
+    public void replaceByApply(Val function, Val ... parameters) {\r
+        getParent().replaceByApply(this, function, this.parameters, parameters);\r
+    }\r
+    \r
+    @Override\r
+    public Object realizeValue(TransientClassBuilder classLoader) {\r
+        return binding.realizeValue(classLoader); \r
+    }\r
+\r
+    @Override\r
+    public void setLabel(String label) {\r
+    }\r
+\r
+    public void updateParentEffect() {\r
+        if(parent instanceof LetApply) {\r
+            LetApply apply = (LetApply)parent;\r
+            if(apply.getFunction() == this)\r
+                apply.updateEffect();\r
+        }\r
+    }\r
+}\r