<commit_before>/*
 * Copyright (c) 2016, Oracle and/or its affiliates.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are
 * permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or other materials provided
 * with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to
 * endorse or promote products derived from this software without specific prior written
 * permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.oracle.truffle.llvm;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
import java.util.function.Consumer;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.eclipse.xtext.util.StringInputStream;

import com.google.inject.Injector;
import com.intel.llvm.ireditor.LLVM_IRStandaloneSetup;
import com.intel.llvm.ireditor.lLVM_IR.Model;
import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.RootCallTarget;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.TruffleLanguage.Env;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.source.MissingNameException;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.vm.PolyglotEngine;
import com.oracle.truffle.api.vm.PolyglotEngine.Builder;
import com.oracle.truffle.llvm.nodes.impl.base.LLVMContext;
import com.oracle.truffle.llvm.nodes.impl.base.LLVMLanguage;
import com.oracle.truffle.llvm.parser.LLVMParserResult;
import com.oracle.truffle.llvm.parser.LLVMParserRuntime;
import com.oracle.truffle.llvm.parser.NodeFactoryFacade;
import com.oracle.truffle.llvm.parser.NodeFactoryFacadeProvider;
import com.oracle.truffle.llvm.parser.bc.impl.LLVMBitcodeVisitor;
import com.oracle.truffle.llvm.parser.impl.LLVMGlobalVariableVisitor;
import com.oracle.truffle.llvm.parser.impl.LLVMGlobalVariableVisitor.LLVMGlobalVariableResult;
import com.oracle.truffle.llvm.parser.impl.LLVMVisitor;
import com.oracle.truffle.llvm.runtime.LLVMLogger;
import com.oracle.truffle.llvm.runtime.LLVMPropertyOptimizationConfiguration;
import com.oracle.truffle.llvm.runtime.options.LLVMBaseOptionFacade;

/**
 * This is the main LLVM execution class.
 */
public class LLVM {

    static final LLVMPropertyOptimizationConfiguration OPTIMIZATION_CONFIGURATION = new LLVMPropertyOptimizationConfiguration();

    static {
        LLVMLanguage.provider = getProvider();
    }

    private static NodeFactoryFacade getNodeFactoryFacade(LLVMParserRuntime parserRuntime) {
        NodeFactoryFacade factoryFacade = getNodeFactoryFacade();
        factoryFacade.setUpFacade(parserRuntime);
        return factoryFacade;
    }

    private static NodeFactoryFacade getNodeFactoryFacade() {
        ServiceLoader<NodeFactoryFacadeProvider> loader = ServiceLoader.load(NodeFactoryFacadeProvider.class);
        if (!loader.iterator().hasNext()) {
            throw new AssertionError("Could not find a " + NodeFactoryFacadeProvider.class.getSimpleName() + " for the creation of the Truffle nodes");
        }
        NodeFactoryFacade facade = null;
        String expectedConfigName = LLVMBaseOptionFacade.getNodeConfiguration();
        for (NodeFactoryFacadeProvider prov : loader) {
            String configName = prov.getConfigurationName();
            if (configName != null && configName.equals(expectedConfigName)) {
                facade = prov.getNodeFactoryFacade();
            }
        }
        if (facade == null) {
            throw new AssertionError("Could not find a " + NodeFactoryFacadeProvider.class.getSimpleName() + " with the name " + expectedConfigName);
        }
        return facade;
    }

