package org.simantics.scl.compiler.internal.codegen.utils; import org.cojen.classfile.TypeDesc; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.internal.codegen.continuations.Cont; import org.simantics.scl.compiler.internal.codegen.continuations.ContRef; import org.simantics.scl.compiler.internal.codegen.continuations.ReturnCont; import org.simantics.scl.compiler.internal.codegen.references.BoundVar; import org.simantics.scl.compiler.internal.codegen.references.IVal; import org.simantics.scl.compiler.internal.codegen.references.Val; import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock; import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator; import org.simantics.scl.compiler.top.SCLCompilerConfiguration; import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import gnu.trove.map.hash.THashMap; import gnu.trove.set.hash.THashSet; public class MethodBuilder extends MethodBuilderBase { ModuleBuilder moduleBuilder; THashMap labels = new THashMap(); THashMap localVariables = new THashMap(); THashSet generatedConts = new THashSet(); THashMap preparationSteps = new THashMap(4); public MethodBuilder(ClassBuilder classBuilder, ModuleBuilder moduleBuilder, boolean isStatic, MethodVisitor methodVisitor, TypeDesc[] parameterTypes) { super(classBuilder, isStatic, methodVisitor, parameterTypes); this.moduleBuilder = moduleBuilder; } public JavaTypeTranslator getJavaTypeTranslator() { return getModuleBuilder().getJavaTypeTranslator(); } public ModuleBuilder getModuleBuilder() { return moduleBuilder; } public void push(IVal val, Type type) { val.push(this); if(Types.canonical(type) instanceof TVar) box(val.getType()); } public void push(Val[] vals, Type[] types) { assert(vals.length == types.length); for(int i=0;i=0;--i) if(parameters[i] != parameterVars[i]) store(parameterVars[i]); if(generatedConts.contains(block)) branch(getLabel(block)); else block.generateCode(this); } else throw new InternalCompilerError(); } public void store(BoundVar var) { Type type = var.getType(); TypeDesc typeDesc = getJavaTypeTranslator().toTypeDesc(type); if(typeDesc.equals(TypeDesc.VOID)) return; LocalVariable lv = getLocalVariable(var); storeLocal(lv); } /** * Generates the continuation code if it does not already exist. */ public void ensureExists(Cont continuation) { if(!generatedConts.contains(continuation)) ((SSABlock)continuation).generateCode(this); } @SuppressWarnings("unchecked") public T getPreparation(PreparationStep step) { return (T)preparationSteps.get(step); } public void addPreparation(PreparationStep step, T result) { preparationSteps.put(step, result); } public LocalVariable cacheValue(IVal val, Type type) { if(val instanceof BoundVar) { BoundVar boundVar = (BoundVar)val; if(!boundVar.generateOnFly) return getLocalVariable(boundVar); } push(val, type); LocalVariable temp = createLocalVariable(null, getJavaTypeTranslator().toTypeDesc(type)); storeLocal(temp); return temp; } }