Search in sources :

Example 1 with Function

use of org.robovm.compiler.llvm.Function in project robovm by robovm.

the class BridgeMethodCompiler method doCompile.

protected Function doCompile(ModuleBuilder moduleBuilder, SootMethod method) {
    validateBridgeMethod(method);
    AnnotationTag bridgeAnnotation = getAnnotation(method, BRIDGE);
    boolean dynamic = readBooleanElem(bridgeAnnotation, "dynamic", false);
    boolean optional = readBooleanElem(bridgeAnnotation, "optional", false);
    boolean useCWrapper = requiresCWrapper(method);
    Function fn = createMethodFunction(method);
    moduleBuilder.addFunction(fn);
    Type[] parameterTypes = fn.getType().getParameterTypes();
    String[] parameterNames = fn.getParameterNames();
    ArrayList<Argument> args = new ArrayList<Argument>();
    for (int i = 0; i < parameterTypes.length; i++) {
        args.add(new Argument(new VariableRef(parameterNames[i], parameterTypes[i])));
    }
    VariableRef env = fn.getParameterRef(0);
    // Load the address of the resolved @Bridge method
    Variable targetFn = fn.newVariable(I8_PTR);
    if (!dynamic) {
        Global targetFnPtr = new Global(Symbols.bridgePtrSymbol(method), _private, new NullConstant(I8_PTR));
        moduleBuilder.addGlobal(targetFnPtr);
        fn.add(new Load(targetFn, targetFnPtr.ref()));
        Label nullLabel = new Label();
        Label notNullLabel = new Label();
        Variable nullCheck = fn.newVariable(I1);
        fn.add(new Icmp(nullCheck, Condition.eq, targetFn.ref(), new NullConstant(I8_PTR)));
        fn.add(new Br(nullCheck.ref(), fn.newBasicBlockRef(nullLabel), fn.newBasicBlockRef(notNullLabel)));
        fn.newBasicBlock(nullLabel);
        call(fn, optional ? BC_THROW_UNSATISIFED_LINK_ERROR_OPTIONAL_BRIDGE_NOT_BOUND : BC_THROW_UNSATISIFED_LINK_ERROR_BRIDGE_NOT_BOUND, env, moduleBuilder.getString(className), moduleBuilder.getString(method.getName()), moduleBuilder.getString(getDescriptor(method)));
        fn.add(new Unreachable());
        fn.newBasicBlock(notNullLabel);
    } else {
        // Dynamic @Bridge methods pass the target function pointer as a
        // long in the first parameter.
        fn.add(new Inttoptr(targetFn, fn.getParameterRef(1), targetFn.getType()));
        args.remove(1);
    }
    // Marshal args
    // Remove Env* from args
    args.remove(0);
    // Save the Object->handle mapping for each marshaled object. We need it
    // after the native call to call updateObject() on the marshaler for 
    // each value. Since the LLVM variables that store these values are used 
    // after the native call we get the nice side effect that neither the
    // Java objects nor the handles can be garbage collected while we're in
    // native code.
    List<MarshaledArg> marshaledArgs = new ArrayList<MarshaledArg>();
    FunctionType targetFnType = getBridgeFunctionType(method, dynamic, false);
    Type[] targetParameterTypes = targetFnType.getParameterTypes();
    if (!method.isStatic()) {
        MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(new MarshalSite(method, MarshalSite.RECEIVER));
        MarshaledArg marshaledArg = new MarshaledArg();
        marshaledArg.paramIndex = MarshalSite.RECEIVER;
        marshaledArgs.add(marshaledArg);
        Type nativeType = targetParameterTypes[0];
        Value nativeValue = marshalObjectToNative(fn, marshalerMethod, marshaledArg, useCWrapper ? I8_PTR : nativeType, env, args.get(0).getValue(), MarshalerFlags.CALL_TYPE_BRIDGE);
        args.set(0, new Argument(nativeValue));
    }
    for (int i = 0, argIdx = 0; i < method.getParameterCount(); i++) {
        if (dynamic && i == 0) {
            // Skip the target function pointer for dynamic bridge methods.
            continue;
        }
        if (!method.isStatic() && argIdx == 0) {
            // Skip the receiver in args. It doesn't correspond to a parameter.
            argIdx++;
        }
        soot.Type type = method.getParameterType(i);
        if (needsMarshaler(type)) {
            MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(new MarshalSite(method, i));
            // The return type of the marshaler's toNative() method is derived from the target function type.
            Type nativeType = targetParameterTypes[argIdx];
            if (nativeType instanceof PrimitiveType) {
                Value nativeValue = marshalValueObjectToNative(fn, marshalerMethod, nativeType, env, args.get(argIdx).getValue(), MarshalerFlags.CALL_TYPE_BRIDGE);
                args.set(argIdx, new Argument(nativeValue));
            } else {
                ParameterAttribute[] parameterAttributes = new ParameterAttribute[0];
                if (isPassByValue(method, i) || isStructRet(method, i)) {
                    // 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(fn, CHECK_NULL, env, args.get(argIdx).getValue());
                }
                MarshaledArg marshaledArg = new MarshaledArg();
                marshaledArg.paramIndex = i;
                marshaledArgs.add(marshaledArg);
                Value nativeValue = marshalObjectToNative(fn, marshalerMethod, marshaledArg, useCWrapper ? I8_PTR : nativeType, env, args.get(argIdx).getValue(), MarshalerFlags.CALL_TYPE_BRIDGE);
                args.set(argIdx, new Argument(nativeValue, parameterAttributes));
            }
        } else {
            args.set(argIdx, new Argument(marshalPrimitiveToNative(fn, method, i, args.get(argIdx).getValue())));
        }
        argIdx++;
    }
    Variable structResult = null;
    Value targetFnRef = null;
    if (useCWrapper) {
        args.add(0, new Argument(targetFn.ref()));
        if (targetFnType.getReturnType() instanceof StructureType) {
            // Allocate space on the stack big enough to hold the returned struct
            Variable tmp = fn.newVariable(new PointerType(targetFnType.getReturnType()));
            fn.add(new Alloca(tmp, targetFnType.getReturnType()));
            structResult = fn.newVariable(I8_PTR);
            fn.add(new Bitcast(structResult, tmp.ref(), I8_PTR));
            args.add(1, new Argument(structResult.ref()));
        }
        String wrapperName = Symbols.bridgeCSymbol(method);
        FunctionType wrapperFnType = getBridgeFunctionType(method, dynamic, true);
        getCWrapperFunctions().add(createBridgeCWrapper(targetFnType.getReturnType(), targetFnType.getParameterTypes(), wrapperFnType.getParameterTypes(), wrapperName));
        FunctionRef wrapperFnRef = getBridgeCWrapperRef(targetFnType, wrapperName);
        moduleBuilder.addFunctionDeclaration(new FunctionDeclaration(wrapperFnRef));
        targetFnRef = wrapperFnRef;
    } else {
        Variable tmp = fn.newVariable(targetFnType);
        fn.add(new Bitcast(tmp, targetFn.ref(), targetFnType));
        targetFnRef = tmp.ref();
    }
    // Execute the call to native code
    BasicBlockRef bbSuccess = fn.newBasicBlockRef(new Label("success"));
    BasicBlockRef bbFailure = fn.newBasicBlockRef(new Label("failure"));
    pushNativeFrame(fn);
    trycatchAllEnter(fn, env, bbSuccess, bbFailure);
    fn.newBasicBlock(bbSuccess.getLabel());
    Value result = callWithArguments(fn, targetFnRef, args);
    trycatchLeave(fn, env);
    popNativeFrame(fn);
    updateObject(method, fn, env, MarshalerFlags.CALL_TYPE_BRIDGE, marshaledArgs);
    // Marshal the return value
    if (needsMarshaler(method.getReturnType())) {
        MarshalerMethod marshalerMethod = config.getMarshalerLookup().findMarshalerMethod(new MarshalSite(method));
        String targetClassName = getInternalName(method.getReturnType());
        if (structResult != null) {
            // Copy to the heap.
            DataLayout dataLayout = config.getDataLayout();
            Value heapCopy = call(fn, BC_COPY_STRUCT, env, structResult.ref(), new IntegerConstant(dataLayout.getAllocSize(targetFnType.getReturnType())));
            result = marshalNativeToObject(fn, marshalerMethod, null, env, targetClassName, heapCopy, MarshalerFlags.CALL_TYPE_BRIDGE);
        } else if (targetFnType.getReturnType() instanceof PrimitiveType) {
            result = marshalNativeToValueObject(fn, marshalerMethod, env, targetClassName, result, MarshalerFlags.CALL_TYPE_BRIDGE);
        } else {
            result = marshalNativeToObject(fn, marshalerMethod, null, env, targetClassName, result, MarshalerFlags.CALL_TYPE_BRIDGE);
        }
    } else {
        result = marshalNativeToPrimitive(fn, method, result);
    }
    fn.add(new Ret(result));
    fn.newBasicBlock(bbFailure.getLabel());
    trycatchLeave(fn, env);
    popNativeFrame(fn);
    Value ex = call(fn, BC_EXCEPTION_CLEAR, env);
    // Call Marshaler.updateObject() for each object that was marshaled before
    // the call.
    updateObject(method, fn, env, MarshalerFlags.CALL_TYPE_BRIDGE, marshaledArgs);
    call(fn, BC_THROW, env, ex);
    fn.add(new Unreachable());
    return fn;
}
Also used : MarshalSite(org.robovm.compiler.MarshalerLookup.MarshalSite) ParameterAttribute(org.robovm.compiler.llvm.ParameterAttribute) Ret(org.robovm.compiler.llvm.Ret) VariableRef(org.robovm.compiler.llvm.VariableRef) Variable(org.robovm.compiler.llvm.Variable) Argument(org.robovm.compiler.llvm.Argument) ArrayList(java.util.ArrayList) Label(org.robovm.compiler.llvm.Label) Inttoptr(org.robovm.compiler.llvm.Inttoptr) PointerType(org.robovm.compiler.llvm.PointerType) Global(org.robovm.compiler.llvm.Global) AnnotationTag(soot.tagkit.AnnotationTag) Function(org.robovm.compiler.llvm.Function) FunctionDeclaration(org.robovm.compiler.llvm.FunctionDeclaration) BasicBlockRef(org.robovm.compiler.llvm.BasicBlockRef) Unreachable(org.robovm.compiler.llvm.Unreachable) PrimitiveType(org.robovm.compiler.llvm.PrimitiveType) FunctionRef(org.robovm.compiler.llvm.FunctionRef) DataLayout(org.robovm.compiler.llvm.DataLayout) Load(org.robovm.compiler.llvm.Load) Alloca(org.robovm.compiler.llvm.Alloca) FunctionType(org.robovm.compiler.llvm.FunctionType) NullConstant(org.robovm.compiler.llvm.NullConstant) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) Br(org.robovm.compiler.llvm.Br) StructureType(org.robovm.compiler.llvm.StructureType) PointerType(org.robovm.compiler.llvm.PointerType) LongType(soot.LongType) Type(org.robovm.compiler.llvm.Type) PrimitiveType(org.robovm.compiler.llvm.PrimitiveType) FunctionType(org.robovm.compiler.llvm.FunctionType) Bitcast(org.robovm.compiler.llvm.Bitcast) StructureType(org.robovm.compiler.llvm.StructureType) Value(org.robovm.compiler.llvm.Value) MarshalerMethod(org.robovm.compiler.MarshalerLookup.MarshalerMethod) PointerMarshalerMethod(org.robovm.compiler.MarshalerLookup.PointerMarshalerMethod) Icmp(org.robovm.compiler.llvm.Icmp)

