<commit_before>/***************************************************************************
                          ASTCreator.cpp
	      This class works as a framework for the
	      creation of an abstract syntax tree specific
	      for a grammar
                          -------------------
    begin                : Sun Jun 2 2002
    copyright            : (C) 2002 by Manuel Astudillo

 ***************************************************************************/
 /***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License as        *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 ***************************************************************************/

 #include "ASTCreator.h"

// Include the header with YOUR AST node classes

 ASTNode *ASTCreator::createTree (const Symbol &reductionTree) {
	 // If the tree is an empty terminal node return null
     return getASTNode (&reductionTree, NULL);
 }

 ASTNode *ASTCreator::getASTNode (const Symbol *reduction, ASTNode *parent) {

	/*!
	  This method has to be customized for YOUR Abstract Grammar.
	  Base your Abstract Grammar in the Context Free Grammar.
	  Check for nodes that are equivalent in both grammars and convert
	  the nodes that are not equivalent.
	 */

	 vector <ASTNode*> *children= NULL;
	 wstring sym = reduction->symbol;

	 deque <Symbol*> rdcChildren;
	 if (reduction->type == NON_TERMINAL) {
		rdcChildren = ((NonTerminal*) reduction)->children;
	 }

	 /*
	  Next is a colection of if statements that checks for the
	  equivalency between nodes in the reduction tree and in the
	  desired Abstract Syntax Tree.

	  Note as we always pass the latest node as the parent for the children.
	  Having the parent is often usefull when doing the type analysis or
	  interpreting the AST.
	 */

	 /*
	// (Example of a simple rule) Check for Start node
	///////////////////////////////////////////////////

	// Original Rule:
	<Start> ::= begin <ConstList> defs <DefsList> prog <StatementList> end

	// Translated to:
	<Start> ::= <ConstList> <DefsList> <StatementList>

	 if ( sym == L"Start" ) {
		Start *start = new Start ();
        start->init (reduction, parent);

		start->addChild (getASTNode(rdcChildren[1], start));
		start->addChild (getASTNode(rdcChildren[3], start));
		start->addChild (getASTNode(rdcChildren[5], start));
		return start;
	 }

	 // (Example of a List)
	 ////////////////////////

	// Original Rule:
	<StatementList> ::= <Statement> ';' <StatementList>
                    |
	// Translated to:
	<StatementList> ::= <Statement>*

	 if (sym == L"StatementList") {
		StatementList *statementList = new StatementList ();
        statementList->init (reduction, parent);

		if (rdcChildren.size() == 3) {
			statementList->addChild (getASTNode (rdcChildren[0], stmtList));

			children = stmtList->getChildren();
			getASTNodeList (children, rdcChildren[2]->reduction, 1, 3, stmtList);
		}

		return stmtList;
	 }
*/
	 /*
        If the symbol constants are included it is possible to do it in the possible way:

            // <If Statement> ::= if <Expression> then <StatementList> end
            if (sym == RULE_IF_THEN_END_STATEMENT) {
                IfStatement *ifStatement = new IfStatement ();
                ifStatement->init (reduction, parent);

                ifStmt->addChild (getASTNode(rdcChildren[1], ifStmt));
                ifStmt->addChild (getASTNode(rdcChildren[3], ifStmt));

                return ifStmt;
            }

            // <If Statement> ::= if <Expression> then <StatementList> else <StatementList> end
            if ( sym == RULE_IF_THEN_END_ELSE_STATEMENT) {
                IfStatement *ifStatement = new IfStatement ();
                ifStatement->init (reduction, parent);

                ifStmt->addChild (getASTNode(rdcChildren[1], ifStmt));
                ifStmt->addChild (getASTNode(rdcChildren[3], ifStmt));
	            ifStmt->addChild (getASTNode(rdcChildren[5], ifStmt));
                return ifStmt;
            }

     */

	 return searchEquivNode( rdcChildren, parent);
 }

/*!
 If the node has not an equivalent in the Abstract Tree we just search
 for more equivalent nodes in their children. If none found return NULL.
*/
 ASTNode *ASTCreator::searchEquivNode (const deque <Symbol*> &rdcChildren,
									   ASTNode *parent) {
 	 ASTNode *result = NULL;
	 for (unsigned short i=0; i < rdcChildren.size(); i ++) {
		 if (rdcChildren[i]->type == NON_TERMINAL) {
			result = getASTNode(rdcChildren[i], parent);
			if (result != NULL) {
				break;
			}
		 }
	 }
	 return result;
 }

/*!
	 This method is usefull to create nodes in the tree for rules that
	 have the following structure:
	 NonTerminal1 ::= NonTerminalA NonTerminalB ... NonTerminal1

	 (Note that left NonTerminal and the last non-terminal in the rule are the same)
	 /param children vector where the children will be added
	 /param reduction reduction tree where the list resides
	 /param nbrInsert specifies the number of children to insert in the vector.
	  Begining from the left of the rule.
	 /param nbrElements specifies the number of element in the "iterative" production.
	 /param parent Parent node, where the list will be hanging.
 */

 void ASTCreator::getASTNodeList (vector <ASTNode*> *children,
    NonTerminal *reduction, int nbrInsert, int nbrElements, ASTNode *parent) {
	    integer i;
	    ASTNode *ast;
	    deque <Symbol*> rdcChildren = reduction->children;

	    int size = rdcChildren.size();

	    if (size > 0) {
		    if (size < nbrElements) {
			    for (i=0; i < rdcChildren.size(); i++) {
				    if (i < nbrInsert) {
					    // if we have a rule that produces a
					    // terminal symbol, we only get the node for this reduction
					    if (rdcChildren[i]->type == TERMINAL) {
						    ast = getASTNode (reduction, parent);
					    } else {
						    ast = getASTNode (rdcChildren[i], parent);
					    }
					    // Do not insert NULL childs
					    if (ast!=NULL) {
						    children->push_back(ast);
					    }
				    }
			    }
		    } else {

            for (i=0; i < rdcChildren.size()-1; i++) {
				if (i < nbrInsert) {
                    ast = getASTNode (rdcChildren[i], parent);
	                if (ast!=NULL) {
						children->push_back(ast);
					}
				}
			}
            if (rdcChildren[i]->type == NON_TERMINAL) {
		 	    getASTNodeList (children, (NonTerminal*) rdcChildren[i],
		 	    nbrInsert, nbrElements, parent);
            }
		}
	}
}

 /*!
	 This method is usefull to create nodes in the tree for rules that
	 have the following structure:
	 NonTerminal1 ::= NonTerminalA NonTerminalB ... NonTerminal1

	 (Note that left NonTerminal and the last non-terminal in the rule are the same)
	 /param children vector where the children will be added
	 /param iterNode name of the Iterative node
	 /param reduction reduction tree where the list resides
	 /param nbrInsert specifies the number of children to insert in the vector.
	  Begining from the left of the rule.
	 /param nbrElements specifies the number of element in the "iterative" production.
	 /param parent Parent node, where the list will be hanging.
 */
 void ASTCreator::getASTNodeList (vector <ASTNode*> *children, wstring iterNode,
	              NonTerminal *reduction, int nbrInsert, int nbrElements, ASTNode *parent) {
	integer i;
	ASTNode *ast;

	wstring sym = reduction->symbol;

	deque <Symbol*> rdcChildren = reduction->children;
	if (sym == iterNode) {
		int size = rdcChildren.size();
		if (size > 0) {
			if (size < nbrElements) {
				for (i=0; i < rdcChildren.size(); i++) {
					if (i < nbrInsert) {
						// if we have a rule that produces a
						// terminal symbol, we only get the node for this reduction
						if (rdcChildren[i]->type == TERMINAL) {
							ast = getASTNode (reduction,parent);
						} else {
							ast = getASTNode (rdcChildren[i],parent);
						}
						// Do not insert NULL childs
						if (ast!=NULL) {
							children->push_back(ast);
						}
					}
				}
			} else {
				for (i=0; i < rdcChildren.size()-1; i++) {
					if (i < nbrInsert) {
						// Do not insert NULL childs
                        if (rdcChildren[i]->type == NON_TERMINAL) {
						    ast = getASTNode (rdcChildren[i], parent);
                        } else {
                            ast = NULL;
                        }

                        if (ast!=NULL) {
							children->push_back(ast);
						}
					}
				}
                if (rdcChildren[i]->type == NON_TERMINAL) {
		   		    getASTNodeList (children, iterNode, (NonTerminal*) rdcChildren[i],
                                    nbrInsert, nbrElements, parent);
                }
			}
		}

	} else {
		// If this is not the iterNode then we just push this node as a child.
		ast = getASTNode (reduction, parent);
		children->push_back(ast);
	}
}

<commit_msg>Removed a warning.<commit_after>/***************************************************************************
                          ASTCreator.cpp
	      This class works as a framework for the
	      creation of an abstract syntax tree specific
	      for a grammar
                          -------------------
    begin                : Sun Jun 2 2002
    copyright            : (C) 2002 by Manuel Astudillo

 ***************************************************************************/
 /***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License as        *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 ***************************************************************************/

 #include "ASTCreator.h"

// Include the header with YOUR AST node classes

 ASTNode *ASTCreator::createTree (const Symbol &reductionTree) {
	 // If the tree is an empty terminal node return null
     return getASTNode (&reductionTree, NULL);
 }

 ASTNode *ASTCreator::getASTNode (const Symbol *reduction, ASTNode *parent) {

	/*!
	  This method has to be customized for YOUR Abstract Grammar.
	  Base your Abstract Grammar in the Context Free Grammar.
	  Check for nodes that are equivalent in both grammars and convert
	  the nodes that are not equivalent.
	 */

	 //vector <ASTNode*> *children= NULL;
	 wstring sym = reduction->symbol;

	 deque <Symbol*> rdcChildren;
	 if (reduction->type == NON_TERMINAL) {
		rdcChildren = ((NonTerminal*) reduction)->children;
	 }

	 /*
	  Next is a colection of if statements that checks for the
	  equivalency between nodes in the reduction tree and in the
	  desired Abstract Syntax Tree.

	  Note as we always pass the latest node as the parent for the children.
	  Having the parent is often usefull when doing the type analysis or
	  interpreting the AST.
	 */

	 /*
	// (Example of a simple rule) Check for Start node
	///////////////////////////////////////////////////

	// Original Rule:
	<Start> ::= begin <ConstList> defs <DefsList> prog <StatementList> end

	// Translated to:
	<Start> ::= <ConstList> <DefsList> <StatementList>

	 if ( sym == L"Start" ) {
		Start *start = new Start ();
        start->init (reduction, parent);

		start->addChild (getASTNode(rdcChildren[1], start));
		start->addChild (getASTNode(rdcChildren[3], start));
		start->addChild (getASTNode(rdcChildren[5], start));
		return start;
	 }

	 // (Example of a List)
	 ////////////////////////

	// Original Rule:
	<StatementList> ::= <Statement> ';' <StatementList>
                    |
	// Translated to:
	<StatementList> ::= <Statement>*

	 if (sym == L"StatementList") {
		StatementList *statementList = new StatementList ();
        statementList->init (reduction, parent);

		if (rdcChildren.size() == 3) {
			statementList->addChild (getASTNode (rdcChildren[0], stmtList));

			children = stmtList->getChildren();
			getASTNodeList (children, rdcChildren[2]->reduction, 1, 3, stmtList);
		}

		return stmtList;
	 }
*/
	 /*
        If the symbol constants are included it is possible to do it in the possible way:

            // <If Statement> ::= if <Expression> then <StatementList> end
            if (sym == RULE_IF_THEN_END_STATEMENT) {
                IfStatement *ifStatement = new IfStatement ();
                ifStatement->init (reduction, parent);

                ifStmt->addChild (getASTNode(rdcChildren[1], ifStmt));
                ifStmt->addChild (getASTNode(rdcChildren[3], ifStmt));

                return ifStmt;
            }

            // <If Statement> ::= if <Expression> then <StatementList> else <StatementList> end
            if ( sym == RULE_IF_THEN_END_ELSE_STATEMENT) {
                IfStatement *ifStatement = new IfStatement ();
                ifStatement->init (reduction, parent);

                ifStmt->addChild (getASTNode(rdcChildren[1], ifStmt));
                ifStmt->addChild (getASTNode(rdcChildren[3], ifStmt));
	            ifStmt->addChild (getASTNode(rdcChildren[5], ifStmt));
                return ifStmt;
            }

     */

	 return searchEquivNode( rdcChildren, parent);
 }

