Package org.renjin.gcc.translate

Source Code of org.renjin.gcc.translate.FunctionContext

package org.renjin.gcc.translate;

import java.util.Map;

import org.renjin.gcc.gimple.CallingConvention;
import org.renjin.gcc.gimple.ins.GimpleCall;
import org.renjin.gcc.gimple.GimpleFunction;
import org.renjin.gcc.gimple.GimpleParameter;
import org.renjin.gcc.gimple.GimpleVarDecl;
import org.renjin.gcc.gimple.expr.*;
import org.renjin.gcc.jimple.JimpleExpr;
import org.renjin.gcc.jimple.JimpleMethodBuilder;
import org.renjin.gcc.jimple.JimpleType;
import org.renjin.gcc.jimple.RealJimpleType;
import org.renjin.gcc.translate.call.MethodRef;
import org.renjin.gcc.translate.expr.*;
import org.renjin.gcc.translate.type.ImType;
import org.renjin.gcc.translate.var.Variable;

import com.google.common.collect.Maps;

public class FunctionContext {

  private TranslationContext translationContext;
  private GimpleFunction gimpleFunction;
  private JimpleMethodBuilder builder;
  private Map<Integer, Variable> symbolTable = Maps.newHashMap();

  private int nextLabelId = 1000;

  public FunctionContext(TranslationContext translationContext, GimpleFunction gimpleFunction,
      JimpleMethodBuilder builder) {
    this.gimpleFunction = gimpleFunction;
    this.translationContext = translationContext;
    this.builder = builder;

    VarUsageInspector varUsage = new VarUsageInspector(gimpleFunction);

    for (GimpleVarDecl decl : gimpleFunction.getVariableDeclarations()) {
      Variable localVariable = translationContext.resolveType(decl.getType())
          .createLocalVariable(this, decl.getName(),
              varUsage.getUsage(decl.getId()));

      symbolTable.put(decl.getId(), localVariable);
    }

    for (GimpleParameter param : gimpleFunction.getParameters()) {
      ImType type = translationContext.resolveType(param.getType());
      builder.addParameter(type.paramType(), "p_" + param.getName());
      ImExpr paramExpr = JvmExprs.toExpr(this, new JimpleExpr("p_" + param.getName()), type.paramType(), true);

      Variable variable = type.createLocalVariable(this, param.getName(), varUsage.getUsage(param.getId()));
      variable.writeAssignment(this, paramExpr);


      symbolTable.put(param.getId(), variable);
    }
  }

  public MethodRef resolveMethod(GimpleCall call) {
    return translationContext.resolveMethod(call, getCallingConvention());
  }

  public CallingConvention getCallingConvention() {
    return gimpleFunction.getCallingConvention();
  }

  public String declareTemp(JimpleType type) {
    return getBuilder().addTempVarDecl(type);
  }

  public String declareTemp(Class clazz) {
    return declareTemp(new RealJimpleType(clazz));
  }

  public JimpleExpr declareTemp(JimpleType type, JimpleExpr value) {
    String tempVar = declareTemp(type);
    getBuilder().addAssignment(tempVar, value);
    return new JimpleExpr(tempVar);
  }

  public JimpleMethodBuilder getBuilder() {
    return builder;
  }

  public TranslationContext getTranslationContext() {
    return translationContext;
  }

  public String newLabel() {
    return "trlabel" + (nextLabelId++) + "__";
  }

  public ImExpr lookupVar(GimpleExpr gimpleExpr) {
    if (gimpleExpr instanceof SymbolRef) {
      SymbolRef symbol = (SymbolRef) gimpleExpr;
      ImExpr variable = symbolTable.get(symbol.getId());

      if(variable != null) {
        return variable;
      }

      if(symbol.getName() != null) {
        variable = translationContext.findGlobal(symbol.getName());
      }

      if (variable == null) {
        throw new IllegalArgumentException("No such variable '" + gimpleExpr + "' (id=" + symbol.getId() + ")");
      }
      return variable;
    } else {
      throw new UnsupportedOperationException("Expected GimpleVar, got: " + gimpleExpr + " ["
          + gimpleExpr.getClass().getSimpleName() + "]");
    }
  }

  public ImExpr resolveExpr(GimpleExpr gimpleExpr) {
    if(gimpleExpr instanceof GimpleMemRef) {
      return resolveExpr(((GimpleMemRef) gimpleExpr).getPointer()).memref();
    } else if(gimpleExpr instanceof SymbolRef) {
      return lookupVar(gimpleExpr);

    } else if(gimpleExpr instanceof GimpleStringConstant) {
      return new ImStringConstant((GimpleStringConstant) gimpleExpr);

    } else if(gimpleExpr instanceof GimpleConstant) {
      return new ImPrimitiveConstant(this, (GimpleConstant) gimpleExpr);

    } else if(gimpleExpr instanceof GimpleAddressOf) {
      return resolveExpr(((GimpleAddressOf) gimpleExpr).getValue()).addressOf();

    } else if(gimpleExpr instanceof GimpleFunctionRef) {
      return new ImFunctionExpr(translationContext.resolveMethod(((GimpleFunctionRef) gimpleExpr).getName()));

    } else if(gimpleExpr instanceof GimpleArrayRef) {
      GimpleArrayRef arrayRef = (GimpleArrayRef) gimpleExpr;
      return resolveExpr(arrayRef.getArray()).elementAt(resolveExpr(arrayRef.getIndex()));

    } else if(gimpleExpr instanceof GimpleComponentRef) {
      GimpleComponentRef componentRef = (GimpleComponentRef) gimpleExpr;
      return resolveExpr(componentRef.getValue()).member(componentRef.getMember());

    } else if(gimpleExpr instanceof GimpleConstantRef) {
      return resolveExpr(((GimpleConstantRef) gimpleExpr).getValue());
    }
    throw new UnsupportedOperationException(gimpleExpr.toString());
  }

}
TOP

Related Classes of org.renjin.gcc.translate.FunctionContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.