use of org.robovm.compiler.llvm.ArrayType in project robovm by robovm.
the class BridgeMethodCompilerTest method testCreateBridgeCWrapperComplexNestedStructByValReturnAndParameter.
@Test
public void testCreateBridgeCWrapperComplexNestedStructByValReturnAndParameter() {
StructureType structType = new StructureType(new StructureType(I8, I16), new StructureType(I32, I64), new StructureType(FLOAT, DOUBLE), new ArrayType(100, I32), new ArrayType(10, new StructureType(FLOAT, FLOAT)), new ArrayType(5, new ArrayType(10, I32)), new StructureType(I8_PTR, new PointerType(new StructureType(I32))));
FunctionType functionType = new FunctionType(structType, structType);
assertEquals("void f(void* target, void* ret, void* p0) {\n" + " struct f_0001_0006 {void* m0;void* m1;};\n" + " struct f_0001_0004 {float m0;float m1;};\n" + " struct f_0001_0002 {float m0;double m1;};\n" + " struct f_0001_0001 {int m0;long long m1;};\n" + " struct f_0001_0000 {char m0;short m1;};\n" + " struct f_0001 {struct f_0001_0000 m0;struct f_0001_0001 m1;struct f_0001_0002 m2;int m3[100];struct f_0001_0004 m4[10];int m5[5][10];struct f_0001_0006 m6;};\n" + " struct f_0000_0006 {void* m0;void* m1;};\n" + " struct f_0000_0004 {float m0;float m1;};\n" + " struct f_0000_0002 {float m0;double m1;};\n" + " struct f_0000_0001 {int m0;long long m1;};\n" + " struct f_0000_0000 {char m0;short m1;};\n" + " struct f_0000 {struct f_0000_0000 m0;struct f_0000_0001 m1;struct f_0000_0002 m2;int m3[100];struct f_0000_0004 m4[10];int m5[5][10];struct f_0000_0006 m6;};\n" + " *((struct f_0000*)ret) = ((struct f_0000 (*)(struct f_0001)) target)(*((struct f_0001*)p0));\n" + "}\n", BridgeMethodCompiler.createBridgeCWrapper(functionType.getReturnType(), functionType.getParameterTypes(), functionType.getParameterTypes(), "f"));
}
use of org.robovm.compiler.llvm.ArrayType in project robovm by robovm.
the class BroMethodCompiler method mergeStructMemberTypes.
static Type mergeStructMemberTypes(DataLayout dataLayout, Type t1, Type t2) {
int align1 = dataLayout.getAlignment(t1);
int align2 = dataLayout.getAlignment(t2);
int size1 = dataLayout.getStoreSize(t1);
int size2 = dataLayout.getStoreSize(t2);
Type result = align1 < align2 ? t2 : t1;
int size = align1 < align2 ? size2 : size1;
int pad = Math.max(size1, size2) - size;
if (pad > 0) {
return new StructureType(result, new ArrayType(pad, I8));
} else {
return result;
}
}
use of org.robovm.compiler.llvm.ArrayType in project robovm by robovm.
the class BroMethodCompiler method loadValueForGetter.
protected Value loadValueForGetter(SootMethod method, Function fn, Type memberType, Value memberPtr, Value env, boolean dereference, long flags) {
soot.Type type = method.getReturnType();
Value result = null;
if (memberType instanceof StructureType) {
// The member is a child struct contained in the current struct
result = memberPtr;
} else if (memberType instanceof ArrayType) {
// The member is an array contained in the current struct
result = memberPtr;
} else if (dereference) {
Variable tmp = fn.newVariable(memberType);
fn.add(new Load(tmp, memberPtr));
result = tmp.ref();
} else {
// Do not dereference the pointer but use it as is. This is needed for
// global values such as _dispatch_main_q which is a struct and not a
// pointer which we should load. We want the address of the struct.
Variable tmp = fn.newVariable(memberType);
fn.add(new Bitcast(tmp, memberPtr, tmp.getType()));
result = tmp.ref();
}
if (needsMarshaler(type)) {
MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(new MarshalSite(method));
String targetClassName = getInternalName(type);
if (memberType instanceof PrimitiveType) {
// Value type wrapping a primitive value (e.g. Enum, Integer and Bits)
result = marshalNativeToValueObject(fn, marshalerMethod, env, targetClassName, result, flags);
} else {
if (memberType instanceof ArrayType) {
// Array
result = marshalNativeToArray(fn, marshalerMethod, env, targetClassName, result, flags, getArrayDimensions(method));
} else {
result = marshalNativeToObject(fn, marshalerMethod, null, env, targetClassName, result, flags);
}
}
} else {
result = marshalNativeToPrimitive(fn, method, result);
}
return result;
}
use of org.robovm.compiler.llvm.ArrayType in project robovm by robovm.
the class BroMethodCompiler method getStructMemberType.
public Type getStructMemberType(SootMethod method) {
String methodType = hasStructMemberAnnotation(method) ? "@StructMember" : "@GlobalValue";
SootMethod getter = method.getParameterCount() == 0 ? method : null;
SootMethod setter = getter == null ? method : null;
soot.Type type = getter != null ? getter.getReturnType() : setter.getParameterType(0);
Type memberType = null;
if (getter != null && hasPointerAnnotation(getter) || setter != null && hasPointerAnnotation(setter, 0)) {
memberType = I8_PTR;
} else if (getter != null && hasMachineSizedFloatAnnotation(getter) || setter != null && hasMachineSizedFloatAnnotation(setter, 0)) {
memberType = config.getArch().is32Bit() ? FLOAT : DOUBLE;
} else if (getter != null && (hasMachineSizedSIntAnnotation(getter) || hasMachineSizedUIntAnnotation(getter)) || setter != null && (hasMachineSizedSIntAnnotation(setter, 0) || hasMachineSizedUIntAnnotation(setter, 0))) {
memberType = config.getArch().is32Bit() ? I32 : I64;
} else if (type instanceof PrimType) {
memberType = getType(type);
} else if (getter != null && hasArrayAnnotation(getter) || setter != null && hasArrayAnnotation(setter, 0)) {
int[] dimensions = getter != null ? getArrayDimensions(getter) : getArrayDimensions(setter, 0);
if (dimensions == null || dimensions.length == 0) {
throw new IllegalArgumentException("No dimensions specified for @Array annotation on " + methodType + " " + (getter != null ? "getter" : "setter") + " " + method);
}
if (type instanceof soot.ArrayType && ((soot.ArrayType) type).numDimensions != dimensions.length) {
throw new IllegalArgumentException("Mismatch in number of dimennsions for @Array annotation " + "and type on " + methodType + " " + (getter != null ? "getter" : "setter") + " " + method);
}
Type baseType = null;
if (type instanceof soot.ArrayType) {
soot.ArrayType arrayType = (soot.ArrayType) type;
if (isStruct(arrayType.baseType)) {
// ByVal is implied for arrays of structs
try {
baseType = getStructType(arrayType.baseType);
} catch (StackOverflowError e) {
throw new IllegalArgumentException("Struct type " + type + " refers to itself");
}
} else {
baseType = getType(arrayType.baseType);
}
} else if (isStruct(type)) {
// ByVal is implied
try {
baseType = getStructType(type);
} catch (StackOverflowError e) {
throw new IllegalArgumentException("Struct type " + type + " refers to itself");
}
} else if (type instanceof RefType) {
MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(getter != null ? new MarshalSite(getter) : new MarshalSite(setter, 0));
baseType = getType(((ArrayMarshalerMethod) marshalerMethod).getBaseType());
}
if (baseType == null) {
throw new IllegalArgumentException("Arrays of " + type + " is not supported");
}
long total = dimensions[0];
for (int i = 1; i < dimensions.length; i++) {
total *= dimensions[i];
}
memberType = new ArrayType(total, baseType);
} else if (isStruct(type)) {
boolean byVal = getter != null ? isPassByValue(getter) : isPassByValue(setter, 0);
if (!byVal) {
// NOTE: We use i8* instead of <StructType>* to support pointers to recursive structs
memberType = I8_PTR;
} else {
try {
memberType = getStructType(type);
} catch (StackOverflowError e) {
throw new IllegalArgumentException("Struct type " + type + " refers to itself");
}
}
} else if (isNativeObject(type)) {
memberType = I8_PTR;
} else {
MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(getter != null ? new MarshalSite(getter) : new MarshalSite(setter, 0));
if (marshalerMethod instanceof ValueMarshalerMethod) {
memberType = ((ValueMarshalerMethod) marshalerMethod).getNativeType(config.getArch());
} else {
memberType = I8_PTR;
}
}
return memberType;
}
use of org.robovm.compiler.llvm.ArrayType in project robovm by robovm.
the class BroMethodCompiler method storeValueForSetter.
protected void storeValueForSetter(SootMethod method, Function function, Type memberType, Value memberPtr, Value env, Value value, long flags) {
soot.Type type = method.getParameterType(0);
if (needsMarshaler(type)) {
MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(new MarshalSite(method, 0));
if (memberType instanceof PrimitiveType) {
value = marshalValueObjectToNative(function, marshalerMethod, memberType, env, value, flags);
} else {
if (memberType instanceof StructureType || memberType instanceof ArrayType) {
// The parameter must not be null. We assume that Structs
// never have a NULL handle so we just check that the Java
// Object isn't null.
call(function, CHECK_NULL, env, value);
}
if (memberType instanceof ArrayType) {
// Array
marshalArrayToNative(function, marshalerMethod, env, value, memberPtr, flags, getArrayDimensions(method, 0));
value = null;
} else {
value = marshalObjectToNative(function, marshalerMethod, null, memberType, env, value, flags);
}
}
} else {
value = marshalPrimitiveToNative(function, method, 0, value);
}
if (value != null) {
function.add(new Store(value, memberPtr));
}
}
Aggregations