/*!
 If the node has not an equivalent in the Abstract Tree we just search
 for more equivalent nodes in their children. If none found return NULL.
*/
 ASTNode *ASTCreator::searchEquivNode (const deque <Symbol*> &rdcChildren,
									   ASTNode *parent) {
 	 ASTNode *result = NULL;
	 for (unsigned short i=0; i < rdcChildren.size(); i ++) {
		 if (rdcChildren[i]->type == NON_TERMINAL) {
			result = getASTNode(rdcChildren[i], parent);
			if (result != NULL) {
				break;
			}
		 }
	 }
	 return result;
 }

/*!
	 This method is usefull to create nodes in the tree for rules that
	 have the following structure:
	 NonTerminal1 ::= NonTerminalA NonTerminalB ... NonTerminal1

	 (Note that left NonTerminal and the last non-terminal in the rule are the same)
	 /param children vector where the children will be added
	 /param reduction reduction tree where the list resides
	 /param nbrInsert specifies the number of children to insert in the vector.
	  Begining from the left of the rule.
	 /param nbrElements specifies the number of element in the "iterative" production.
	 /param parent Parent node, where the list will be hanging.
 */

 void ASTCreator::getASTNodeList (vector <ASTNode*> *children,
    NonTerminal *reduction, int nbrInsert, int nbrElements, ASTNode *parent) {
	    integer i;
	    ASTNode *ast;
	    deque <Symbol*> rdcChildren = reduction->children;

	    int size = rdcChildren.size();

	    if (size > 0) {
		    if (size < nbrElements) {
			    for (i=0; i < rdcChildren.size(); i++) {
				    if (i < nbrInsert) {
					    // if we have a rule that produces a
					    // terminal symbol, we only get the node for this reduction
					    if (rdcChildren[i]->type == TERMINAL) {
						    ast = getASTNode (reduction, parent);
					    } else {
						    ast = getASTNode (rdcChildren[i], parent);
					    }
					    // Do not insert NULL childs
					    if (ast!=NULL) {
						    children->push_back(ast);
					    }
				    }
			    }
		    } else {

            for (i=0; i < rdcChildren.size()-1; i++) {
				if (i < nbrInsert) {
                    ast = getASTNode (rdcChildren[i], parent);
	                if (ast!=NULL) {
						children->push_back(ast);
					}
				}
			}
            if (rdcChildren[i]->type == NON_TERMINAL) {
		 	    getASTNodeList (children, (NonTerminal*) rdcChildren[i],
		 	    nbrInsert, nbrElements, parent);
            }
		}
	}
}

 /*!
	 This method is usefull to create nodes in the tree for rules that
	 have the following structure:
	 NonTerminal1 ::= NonTerminalA NonTerminalB ... NonTerminal1

	 (Note that left NonTerminal and the last non-terminal in the rule are the same)
	 /param children vector where the children will be added
	 /param iterNode name of the Iterative node
	 /param reduction reduction tree where the list resides
	 /param nbrInsert specifies the number of children to insert in the vector.
	  Begining from the left of the rule.
	 /param nbrElements specifies the number of element in the "iterative" production.
	 /param parent Parent node, where the list will be hanging.
 */
 void ASTCreator::getASTNodeList (vector <ASTNode*> *children, wstring iterNode,
	              NonTerminal *reduction, int nbrInsert, int nbrElements, ASTNode *parent) {
	integer i;
	ASTNode *ast;

	wstring sym = reduction->symbol;

	deque <Symbol*> rdcChildren = reduction->children;
	if (sym == iterNode) {
		int size = rdcChildren.size();
		if (size > 0) {
			if (size < nbrElements) {
				for (i=0; i < rdcChildren.size(); i++) {
					if (i < nbrInsert) {
						// if we have a rule that produces a
						// terminal symbol, we only get the node for this reduction
						if (rdcChildren[i]->type == TERMINAL) {
							ast = getASTNode (reduction,parent);
						} else {
							ast = getASTNode (rdcChildren[i],parent);
						}
						// Do not insert NULL childs
						if (ast!=NULL) {
							children->push_back(ast);
						}
					}
				}
			} else {
				for (i=0; i < rdcChildren.size()-1; i++) {
					if (i < nbrInsert) {
						// Do not insert NULL childs
                        if (rdcChildren[i]->type == NON_TERMINAL) {
						    ast = getASTNode (rdcChildren[i], parent);
                        } else {
                            ast = NULL;
                        }

                        if (ast!=NULL) {
							children->push_back(ast);
						}
					}
				}
                if (rdcChildren[i]->type == NON_TERMINAL) {
		   		    getASTNodeList (children, iterNode, (NonTerminal*) rdcChildren[i],
                                    nbrInsert, nbrElements, parent);
                }
			}
		}

	} else {
		// If this is not the iterNode then we just push this node as a child.
		ast = getASTNode (reduction, parent);
		children->push_back(ast);
	}
}

<|endoftext|>


<commit_before>#include "Srch2Android.h"
#include "util/Logger.h"

using namespace srch2::sdk;
using srch2::util::Logger;

#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void Java_com_srch2_mobile_ndksearch_Srch2Lib_setLoggerFile(
		JNIEnv* env, jobject javaThis, jstring logfile) {
	const char *nativeStringLogFile = env->GetStringUTFChars(logfile, NULL);
	FILE* fpLog = fopen(nativeStringLogFile, "a");
	Logger::setOutputFile(fpLog);
	env->ReleaseStringUTFChars(logfile, nativeStringLogFile);
}
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jlong Java_com_srch2_mobile_ndksearch_Srch2Lib_createIndex(
		JNIEnv* env, jobject javaThis, jstring testFile, jstring indexDir,
		jint lineLimit, jboolean isGeo) {
	Logger::console("createIndex");
	const char *nativeStringDataFile = env->GetStringUTFChars(testFile, NULL);
	const char *nativeStringIndexPath = env->GetStringUTFChars(indexDir, NULL);

	string strIndexPath(nativeStringIndexPath);
	string strTestFile(nativeStringDataFile);

	srch2::instantsearch::TermType termType = PREFIX;

	Logger::console("Read data from %s", strTestFile.c_str());
	Logger::console("Save index to %s", strIndexPath.c_str());

	Indexer* indexer = createIndex(strTestFile, strIndexPath, lineLimit, isGeo);

	env->ReleaseStringUTFChars(testFile, nativeStringDataFile);
	env->ReleaseStringUTFChars(indexDir, nativeStringIndexPath);
	long ptr = (long) indexer;
	Logger::console("createIndex done");
	return ptr;
}
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jlong Java_com_srch2_mobile_ndksearch_Srch2Lib_loadIndex(JNIEnv* env,
		jobject javaThis, jstring indexDir) {
	Logger::console("loadIndex");
	const char *nativeStringIndexPath = env->GetStringUTFChars(indexDir, NULL);
	string strIndexDir(nativeStringIndexPath);

	Logger::console("Load index from %s", strIndexDir.c_str());
	Indexer* indexer = loadIndex(strIndexDir);
	env->ReleaseStringUTFChars(indexDir, nativeStringIndexPath);
	long ptr = (long) indexer;
	Logger::console("loadIndex done");
	return ptr;
}
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void Java_com_srch2_mobile_ndksearch_Srch2Lib_saveIndex(
		jlong ptr) {
	Logger::console("saveIndex");
	Indexer* index = (Indexer*)ptr;
	saveIndex(index);
	Logger::console("saveIndex done");
}
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void Java_com_srch2_mobile_ndksearch_Srch2Lib_query(JNIEnv* env,
		jobject javaThis, jlong index, jstring queryStr, jboolean isGeo) {

}
#ifdef __cplusplus
}
#endif
<commit_msg>make sdk work on Android<commit_after>#include "Srch2Android.h"
#include "util/Logger.h"

using namespace srch2::sdk;
using srch2::util::Logger;

#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void Java_com_srch2_mobile_ndksearch_Srch2Lib_setLoggerFile(
		JNIEnv* env, jobject javaThis, jstring logfile) {
	const char *nativeStringLogFile = env->GetStringUTFChars(logfile, NULL);
	FILE* fpLog = fopen(nativeStringLogFile, "a");
	Logger::setOutputFile(fpLog);
	env->ReleaseStringUTFChars(logfile, nativeStringLogFile);
}
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jlong Java_com_srch2_mobile_ndksearch_Srch2Lib_createIndex(
		JNIEnv* env, jobject javaThis, jstring testFile, jstring indexDir,
		jint lineLimit, jboolean isGeo) {
	Logger::console("createIndex");
	const char *nativeStringDataFile = env->GetStringUTFChars(testFile, NULL);
	const char *nativeStringIndexPath = env->GetStringUTFChars(indexDir, NULL);

	string strIndexPath(nativeStringIndexPath);
	string strTestFile(nativeStringDataFile);

	srch2::instantsearch::TermType termType = PREFIX;

	Logger::console("Read data from %s", strTestFile.c_str());
	Logger::console("Save index to %s", strIndexPath.c_str());

	Indexer* indexer = createIndex(strTestFile, strIndexPath, lineLimit, isGeo);

	env->ReleaseStringUTFChars(testFile, nativeStringDataFile);
	env->ReleaseStringUTFChars(indexDir, nativeStringIndexPath);
	long ptr = (long) indexer;
	Logger::console("createIndex done");
	return ptr;
}
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jlong Java_com_srch2_mobile_ndksearch_Srch2Lib_loadIndex(JNIEnv* env,
		jobject javaThis, jstring indexDir) {
	Logger::console("loadIndex");
	const char *nativeStringIndexPath = env->GetStringUTFChars(indexDir, NULL);
	string strIndexDir(nativeStringIndexPath);

	Logger::console("Load index from %s", strIndexDir.c_str());
	Indexer* indexer = loadIndex(strIndexDir);
	env->ReleaseStringUTFChars(indexDir, nativeStringIndexPath);
	long ptr = (long) indexer;
	Logger::console("loadIndex done");
	return ptr;
}
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void Java_com_srch2_mobile_ndksearch_Srch2Lib_saveIndex(JNIEnv* env,
		jobject javaThis, jlong ptr) {
	Logger::console("saveIndex");
	Indexer* index = (Indexer*) ptr;
	saveIndex(index);
	Logger::console("saveIndex done");
}
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void Java_com_srch2_mobile_ndksearch_Srch2Lib_query(JNIEnv* env,
		jobject javaThis, jlong index, jstring queryStr, jboolean isGeo) {

}
#ifdef __cplusplus
}
#endif

//TODO: delete the index
<|endoftext|>


<commit_before>/*
 *  Copyright 2008-2013 NVIDIA Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/*! \file distance.h
 *  \brief Device implementations for distance.
 */

#pragma once

#include <thrust/detail/config.h>
#include <thrust/detail/get_iterator_value.h>
#include <thrust/extrema.h>
#include <thrust/functional.h>
#include <thrust/pair.h>
#include <thrust/reduce.h>
#include <thrust/transform_reduce.h>

#include <thrust/iterator/iterator_traits.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/iterator/zip_iterator.h>

namespace thrust
{
namespace system
{
namespace detail
{
namespace generic
{
namespace detail
{

//////////////
// Functors //
//////////////
//

// return the smaller/larger element making sure to prefer the
// first occurance of the minimum/maximum element
template <typename InputType, typename IndexType, typename BinaryPredicate>
struct min_element_reduction
{
  BinaryPredicate comp;

  __host__ __device__
  min_element_reduction(BinaryPredicate comp) : comp(comp){}

