aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-03-15 06:13:50 +0000
committerDavid Robillard <d@drobilla.net>2009-03-15 06:13:50 +0000
commitd28e4f7ad0d0d8d32d65a098a16f65036e5d318c (patch)
tree24b6713cb0b4c70eb0d573e804921b6f4ac55169
parenteea2c8f035d2e5ae768fd2de0e704bfb49652cf0 (diff)
downloadresp-d28e4f7ad0d0d8d32d65a098a16f65036e5d318c.tar.gz
resp-d28e4f7ad0d0d8d32d65a098a16f65036e5d318c.tar.bz2
resp-d28e4f7ad0d0d8d32d65a098a16f65036e5d318c.zip
Remove duplicated code.
git-svn-id: http://svn.drobilla.net/resp/tuplr@100 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r--llvm.cpp75
1 files changed, 25 insertions, 50 deletions
diff --git a/llvm.cpp b/llvm.cpp
index 8417163..e00b55d 100644
--- a/llvm.cpp
+++ b/llvm.cpp
@@ -195,44 +195,15 @@ void
AClosure::lift(CEnv& cenv)
{
AType* type = cenv.type(this);
- if (!type->concrete() || funcs.find(type))
+ if (funcs.find(type) || !type->concrete())
return;
-
- // Write function declaration
- string name = this->name == "" ? cenv.gensym("_fn") : this->name;
- ATuple* protT = dynamic_cast<ATuple*>(type->at(1));
- assert(protT);
- Function* f = compileFunction(cenv, name,
- lltype(dynamic_cast<AType*>(type->at(type->size() - 1))),
- *protT);
- cenv.push();
- Subst oldSubst = cenv.tsubst;
- cenv.tsubst = Subst::compose(cenv.tsubst, *subst);
-
- // Bind argument values in CEnv
- vector<Value*> args;
- const_iterator p = prot()->begin();
- size_t i = 0;
- for (Function::arg_iterator a = f->arg_begin(); a != f->arg_end(); ++a, ++p)
- cenv.def((*p)->as<ASymbol*>(), *p, protT->at(i++)->as<AType*>(), &*a);
+ ATuple* protT = type->at(1)->as<ATuple*>();
+ vector<AType*> argsT;
+ for (size_t i = 0; i < protT->size(); ++i)
+ argsT.push_back(protT->at(i)->as<AType*>());
- // Write function body
- try {
- // Define value first for recursion
- cenv.precompile(this, f);
- funcs.push_back(make_pair(type, f));
-
- CValue retVal = cenv.compile(at(2));
- llengine(cenv)->builder.CreateRet(LLVal(retVal)); // Finish function
- cenv.optimise(LLFunc(f));
- } catch (Error& e) {
- f->eraseFromParent(); // Error reading body, remove function
- cenv.pop();
- throw e;
- }
- cenv.tsubst = oldSubst;
- cenv.pop();
+ liftCall(cenv, argsT);
}
void
@@ -242,23 +213,28 @@ AClosure::liftCall(CEnv& cenv, const vector<AType*>& argsT)
assert(gt != cenv.tenv.genericTypes.end());
AType* genericType = new AType(*gt->second);
- // Find type and build substitution
- assert(argsT.size() == prot()->size());
- Subst argsSubst;
- ATuple* genericProtT = dynamic_cast<ATuple*>(genericType->at(1));
- assert(genericProtT);
- for (size_t i = 0; i < argsT.size(); ++i)
- argsSubst[dynamic_cast<AType*>(genericProtT->at(i))] = dynamic_cast<AType*>(argsT.at(i));
-
- AType* thisType = argsSubst.apply(genericType)->as<AType*>();
+ AType* thisType = NULL;
+ Subst argsSubst;
+ if (!genericType->concrete()) {
+ // Find type and build substitution
+ assert(argsT.size() == prot()->size());
+ ATuple* genericProtT = dynamic_cast<ATuple*>(genericType->at(1));
+ assert(genericProtT);
+ for (size_t i = 0; i < argsT.size(); ++i)
+ argsSubst[dynamic_cast<AType*>(genericProtT->at(i))] = dynamic_cast<AType*>(argsT.at(i));
+
+ thisType = argsSubst.apply(genericType)->as<AType*>();
+
+ if (!thisType->concrete())
+ throw Error("unable to resolve concrete type for function", loc);
+ } else {
+ thisType = cenv.type(this);
+ }
- if (!thisType->concrete())
- throw Error("unable to resolve concrete type for function", loc);
-
if (funcs.find(thisType))
return;
-
- ATuple* protT = dynamic_cast<ATuple*>(thisType->at(1));
+
+ ATuple* protT = thisType->at(1)->as<ATuple*>();
// Write function declaration
string name = this->name == "" ? cenv.gensym("_fn") : this->name;
@@ -286,7 +262,6 @@ AClosure::liftCall(CEnv& cenv, const vector<AType*>& argsT)
CValue retVal = cenv.compile(at(2));
llengine(cenv)->builder.CreateRet(LLVal(retVal)); // Finish function
cenv.optimise(LLFunc(f));
-
} catch (Error& e) {
f->eraseFromParent(); // Error reading body, remove function
cenv.pop();