Example 2 with Function

use of org.robovm.compiler.llvm.Function in project robovm by robovm.

the class MethodCompiler method ldcString.

private FunctionRef ldcString(String s) {
    byte[] modUtf8 = stringToModifiedUtf8Z(s);
    FunctionRef fref = new FunctionRef(Symbols.ldcStringSymbol(modUtf8), new FunctionType(OBJECT_PTR, ENV_PTR));
    if (moduleBuilder.hasSymbol(fref.getName())) {
        return fref;
    }
    Global g = new Global(Symbols.ldcStringPtrSymbol(modUtf8), weak, new NullConstant(OBJECT_PTR));
    moduleBuilder.addGlobal(g);
    Function f = new FunctionBuilder(fref).linkage(weak).build();
    moduleBuilder.addFunction(f);
    Value result = Functions.call(f, BC_LDC_STRING, f.getParameterRef(0), g.ref(), moduleBuilder.getString(s), new IntegerConstant(s.length()));
    f.add(new Ret(result));
    return fref;
}
Also used : Ret(org.robovm.compiler.llvm.Ret) Function(org.robovm.compiler.llvm.Function) FunctionType(org.robovm.compiler.llvm.FunctionType) Value(org.robovm.compiler.llvm.Value) NullConstant(org.robovm.compiler.llvm.NullConstant) Global(org.robovm.compiler.llvm.Global) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) FunctionRef(org.robovm.compiler.llvm.FunctionRef)