  __host__ __device__
  thrust::tuple<InputType, IndexType>
  operator()(const thrust::tuple<InputType, IndexType>& lhs,
             const thrust::tuple<InputType, IndexType>& rhs )
  {
    if(comp(thrust::get<0>(lhs), thrust::get<0>(rhs)))
      return lhs;
    if(comp(thrust::get<0>(rhs), thrust::get<0>(lhs)))
      return rhs;

    // values are equivalent, prefer value with smaller index
    if(thrust::get<1>(lhs) < thrust::get<1>(rhs))
      return lhs;
    else
      return rhs;
  } // end operator()()
}; // end min_element_reduction

template <typename InputType, typename IndexType, typename BinaryPredicate>
struct max_element_reduction
{
  BinaryPredicate comp;

  __host__ __device__
  max_element_reduction(BinaryPredicate comp) : comp(comp){}

  __host__ __device__
  thrust::tuple<InputType, IndexType>
  operator()(const thrust::tuple<InputType, IndexType>& lhs,
             const thrust::tuple<InputType, IndexType>& rhs )
  {
    if(comp(thrust::get<0>(lhs), thrust::get<0>(rhs)))
      return rhs;
    if(comp(thrust::get<0>(rhs), thrust::get<0>(lhs)))
      return lhs;

    // values are equivalent, prefer value with smaller index
    if(thrust::get<1>(lhs) < thrust::get<1>(rhs))
      return lhs;
    else
      return rhs;
  } // end operator()()
}; // end max_element_reduction

// return the smaller & larger element making sure to prefer the
// first occurance of the minimum/maximum element
template <typename InputType, typename IndexType, typename BinaryPredicate>
struct minmax_element_reduction
{
  BinaryPredicate comp;

  __host__ __device__
  minmax_element_reduction(BinaryPredicate comp) : comp(comp){}

  __host__ __device__
  thrust::tuple< thrust::tuple<InputType,IndexType>, thrust::tuple<InputType,IndexType> >
  operator()(const thrust::tuple< thrust::tuple<InputType,IndexType>, thrust::tuple<InputType,IndexType> >& lhs,
             const thrust::tuple< thrust::tuple<InputType,IndexType>, thrust::tuple<InputType,IndexType> >& rhs )
  {

    return thrust::make_tuple(min_element_reduction<InputType, IndexType, BinaryPredicate>(comp)(thrust::get<0>(lhs), thrust::get<0>(rhs)),
                              max_element_reduction<InputType, IndexType, BinaryPredicate>(comp)(thrust::get<1>(lhs), thrust::get<1>(rhs)));
  } // end operator()()
}; // end minmax_element_reduction

template <typename InputType, typename IndexType>
struct duplicate_tuple
{
  __host__ __device__
  thrust::tuple< thrust::tuple<InputType,IndexType>, thrust::tuple<InputType,IndexType> >
  operator()(const thrust::tuple<InputType,IndexType>& t)
  {
    return thrust::make_tuple(t, t);
  }
}; // end duplicate_tuple

} // end namespace detail

template <typename DerivedPolicy, typename ForwardIterator>
__host__ __device__
ForwardIterator min_element(thrust::execution_policy<DerivedPolicy> &exec,
                            ForwardIterator first,
                            ForwardIterator last)
{
  typedef typename thrust::iterator_value<ForwardIterator>::type value_type;

  return thrust::min_element(exec, first, last, thrust::less<value_type>());
} // end min_element()

template <typename DerivedPolicy, typename ForwardIterator, typename BinaryPredicate>
__host__ __device__
ForwardIterator min_element(thrust::execution_policy<DerivedPolicy> &exec,
                            ForwardIterator first,
                            ForwardIterator last,
                            BinaryPredicate comp)
{
  if (first == last)
    return last;

  typedef typename thrust::iterator_traits<ForwardIterator>::value_type      InputType;
  typedef typename thrust::iterator_traits<ForwardIterator>::difference_type IndexType;

  thrust::tuple<InputType, IndexType> result =
    thrust::reduce
      (exec,
       thrust::make_zip_iterator(thrust::make_tuple(first, thrust::counting_iterator<IndexType>(0))),
       thrust::make_zip_iterator(thrust::make_tuple(first, thrust::counting_iterator<IndexType>(0))) + (last - first),
       thrust::tuple<InputType, IndexType>(get_iterator_value(derived_cast(exec), first), 0),
       detail::min_element_reduction<InputType, IndexType, BinaryPredicate>(comp));

  return first + thrust::get<1>(result);
} // end min_element()

template <typename DerivedPolicy, typename ForwardIterator>
__host__ __device__
ForwardIterator max_element(thrust::execution_policy<DerivedPolicy> &exec,
                            ForwardIterator first,
                            ForwardIterator last)
{
  typedef typename thrust::iterator_value<ForwardIterator>::type value_type;

  return thrust::max_element(exec, first, last, thrust::less<value_type>());
} // end max_element()

template <typename DerivedPolicy, typename ForwardIterator, typename BinaryPredicate>
__host__ __device__
ForwardIterator max_element(thrust::execution_policy<DerivedPolicy> &exec,
                            ForwardIterator first,
                            ForwardIterator last,
                            BinaryPredicate comp)
{
  if (first == last)
    return last;

  typedef typename thrust::iterator_traits<ForwardIterator>::value_type      InputType;
  typedef typename thrust::iterator_traits<ForwardIterator>::difference_type IndexType;

  thrust::tuple<InputType, IndexType> result =
    thrust::reduce
      (exec,
       thrust::make_zip_iterator(thrust::make_tuple(first, thrust::counting_iterator<IndexType>(0))),
       thrust::make_zip_iterator(thrust::make_tuple(first, thrust::counting_iterator<IndexType>(0))) + (last - first),
       thrust::tuple<InputType, IndexType>(get_iterator_value(derived_cast(exec),first), 0),
       detail::max_element_reduction<InputType, IndexType, BinaryPredicate>(comp));

  return first + thrust::get<1>(result);
} // end max_element()

template <typename DerivedPolicy, typename ForwardIterator>
__host__ __device__
thrust::pair<ForwardIterator,ForwardIterator> minmax_element(thrust::execution_policy<DerivedPolicy> &exec,
                                                             ForwardIterator first,
                                                             ForwardIterator last)
{
  typedef typename thrust::iterator_value<ForwardIterator>::type value_type;

  return thrust::minmax_element(exec, first, last, thrust::less<value_type>());
} // end minmax_element()

template <typename DerivedPolicy, typename ForwardIterator, typename BinaryPredicate>
__host__ __device__
thrust::pair<ForwardIterator,ForwardIterator> minmax_element(thrust::execution_policy<DerivedPolicy> &exec,
                                                             ForwardIterator first,
                                                             ForwardIterator last,
                                                             BinaryPredicate comp)
{
  if (first == last)
    return thrust::make_pair(last, last);

  typedef typename thrust::iterator_traits<ForwardIterator>::value_type      InputType;
  typedef typename thrust::iterator_traits<ForwardIterator>::difference_type IndexType;

  thrust::tuple< thrust::tuple<InputType,IndexType>, thrust::tuple<InputType,IndexType> > result =
    thrust::transform_reduce
      (exec,
       thrust::make_zip_iterator(thrust::make_tuple(first, thrust::counting_iterator<IndexType>(0))),
       thrust::make_zip_iterator(thrust::make_tuple(first, thrust::counting_iterator<IndexType>(0))) + (last - first),
       detail::duplicate_tuple<InputType, IndexType>(),
       detail::duplicate_tuple<InputType, IndexType>()(
         thrust::tuple<InputType, IndexType>(get_iterator_value(derived_cast(exec),first), 0)),
       detail::minmax_element_reduction<InputType, IndexType, BinaryPredicate>(comp));

  return thrust::make_pair(first + thrust::get<1>(thrust::get<0>(result)), first + thrust::get<1>(thrust::get<1>(result)));
} // end minmax_element()

} // end namespace generic
} // end namespace detail
} // end namespace system
} // end namespace thrust

<commit_msg>invoke get_iterator_value via thrust::detail::get_iterator_value<commit_after>/*
 *  Copyright 2008-2013 NVIDIA Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/*! \file distance.h
 *  \brief Device implementations for distance.
 */

#pragma once

#include <thrust/detail/config.h>
#include <thrust/detail/get_iterator_value.h>
#include <thrust/extrema.h>
#include <thrust/functional.h>
#include <thrust/pair.h>
#include <thrust/reduce.h>
#include <thrust/transform_reduce.h>

#include <thrust/iterator/iterator_traits.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/iterator/zip_iterator.h>

namespace thrust
{
namespace system
{
namespace detail
{
namespace generic
{
namespace detail
{

//////////////
// Functors //
//////////////
//

// return the smaller/larger element making sure to prefer the
// first occurance of the minimum/maximum element
template <typename InputType, typename IndexType, typename BinaryPredicate>
struct min_element_reduction
{
  BinaryPredicate comp;

  __host__ __device__
  min_element_reduction(BinaryPredicate comp) : comp(comp){}

  __host__ __device__
  thrust::tuple<InputType, IndexType>
  operator()(const thrust::tuple<InputType, IndexType>& lhs,
             const thrust::tuple<InputType, IndexType>& rhs )
  {
    if(comp(thrust::get<0>(lhs), thrust::get<0>(rhs)))
      return lhs;
    if(comp(thrust::get<0>(rhs), thrust::get<0>(lhs)))
      return rhs;

    // values are equivalent, prefer value with smaller index
    if(thrust::get<1>(lhs) < thrust::get<1>(rhs))
      return lhs;
    else
      return rhs;
  } // end operator()()
}; // end min_element_reduction

template <typename InputType, typename IndexType, typename BinaryPredicate>
struct max_element_reduction
{
  BinaryPredicate comp;

  __host__ __device__
  max_element_reduction(BinaryPredicate comp) : comp(comp){}

  __host__ __device__
  thrust::tuple<InputType, IndexType>
  operator()(const thrust::tuple<InputType, IndexType>& lhs,
             const thrust::tuple<InputType, IndexType>& rhs )
  {
    if(comp(thrust::get<0>(lhs), thrust::get<0>(rhs)))
      return rhs;
    if(comp(thrust::get<0>(rhs), thrust::get<0>(lhs)))
      return lhs;

    // values are equivalent, prefer value with smaller index
    if(thrust::get<1>(lhs) < thrust::get<1>(rhs))
      return lhs;
    else
      return rhs;
  } // end operator()()
}; // end max_element_reduction

// return the smaller & larger element making sure to prefer the
// first occurance of the minimum/maximum element
template <typename InputType, typename IndexType, typename BinaryPredicate>
struct minmax_element_reduction
{
  BinaryPredicate comp;

  __host__ __device__
  minmax_element_reduction(BinaryPredicate comp) : comp(comp){}

