diff options
Diffstat (limited to 'llvm.cpp')
-rw-r--r-- | llvm.cpp | 75 |
1 files changed, 25 insertions, 50 deletions
@@ -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(); |