Skip to content

Commit

Permalink
Refactored @bridge and @callback method compilation to utilize clang …
Browse files Browse the repository at this point in the history
…to handle

the passing/returning of structs by value. (#754)
  • Loading branch information
ntherning committed Feb 11, 2015
1 parent 328ad10 commit c430940
Show file tree
Hide file tree
Showing 13 changed files with 848 additions and 295 deletions.
224 changes: 137 additions & 87 deletions compiler/src/main/java/org/robovm/compiler/BridgeMethodCompiler.java

Large diffs are not rendered by default.

78 changes: 72 additions & 6 deletions compiler/src/main/java/org/robovm/compiler/BroMethodCompiler.java
Expand Up @@ -24,13 +24,16 @@


import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;


import org.robovm.compiler.Annotations.Visibility; import org.robovm.compiler.Annotations.Visibility;
import org.robovm.compiler.MarshalerLookup.ArrayMarshalerMethod; import org.robovm.compiler.MarshalerLookup.ArrayMarshalerMethod;
import org.robovm.compiler.MarshalerLookup.MarshalSite; import org.robovm.compiler.MarshalerLookup.MarshalSite;
import org.robovm.compiler.MarshalerLookup.MarshalerMethod; import org.robovm.compiler.MarshalerLookup.MarshalerMethod;
import org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod; import org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod;
import org.robovm.compiler.clazz.Clazz;
import org.robovm.compiler.config.Config; import org.robovm.compiler.config.Config;
import org.robovm.compiler.llvm.AggregateType;
import org.robovm.compiler.llvm.Alloca; import org.robovm.compiler.llvm.Alloca;
import org.robovm.compiler.llvm.ArrayType; import org.robovm.compiler.llvm.ArrayType;
import org.robovm.compiler.llvm.Bitcast; import org.robovm.compiler.llvm.Bitcast;
Expand All @@ -43,6 +46,7 @@
import org.robovm.compiler.llvm.FunctionType; import org.robovm.compiler.llvm.FunctionType;
import org.robovm.compiler.llvm.GlobalRef; import org.robovm.compiler.llvm.GlobalRef;
import org.robovm.compiler.llvm.IntegerConstant; import org.robovm.compiler.llvm.IntegerConstant;
import org.robovm.compiler.llvm.IntegerType;
import org.robovm.compiler.llvm.Inttoptr; import org.robovm.compiler.llvm.Inttoptr;
import org.robovm.compiler.llvm.Load; import org.robovm.compiler.llvm.Load;
import org.robovm.compiler.llvm.PointerType; import org.robovm.compiler.llvm.PointerType;
Expand Down Expand Up @@ -74,11 +78,22 @@
* *
*/ */
public abstract class BroMethodCompiler extends AbstractMethodCompiler { public abstract class BroMethodCompiler extends AbstractMethodCompiler {
private final List<String> cWrapperFunctions = new ArrayList<>();


public BroMethodCompiler(Config config) { public BroMethodCompiler(Config config) {
super(config); super(config);
} }


@Override
public void reset(Clazz clazz) {
cWrapperFunctions.clear();
super.reset(clazz);
}

public List<String> getCWrapperFunctions() {
return cWrapperFunctions;
}

protected Value ldcClass(Function fn, String name, Value env) { protected Value ldcClass(Function fn, String name, Value env) {
if (isArray(name) && isPrimitiveBaseType(name)) { if (isArray(name) && isPrimitiveBaseType(name)) {
String primitiveDesc = name.substring(name.length() - 1); String primitiveDesc = name.substring(name.length() - 1);
Expand Down Expand Up @@ -415,8 +430,6 @@ private Type getReturnType(String anno, SootMethod method) {
// Structs are returned by reference by default // Structs are returned by reference by default
return new PointerType(getStructType(sootType)); return new PointerType(getStructType(sootType));
} }
// Only small Structs can be returned by value. How small is defined by the target ABI.
// Larger Structs should be passed as parameters with the @StructRet annotation.
return getStructType(sootType); return getStructType(sootType);
} else if (isNativeObject(sootType)) { } else if (isNativeObject(sootType)) {
// NativeObjects are always returned by reference. // NativeObjects are always returned by reference.
Expand Down Expand Up @@ -478,10 +491,7 @@ private Type getParameterType(String anno, SootMethod method, int i) {
if (isStruct(sootType)) { if (isStruct(sootType)) {
StructureType structType = getStructType(sootType); StructureType structType = getStructType(sootType);
if (hasByValAnnotation(method, i)) { if (hasByValAnnotation(method, i)) {
int size = config.getDataLayout().getAllocSize(structType); return getStructType(sootType);
if (!config.getOs().useByvalForAggregateOfSize(config.getArch(), size)) {
return getStructType(sootType);
}
} }
return new PointerType(structType); return new PointerType(structType);
} else if (isNativeObject(sootType)) { } else if (isNativeObject(sootType)) {
Expand Down Expand Up @@ -656,6 +666,62 @@ static Type mergeStructMemberTypes(DataLayout dataLayout, Type t1, Type t2) {
} }
} }


protected static String getHiType(Type type) {
if (type == Type.VOID) {
return "void";
}
if (type instanceof PointerType || type instanceof AggregateType) {
return "void*";
} else if (type instanceof IntegerType) {
switch (((IntegerType) type).getBits()) {
case 8:
return "char";
case 16:
return "short";
case 32:
return "int";
case 64:
return "long long";
}
} else if (type == Type.FLOAT) {
return "float";
} else if (type == Type.DOUBLE) {
return "double";
}
throw new IllegalArgumentException("Cannot convert type " + type + " to C type");
}

protected static String getLoType(final Type type, String base, int index, Map<String, String> structs) {
if (type instanceof StructureType) {
StringBuilder sb = new StringBuilder();
StructureType st = (StructureType) type;
sb.append("{");
String name = String.format("%s_%04d", base, index);
for (int i = 0; i < st.getTypeCount(); i++) {
Type t = st.getTypeAt(i);
if (i == 0 && t instanceof StructureType) {
if (((StructureType) t).getTypeCount() == 0) {
// Skip empty structs as first member
continue;
}
}
// Only support arrays embedded in structs
StringBuilder dims = new StringBuilder();
while (t instanceof ArrayType) {
ArrayType at = (ArrayType) t;
dims.append('[').append(at.getSize()).append(']');
t = ((ArrayType) t).getElementType();
}
sb.append(getLoType(t, name, i, structs)).append(" m" + i).append(dims).append(";");
}
sb.append("}");
structs.put(name, sb.toString());
return "struct " + name;
} else {
return getHiType(type);
}
}

public Type getStructMemberType(SootMethod method) { public Type getStructMemberType(SootMethod method) {
String methodType = hasStructMemberAnnotation(method) ? "@StructMember" : "@GlobalValue"; String methodType = hasStructMemberAnnotation(method) ? "@StructMember" : "@GlobalValue";
SootMethod getter = method.getParameterCount() == 0 ? method : null; SootMethod getter = method.getParameterCount() == 0 ? method : null;
Expand Down

0 comments on commit c430940

Please sign in to comment.