Example 3 with Function

use of org.robovm.compiler.llvm.Function 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;
}
Also used : Ret(org.robovm.compiler.llvm.Ret) ModifiedUtf8HashFunction(org.robovm.compiler.hash.ModifiedUtf8HashFunction) Function(org.robovm.compiler.llvm.Function) FunctionDeclaration(org.robovm.compiler.llvm.FunctionDeclaration) Value(org.robovm.compiler.llvm.Value) FunctionRef(org.robovm.compiler.llvm.FunctionRef)

Example 4 with Function

use of org.robovm.compiler.llvm.Function 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;
}
Also used : Ret(org.robovm.compiler.llvm.Ret) ModifiedUtf8HashFunction(org.robovm.compiler.hash.ModifiedUtf8HashFunction) Function(org.robovm.compiler.llvm.Function) Value(org.robovm.compiler.llvm.Value) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant)

Example 5 with Function

use of org.robovm.compiler.llvm.Function in project robovm by robovm.

the class Linker method link.

public void link(Set<Clazz> classes) throws IOException {
    for (CompilerPlugin plugin : config.getCompilerPlugins()) {
        plugin.beforeLinker(config, this, classes);
    }
    Arch arch = config.getArch();
    OS os = config.getOs();
    Set<Clazz> linkClasses = new TreeSet<Clazz>(classes);
    config.getLogger().info("Linking %d classes (%s %s %s)", linkClasses.size(), os, arch, config.isDebug() ? "debug" : "release");
    ModuleBuilder mb = new ModuleBuilder();
    mb.addInclude(getClass().getClassLoader().getResource(String.format("header-%s-%s.ll", os.getFamily(), arch)));
    mb.addInclude(getClass().getClassLoader().getResource("header.ll"));
    mb.addGlobal(new Global("_bcRuntimeData", runtimeDataToBytes()));
    ArrayConstantBuilder staticLibs = new ArrayConstantBuilder(I8_PTR);
    for (Config.Lib lib : config.getLibs()) {
        String p = lib.getValue();
        if (p.endsWith(".a")) {
            p = new File(p).getName();
            String libName = p.substring(0, p.length() - 2);
            if (libName.startsWith("lib")) {
                libName = libName.substring(3);
            }
            staticLibs.add(mb.getString(libName));
        }
    }
    staticLibs.add(new NullConstant(Type.I8_PTR));
    mb.addGlobal(new Global("_bcStaticLibs", new ConstantGetelementptr(mb.newGlobal(staticLibs.build()).ref(), 0, 0)));
    HashTableGenerator<String, Constant> bcpHashGen = new HashTableGenerator<String, Constant>(new ModifiedUtf8HashFunction());
    HashTableGenerator<String, Constant> cpHashGen = new HashTableGenerator<String, Constant>(new ModifiedUtf8HashFunction());
    int classCount = 0;
    Map<ClazzInfo, TypeInfo> typeInfos = new HashMap<ClazzInfo, TypeInfo>();
    for (Clazz clazz : linkClasses) {
        TypeInfo typeInfo = new TypeInfo();
        typeInfo.clazz = clazz;
        typeInfo.id = classCount++;
        typeInfos.put(clazz.getClazzInfo(), typeInfo);
        StructureConstant infoErrorStruct = createClassInfoErrorStruct(mb, clazz.getClazzInfo());
        Global info = null;
        if (infoErrorStruct == null) {
            info = new Global(Symbols.infoStructSymbol(clazz.getInternalName()), external, I8_PTR, false);
        } else {
            typeInfo.error = true;
            info = new Global(Symbols.infoStructSymbol(clazz.getInternalName()), infoErrorStruct);
        }
        mb.addGlobal(info);
        if (clazz.isInBootClasspath()) {
            bcpHashGen.put(clazz.getInternalName(), new ConstantBitcast(info.ref(), I8_PTR));
        } else {
            cpHashGen.put(clazz.getInternalName(), new ConstantBitcast(info.ref(), I8_PTR));
        }
    }
    mb.addGlobal(new Global("_bcBootClassesHash", new ConstantGetelementptr(mb.newGlobal(bcpHashGen.generate(), true).ref(), 0, 0)));
    mb.addGlobal(new Global("_bcClassesHash", new ConstantGetelementptr(mb.newGlobal(cpHashGen.generate(), true).ref(), 0, 0)));
    ArrayConstantBuilder bootClasspathValues = new ArrayConstantBuilder(I8_PTR);
    ArrayConstantBuilder classpathValues = new ArrayConstantBuilder(I8_PTR);
    List<Path> allPaths = new ArrayList<Path>();
    allPaths.addAll(config.getClazzes().getPaths());
    allPaths.addAll(config.getResourcesPaths());
    for (Path path : allPaths) {
        String entryName = null;
        if (config.isSkipInstall() && config.getTarget().canLaunchInPlace()) {
            entryName = path.getFile().getAbsolutePath();
        } else {
            entryName = config.getTarget().getInstallRelativeArchivePath(path);
        }
        if (path.isInBootClasspath()) {
            bootClasspathValues.add(mb.getString(entryName));
        } else {
            classpathValues.add(mb.getString(entryName));
        }
    }
    bootClasspathValues.add(new NullConstant(Type.I8_PTR));
    classpathValues.add(new NullConstant(Type.I8_PTR));
    mb.addGlobal(new Global("_bcBootclasspath", new ConstantGetelementptr(mb.newGlobal(bootClasspathValues.build()).ref(), 0, 0)));
    mb.addGlobal(new Global("_bcClasspath", new ConstantGetelementptr(mb.newGlobal(classpathValues.build()).ref(), 0, 0)));
    if (config.getMainClass() != null) {
        mb.addGlobal(new Global("_bcMainClass", mb.getString(config.getMainClass())));
    }
    ModuleBuilder[] mbs = new ModuleBuilder[config.getThreads() + 1];
    FunctionRef[] stubRefs = new FunctionRef[mbs.length];
    ArrayConstantBuilder stubRefsArray = new ArrayConstantBuilder(I8_PTR);
    mbs[0] = mb;
    for (int i = 1; i < mbs.length; i++) {
        mbs[i] = new ModuleBuilder();
        mbs[i].addInclude(getClass().getClassLoader().getResource(String.format("header-%s-%s.ll", os.getFamily(), arch)));
        mbs[i].addInclude(getClass().getClassLoader().getResource("header.ll"));
        Function fn = new FunctionBuilder("_stripped_method" + i, new FunctionType(VOID, ENV_PTR)).linkage(external).build();
        call(fn, BC_THROW_NO_SUCH_METHOD_ERROR, fn.getParameterRef(0), mbs[i].getString("Method has been stripped out of the executable"));
        fn.add(new Unreachable());
        mbs[i].addFunction(fn);
        mb.addFunctionDeclaration(new FunctionDeclaration(fn.ref()));
        stubRefs[i] = fn.ref();
        stubRefsArray.add(new ConstantBitcast(fn.ref(), I8_PTR));
    }
    stubRefsArray.add(new NullConstant(I8_PTR));
    mb.addGlobal(new Global("_bcStrippedMethodStubs", stubRefsArray.build()));
    Random rnd = new Random();
    buildTypeInfos(typeInfos);
    Set<String> checkcasts = new HashSet<>();
    Set<String> instanceofs = new HashSet<>();
    Set<String> invokes = new HashSet<>();
    for (Clazz clazz : linkClasses) {
        ClazzInfo ci = clazz.getClazzInfo();
        checkcasts.addAll(ci.getCheckcasts());
        instanceofs.addAll(ci.getInstanceofs());
        invokes.addAll(ci.getInvokes());
    }
    Set<String> reachableMethods = new HashSet<>();
    for (Triple<String, String, String> node : config.getDependencyGraph().findReachableMethods()) {
        reachableMethods.add(node.getLeft() + "." + node.getMiddle() + node.getRight());
    }
    int totalMethodCount = 0;
    int reachableMethodCount = 0;
    for (Clazz clazz : linkClasses) {
        int mbIdx = rnd.nextInt(mbs.length - 1) + 1;
        ClazzInfo ci = clazz.getClazzInfo();
        // symbols errors.
        for (MethodInfo mi : ci.getMethods()) {
            if (!mi.isAbstract()) {
                totalMethodCount++;
                if (!reachableMethods.contains(clazz.getInternalName() + "." + mi.getName() + mi.getDesc())) {
                    createStrippedMethodStub(stubRefs[mbIdx], mbs[mbIdx], clazz, mi);
                } else {
                    reachableMethodCount++;
                }
            }
        }
        TypeInfo typeInfo = typeInfos.get(ci);
        if (typeInfo.error) {
            // Add an empty TypeInfo
            mb.addGlobal(new Global(Symbols.typeInfoSymbol(clazz.getInternalName()), new StructureConstantBuilder().add(new IntegerConstant(typeInfo.id)).add(new IntegerConstant(0)).add(new IntegerConstant(-1)).add(new IntegerConstant(0)).add(new IntegerConstant(0)).build()));
        } else {
            int[] classIds = new int[typeInfo.classTypes.length];
            for (int i = 0; i < typeInfo.classTypes.length; i++) {
                classIds[i] = typeInfo.classTypes[i].id;
            }
            int[] interfaceIds = new int[typeInfo.interfaceTypes.length];
            for (int i = 0; i < typeInfo.interfaceTypes.length; i++) {
                interfaceIds[i] = typeInfo.interfaceTypes[i].id;
            }
            mb.addGlobal(new Global(Symbols.typeInfoSymbol(clazz.getInternalName()), new StructureConstantBuilder().add(new IntegerConstant(typeInfo.id)).add(new IntegerConstant((typeInfo.classTypes.length - 1) * 4 + 5 * 4)).add(new IntegerConstant(-1)).add(new IntegerConstant(typeInfo.classTypes.length)).add(new IntegerConstant(typeInfo.interfaceTypes.length)).add(new ArrayConstantBuilder(I32).add(classIds).build()).add(new ArrayConstantBuilder(I32).add(interfaceIds).build()).build()));
            if (!config.isDebug() && !ci.isInterface() && !ci.isFinal() && typeInfo.children.isEmpty()) {
                // which doesn't do any lookup.
                for (MethodInfo mi : ci.getMethods()) {
                    String name = mi.getName();
                    if (!name.equals("<clinit>") && !name.equals("<init>") && !mi.isPrivate() && !mi.isStatic() && !mi.isFinal() && !mi.isAbstract()) {
                        if (invokes.contains(clazz.getInternalName() + "." + name + mi.getDesc())) {
                            if (reachableMethods.contains(clazz.getInternalName() + "." + name + mi.getDesc())) {
                                mbs[mbIdx].addFunction(createLookup(mbs[mbIdx], ci, mi));
                            }
                        }
                    }
                }
            }
        }
        if (checkcasts.contains(clazz.getInternalName())) {
            mbs[mbIdx].addFunction(createCheckcast(mbs[mbIdx], clazz, typeInfo));
        }
        if (instanceofs.contains(clazz.getInternalName())) {
            mbs[mbIdx].addFunction(createInstanceof(mbs[mbIdx], clazz, typeInfo));
        }
    }
    config.getLogger().info("%d methods out of %d included in the executable", reachableMethodCount, totalMethodCount);
    List<File> objectFiles = new ArrayList<File>();
    generateMachineCode(config, mbs, objectFiles);
    for (Clazz clazz : linkClasses) {
        objectFiles.add(config.getOFile(clazz));
    }
    /*
         * Assemble the lines files for all linked classes into the module.
         */
    for (Clazz clazz : linkClasses) {
        File f = config.getLinesOFile(clazz);
        if (f.exists() && f.length() > 0) {
            objectFiles.add(f);
        }
    }
    config.getTarget().build(objectFiles);
}
Also used : HashMap(java.util.HashMap) CompilerPlugin(org.robovm.compiler.plugin.CompilerPlugin) Config(org.robovm.compiler.config.Config) NullConstant(org.robovm.compiler.llvm.NullConstant) StructureConstant(org.robovm.compiler.llvm.StructureConstant) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) Constant(org.robovm.compiler.llvm.Constant) ArrayConstant(org.robovm.compiler.llvm.ArrayConstant) ConstantBitcast(org.robovm.compiler.llvm.ConstantBitcast) ArrayList(java.util.ArrayList) Global(org.robovm.compiler.llvm.Global) HashTableGenerator(org.robovm.compiler.hash.HashTableGenerator) ModifiedUtf8HashFunction(org.robovm.compiler.hash.ModifiedUtf8HashFunction) ArrayConstantBuilder(org.robovm.compiler.llvm.ArrayConstantBuilder) ModifiedUtf8HashFunction(org.robovm.compiler.hash.ModifiedUtf8HashFunction) Function(org.robovm.compiler.llvm.Function) FunctionDeclaration(org.robovm.compiler.llvm.FunctionDeclaration) Random(java.util.Random) Unreachable(org.robovm.compiler.llvm.Unreachable) TreeSet(java.util.TreeSet) Clazz(org.robovm.compiler.clazz.Clazz) FunctionRef(org.robovm.compiler.llvm.FunctionRef) HashSet(java.util.HashSet) Path(org.robovm.compiler.clazz.Path) OS(org.robovm.compiler.config.OS) FunctionType(org.robovm.compiler.llvm.FunctionType) Arch(org.robovm.compiler.config.Arch) NullConstant(org.robovm.compiler.llvm.NullConstant) ClazzInfo(org.robovm.compiler.clazz.ClazzInfo) StructureConstantBuilder(org.robovm.compiler.llvm.StructureConstantBuilder) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) StructureConstant(org.robovm.compiler.llvm.StructureConstant) MethodInfo(org.robovm.compiler.clazz.MethodInfo) File(java.io.File) ConstantGetelementptr(org.robovm.compiler.llvm.ConstantGetelementptr)

