polymorph.h
No OneTemporary

File Metadata

Created
Mon, Aug 24, 3:56 PM

polymorph.h

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Author: pgess <v.melnychenko@xreate.org>
*
* Created on October 7, 2017
*/
/**
* \file src/compilation/polymorph.h
* \brief Polymorphism-aware compilation routines
*/
#ifndef POLYMORPHCOMPILER_H
#define POLYMORPHCOMPILER_H
#include "pass/compilepass.h"
#include "query/polymorph.h"
#include "compilation/latetranscend.h"
#include "compilation/targetinterpretation.h"
namespace xreate{
namespace polymorph{
typedef Expression Selector;
/** \brief An instance of \ref compilation::IFnInvocation to manage polymorphic functions invocation*/
class PolymorphFnInvocation: public compilation::IFnInvocation{
public:
PolymorphFnInvocation(const latereasoning::LateAnnotation& selector,
std::list<ManagedFnPtr> calleeSpecializations,
CompilePass* pass,
PolymorphQuery* query,
LLVMLayer* llvm,
latereasoning::LateReasoningCompiler* compiler);
llvm::Value* operator()(std::vector<llvm::Value *>&& args, const std::string& hintDecl = "");
private:
latereasoning::LateAnnotation __selector;
std::list<ManagedFnPtr> __calleeSpecializations;
CompilePass* __pass;
PolymorphQuery* __query;
LLVMLayer* __llvm;
latereasoning::LateReasoningCompiler* __compiler;
} ;
/**
* \brief Polymorphism aware \ref xreate::compilation::ICodeScopeUnit decorator
* \implements xreate::compilation::ICodeScopeUnit
*/
template <class Parent>
class PolymorphCodeScopeUnit: public Parent{
public:
PolymorphCodeScopeUnit(const CodeScope * const codeScope,
compilation::IFunctionUnit* f,
CompilePass* compilePass)
: Parent(codeScope, f, compilePass){ }
protected:
compilation::IFnInvocation*
findFunction(const Expression& opCall) override{
// //Check does invocation require guards satisfaction
const std::string& nameCallee = opCall.getValueString();
const std::list<ManagedFnPtr>& specializations =
Parent::pass->man->root->getFunctionSpecializations(nameCallee);
//Extern function
if(specializations.size() == 0){
return Parent::findFunction(opCall);
}
//No other specializations. Check if it has no guard
if(specializations.size() == 1){
if(!specializations.front()->guard.isValid()){
return Parent::findFunction(opCall);
}
}
//Several specializations
PolymorphQuery* query = dynamic_cast<PolymorphQuery*> (
Parent::pass->man->transcend->getQuery(QueryId::PolymorphQuery));
const latereasoning::LateAnnotation& selector = query->get(opCall);
compilation::Context ctx{this, Parent::function, Parent::pass};
interpretation::InterpretationScope* scopeIntrpr =
Parent::pass->targetInterpretation->transformContext(ctx);
latereasoning::LateReasoningCompiler* compiler
= new latereasoning::LateReasoningCompiler(dynamic_cast<interpretation::InterpretationFunction*> (scopeIntrpr->function), ctx);
return new PolymorphFnInvocation(selector, specializations, Parent::pass,
query, Parent::pass->man->llvm, compiler);
}
} ;
}
} //end of xreate::polymorph
#endif /* POLYMORPHCOMPILER_H */

Event Timeline