use of org.robovm.compiler.llvm.Value in project robovm by robovm.
the class MethodCompiler method invokeExpr.
private Value invokeExpr(Stmt stmt, InvokeExpr expr) {
SootMethodRef methodRef = expr.getMethodRef();
ArrayList<Value> args = new ArrayList<Value>();
args.add(env);
if (!(expr instanceof StaticInvokeExpr)) {
Value base = immediate(stmt, (Immediate) ((InstanceInvokeExpr) expr).getBase());
checkNull(stmt, base);
args.add(base);
}
int i = 0;
for (soot.Value sootArg : (List<soot.Value>) expr.getArgs()) {
Value arg = immediate(stmt, (Immediate) sootArg);
args.add(narrowFromI32Value(stmt, getType(methodRef.parameterType(i)), arg));
i++;
}
Value result = null;
FunctionRef functionRef = config.isDebug() ? null : Intrinsics.getIntrinsic(sootMethod, stmt, expr);
if (functionRef == null) {
Trampoline trampoline = null;
String targetClassName = getInternalName(methodRef.declaringClass());
String methodName = methodRef.name();
String methodDesc = getDescriptor(methodRef);
if (expr instanceof SpecialInvokeExpr) {
soot.Type runtimeType = ((SpecialInvokeExpr) expr).getBase().getType();
String runtimeClassName = runtimeType == NullType.v() ? targetClassName : getInternalName(runtimeType);
trampoline = new Invokespecial(this.className, targetClassName, methodName, methodDesc, runtimeClassName);
} else if (expr instanceof StaticInvokeExpr) {
trampoline = new Invokestatic(this.className, targetClassName, methodName, methodDesc);
} else if (expr instanceof VirtualInvokeExpr) {
soot.Type runtimeType = ((VirtualInvokeExpr) expr).getBase().getType();
String runtimeClassName = runtimeType == NullType.v() ? targetClassName : getInternalName(runtimeType);
trampoline = new Invokevirtual(this.className, targetClassName, methodName, methodDesc, runtimeClassName);
} else if (expr instanceof InterfaceInvokeExpr) {
trampoline = new Invokeinterface(this.className, targetClassName, methodName, methodDesc);
}
trampolines.add(trampoline);
if (canCallDirectly(expr)) {
SootMethod method = this.sootMethod.getDeclaringClass().getMethod(methodRef.name(), methodRef.parameterTypes(), methodRef.returnType());
if (method.isSynchronized()) {
functionRef = FunctionBuilder.synchronizedWrapper(method).ref();
} else {
functionRef = createMethodFunction(method).ref();
}
} else {
functionRef = trampoline.getFunctionRef();
}
}
result = call(stmt, functionRef, args.toArray(new Value[0]));
if (result != null) {
return widenToI32Value(stmt, result, methodRef.returnType().equals(CharType.v()));
} else {
return null;
}
}
use of org.robovm.compiler.llvm.Value in project robovm by robovm.
the class MethodCompiler method tableSwitch.
private void tableSwitch(TableSwitchStmt stmt) {
Map<IntegerConstant, BasicBlockRef> targets = new HashMap<IntegerConstant, BasicBlockRef>();
for (int i = stmt.getLowIndex(); i <= stmt.getHighIndex(); i++) {
Unit target = stmt.getTarget(i - stmt.getLowIndex());
targets.put(new IntegerConstant(i), function.newBasicBlockRef(new Label(target)));
}
BasicBlockRef def = function.newBasicBlockRef(new Label(stmt.getDefaultTarget()));
Value key = immediate(stmt, (Immediate) stmt.getKey());
function.add(new Switch(key, def, targets)).attach(stmt);
}
use of org.robovm.compiler.llvm.Value in project robovm by robovm.
the class MethodCompiler method exitMonitor.
private void exitMonitor(ExitMonitorStmt stmt) {
Value op = immediate(stmt, (Immediate) stmt.getOp());
checkNull(stmt, op);
call(stmt, MONITOREXIT, env, op);
}
use of org.robovm.compiler.llvm.Value in project robovm by robovm.
the class Linker method createLookup.
private Function createLookup(ModuleBuilder mb, ClazzInfo ci, MethodInfo mi) {
Function function = FunctionBuilder.lookup(ci, mi, false);
String targetFnName = mi.isSynchronized() ? Symbols.synchronizedWrapperSymbol(ci.getInternalName(), mi.getName(), mi.getDesc()) : Symbols.methodSymbol(ci.getInternalName(), mi.getName(), mi.getDesc());
FunctionRef fn = new FunctionRef(targetFnName, function.getType());
if (!mb.hasSymbol(fn.getName())) {
mb.addFunctionDeclaration(new FunctionDeclaration(fn));
}
Value result = tailcall(function, fn, function.getParameterRefs());
function.add(new Ret(result));
return function;
}
use of org.robovm.compiler.llvm.Value in project robovm by robovm.
the class Linker method createInstanceof.
private Function createInstanceof(ModuleBuilder mb, Clazz clazz, TypeInfo typeInfo) {
Function fn = FunctionBuilder.instanceOf(clazz);
Value info = getInfoStruct(mb, fn, clazz);
if (typeInfo.error) {
// This will trigger an exception
call(fn, BC_LDC_CLASS, fn.getParameterRef(0), info);
fn.add(new Ret(new IntegerConstant(0)));
} else if (!clazz.getClazzInfo().isInterface()) {
Value result = call(fn, INSTANCEOF_CLASS, fn.getParameterRef(0), info, fn.getParameterRef(1), new IntegerConstant((typeInfo.classTypes.length - 1) * 4 + 5 * 4), new IntegerConstant(typeInfo.id));
fn.add(new Ret(result));
} else {
Value result = call(fn, INSTANCEOF_INTERFACE, fn.getParameterRef(0), info, fn.getParameterRef(1), new IntegerConstant(typeInfo.id));
fn.add(new Ret(result));
}
return fn;
}
Aggregations