  __host__ __device__
  thrust::tuple< thrust::tuple<InputType,IndexType>, thrust::tuple<InputType,IndexType> >
  operator()(const thrust::tuple< thrust::tuple<InputType,IndexType>, thrust::tuple<InputType,IndexType> >& lhs,
             const thrust::tuple< thrust::tuple<InputType,IndexType>, thrust::tuple<InputType,IndexType> >& rhs )
  {

    return thrust::make_tuple(min_element_reduction<InputType, IndexType, BinaryPredicate>(comp)(thrust::get<0>(lhs), thrust::get<0>(rhs)),
                              max_element_reduction<InputType, IndexType, BinaryPredicate>(comp)(thrust::get<1>(lhs), thrust::get<1>(rhs)));
  } // end operator()()
}; // end minmax_element_reduction

template <typename InputType, typename IndexType>
struct duplicate_tuple
{
  __host__ __device__
  thrust::tuple< thrust::tuple<InputType,IndexType>, thrust::tuple<InputType,IndexType> >
  operator()(const thrust::tuple<InputType,IndexType>& t)
  {
    return thrust::make_tuple(t, t);
  }
}; // end duplicate_tuple

} // end namespace detail

template <typename DerivedPolicy, typename ForwardIterator>
__host__ __device__
ForwardIterator min_element(thrust::execution_policy<DerivedPolicy> &exec,
                            ForwardIterator first,
                            ForwardIterator last)
{
  typedef typename thrust::iterator_value<ForwardIterator>::type value_type;

  return thrust::min_element(exec, first, last, thrust::less<value_type>());
} // end min_element()

template <typename DerivedPolicy, typename ForwardIterator, typename BinaryPredicate>
__host__ __device__
ForwardIterator min_element(thrust::execution_policy<DerivedPolicy> &exec,
                            ForwardIterator first,
                            ForwardIterator last,
                            BinaryPredicate comp)
{
  if (first == last)
    return last;

  typedef typename thrust::iterator_traits<ForwardIterator>::value_type      InputType;
  typedef typename thrust::iterator_traits<ForwardIterator>::difference_type IndexType;

  thrust::tuple<InputType, IndexType> result =
    thrust::reduce
      (exec,
       thrust::make_zip_iterator(thrust::make_tuple(first, thrust::counting_iterator<IndexType>(0))),
       thrust::make_zip_iterator(thrust::make_tuple(first, thrust::counting_iterator<IndexType>(0))) + (last - first),
       thrust::tuple<InputType, IndexType>(thrust::detail::get_iterator_value(derived_cast(exec), first), 0),
       detail::min_element_reduction<InputType, IndexType, BinaryPredicate>(comp));

  return first + thrust::get<1>(result);
} // end min_element()

template <typename DerivedPolicy, typename ForwardIterator>
__host__ __device__
ForwardIterator max_element(thrust::execution_policy<DerivedPolicy> &exec,
                            ForwardIterator first,
                            ForwardIterator last)
{
  typedef typename thrust::iterator_value<ForwardIterator>::type value_type;

  return thrust::max_element(exec, first, last, thrust::less<value_type>());
} // end max_element()

template <typename DerivedPolicy, typename ForwardIterator, typename BinaryPredicate>
__host__ __device__
ForwardIterator max_element(thrust::execution_policy<DerivedPolicy> &exec,
                            ForwardIterator first,
                            ForwardIterator last,
                            BinaryPredicate comp)
{
  if (first == last)
    return last;

  typedef typename thrust::iterator_traits<ForwardIterator>::value_type      InputType;
  typedef typename thrust::iterator_traits<ForwardIterator>::difference_type IndexType;

  thrust::tuple<InputType, IndexType> result =
    thrust::reduce
      (exec,
       thrust::make_zip_iterator(thrust::make_tuple(first, thrust::counting_iterator<IndexType>(0))),
       thrust::make_zip_iterator(thrust::make_tuple(first, thrust::counting_iterator<IndexType>(0))) + (last - first),
       thrust::tuple<InputType, IndexType>(thrust::detail::get_iterator_value(derived_cast(exec),first), 0),
       detail::max_element_reduction<InputType, IndexType, BinaryPredicate>(comp));

  return first + thrust::get<1>(result);
} // end max_element()

template <typename DerivedPolicy, typename ForwardIterator>
__host__ __device__
thrust::pair<ForwardIterator,ForwardIterator> minmax_element(thrust::execution_policy<DerivedPolicy> &exec,
                                                             ForwardIterator first,
                                                             ForwardIterator last)
{
  typedef typename thrust::iterator_value<ForwardIterator>::type value_type;

  return thrust::minmax_element(exec, first, last, thrust::less<value_type>());
} // end minmax_element()

template <typename DerivedPolicy, typename ForwardIterator, typename BinaryPredicate>
__host__ __device__
thrust::pair<ForwardIterator,ForwardIterator> minmax_element(thrust::execution_policy<DerivedPolicy> &exec,
                                                             ForwardIterator first,
                                                             ForwardIterator last,
                                                             BinaryPredicate comp)
{
  if (first == last)
    return thrust::make_pair(last, last);

  typedef typename thrust::iterator_traits<ForwardIterator>::value_type      InputType;
  typedef typename thrust::iterator_traits<ForwardIterator>::difference_type IndexType;

  thrust::tuple< thrust::tuple<InputType,IndexType>, thrust::tuple<InputType,IndexType> > result =
    thrust::transform_reduce
      (exec,
       thrust::make_zip_iterator(thrust::make_tuple(first, thrust::counting_iterator<IndexType>(0))),
       thrust::make_zip_iterator(thrust::make_tuple(first, thrust::counting_iterator<IndexType>(0))) + (last - first),
       detail::duplicate_tuple<InputType, IndexType>(),
       detail::duplicate_tuple<InputType, IndexType>()(
         thrust::tuple<InputType, IndexType>(thrust::detail::get_iterator_value(derived_cast(exec),first), 0)),
       detail::minmax_element_reduction<InputType, IndexType, BinaryPredicate>(comp));

  return thrust::make_pair(first + thrust::get<1>(thrust::get<0>(result)), first + thrust::get<1>(thrust::get<1>(result)));
} // end minmax_element()

} // end namespace generic
} // end namespace detail
} // end namespace system
} // end namespace thrust

<|endoftext|>


<commit_before>//===------------------------- cxa_exception.cpp --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//
//  This file implements the "Exception Handling APIs"
//  http://mentorembedded.github.io/cxx-abi/abi-eh.html
//
//===----------------------------------------------------------------------===//

// Support functions for the no-exceptions libc++ library

#include "config.h"
#include "cxxabi.h"

#include <exception>        // for std::terminate
#include "cxa_exception.hpp"
#include "cxa_handlers.hpp"

namespace __cxxabiv1 {

extern "C" {

void
__cxa_increment_exception_refcount(void *thrown_object) throw() {
    if (thrown_object != nullptr)
        std::terminate();
}

void
__cxa_decrement_exception_refcount(void *thrown_object) throw() {
    if (thrown_object != nullptr)
      std::terminate();
}

void *__cxa_current_primary_exception() throw() { return nullptr; }

void
__cxa_rethrow_primary_exception(void* thrown_object) {
    if (thrown_object != nullptr)
      std::terminate();
}

bool
__cxa_uncaught_exception() throw() { return false; }

unsigned int
__cxa_uncaught_exceptions() throw() { return 0; }

}  // extern "C"

}  // abi
<commit_msg>[libc++abi] Remove missed use of config.h<commit_after>//===------------------------- cxa_exception.cpp --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//
//  This file implements the "Exception Handling APIs"
//  http://mentorembedded.github.io/cxx-abi/abi-eh.html
//
//===----------------------------------------------------------------------===//

// Support functions for the no-exceptions libc++ library

#include "cxxabi.h"

#include <exception>        // for std::terminate
#include "cxa_exception.hpp"
#include "cxa_handlers.hpp"

namespace __cxxabiv1 {

extern "C" {

void
__cxa_increment_exception_refcount(void *thrown_object) throw() {
    if (thrown_object != nullptr)
        std::terminate();
}

void
__cxa_decrement_exception_refcount(void *thrown_object) throw() {
    if (thrown_object != nullptr)
      std::terminate();
}

void *__cxa_current_primary_exception() throw() { return nullptr; }

void
__cxa_rethrow_primary_exception(void* thrown_object) {
    if (thrown_object != nullptr)
      std::terminate();
}

bool
__cxa_uncaught_exception() throw() { return false; }

unsigned int
__cxa_uncaught_exceptions() throw() { return 0; }

}  // extern "C"

}  // abi
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * 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.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software 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 OWNER 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.
//
//////////////////////////////////////////////////////////////////////////

#include "IECore/ObjectReader.h"
#include "IECore/FileIndexedIO.h"
#include "IECore/FileNameParameter.h"

#ifdef IECORE_WITH_SQLITE
    #include "IECore/SQLiteIndexedIO.h"
#endif // IECORE_WITH_SQLITE

#include <cassert>

using namespace IECore;
using namespace boost;

const Reader::ReaderDescription<ObjectReader> ObjectReader::g_readerDescription( "cob" );

ObjectReader::ObjectReader() :
		Reader( "ObjectReader", "Reads instances of a single Object from a file with a .cob extension" )
{
}

ObjectReader::ObjectReader( const std::string &fileName ) :
		Reader( "ObjectReader", "Reads instances of a single Object from a file with a .cob extension" )
{
	m_fileNameParameter->setTypedValue( fileName );
}

ObjectReader::~ObjectReader()
{
}

bool ObjectReader::canRead( const std::string &fileName )
{
	// Ideally we'd like to look inside the file and see if it contains one object only
	// but for efficiency purposes we'll just try and open the file as a database and
	// see if that succeeds. We could possibly query the structure of the database and
	// check that it matches the signature of a one-object cache without needing to
	// actually read the data.
	IndexedIOInterfacePtr io = 0;

	try
	{
		io = open(fileName);
		return true;
	}
	catch (Exception &e)
	{
		return false;
	}

	return io != 0;
}

ObjectPtr ObjectReader::doOperation( ConstCompoundObjectPtr operands )
{
	IndexedIOInterfacePtr io = open(fileName());
	return Object::load( io );
}

CompoundDataPtr ObjectReader::readHeader() const
{
	IndexedIOInterfacePtr io = open(fileName());
	io->chdir( "header" );
	return runTimeCast<CompoundData>( Object::load( io ) );
}

IndexedIOInterfacePtr ObjectReader::open( const std::string &fileName )
{
	IndexedIOInterfacePtr iface;

#ifdef IECORE_WITH_SQLITE
	try
	{
		iface = new FileIndexedIO( fileName, "/", IndexedIO::Shared | IndexedIO::Read );
	}
	catch (...)
	{
		iface = new SQLiteIndexedIO( fileName, "/", IndexedIO::Shared | IndexedIO::Read );
	}
#else
	iface = new FileIndexedIO( fileName, "/", IndexedIO::Shared | IndexedIO::Read );
#endif

	return iface;
}
<commit_msg>Now calling optimised FileIndexedIO::canRead<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * 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.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software 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 OWNER 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.
//
//////////////////////////////////////////////////////////////////////////

#include "IECore/ObjectReader.h"
#include "IECore/FileIndexedIO.h"
#include "IECore/FileNameParameter.h"

#ifdef IECORE_WITH_SQLITE
    #include "IECore/SQLiteIndexedIO.h"
#endif // IECORE_WITH_SQLITE

#include <cassert>

using namespace IECore;
using namespace boost;

const Reader::ReaderDescription<ObjectReader> ObjectReader::g_readerDescription( "cob" );

ObjectReader::ObjectReader() :
		Reader( "ObjectReader", "Reads instances of a single Object from a file with a .cob extension" )
{
}

ObjectReader::ObjectReader( const std::string &fileName ) :
		Reader( "ObjectReader", "Reads instances of a single Object from a file with a .cob extension" )
{
	m_fileNameParameter->setTypedValue( fileName );
}

ObjectReader::~ObjectReader()
{
}

bool ObjectReader::canRead( const std::string &fileName )
{
	// Ideally we'd like to look inside the file and see if it contains one object only
	// but for efficiency purposes we'll just try and open the file as a database and
	// see if that succeeds. We could possibly query the structure of the database and
	// check that it matches the signature of a one-object cache without needing to
	// actually read the data.
	IndexedIOInterfacePtr io = 0;

	try
	{
		if ( FileIndexedIO::canRead( fileName ) )
		{
			return true;
		}

		io = open(fileName);
		return true;
	}
	catch (Exception &e)
	{
		return false;
	}

	return io != 0;
}

ObjectPtr ObjectReader::doOperation( ConstCompoundObjectPtr operands )
{
	IndexedIOInterfacePtr io = open(fileName());
	return Object::load( io );
}

CompoundDataPtr ObjectReader::readHeader() const
{
	IndexedIOInterfacePtr io = open(fileName());
	io->chdir( "header" );
	return runTimeCast<CompoundData>( Object::load( io ) );
}

IndexedIOInterfacePtr ObjectReader::open( const std::string &fileName )
{
	IndexedIOInterfacePtr iface;

#ifdef IECORE_WITH_SQLITE
	try
	{
		iface = new FileIndexedIO( fileName, "/", IndexedIO::Shared | IndexedIO::Read );
	}
	catch (...)
	{
		iface = new SQLiteIndexedIO( fileName, "/", IndexedIO::Shared | IndexedIO::Read );
	}
#else
	iface = new FileIndexedIO( fileName, "/", IndexedIO::Shared | IndexedIO::Read );
#endif

	return iface;
}
<|endoftext|>


