Package org.renjin.gcc.translate.call

Source Code of org.renjin.gcc.translate.call.MallocCallTranslator

package org.renjin.gcc.translate.call;


import org.renjin.gcc.gimple.ins.GimpleCall;
import org.renjin.gcc.jimple.JimpleExpr;
import org.renjin.gcc.jimple.JimpleType;
import org.renjin.gcc.translate.FunctionContext;
import org.renjin.gcc.translate.expr.ImExpr;
import org.renjin.gcc.translate.expr.ImLValue;
import org.renjin.gcc.translate.expr.NewArrayExpr;
import org.renjin.gcc.translate.type.ImPrimitiveArrayPtrType;
import org.renjin.gcc.translate.type.ImPrimitivePtrType;
import org.renjin.gcc.translate.type.ImPrimitiveType;

/**
* Translates a call to malloc
*/
public class MallocCallTranslator extends NamedCallTranslator {

  public MallocCallTranslator(String functionName) {
    super(functionName);
  }

  @Override
  public void writeCall(FunctionContext context, GimpleCall call) {
    if(call.getLhs() == null) {
      // no effect
      return;
    }

    ImExpr sizeArg = computeSize(context, call);
    ImExpr lhs = context.resolveExpr(call.getLhs());

    if(lhs.type() instanceof ImPrimitivePtrType) {
      writeNewPrimitiveArray(context, lhs, sizeArg);

    } else if(lhs.type() instanceof ImPrimitiveArrayPtrType) {
      writeNewPrimitiveArrayPtr(context, lhs, sizeArg);

    } else {
      throw new UnsupportedOperationException("type: " + lhs.type());
    }
  }

  private void writeNewPrimitiveArray(FunctionContext context, ImExpr lhs, ImExpr sizeArg) {

    ImPrimitivePtrType type = (ImPrimitivePtrType) lhs.type();

    JimpleExpr elementCount = getNumElementsExpr(context, sizeArg, type.getBaseType());

    // assign to our lhs
    ((ImLValue)lhs).writeAssignment(context, new NewArrayExpr(type, elementCount));
  }


  private void writeNewPrimitiveArrayPtr(FunctionContext context, ImExpr lhs, ImExpr sizeArg) {

    ImPrimitiveArrayPtrType type = (ImPrimitiveArrayPtrType) lhs.type();

    JimpleExpr elementCount = getNumElementsExpr(context, sizeArg, type.baseType().componentType());

    // assign to our lhs
    ((ImLValue)lhs).writeAssignment(context, new NewArrayExpr(type.baseType().componentType().pointerType(),
        elementCount));
  }


  private JimpleExpr getNumElementsExpr(FunctionContext context, ImExpr sizeArg, ImPrimitiveType type) {
    // malloc is given a size in bytes, we need to divide by the underlying storage
    // size to get the number of elements to allocate

    // get the argument as a primitive expression that evaluates to number of bytes
    JimpleExpr byteSizeExpr = sizeArg.translateToPrimitive(context, ImPrimitiveType.INT);

    // calculate number of elements
    JimpleExpr elementCount = new JimpleExpr(context.declareTemp(JimpleType.INT));
    context.getBuilder().addAssignment(elementCount, JimpleExpr.binaryInfix("/", byteSizeExpr,
      JimpleExpr.integerConstant(type.getStorageSizeInBytes())));
    return elementCount;
  }

  protected ImExpr computeSize(FunctionContext context, GimpleCall call) {
    if(call.getArguments().size() != 1) {
      throw new UnsupportedOperationException("expected call to malloc with 1 arg");
    }
    return context.resolveExpr(call.getArguments().get(0));
  }

}
TOP

Related Classes of org.renjin.gcc.translate.call.MallocCallTranslator

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.