    private static LLVMLanguage.LLVMLanguageProvider getProvider() {
        return new LLVMLanguage.LLVMLanguageProvider() {

            @Override
            public CallTarget parse(Source code, Node contextNode, String... argumentNames) throws IOException {
                try {
                    return parse(code);
                } catch (Throwable t) {
                    throw new IOException("Error while trying to parse " + code.getPath(), t);
                }
            }

            private CallTarget parse(Source code) throws IOException {
                Node findContext = LLVMLanguage.INSTANCE.createFindContextNode0();
                LLVMContext context = LLVMLanguage.INSTANCE.findContext0(findContext);
                final CallTarget[] mainFunction = new CallTarget[]{null};
                if (code.getMimeType().equals(LLVMLanguage.LLVM_IR_MIME_TYPE)) {
                    List<String> resolvedVariables = getAllResolvedGlobalVariables(code);
                    context.setResolvedVariableNames(resolvedVariables);
                    String path = code.getPath();
                    LLVMParserResult parserResult;
                    try {
                        if (path == null) {
                            parserResult = parseString(code, context);
                        } else {
                            parserResult = parseFile(code, context);
                        }
                    } catch (IllegalStateException e) {
                        throw new IOException(e);
                    }
                    mainFunction[0] = parserResult.getMainFunction();
                    handleParserResult(context, parserResult);
                } else if (code.getMimeType().equals(LLVMLanguage.LLVM_BITCODE_MIME_TYPE)) {
                    // TODO we need to set the global variables for .bc files
                    LLVMParserResult parserResult = parseBitcodeFile(code, context);
                    mainFunction[0] = parserResult.getMainFunction();
                    handleParserResult(context, parserResult);
                } else if (code.getMimeType().equals(LLVMLanguage.SULONG_LIBRARY_MIME_TYPE)) {
                    final SulongLibrary library = new SulongLibrary(new File(code.getPath()));
                    List<String> resolvedVariables = new ArrayList<>();
                    List<Source> sourceFiles = new ArrayList<>();
                    library.readContents(dependentLibrary -> {
                        context.addLibraryToNativeLookup(dependentLibrary);
                    }, source -> {
                        sourceFiles.add(source);
                        try {
                            addResolvedGlobalVariables(resolvedVariables, source);
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    });
                    context.setResolvedVariableNames(resolvedVariables);
                    for (Source source : sourceFiles) {
                        LLVMParserResult parserResult;
                        try {
                            parserResult = parseString(source, context);
                        } catch (IOException e) {<commit_msg>Set Global Variables for Bitcode-Files<commit_after>/*
 * Copyright (c) 2016, Oracle and/or its affiliates.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are
 * permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or other materials provided
 * with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to
 * endorse or promote products derived from this software without specific prior written
 * permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.oracle.truffle.llvm;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
import java.util.function.Consumer;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.eclipse.xtext.util.StringInputStream;

import com.google.inject.Injector;
import com.intel.llvm.ireditor.LLVM_IRStandaloneSetup;
import com.intel.llvm.ireditor.lLVM_IR.Model;
import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.RootCallTarget;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.TruffleLanguage.Env;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.source.MissingNameException;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.vm.PolyglotEngine;
import com.oracle.truffle.api.vm.PolyglotEngine.Builder;
import com.oracle.truffle.llvm.nodes.impl.base.LLVMContext;
import com.oracle.truffle.llvm.nodes.impl.base.LLVMLanguage;
import com.oracle.truffle.llvm.parser.LLVMParserResult;
import com.oracle.truffle.llvm.parser.LLVMParserRuntime;
import com.oracle.truffle.llvm.parser.NodeFactoryFacade;
import com.oracle.truffle.llvm.parser.NodeFactoryFacadeProvider;
import com.oracle.truffle.llvm.parser.bc.impl.LLVMBitcodeVisitor;
import com.oracle.truffle.llvm.parser.impl.LLVMGlobalVariableVisitor;
import com.oracle.truffle.llvm.parser.impl.LLVMGlobalVariableVisitor.LLVMGlobalVariableResult;
import com.oracle.truffle.llvm.parser.impl.LLVMVisitor;
import com.oracle.truffle.llvm.runtime.LLVMLogger;
import com.oracle.truffle.llvm.runtime.LLVMPropertyOptimizationConfiguration;
import com.oracle.truffle.llvm.runtime.options.LLVMBaseOptionFacade;

/**
 * This is the main LLVM execution class.
 */
public class LLVM {

    static final LLVMPropertyOptimizationConfiguration OPTIMIZATION_CONFIGURATION = new LLVMPropertyOptimizationConfiguration();

    static {
        LLVMLanguage.provider = getProvider();
    }

    private static NodeFactoryFacade getNodeFactoryFacade(LLVMParserRuntime parserRuntime) {
        NodeFactoryFacade factoryFacade = getNodeFactoryFacade();
        factoryFacade.setUpFacade(parserRuntime);
        return factoryFacade;
    }

    private static NodeFactoryFacade getNodeFactoryFacade() {
        ServiceLoader<NodeFactoryFacadeProvider> loader = ServiceLoader.load(NodeFactoryFacadeProvider.class);
        if (!loader.iterator().hasNext()) {
            throw new AssertionError("Could not find a " + NodeFactoryFacadeProvider.class.getSimpleName() + " for the creation of the Truffle nodes");
        }
        NodeFactoryFacade facade = null;
        String expectedConfigName = LLVMBaseOptionFacade.getNodeConfiguration();
        for (NodeFactoryFacadeProvider prov : loader) {
            String configName = prov.getConfigurationName();
            if (configName != null && configName.equals(expectedConfigName)) {
                facade = prov.getNodeFactoryFacade();
            }
        }
        if (facade == null) {
            throw new AssertionError("Could not find a " + NodeFactoryFacadeProvider.class.getSimpleName() + " with the name " + expectedConfigName);
        }
        return facade;
    }

    private static LLVMLanguage.LLVMLanguageProvider getProvider() {
        return new LLVMLanguage.LLVMLanguageProvider() {

            @Override
            public CallTarget parse(Source code, Node contextNode, String... argumentNames) throws IOException {
                try {
                    return parse(code);
                } catch (Throwable t) {
                    throw new IOException("Error while trying to parse " + code.getPath(), t);
                }
            }

            private CallTarget parse(Source code) throws IOException {
                Node findContext = LLVMLanguage.INSTANCE.createFindContextNode0();
                LLVMContext context = LLVMLanguage.INSTANCE.findContext0(findContext);
                final CallTarget[] mainFunction = new CallTarget[]{null};
                if (code.getMimeType().equals(LLVMLanguage.LLVM_IR_MIME_TYPE)) {
                    List<String> resolvedVariables = getAllResolvedGlobalVariables(code);
                    context.setResolvedVariableNames(resolvedVariables);
                    String path = code.getPath();
                    LLVMParserResult parserResult;
                    try {
                        if (path == null) {
                            parserResult = parseString(code, context);
                        } else {
                            parserResult = parseFile(code, context);
                        }
                    } catch (IllegalStateException e) {
                        throw new IOException(e);
                    }
                    mainFunction[0] = parserResult.getMainFunction();
                    handleParserResult(context, parserResult);
                } else if (code.getMimeType().equals(LLVMLanguage.LLVM_BITCODE_MIME_TYPE)) {
                    List<String> resolvedVariables = getAllResolvedGlobalVariables(code);
                    context.setResolvedVariableNames(resolvedVariables);
                    LLVMParserResult parserResult = parseBitcodeFile(code, context);
                    mainFunction[0] = parserResult.getMainFunction();
                    handleParserResult(context, parserResult);
                } else if (code.getMimeType().equals(LLVMLanguage.SULONG_LIBRARY_MIME_TYPE)) {
                    final SulongLibrary library = new SulongLibrary(new File(code.getPath()));
                    List<String> resolvedVariables = new ArrayList<>();
                    List<Source> sourceFiles = new ArrayList<>();
                    library.readContents(dependentLibrary -> {
                        context.addLibraryToNativeLookup(dependentLibrary);
                    }, source -> {
                        sourceFiles.add(source);
                        try {
                            addResolvedGlobalVariables(resolvedVariables, source);
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    });
                    context.setResolvedVariableNames(resolvedVariables);
                    for (Source source : sourceFiles) {
                        LLVMParserResult parserResult;
                        try {
                            parserResult = parseString(source, context);
                        } catch (IOException e) {
{'fraction_non_alphanumeric': 0.08006632713490465, 'fraction_numerical': 0.0013028544356271468, 'mean_word_length': 2.7073545554335894, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5712922', 'n_tokens_mistral': 4434, 'n_tokens_neox': 4207, 'n_words': 1091}