<commit_before>//===---- llvm/MDBuilder.cpp - Builder for LLVM metadata ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MDBuilder class, which is used as a convenient way to
// create LLVM metadata with a consistent and simplified interface.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Metadata.h"
using namespace llvm;

MDString *MDBuilder::createString(StringRef Str) {
  return MDString::get(Context, Str);
}

ConstantAsMetadata *MDBuilder::createConstant(Constant *C) {
  return ConstantAsMetadata::get(C);
}

MDNode *MDBuilder::createFPMath(float Accuracy) {
  if (Accuracy == 0.0)
    return nullptr;
  assert(Accuracy > 0.0 && "Invalid fpmath accuracy!");
  auto *Op =
      createConstant(ConstantFP::get(Type::getFloatTy(Context), Accuracy));
  return MDNode::get(Context, Op);
}

MDNode *MDBuilder::createBranchWeights(uint32_t TrueWeight,
                                       uint32_t FalseWeight) {
  return createBranchWeights({TrueWeight, FalseWeight});
}

MDNode *MDBuilder::createBranchWeights(ArrayRef<uint32_t> Weights) {
  assert(Weights.size() >= 1 && "Need at least one branch weights!");

  SmallVector<Metadata *, 4> Vals(Weights.size() + 1);
  Vals[0] = createString("branch_weights");

  Type *Int32Ty = Type::getInt32Ty(Context);
  for (unsigned i = 0, e = Weights.size(); i != e; ++i)
    Vals[i + 1] = createConstant(ConstantInt::get(Int32Ty, Weights[i]));

  return MDNode::get(Context, Vals);
}

MDNode *MDBuilder::createUnpredictable() {
  return MDNode::get(Context, None);
}

MDNode *MDBuilder::createFunctionEntryCount(
    uint64_t Count, const DenseSet<GlobalValue::GUID> *Imports) {
  Type *Int64Ty = Type::getInt64Ty(Context);
  SmallVector<Metadata *, 8> Ops;
  Ops.push_back(createString("function_entry_count"));
  Ops.push_back(createConstant(ConstantInt::get(Int64Ty, Count)));
  if (Imports)
    for (auto ID : *Imports)
      Ops.push_back(createConstant(ConstantInt::get(Int64Ty, ID)));
  return MDNode::get(Context, Ops);
}

MDNode *MDBuilder::createFunctionSectionPrefix(StringRef Prefix) {
  return MDNode::get(Context,
                     {createString("function_section_prefix"),
                      createString(Prefix)});
}

MDNode *MDBuilder::createRange(const APInt &Lo, const APInt &Hi) {
  assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!");

  Type *Ty = IntegerType::get(Context, Lo.getBitWidth());
  return createRange(ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi));
}

MDNode *MDBuilder::createRange(Constant *Lo, Constant *Hi) {
  // If the range is everything then it is useless.
  if (Hi == Lo)
    return nullptr;

  // Return the range [Lo, Hi).
  return MDNode::get(Context, {createConstant(Lo), createConstant(Hi)});
}

MDNode *MDBuilder::createAnonymousAARoot(StringRef Name, MDNode *Extra) {
  // To ensure uniqueness the root node is self-referential.
  auto Dummy = MDNode::getTemporary(Context, None);

  SmallVector<Metadata *, 3> Args(1, Dummy.get());
  if (Extra)
    Args.push_back(Extra);
  if (!Name.empty())
    Args.push_back(createString(Name));
  MDNode *Root = MDNode::get(Context, Args);

  // At this point we have
  //   !0 = metadata !{}            <- dummy
  //   !1 = metadata !{metadata !0} <- root
  // Replace the dummy operand with the root node itself and delete the dummy.
  Root->replaceOperandWith(0, Root);

  // We now have
  //   !1 = metadata !{metadata !1} <- self-referential root
  return Root;
}

MDNode *MDBuilder::createTBAARoot(StringRef Name) {
  return MDNode::get(Context, createString(Name));
}

/// \brief Return metadata for a non-root TBAA node with the given name,
/// parent in the TBAA tree, and value for 'pointsToConstantMemory'.
MDNode *MDBuilder::createTBAANode(StringRef Name, MDNode *Parent,
                                  bool isConstant) {
  if (isConstant) {
    Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1);
    return MDNode::get(Context,
                       {createString(Name), Parent, createConstant(Flags)});
  }
  return MDNode::get(Context, {createString(Name), Parent});
}

MDNode *MDBuilder::createAliasScopeDomain(StringRef Name) {
  return MDNode::get(Context, createString(Name));
}

MDNode *MDBuilder::createAliasScope(StringRef Name, MDNode *Domain) {
  return MDNode::get(Context, {createString(Name), Domain});
}

/// \brief Return metadata for a tbaa.struct node with the given
/// struct field descriptions.
MDNode *MDBuilder::createTBAAStructNode(ArrayRef<TBAAStructField> Fields) {
  SmallVector<Metadata *, 4> Vals(Fields.size() * 3);
  Type *Int64 = Type::getInt64Ty(Context);
  for (unsigned i = 0, e = Fields.size(); i != e; ++i) {
    Vals[i * 3 + 0] = createConstant(ConstantInt::get(Int64, Fields[i].Offset));
    Vals[i * 3 + 1] = createConstant(ConstantInt::get(Int64, Fields[i].Size));
    Vals[i * 3 + 2] = Fields[i].TBAA;
  }
  return MDNode::get(Context, Vals);
}

/// \brief Return metadata for a TBAA struct node in the type DAG
/// with the given name, a list of pairs (offset, field type in the type DAG).
MDNode *MDBuilder::createTBAAStructTypeNode(
    StringRef Name, ArrayRef<std::pair<MDNode *, uint64_t>> Fields) {
  SmallVector<Metadata *, 4> Ops(Fields.size() * 2 + 1);
  Type *Int64 = Type::getInt64Ty(Context);
  Ops[0] = createString(Name);
  for (unsigned i = 0, e = Fields.size(); i != e; ++i) {
    Ops[i * 2 + 1] = Fields[i].first;
    Ops[i * 2 + 2] = createConstant(ConstantInt::get(Int64, Fields[i].second));
  }
  return MDNode::get(Context, Ops);
}

/// \brief Return metadata for a TBAA scalar type node with the
/// given name, an offset and a parent in the TBAA type DAG.
MDNode *MDBuilder::createTBAAScalarTypeNode(StringRef Name, MDNode *Parent,
                                            uint64_t Offset) {
  ConstantInt *Off = ConstantInt::get(Type::getInt64Ty(Context), Offset);
  return MDNode::get(Context,
                     {createString(Name), Parent, createConstant(Off)});
}

/// \brief Return metadata for a TBAA tag node with the given
/// base type, access type and offset relative to the base type.
MDNode *MDBuilder::createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType,
                                           uint64_t Offset, bool IsConstant) {
  IntegerType *Int64 = Type::getInt64Ty(Context);
  ConstantInt *Off = ConstantInt::get(Int64, Offset);
  if (IsConstant) {
    return MDNode::get(Context, {BaseType, AccessType, createConstant(Off),
                                 createConstant(ConstantInt::get(Int64, 1))});
  }
  return MDNode::get(Context, {BaseType, AccessType, createConstant(Off)});
}
<commit_msg>[PGO] Fixed non-determinism with DenseSet storing function importing info.<commit_after>//===---- llvm/MDBuilder.cpp - Builder for LLVM metadata ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MDBuilder class, which is used as a convenient way to
// create LLVM metadata with a consistent and simplified interface.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Metadata.h"
using namespace llvm;

MDString *MDBuilder::createString(StringRef Str) {
  return MDString::get(Context, Str);
}

ConstantAsMetadata *MDBuilder::createConstant(Constant *C) {
  return ConstantAsMetadata::get(C);
}

MDNode *MDBuilder::createFPMath(float Accuracy) {
  if (Accuracy == 0.0)
    return nullptr;
  assert(Accuracy > 0.0 && "Invalid fpmath accuracy!");
  auto *Op =
      createConstant(ConstantFP::get(Type::getFloatTy(Context), Accuracy));
  return MDNode::get(Context, Op);
}

MDNode *MDBuilder::createBranchWeights(uint32_t TrueWeight,
                                       uint32_t FalseWeight) {
  return createBranchWeights({TrueWeight, FalseWeight});
}

MDNode *MDBuilder::createBranchWeights(ArrayRef<uint32_t> Weights) {
  assert(Weights.size() >= 1 && "Need at least one branch weights!");

  SmallVector<Metadata *, 4> Vals(Weights.size() + 1);
  Vals[0] = createString("branch_weights");

  Type *Int32Ty = Type::getInt32Ty(Context);
  for (unsigned i = 0, e = Weights.size(); i != e; ++i)
    Vals[i + 1] = createConstant(ConstantInt::get(Int32Ty, Weights[i]));

  return MDNode::get(Context, Vals);
}

MDNode *MDBuilder::createUnpredictable() {
  return MDNode::get(Context, None);
}

MDNode *MDBuilder::createFunctionEntryCount(
    uint64_t Count, const DenseSet<GlobalValue::GUID> *Imports) {
  Type *Int64Ty = Type::getInt64Ty(Context);
  SmallVector<Metadata *, 8> Ops;
  Ops.push_back(createString("function_entry_count"));
  Ops.push_back(createConstant(ConstantInt::get(Int64Ty, Count)));
  if (Imports) {
    SmallVector<GlobalValue::GUID, 2> OrderID(Imports->begin(), Imports->end());
    std::stable_sort(OrderID.begin(), OrderID.end(),
      [] (GlobalValue::GUID A, GlobalValue::GUID B) {
        return A < B;});
    for (auto ID : OrderID)
      Ops.push_back(createConstant(ConstantInt::get(Int64Ty, ID)));
  }
  return MDNode::get(Context, Ops);
}

MDNode *MDBuilder::createFunctionSectionPrefix(StringRef Prefix) {
  return MDNode::get(Context,
                     {createString("function_section_prefix"),
                      createString(Prefix)});
}

MDNode *MDBuilder::createRange(const APInt &Lo, const APInt &Hi) {
  assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!");

  Type *Ty = IntegerType::get(Context, Lo.getBitWidth());
  return createRange(ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi));
}

MDNode *MDBuilder::createRange(Constant *Lo, Constant *Hi) {
  // If the range is everything then it is useless.
  if (Hi == Lo)
    return nullptr;

  // Return the range [Lo, Hi).
  return MDNode::get(Context, {createConstant(Lo), createConstant(Hi)});
}

MDNode *MDBuilder::createAnonymousAARoot(StringRef Name, MDNode *Extra) {
  // To ensure uniqueness the root node is self-referential.
  auto Dummy = MDNode::getTemporary(Context, None);

  SmallVector<Metadata *, 3> Args(1, Dummy.get());
  if (Extra)
    Args.push_back(Extra);
  if (!Name.empty())
    Args.push_back(createString(Name));
  MDNode *Root = MDNode::get(Context, Args);

  // At this point we have
  //   !0 = metadata !{}            <- dummy
  //   !1 = metadata !{metadata !0} <- root
  // Replace the dummy operand with the root node itself and delete the dummy.
  Root->replaceOperandWith(0, Root);

  // We now have
  //   !1 = metadata !{metadata !1} <- self-referential root
  return Root;
}

MDNode *MDBuilder::createTBAARoot(StringRef Name) {
  return MDNode::get(Context, createString(Name));
}

/// \brief Return metadata for a non-root TBAA node with the given name,
/// parent in the TBAA tree, and value for 'pointsToConstantMemory'.
MDNode *MDBuilder::createTBAANode(StringRef Name, MDNode *Parent,
                                  bool isConstant) {
  if (isConstant) {
    Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1);
    return MDNode::get(Context,
                       {createString(Name), Parent, createConstant(Flags)});
  }
  return MDNode::get(Context, {createString(Name), Parent});
}

MDNode *MDBuilder::createAliasScopeDomain(StringRef Name) {
  return MDNode::get(Context, createString(Name));
}

MDNode *MDBuilder::createAliasScope(StringRef Name, MDNode *Domain) {
  return MDNode::get(Context, {createString(Name), Domain});
}