Aggregations

Function (org.robovm.compiler.llvm.Function)29 Ret (org.robovm.compiler.llvm.Ret)24 Value (org.robovm.compiler.llvm.Value)22 FunctionRef (org.robovm.compiler.llvm.FunctionRef)16 IntegerConstant (org.robovm.compiler.llvm.IntegerConstant)9 FunctionType (org.robovm.compiler.llvm.FunctionType)7 Global (org.robovm.compiler.llvm.Global)7 NullConstant (org.robovm.compiler.llvm.NullConstant)7 ArrayList (java.util.ArrayList)6 ConstantBitcast (org.robovm.compiler.llvm.ConstantBitcast)6 Label (org.robovm.compiler.llvm.Label)6 PointerType (org.robovm.compiler.llvm.PointerType)6 StructureType (org.robovm.compiler.llvm.StructureType)6 Unreachable (org.robovm.compiler.llvm.Unreachable)6 Variable (org.robovm.compiler.llvm.Variable)6 Bitcast (org.robovm.compiler.llvm.Bitcast)5 FunctionDeclaration (org.robovm.compiler.llvm.FunctionDeclaration)5 Load (org.robovm.compiler.llvm.Load)5 Type (org.robovm.compiler.llvm.Type)5 ModifiedUtf8HashFunction (org.robovm.compiler.hash.ModifiedUtf8HashFunction)4