use of org.robovm.compiler.llvm.Variable in project robovm by robovm.
the class StructMemberMethodCompiler method structMember.
private Function structMember(ModuleBuilder moduleBuilder, SootMethod method) {
Function function = createMethodFunction(method);
moduleBuilder.addFunction(function);
// Get the value of the handle field in the Struct base class and cast it to a <structType>*
Variable handleI64 = function.newVariable(I64);
function.add(new Load(handleI64, getFieldPtr(function, function.getParameterRef(1), offsetof(new StructureType(DATA_OBJECT, new StructureType(I64)), 1, 0), I64)));
Variable handlePtr = function.newVariable(new PointerType(structType));
function.add(new Inttoptr(handlePtr, handleI64.ref(), handlePtr.getType()));
// Add 1 since the first type in structType is the superclass type or {}.
int offset = getStructMemberOffset(method) + 1;
Type memberType = getStructMemberType(method);
Variable memberPtr = function.newVariable(new PointerType(memberType));
if (memberType != structType.getTypeAt(offset)) {
// Several @StructMembers of different types have this offset (union)
Variable tmp = function.newVariable(new PointerType(structType.getTypeAt(offset)));
function.add(new Getelementptr(tmp, handlePtr.ref(), 0, offset));
function.add(new Bitcast(memberPtr, tmp.ref(), memberPtr.getType()));
} else {
function.add(new Getelementptr(memberPtr, handlePtr.ref(), 0, offset));
}
VariableRef env = function.getParameterRef(0);
if (method.getParameterCount() == 0) {
// Getter
Value result = loadValueForGetter(method, function, memberType, memberPtr.ref(), function.getParameterRef(0), true, MarshalerFlags.CALL_TYPE_STRUCT_MEMBER);
function.add(new Ret(result));
} else {
// Setter
// 'env' is parameter 0, 'this' is at 1, the value we're interested in is at index 2
Value value = function.getParameterRef(2);
storeValueForSetter(method, function, memberType, memberPtr.ref(), env, value, MarshalerFlags.CALL_TYPE_STRUCT_MEMBER);
if (method.getReturnType().equals(VoidType.v())) {
function.add(new Ret());
} else {
function.add(new Ret(function.getParameterRef(1)));
}
}
return function;
}
use of org.robovm.compiler.llvm.Variable in project robovm by robovm.
the class MethodCompiler method if_.
private void if_(IfStmt stmt) {
ConditionExpr condition = (ConditionExpr) stmt.getCondition();
Value op1 = immediate(stmt, (Immediate) condition.getOp1());
Value op2 = immediate(stmt, (Immediate) condition.getOp2());
Icmp.Condition c = null;
if (condition instanceof EqExpr) {
c = Icmp.Condition.eq;
} else if (condition instanceof NeExpr) {
c = Icmp.Condition.ne;
} else if (condition instanceof GtExpr) {
c = Icmp.Condition.sgt;
} else if (condition instanceof LtExpr) {
c = Icmp.Condition.slt;
} else if (condition instanceof GeExpr) {
c = Icmp.Condition.sge;
} else if (condition instanceof LeExpr) {
c = Icmp.Condition.sle;
}
Variable result = function.newVariable(Type.I1);
function.add(new Icmp(result, c, op1, op2)).attach(stmt);
Unit nextUnit = sootMethod.getActiveBody().getUnits().getSuccOf(stmt);
function.add(new Br(new VariableRef(result), function.newBasicBlockRef(new Label(stmt.getTarget())), function.newBasicBlockRef(new Label(nextUnit)))).attach(stmt);
}
use of org.robovm.compiler.llvm.Variable in project robovm by robovm.
the class BroMethodCompiler method marshalLongToPointer.
protected Value marshalLongToPointer(Function fn, Value handle) {
Variable result = fn.newVariable(I8_PTR);
fn.add(new Inttoptr(result, handle, I8_PTR));
return result.ref();
}
use of org.robovm.compiler.llvm.Variable 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.Variable in project robovm by robovm.
the class BroMethodCompiler method marshalMachineSizedFloatToFloat.
protected Value marshalMachineSizedFloatToFloat(Function fn, Value value) {
if (!config.getArch().is32Bit()) {
Variable result = fn.newVariable(FLOAT);
fn.add(new Fptrunc(result, value, FLOAT));
return result.ref();
} else {
return value;
}
}
Aggregations