/// \brief Return metadata for a tbaa.struct node with the given
/// struct field descriptions.
MDNode *MDBuilder::createTBAAStructNode(ArrayRef<TBAAStructField> Fields) {
  SmallVector<Metadata *, 4> Vals(Fields.size() * 3);
  Type *Int64 = Type::getInt64Ty(Context);
  for (unsigned i = 0, e = Fields.size(); i != e; ++i) {
    Vals[i * 3 + 0] = createConstant(ConstantInt::get(Int64, Fields[i].Offset));
    Vals[i * 3 + 1] = createConstant(ConstantInt::get(Int64, Fields[i].Size));
    Vals[i * 3 + 2] = Fields[i].TBAA;
  }
  return MDNode::get(Context, Vals);
}

/// \brief Return metadata for a TBAA struct node in the type DAG
/// with the given name, a list of pairs (offset, field type in the type DAG).
MDNode *MDBuilder::createTBAAStructTypeNode(
    StringRef Name, ArrayRef<std::pair<MDNode *, uint64_t>> Fields) {
  SmallVector<Metadata *, 4> Ops(Fields.size() * 2 + 1);
  Type *Int64 = Type::getInt64Ty(Context);
  Ops[0] = createString(Name);
  for (unsigned i = 0, e = Fields.size(); i != e; ++i) {
    Ops[i * 2 + 1] = Fields[i].first;
    Ops[i * 2 + 2] = createConstant(ConstantInt::get(Int64, Fields[i].second));
  }
  return MDNode::get(Context, Ops);
}

/// \brief Return metadata for a TBAA scalar type node with the
/// given name, an offset and a parent in the TBAA type DAG.
MDNode *MDBuilder::createTBAAScalarTypeNode(StringRef Name, MDNode *Parent,
                                            uint64_t Offset) {
  ConstantInt *Off = ConstantInt::get(Type::getInt64Ty(Context), Offset);
  return MDNode::get(Context,
                     {createString(Name), Parent, createConstant(Off)});
}

/// \brief Return metadata for a TBAA tag node with the given
/// base type, access type and offset relative to the base type.
MDNode *MDBuilder::createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType,
                                           uint64_t Offset, bool IsConstant) {
  IntegerType *Int64 = Type::getInt64Ty(Context);
  ConstantInt *Off = ConstantInt::get(Int64, Offset);
  if (IsConstant) {
    return MDNode::get(Context, {BaseType, AccessType, createConstant(Off),
                                 createConstant(ConstantInt::get(Int64, 1))});
  }
  return MDNode::get(Context, {BaseType, AccessType, createConstant(Off)});
}
<|endoftext|>


<commit_before>//===---- lib/Jit/LLILCJit.cpp --------------------------------*- C++ -*-===//
//
// LLILC
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license.
// See LICENSE file in the project root for full license information.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Implementation of the main Jit entry points.
///
//===----------------------------------------------------------------------===//

#include "jitpch.h"
#include "LLILCJit.h"
#include "options.h"
#include "readerir.h"
#include "abi.h"
#include "EEMemoryManager.h"
#include "llvm/CodeGen/GCs.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include <string>

using namespace llvm;

// Get the LLVM IR dump level. For now this is done by directly
// accessing environment variable. When CLR config support is
// included, update it here.
LLVMDumpLevel dumpLevel() {
  const char *LevelCStr = getenv("DUMPLLVMIR");
  if (LevelCStr) {
    std::string Level = LevelCStr;
    std::transform(Level.begin(), Level.end(), Level.begin(), ::toupper);
    if (Level.compare("VERBOSE") == 0) {
      return VERBOSE;
    }
    if (Level.compare("SUMMARY") == 0) {
      return SUMMARY;
    }
  }
  return NODUMP;
}

// Get the GC-Scheme used by the runtime -- conservative/precise
// For now this is done by directly accessing environment variable.
// When CLR config support is included, update it here.
bool shouldUseConservativeGC() {
  const char *LevelCStr = getenv("COMPLUS_GCCONSERVATIVE");
  return (LevelCStr != nullptr) && (strcmp(LevelCStr, "1") == 0);
}

// The one and only Jit Object.
LLILCJit *LLILCJit::TheJit = nullptr;

// This is guaranteed to be called by the EE
// in single-threaded mode.
ICorJitCompiler *__stdcall getJit() {

  if (LLILCJit::TheJit == nullptr) {
    // These are one-time only operations.
    // Create the singleton jit object.
    LLILCJit::TheJit = new LLILCJit();

    // Register a signal handler, mainly so that the critical
    // section that is entered on windows when LLVM gets a fatal error
    // is properly initialized.
    sys::AddSignalHandler(&LLILCJit::signalHandler, LLILCJit::TheJit);

    // Allow LLVM to pick up options via the environment
    cl::ParseEnvironmentOptions("LLILCJit", "COMplus_altjitOptions");
  }

  return LLILCJit::TheJit;
}

// Construct the JIT instance
LLILCJit::LLILCJit() {
  InitializeNativeTarget();
  InitializeNativeTargetAsmPrinter();
  InitializeNativeTargetAsmParser();
  llvm::linkStatepointExampleGC();

  ShouldUseConservativeGC = shouldUseConservativeGC();
}

#ifdef LLVM_ON_WIN32
// Windows only
BOOL WINAPI DllMain(HANDLE Instance, DWORD Reason, LPVOID Reserved) {
  if (Reason == DLL_PROCESS_ATTACH) {
    DisableThreadLibraryCalls((HINSTANCE)Instance);
  } else if (Reason == DLL_PROCESS_DETACH) {
    // TBD
  }
  return TRUE;
}
#endif // LLVM_ON_WIN32

extern "C" void __stdcall sxsJitStartup(void *CcCallbacks) {
  // nothing to do
}

void LLILCJitContext::outputDebugMethodName() {
  const size_t SizeOfBuffer = 512;
  char TempBuffer[SizeOfBuffer];
  const char *DebugClassName = nullptr;
  const char *DebugMethodName = nullptr;

  DebugMethodName = JitInfo->getMethodName(MethodInfo->ftn, &DebugClassName);
  dbgs() << format("INFO:  jitting method %s::%s using LLILCJit\n",
                   DebugClassName, DebugMethodName);
}

LLILCJitContext::LLILCJitContext(LLILCJitPerThreadState *PerThreadState)
    : State(PerThreadState), HasLoadedBitCode(false), Options(this) {
  this->Next = State->JitContext;
  State->JitContext = this;
}

LLILCJitContext::~LLILCJitContext() {
  LLILCJitContext *TopContext = State->JitContext;
  assert(this == TopContext && "Unbalanced contexts!");
  State->JitContext = TopContext->Next;
}

// This is the method invoked by the EE to Jit code.
CorJitResult LLILCJit::compileMethod(ICorJitInfo *JitInfo,
                                     CORINFO_METHOD_INFO *MethodInfo,
                                     UINT Flags, BYTE **NativeEntry,
                                     ULONG *NativeSizeOfCode) {

  // Bail if input is malformed
  if (nullptr == JitInfo || nullptr == MethodInfo || nullptr == NativeEntry ||
      nullptr == NativeSizeOfCode) {
    return CORJIT_INTERNALERROR;
  }

  // Prep main outputs
  *NativeEntry = nullptr;
  *NativeSizeOfCode = 0;

  // Set up state for this thread (if necessary)
  LLILCJitPerThreadState *PerThreadState = State.get();
  if (PerThreadState == nullptr) {
    PerThreadState = new LLILCJitPerThreadState();
    State.set(PerThreadState);
  }

  // Set up context for this Jit request
  LLILCJitContext Context = LLILCJitContext(PerThreadState);

  // Fill in context information from the CLR
  Context.JitInfo = JitInfo;
  Context.MethodInfo = MethodInfo;
  Context.Flags = Flags;
  JitInfo->getEEInfo(&Context.EEInfo);

  // Fill in context information from LLVM
  Context.LLVMContext = &PerThreadState->LLVMContext;
  std::unique_ptr<Module> M = Context.getModuleForMethod(MethodInfo);
  Context.CurrentModule = M.get();
  Context.CurrentModule->setTargetTriple(LLVM_DEFAULT_TARGET_TRIPLE);
  Context.TheABIInfo = ABIInfo::get(*Context.CurrentModule);

  // Initialize per invocation JIT options. This should be done after the
  // rest of the Context is filled out as it has dependencies on Flags and
  // MethodInfo
  Context.Options.initialize();

  EngineBuilder Builder(std::move(M));
  std::string ErrStr;
  Builder.setErrorStr(&ErrStr);

  std::unique_ptr<RTDyldMemoryManager> MM(new EEMemoryManager(&Context));
  Builder.setMCJITMemoryManager(std::move(MM));

  TargetOptions Options;

  // Statepoint GC does not support FastIsel yet.
  Options.EnableFastISel = false;

  if (Context.Options.OptLevel != OptLevel::DEBUG_CODE) {
    Builder.setOptLevel(CodeGenOpt::Level::Default);
  } else {
    Builder.setOptLevel(CodeGenOpt::Level::None);
    Options.NoFramePointerElim = true;
  }

  Builder.setTargetOptions(Options);

  ExecutionEngine *NewEngine = Builder.create();

  if (!NewEngine) {
    errs() << "Could not create ExecutionEngine: " << ErrStr << "\n";
    return CORJIT_INTERNALERROR;
  }

  Context.EE = NewEngine;

  // Now jit the method.
  CorJitResult Result = CORJIT_INTERNALERROR;
  if (Context.Options.DumpLevel == VERBOSE) {
    Context.outputDebugMethodName();
  }
  bool HasMethod = this->readMethod(&Context);

  if (HasMethod) {

    if (!ShouldUseConservativeGC) {
      // If using Precise GC, run the GC-Safepoint insertion
      // and lowering passes before generating code.
      legacy::PassManager Passes;
      Passes.add(createPlaceSafepointsPass());

      PassManagerBuilder PMBuilder;
      PMBuilder.OptLevel = 0;  // Set optimization level to -O0
      PMBuilder.SizeLevel = 0; // so that no additional phases are run.
      PMBuilder.populateModulePassManager(Passes);

      Passes.add(createRewriteStatepointsForGCPass(false));
      Passes.run(*Context.CurrentModule);
    }

    Context.EE->generateCodeForModule(Context.CurrentModule);

    // You need to pick up the COFFDyld changes from the MS branch of LLVM
    // or this will fail with an "Incompatible object format!" error
    // from LLVM's dynamic loader.
    uint64_t FunctionAddress =
        Context.EE->getFunctionAddress(Context.MethodName);
    *NativeEntry = (BYTE *)FunctionAddress;

    // TODO: ColdCodeSize, or separated code, is not enabled or included.
    *NativeSizeOfCode = Context.HotCodeSize + Context.ReadOnlyDataSize;

    // This is a stop-gap point to issue a default stub of GC info. This lets
    // the CLR consume our methods cleanly. (and the ETW tracing still works)
    // Down the road this will be superseded by a CLR specific
    // GCMetadataPrinter instance or similar.
    this->outputGCInfo(&Context);

    // Dump out any enabled timing info.
    TimerGroup::printAll(errs());

    // Tell the CLR that we've successfully generated code for this method.
    Result = CORJIT_OK;
  }

  // Clean up a bit
  delete Context.EE;
  Context.EE = nullptr;
  delete Context.TheABIInfo;
  Context.TheABIInfo = nullptr;

  return Result;
}

std::unique_ptr<Module>
LLILCJitContext::getModuleForMethod(CORINFO_METHOD_INFO *MethodInfo) {
  // Grab name info from the EE.
  const char *DebugClassName = nullptr;
  const char *DebugMethodName = nullptr;
  DebugMethodName = JitInfo->getMethodName(MethodInfo->ftn, &DebugClassName);

  // Stop gap name.  The full naming will likely require some more info.
  std::string ModName(DebugClassName);
  ModName.append(1, '.');
  ModName.append(DebugMethodName);

  std::unique_ptr<Module> M;
  char *BitcodePath = getenv("BITCODE_PATH");

  if (BitcodePath != nullptr) {
    SMDiagnostic Err;
    std::string Path = std::string(BitcodePath);

    // If there is a bitcode path, use the debug module name to look for an .bc
    // file. If one is found then load it directly.
    Path.append("\\");
    Path.append(ModName);
    Path.append(".bc");
    M = llvm::parseIRFile(Path, Err, *this->LLVMContext);

    if (!M) {
      // Err.print("IR Parsing failed: ", errs());
      this->HasLoadedBitCode = false;
    } else {
      std::string Message("Loaded bitcode from: ");
      Message.append(Path);
      dbgs() << Message;
      this->HasLoadedBitCode = true;
    }
  }

  if (!this->HasLoadedBitCode) {
    M = std::unique_ptr<Module>(new Module(ModName, *this->LLVMContext));
  }

  return std::move(M);
}

