use of org.robovm.compiler.llvm.Ret in project robovm by robovm.
the class TrampolineCompiler method createLdcArray.
private FunctionRef createLdcArray(String targetClass) {
if (isPrimitiveComponentType(targetClass)) {
throw new IllegalArgumentException();
}
String fnName = Symbols.arrayldcSymbol(targetClass);
FunctionRef fnRef = new FunctionRef(fnName, new FunctionType(OBJECT_PTR, ENV_PTR));
if (!mb.hasSymbol(fnName)) {
Function fn = new FunctionBuilder(fnRef).name(fnName).linkage(weak).build();
Global g = new Global(Symbols.arrayPtrSymbol(targetClass), weak, new NullConstant(OBJECT_PTR));
if (!mb.hasSymbol(g.getName())) {
mb.addGlobal(g);
}
FunctionRef ldcArrayClassFn = BC_LDC_ARRAY_BOOT_CLASS;
if (!isPrimitiveBaseType(targetClass)) {
Clazz baseType = config.getClazzes().load(getBaseType(targetClass));
if (!baseType.isInBootClasspath()) {
ldcArrayClassFn = BC_LDC_ARRAY_CLASS;
}
}
Value arrayClass = call(fn, ldcArrayClassFn, fn.getParameterRef(0), g.ref(), mb.getString(targetClass));
fn.add(new Ret(arrayClass));
mb.addFunction(fn);
}
return fnRef;
}
use of org.robovm.compiler.llvm.Ret in project robovm by robovm.
the class TrampolineCompiler method createCheckcastArray.
private FunctionRef createCheckcastArray(Checkcast t) {
String fnName = Symbols.arraycheckcastSymbol(t.getTarget());
if (!mb.hasSymbol(fnName)) {
Function fn = new FunctionBuilder(t).name(fnName).linkage(weak).build();
Value arrayClass = callLdcArray(fn, t.getTarget());
Value result = call(fn, BC_CHECKCAST_ARRAY, fn.getParameterRef(0), arrayClass, fn.getParameterRef(1));
fn.add(new Ret(result));
mb.addFunction(fn);
}
return new FunctionRef(fnName, t.getFunctionType());
}
use of org.robovm.compiler.llvm.Ret in project robovm by robovm.
the class ClassCompiler method createLookupFunction.
private void createLookupFunction(SootMethod m) {
Function function = FunctionBuilder.lookup(m, true);
mb.addFunction(function);
Variable reserved0 = function.newVariable(I8_PTR_PTR);
function.add(new Getelementptr(reserved0, function.getParameterRef(0), 0, 4));
Variable reserved1 = function.newVariable(I8_PTR_PTR);
function.add(new Getelementptr(reserved1, function.getParameterRef(0), 0, 5));
function.add(new Store(getString(m.getName()), reserved0.ref()));
function.add(new Store(getString(getDescriptor(m)), reserved1.ref()));
if (!sootClass.isInterface()) {
int vtableIndex = 0;
try {
VTable vtable = config.getVTableCache().get(sootClass);
vtableIndex = vtable.getEntry(m).getIndex();
} catch (IllegalArgumentException e) {
// VTable throws this if any of the superclasses of the class is actually an interface.
// Shouldn't happen frequently but the DRLVM test suite has some tests for this.
// Use 0 as vtableIndex since this lookup function will never be called anyway.
}
Value classPtr = call(function, OBJECT_CLASS, function.getParameterRef(1));
Value vtablePtr = call(function, CLASS_VITABLE, classPtr);
Variable funcPtrPtr = function.newVariable(I8_PTR_PTR);
function.add(new Getelementptr(funcPtrPtr, vtablePtr, 0, 1, vtableIndex));
Variable funcPtr = function.newVariable(I8_PTR);
function.add(new Load(funcPtr, funcPtrPtr.ref()));
Variable f = function.newVariable(function.getType());
function.add(new Bitcast(f, funcPtr.ref(), f.getType()));
Value result = tailcall(function, f.ref(), function.getParameterRefs());
function.add(new Ret(result));
} else {
ITable itable = config.getITableCache().get(sootClass);
ITable.Entry entry = itable.getEntry(m);
List<Value> args = new ArrayList<Value>();
args.add(function.getParameterRef(0));
args.add(getInfoStruct(function, sootClass));
args.add(function.getParameterRef(1));
args.add(new IntegerConstant(entry.getIndex()));
Value fptr = call(function, BC_LOOKUP_INTERFACE_METHOD_IMPL, args);
Variable f = function.newVariable(function.getType());
function.add(new Bitcast(f, fptr, f.getType()));
Value result = tailcall(function, f.ref(), function.getParameterRefs());
function.add(new Ret(result));
}
}
use of org.robovm.compiler.llvm.Ret in project robovm by robovm.
the class GlobalValueMethodCompiler method doCompile.
protected Function doCompile(ModuleBuilder moduleBuilder, SootMethod method) {
AnnotationTag globalValueAnnotation = getAnnotation(method, GLOBAL_VALUE);
validateGlobalValueMethod(method, globalValueAnnotation);
boolean optional = readBooleanElem(globalValueAnnotation, "optional", false);
boolean dereference = readBooleanElem(globalValueAnnotation, "dereference", true);
Function fn = createMethodFunction(method);
moduleBuilder.addFunction(fn);
Type valueType = getStructMemberType(method);
// Load the address of the resolved @GlobalValue method
Variable valuePtr = fn.newVariable(new PointerType(valueType));
Global valuePtrPtr = new Global(Symbols.globalValuePtrSymbol(method), _private, new NullConstant(I8_PTR));
moduleBuilder.addGlobal(valuePtrPtr);
fn.add(new Load(valuePtr, new ConstantBitcast(valuePtrPtr.ref(), new PointerType(valuePtr.getType()))));
Label nullLabel = new Label();
Label notNullLabel = new Label();
Variable nullCheck = fn.newVariable(I1);
fn.add(new Icmp(nullCheck, Condition.eq, valuePtr.ref(), new NullConstant(valuePtr.getType())));
fn.add(new Br(nullCheck.ref(), fn.newBasicBlockRef(nullLabel), fn.newBasicBlockRef(notNullLabel)));
fn.newBasicBlock(nullLabel);
VariableRef env = fn.getParameterRef(0);
call(fn, BC_THROW_UNSATISIFED_LINK_ERROR, env, moduleBuilder.getString(String.format((optional ? "Optional " : "") + "@GlobalValue method %s.%s%s not bound", className, method.getName(), getDescriptor(method))));
fn.add(new Unreachable());
fn.newBasicBlock(notNullLabel);
if (method.getParameterCount() == 0) {
// Getter
Value result = loadValueForGetter(method, fn, valueType, valuePtr.ref(), env, dereference, MarshalerFlags.CALL_TYPE_GLOBAL_VALUE);
fn.add(new Ret(result));
} else {
// Setter
// 'env' is parameter 0, the value we're interested in is at index 1
Value value = fn.getParameterRef(1);
storeValueForSetter(method, fn, valueType, valuePtr.ref(), env, value, MarshalerFlags.CALL_TYPE_GLOBAL_VALUE);
fn.add(new Ret());
}
return fn;
}
use of org.robovm.compiler.llvm.Ret in project robovm by robovm.
the class NativeMethodCompiler method doCompile.
protected Function doCompile(ModuleBuilder moduleBuilder, SootMethod method) {
Function fn = createMethodFunction(method);
moduleBuilder.addFunction(fn);
Value env = fn.getParameterRef(0);
ArrayList<Value> args = new ArrayList<Value>(Arrays.asList(fn.getParameterRefs()));
if (method.isStatic()) {
// Add the current class as second parameter
FunctionRef ldcFn = FunctionBuilder.ldcInternal(sootMethod.getDeclaringClass()).ref();
Value clazz = call(fn, ldcFn, env);
args.add(1, clazz);
}
pushNativeFrame(fn);
FunctionRef targetFn = createNative(moduleBuilder, method);
Value result = call(fn, targetFn, args);
popNativeFrame(fn);
call(fn, BC_THROW_IF_EXCEPTION_OCCURRED, env);
fn.add(new Ret(result));
return fn;
}
Aggregations