use of org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod in project robovm by robovm.
the class BroMethodCompiler method getReturnType.
private Type getReturnType(String anno, SootMethod method) {
soot.Type sootType = method.getReturnType();
if (hasPointerAnnotation(method)) {
if (!sootType.equals(LongType.v())) {
throw new IllegalArgumentException(anno + " annotated method " + method + " must return long when annotated with @Pointer");
}
return I8_PTR;
}
if (hasMachineSizedFloatAnnotation(method)) {
if (!sootType.equals(DoubleType.v()) && !sootType.equals(FloatType.v())) {
throw new IllegalArgumentException(anno + " annotated method " + method + " must return float or double when annotated with @MachineSizedFloat");
}
return config.getArch().is32Bit() ? FLOAT : DOUBLE;
}
if (hasMachineSizedSIntAnnotation(method) || hasMachineSizedUIntAnnotation(method)) {
if (!sootType.equals(LongType.v())) {
throw new IllegalArgumentException(anno + " annotated method " + method + " must return long when annotated with @MachineSizedSInt or @MachineSizedUInt");
}
return config.getArch().is32Bit() ? I32 : I64;
}
if (isStruct(sootType)) {
if (!isPassByValue(method)) {
// Structs are returned by reference by default
return new PointerType(getStructType(sootType));
}
return getStructType(sootType);
} else if (isNativeObject(sootType)) {
// NativeObjects are always returned by reference.
return I8_PTR;
} else if (sootType instanceof PrimType || sootType == VoidType.v()) {
return getType(sootType);
}
MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(new MarshalSite(method));
if (marshalerMethod instanceof ValueMarshalerMethod) {
return ((ValueMarshalerMethod) marshalerMethod).getNativeType(config.getArch());
} else {
return I8_PTR;
}
}
use of org.robovm.compiler.MarshalerLookup.ValueMarshalerMethod 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.MarshalerLookup.ValueMarshalerMethod in project robovm by robovm.
the class BroMethodCompiler method getParameterType.
private Type getParameterType(String anno, SootMethod method, int i) {
soot.Type sootType = method.getParameterType(i);
if (hasPointerAnnotation(method, i)) {
if (!sootType.equals(LongType.v())) {
throw new IllegalArgumentException("Parameter " + (i + 1) + " of " + anno + " annotated method " + method + " must be of type long when annotated with @Pointer.");
}
return I8_PTR;
}
if (hasMachineSizedFloatAnnotation(method, i)) {
if (!sootType.equals(DoubleType.v()) && !sootType.equals(FloatType.v())) {
throw new IllegalArgumentException("Parameter " + (i + 1) + " of " + anno + " annotated method " + method + " must be of type float or double when annotated with @MachineSizedFloat.");
}
return config.getArch().is32Bit() ? FLOAT : DOUBLE;
}
if (hasMachineSizedSIntAnnotation(method, i) || hasMachineSizedUIntAnnotation(method, i)) {
if (!sootType.equals(LongType.v())) {
throw new IllegalArgumentException("Parameter " + (i + 1) + " of " + anno + " annotated method " + method + " must be of type long when annotated with " + "@MachineSizedSInt or @MachineSizedUInt");
}
return config.getArch().is32Bit() ? I32 : I64;
}
if (hasStructRetAnnotation(method, i)) {
if (i > 0) {
throw new IllegalArgumentException("Parameter " + (i + 1) + " of " + anno + " annotated method " + method + " cannot be annotated with @StructRet. Only the first" + " parameter may have this annotation.");
}
if (!isStruct(sootType)) {
throw new IllegalArgumentException("Parameter " + (i + 1) + " of " + anno + " annotated method " + method + " must be a sub class of Struct when annotated with @StructRet.");
}
// @StructRet implies pass by reference
return new PointerType(getStructType(sootType));
}
if (isStruct(sootType)) {
StructureType structType = getStructType(sootType);
if (hasByValAnnotation(method, i)) {
return getStructType(sootType);
}
return new PointerType(structType);
} else if (isNativeObject(sootType)) {
// NativeObjects are always passed by reference.
return I8_PTR;
} else if (sootType instanceof PrimType) {
return getType(sootType);
}
MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(new MarshalSite(method, i));
if (marshalerMethod instanceof ValueMarshalerMethod) {
return ((ValueMarshalerMethod) marshalerMethod).getNativeType(config.getArch());
} else {
return I8_PTR;
}
}
Aggregations