// Read method MSIL and construct LLVM bitcode
bool LLILCJit::readMethod(LLILCJitContext *JitContext) {
  if (JitContext->HasLoadedBitCode) {
    // This is a case where we side loaded a llvm bitcode module.
    // The module is already complete so we avoid reading entirely.
    return true;
  }

  LLVMDumpLevel DumpLevel = JitContext->Options.DumpLevel;

  LLILCJitPerThreadState *PerThreadState = State.get();
  GenIR Reader(JitContext, &PerThreadState->ClassTypeMap,
               &PerThreadState->ReverseClassTypeMap,
               &PerThreadState->BoxedTypeMap, &PerThreadState->ArrayTypeMap,
               &PerThreadState->FieldIndexMap);

  std::string FuncName = JitContext->CurrentModule->getModuleIdentifier();

  try {
    Reader.msilToIR();
  } catch (NotYetImplementedException &Nyi) {
    if (DumpLevel >= SUMMARY) {
      errs() << "Failed to read " << FuncName << '[' << Nyi.reason() << "]\n";
    }
    return false;
  }

  Function *Func = JitContext->CurrentModule->getFunction(FuncName);
  bool IsOk = !verifyFunction(*Func, &dbgs());

  if (IsOk) {
    if (DumpLevel >= SUMMARY) {
      errs() << "Successfully read " << FuncName << '\n';
    }
  } else {
    if (DumpLevel >= SUMMARY) {
      errs() << "Read " << FuncName << " but failed verification\n";
    }
  }

  if (DumpLevel == VERBOSE) {
    Func->dump();
  }

  JitContext->MethodName = FuncName;

  return IsOk;
}

// Stop gap function to allocate and emit stub GCInfo for the method.
// This avoids a crash in the EE.
// Assuming that this will be replaced by an override of the GCMetaData
// or similar writer in LLVM once we move to the safepoint design.
bool LLILCJit::outputGCInfo(LLILCJitContext *JitContext) {
  size_t Size = 5;
  void *GCInfoBuffer = JitContext->JitInfo->allocGCInfo(Size);

  if (GCInfoBuffer == nullptr) {
    return false;
  }

  // First word of the GCInfoBuffer should be the size of the method.
  *(uint32_t *)GCInfoBuffer = JitContext->HotCodeSize;

  // 0x8 is the end sentinel of the buffer.
  *(((char *)GCInfoBuffer) + 4) = 0x8;

  return true;
}

// Notification from the runtime that any caches should be cleaned up.
void LLILCJit::clearCache() { return; }

// Notify runtime if we have something to clean up
BOOL LLILCJit::isCacheCleanupRequired() { return FALSE; }

// Verify the JIT/EE interface identifier.
void LLILCJit::getVersionIdentifier(GUID *VersionIdentifier) {
  _ASSERTE(VersionIdentifier != nullptr);
  memcpy(VersionIdentifier, &JITEEVersionIdentifier, sizeof(GUID));
}

// Raise a fatal error.
void __cdecl LLILCJit::fatal(int Errnum, ...) {
  _ASSERTE(FAILED(Errnum));
  ULONG_PTR ExceptArg = Errnum;
  RaiseException(CORJIT_INTERNALERROR, EXCEPTION_NONCONTINUABLE, 1, &ExceptArg);
}

//  Handle an abort signal from LLVM. We don't do anything, but registering
//  this handler avoids a crash when LLVM goes down.
void LLILCJit::signalHandler(void *Cookie) {
  // do nothing
}
<commit_msg>Disable symbol searching.<commit_after>//===---- lib/Jit/LLILCJit.cpp --------------------------------*- C++ -*-===//
//
// LLILC
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license.
// See LICENSE file in the project root for full license information.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Implementation of the main Jit entry points.
///
//===----------------------------------------------------------------------===//

#include "jitpch.h"
#include "LLILCJit.h"
#include "options.h"
#include "readerir.h"
#include "abi.h"
#include "EEMemoryManager.h"
#include "llvm/CodeGen/GCs.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include <string>

using namespace llvm;

// Get the LLVM IR dump level. For now this is done by directly
// accessing environment variable. When CLR config support is
// included, update it here.
LLVMDumpLevel dumpLevel() {
  const char *LevelCStr = getenv("DUMPLLVMIR");
  if (LevelCStr) {
    std::string Level = LevelCStr;
    std::transform(Level.begin(), Level.end(), Level.begin(), ::toupper);
    if (Level.compare("VERBOSE") == 0) {
      return VERBOSE;
    }
    if (Level.compare("SUMMARY") == 0) {
      return SUMMARY;
    }
  }
  return NODUMP;
}

// Get the GC-Scheme used by the runtime -- conservative/precise
// For now this is done by directly accessing environment variable.
// When CLR config support is included, update it here.
bool shouldUseConservativeGC() {
  const char *LevelCStr = getenv("COMPLUS_GCCONSERVATIVE");
  return (LevelCStr != nullptr) && (strcmp(LevelCStr, "1") == 0);
}

// The one and only Jit Object.
LLILCJit *LLILCJit::TheJit = nullptr;

// This is guaranteed to be called by the EE
// in single-threaded mode.
ICorJitCompiler *__stdcall getJit() {

  if (LLILCJit::TheJit == nullptr) {
    // These are one-time only operations.
    // Create the singleton jit object.
    LLILCJit::TheJit = new LLILCJit();

    // Register a signal handler, mainly so that the critical
    // section that is entered on windows when LLVM gets a fatal error
    // is properly initialized.
    sys::AddSignalHandler(&LLILCJit::signalHandler, LLILCJit::TheJit);

    // Allow LLVM to pick up options via the environment
    cl::ParseEnvironmentOptions("LLILCJit", "COMplus_altjitOptions");
  }

  return LLILCJit::TheJit;
}

// Construct the JIT instance
LLILCJit::LLILCJit() {
  InitializeNativeTarget();
  InitializeNativeTargetAsmPrinter();
  InitializeNativeTargetAsmParser();
  llvm::linkStatepointExampleGC();

  ShouldUseConservativeGC = shouldUseConservativeGC();
}

#ifdef LLVM_ON_WIN32
// Windows only
BOOL WINAPI DllMain(HANDLE Instance, DWORD Reason, LPVOID Reserved) {
  if (Reason == DLL_PROCESS_ATTACH) {
    DisableThreadLibraryCalls((HINSTANCE)Instance);
  } else if (Reason == DLL_PROCESS_DETACH) {
    // TBD
  }
  return TRUE;
}
#endif // LLVM_ON_WIN32

extern "C" void __stdcall sxsJitStartup(void *CcCallbacks) {
  // nothing to do
}

void LLILCJitContext::outputDebugMethodName() {
  const size_t SizeOfBuffer = 512;
  char TempBuffer[SizeOfBuffer];
  const char *DebugClassName = nullptr;
  const char *DebugMethodName = nullptr;

  DebugMethodName = JitInfo->getMethodName(MethodInfo->ftn, &DebugClassName);
  dbgs() << format("INFO:  jitting method %s::%s using LLILCJit\n",
                   DebugClassName, DebugMethodName);
}

LLILCJitContext::LLILCJitContext(LLILCJitPerThreadState *PerThreadState)
    : State(PerThreadState), HasLoadedBitCode(false), Options(this) {
  this->Next = State->JitContext;
  State->JitContext = this;
}

LLILCJitContext::~LLILCJitContext() {
  LLILCJitContext *TopContext = State->JitContext;
  assert(this == TopContext && "Unbalanced contexts!");
  State->JitContext = TopContext->Next;
}

// This is the method invoked by the EE to Jit code.
CorJitResult LLILCJit::compileMethod(ICorJitInfo *JitInfo,
                                     CORINFO_METHOD_INFO *MethodInfo,
                                     UINT Flags, BYTE **NativeEntry,
                                     ULONG *NativeSizeOfCode) {

  // Bail if input is malformed
  if (nullptr == JitInfo || nullptr == MethodInfo || nullptr == NativeEntry ||
      nullptr == NativeSizeOfCode) {
    return CORJIT_INTERNALERROR;
  }

  // Prep main outputs
  *NativeEntry = nullptr;
  *NativeSizeOfCode = 0;

  // Set up state for this thread (if necessary)
  LLILCJitPerThreadState *PerThreadState = State.get();
  if (PerThreadState == nullptr) {
    PerThreadState = new LLILCJitPerThreadState();
    State.set(PerThreadState);
  }

  // Set up context for this Jit request
  LLILCJitContext Context = LLILCJitContext(PerThreadState);

  // Fill in context information from the CLR
  Context.JitInfo = JitInfo;
  Context.MethodInfo = MethodInfo;
  Context.Flags = Flags;
  JitInfo->getEEInfo(&Context.EEInfo);

  // Fill in context information from LLVM
  Context.LLVMContext = &PerThreadState->LLVMContext;
  std::unique_ptr<Module> M = Context.getModuleForMethod(MethodInfo);
  Context.CurrentModule = M.get();
  Context.CurrentModule->setTargetTriple(LLVM_DEFAULT_TARGET_TRIPLE);
  Context.TheABIInfo = ABIInfo::get(*Context.CurrentModule);

  // Initialize per invocation JIT options. This should be done after the
  // rest of the Context is filled out as it has dependencies on Flags and
  // MethodInfo
  Context.Options.initialize();

  EngineBuilder Builder(std::move(M));
  std::string ErrStr;
  Builder.setErrorStr(&ErrStr);

  std::unique_ptr<RTDyldMemoryManager> MM(new EEMemoryManager(&Context));
  Builder.setMCJITMemoryManager(std::move(MM));

  TargetOptions Options;

  // Statepoint GC does not support FastIsel yet.
  Options.EnableFastISel = false;

  if (Context.Options.OptLevel != OptLevel::DEBUG_CODE) {
    Builder.setOptLevel(CodeGenOpt::Level::Default);
  } else {
    Builder.setOptLevel(CodeGenOpt::Level::None);
    Options.NoFramePointerElim = true;
  }

  Builder.setTargetOptions(Options);

  ExecutionEngine *NewEngine = Builder.create();

  if (!NewEngine) {
    errs() << "Could not create ExecutionEngine: " << ErrStr << "\n";
    return CORJIT_INTERNALERROR;
  }

  // Don't allow the EE to search for external symbols.
  NewEngine->DisableSymbolSearching();
  Context.EE = NewEngine;

  // Now jit the method.
  CorJitResult Result = CORJIT_INTERNALERROR;
  if (Context.Options.DumpLevel == VERBOSE) {
    Context.outputDebugMethodName();
  }
  bool HasMethod = this->readMethod(&Context);

  if (HasMethod) {

    if (!ShouldUseConservativeGC) {
      // If using Precise GC, run the GC-Safepoint insertion
      // and lowering passes before generating code.
      legacy::PassManager Passes;
      Passes.add(createPlaceSafepointsPass());

      PassManagerBuilder PMBuilder;
      PMBuilder.OptLevel = 0;  // Set optimization level to -O0
      PMBuilder.SizeLevel = 0; // so that no additional phases are run.
      PMBuilder.populateModulePassManager(Passes);

      Passes.add(createRewriteStatepointsForGCPass(false));
      Passes.run(*Context.CurrentModule);
    }

    Context.EE->generateCodeForModule(Context.CurrentModule);

    // You need to pick up the COFFDyld changes from the MS branch of LLVM
    // or this will fail with an "Incompatible object format!" error
    // from LLVM's dynamic loader.
    uint64_t FunctionAddress =
        Context.EE->getFunctionAddress(Context.MethodName);
    *NativeEntry = (BYTE *)FunctionAddress;

    // TODO: ColdCodeSize, or separated code, is not enabled or included.
    *NativeSizeOfCode = Context.HotCodeSize + Context.ReadOnlyDataSize;

    // This is a stop-gap point to issue a default stub of GC info. This lets
    // the CLR consume our methods cleanly. (and the ETW tracing still works)
    // Down the road this will be superseded by a CLR specific
    // GCMetadataPrinter instance or similar.
    this->outputGCInfo(&Context);

    // Dump out any enabled timing info.
    TimerGroup::printAll(errs());

    // Tell the CLR that we've successfully generated code for this method.
    Result = CORJIT_OK;
  }

  // Clean up a bit
  delete Context.EE;
  Context.EE = nullptr;
  delete Context.TheABIInfo;
  Context.TheABIInfo = nullptr;

  return Result;
}

std::unique_ptr<Module>
LLILCJitContext::getModuleForMethod(CORINFO_METHOD_INFO *MethodInfo) {
  // Grab name info from the EE.
  const char *DebugClassName = nullptr;
  const char *DebugMethodName = nullptr;
  DebugMethodName = JitInfo->getMethodName(MethodInfo->ftn, &DebugClassName);

  // Stop gap name.  The full naming will likely require some more info.
  std::string ModName(DebugClassName);
  ModName.append(1, '.');
  ModName.append(DebugMethodName);

  std::unique_ptr<Module> M;
  char *BitcodePath = getenv("BITCODE_PATH");

  if (BitcodePath != nullptr) {
    SMDiagnostic Err;
    std::string Path = std::string(BitcodePath);

    // If there is a bitcode path, use the debug module name to look for an .bc
    // file. If one is found then load it directly.
    Path.append("\\");
    Path.append(ModName);
    Path.append(".bc");
    M = llvm::parseIRFile(Path, Err, *this->LLVMContext);

    if (!M) {
      // Err.print("IR Parsing failed: ", errs());
      this->HasLoadedBitCode = false;
    } else {
      std::string Message("Loaded bitcode from: ");
      Message.append(Path);
      dbgs() << Message;
      this->HasLoadedBitCode = true;
    }
  }

  if (!this->HasLoadedBitCode) {
    M = std::unique_ptr<Module>(new Module(ModName, *this->LLVMContext));
  }

  return std::move(M);
}

// Read method MSIL and construct LLVM bitcode
bool LLILCJit::readMethod(LLILCJitContext *JitContext) {
  if (JitContext->HasLoadedBitCode) {
    // This is a case where we side loaded a llvm bitcode module.
    // The module is already complete so we avoid reading entirely.
    return true;
  }

  LLVMDumpLevel DumpLevel = JitContext->Options.DumpLevel;

  LLILCJitPerThreadState *PerThreadState = State.get();
  GenIR Reader(JitContext, &PerThreadState->ClassTypeMap,
               &PerThreadState->ReverseClassTypeMap,
               &PerThreadState->BoxedTypeMap, &PerThreadState->ArrayTypeMap,
               &PerThreadState->FieldIndexMap);

  std::string FuncName = JitContext->CurrentModule->getModuleIdentifier();

  try {
    Reader.msilToIR();
  } catch (NotYetImplementedException &Nyi) {
    if (DumpLevel >= SUMMARY) {
      errs() << "Failed to read " << FuncName << '[' << Nyi.reason() << "]\n";
    }
    return false;
  }

  Function *Func = JitContext->CurrentModule->getFunction(FuncName);
  bool IsOk = !verifyFunction(*Func, &dbgs());

  if (IsOk) {
    if (DumpLevel >= SUMMARY) {
      errs() << "Successfully read " << FuncName << '\n';
    }
  } else {
    if (DumpLevel >= SUMMARY) {
      errs() << "Read " << FuncName << " but failed verification\n";
    }
  }

  if (DumpLevel == VERBOSE) {
    Func->dump();
  }

  JitContext->MethodName = FuncName;

  return IsOk;
}

// Stop gap function to allocate and emit stub GCInfo for the method.
// This avoids a crash in the EE.
// Assuming that this will be replaced by an override of the GCMetaData
// or similar writer in LLVM once we move to the safepoint design.
bool LLILCJit::outputGCInfo(LLILCJitContext *JitContext) {
  size_t Size = 5;
  void *GCInfoBuffer = JitContext->JitInfo->allocGCInfo(Size);

  if (GCInfoBuffer == nullptr) {
    return false;
  }

  // First word of the GCInfoBuffer should be the size of the method.
  *(uint32_t *)GCInfoBuffer = JitContext->HotCodeSize;

  // 0x8 is the end sentinel of the buffer.
  *(((char *)GCInfoBuffer) + 4) = 0x8;

  return true;
}

// Notification from the runtime that any caches should be cleaned up.
void LLILCJit::clearCache() { return; }

// Notify runtime if we have something to clean up
BOOL LLILCJit::isCacheCleanupRequired() { return FALSE; }

// Verify the JIT/EE interface identifier.
void LLILCJit::getVersionIdentifier(GUID *VersionIdentifier) {
  _ASSERTE(VersionIdentifier != nullptr);
  memcpy(VersionIdentifier, &JITEEVersionIdentifier, sizeof(GUID));
}

// Raise a fatal error.
void __cdecl LLILCJit::fatal(int Errnum, ...) {
  _ASSERTE(FAILED(Errnum));
  ULONG_PTR ExceptArg = Errnum;
  RaiseException(CORJIT_INTERNALERROR, EXCEPTION_NONCONTINUABLE, 1, &ExceptArg);
}

//  Handle an abort signal from LLVM. We don't do anything, but registering
//  this handler avoids a crash when LLVM goes down.
void LLILCJit::signalHandler(void *Cookie) {
  // do nothing
}
<|endoftext|>


<commit_before>#ifndef _EventHandler_Hpp
#define _EventHandler_Hpp

// -- this will speed up the process ever so slightly
// -- for the overall development of our event structures.
#define DEFINE_EVENT(EventClass) \
	public: \
	EventClass() { }; \
	~EventClass() { }; \
	void Execute(void) \

class Event
{
	public:
		Event();
		virtual ~Event();

	protected:
		time_t  mInitTime;  // the initiation time for the event
		double  mSecondsToExecute; // suspect time of ending
		bool    mWillRestart;  // will it restart when it is done?
		int 	mEvType;
	public:
		virtual void Execute ( void ) = 0;
		void setType ( int t ) { mEvType = t; }
		int getType ( void ) { return mEvType; }

		void setInitTime ( time_t t )
		{
			mInitTime = t;
		}
		void setSeconds ( double t )
		{
			mSecondsToExecute = t;
		}

		double getSeconds ( void )
		{
			return mSecondsToExecute;
		}

		time_t getInitTime ( void )
		{
			return mInitTime;
		}

		bool hasElapsed ( void )   // has the event elapsed its seconds requirements?
		{
			double elapsed = difftime ( time ( NULL ), mInitTime );
			if ( elapsed >= mSecondsToExecute )
			{ return true; }
			return false;
		}
		bool isRestart ( void )
		{
			return mWillRestart;
		}
		void setRestart ( bool t )
		{
			mWillRestart = t;
		}
};

class EventHandler
{
	public:
		EventHandler() { }
		~EventHandler()
		{
			destroyEvents();
		}
	private:
		EventHandler ( const EventHandler& );
		EventHandler&operator= ( const EventHandler& );

		std::list<Event*>mEventList;
	public:
		std::list<Event *>::iterator getFirst() { return mEventList.begin(); }
		std::list<Event *>::iterator getLast() { return mEventList.end(); }
		void BootupEvents();
		int updateEvents ( void );
		void destroyEvents ( void );
		void destroyEvent ( Event *ev );
		Event *addEvent ( Event *ev, bool repeat, double seconds ); // return the event so we can store certain events easily

};

#endif
<commit_msg>Update EventHandler.hpp<commit_after>#ifndef _EventHandler_Hpp
#define _EventHandler_Hpp

// -- this will speed up the process ever so slightly
// -- for the overall development of our event structures.
#define DEFINE_EVENT(EventClass) \
	public: \
	EventClass() { }; \
	~EventClass() { }; \
	void Execute(void)

class Event
{
	public:
		Event();
		virtual ~Event();

	protected:
		time_t  mInitTime;  // the initiation time for the event
		double  mSecondsToExecute; // suspect time of ending
		bool    mWillRestart;  // will it restart when it is done?
		int 	mEvType;
	public:
		virtual void Execute ( void ) = 0;
		void setType ( int t ) { mEvType = t; }
		int getType ( void ) { return mEvType; }

		void setInitTime ( time_t t )
		{
			mInitTime = t;
		}
		void setSeconds ( double t )
		{
			mSecondsToExecute = t;
		}

		double getSeconds ( void )
		{
			return mSecondsToExecute;
		}

		time_t getInitTime ( void )
		{
			return mInitTime;
		}

		bool hasElapsed ( void )   // has the event elapsed its seconds requirements?
		{
			double elapsed = difftime ( time ( NULL ), mInitTime );
			if ( elapsed >= mSecondsToExecute )
			{ return true; }
			return false;
		}
		bool isRestart ( void )
		{
			return mWillRestart;
		}
		void setRestart ( bool t )
		{
			mWillRestart = t;
		}
};

class EventHandler
{
	public:
		EventHandler() { }
		~EventHandler()
		{
			destroyEvents();
		}
	private:
		EventHandler ( const EventHandler& );
		EventHandler&operator= ( const EventHandler& );

		std::list<Event*>mEventList;
	public:
		std::list<Event *>::iterator getFirst() { return mEventList.begin(); }
		std::list<Event *>::iterator getLast() { return mEventList.end(); }
		void BootupEvents();
		int processEvents ( int ev_type );
		void destroyEvents ( void );
		void destroyEvent ( Event *ev );
		Event *addEvent ( Event *ev, bool repeat, double seconds ); // return the event so we can store certain events easily

};

#endif
<|endoftext|>


<commit_before>/*
 * File:   Sphere.hpp
 * Author: Benedikt Vogler
 *
 * Created on 4. Juli 2014, 19:25
 */

#ifndef SPHERE_HPP
#define	SPHERE_HPP

#include <glm/glm.hpp>
#include "ray.hpp"
#include "RenderObject.hpp"

class Sphere: public RenderObject {
public:
    Sphere():
        RenderObject("unnamed", Material()), radius(0)
    {};

    /**
     * Creates a shpere.
     * @param name The name of the shpere.
     * @param center the center position vector of the sphere
     * @param radius The radius of the sphere.
     * @param material
     */
    Sphere(string name, glm::vec3 const& center, float const radius, Material material) :
        RenderObject(name, material), center(center), radius(radius)
    {}

    Sphere(const Sphere& orig);
    virtual ~Sphere();
    std::pair<bool, glm::vec3> intersect(Ray const& ray) const;

private:
    float radius;
    glm::vec3 center;
};

#endif	/* SPHERE_HPP */

<commit_msg>const correctnes<commit_after>/*
 * File:   Sphere.hpp
 * Author: Benedikt Vogler
 *
 * Created on 4. Juli 2014, 19:25
 */

#ifndef SPHERE_HPP
#define	SPHERE_HPP

#include <glm/glm.hpp>
#include "ray.hpp"
#include "RenderObject.hpp"

class Sphere: public RenderObject {
public:
    Sphere():
        RenderObject("unnamed", Material()), radius(0)
    {};

    /**
     * Creates a shpere.
     * @param name The name of the shpere.
     * @param center the center position vector of the sphere
     * @param radius The radius of the sphere.
     * @param material
     */
    Sphere(string name, glm::vec3 const& center, float const radius, Material const& material) :
        RenderObject(name, material), center(center), radius(radius)
    {}

    Sphere(const Sphere& orig);
    virtual ~Sphere();
    std::pair<bool, glm::vec3> intersect(Ray const& ray) const;

private:
    float radius;
    glm::vec3 center;
};

#endif	/* SPHERE_HPP */

<|endoftext|>