diff options
Diffstat (limited to 'llvm.cpp')
-rw-r--r-- | llvm.cpp | 54 |
1 files changed, 38 insertions, 16 deletions
@@ -165,7 +165,7 @@ compileFunction(CEnv& cenv, const std::string& name, const Type* retT, const ATu if (f->getName() != name) { f->eraseFromParent(); - throw Error(loc, "function redefined"); + throw Error(loc, (format("function `%1%' redefined") % name).str()); } // Set argument names in generated code @@ -211,23 +211,22 @@ AClosure::liftCall(CEnv& cenv, const vector<AType*>& argsT) { TEnv::GenericTypes::const_iterator gt = cenv.tenv.genericTypes.find(this); assert(gt != cenv.tenv.genericTypes.end()); - AType* genericType = new AType(*gt->second); - - AType* thisType = genericType; + AType* thisType = new AType(*gt->second); Subst argsSubst; if (!thisType->concrete()) { - // Find type and build substitution + // Build substitution to apply to generic type assert(argsT.size() == prot()->size()); - ATuple* genericProtT = genericType->at(1)->as<ATuple*>(); + ATuple* genericProtT = gt->second->at(1)->as<ATuple*>(); for (size_t i = 0; i < argsT.size(); ++i) - argsSubst[*genericProtT->at(i)->to<AType*>()] = argsT.at(i)->to<AType*>(); - thisType = argsSubst.apply(genericType)->as<AType*>(); + argsSubst[genericProtT->at(i)->to<AType*>()] = argsT.at(i)->to<AType*>(); + + // Apply substitution to get concrete type for this call + thisType = argsSubst.apply(thisType)->as<AType*>(); if (!thisType->concrete()) throw Error(loc, "unable to resolve concrete type for function"); - } else { - thisType = genericType; } + AST::pool.addRoot(thisType); if (funcs.find(thisType)) return; @@ -241,7 +240,7 @@ AClosure::liftCall(CEnv& cenv, const vector<AType*>& argsT) cenv.push(); Subst oldSubst = cenv.tsubst; - cenv.tsubst = Subst::compose(cenv.tsubst, Subst::compose(argsSubst, *subst)); + cenv.tsubst = Subst::compose(cenv.tsubst, Subst::compose(argsSubst, subst)); // Bind argument values in CEnv vector<Value*> args; @@ -304,15 +303,15 @@ ACall::compile(CEnv& cenv) if (!c) return NULL; // Primitive - AType* protT = new AType(loc, NULL); + AType protT(loc, NULL); for (size_t i = 1; i < size(); ++i) - protT->push_back(cenv.type(at(i))); + protT.push_back(cenv.type(at(i))); TEnv::GenericTypes::const_iterator gt = cenv.tenv.genericTypes.find(c); assert(gt != cenv.tenv.genericTypes.end()); - AType* fnT = new AType(loc, cenv.penv.sym("Fn"), protT, cenv.type(this), 0); - Function* f = (Function*)c->funcs.find(fnT); - THROW_IF(!f, loc, (format("callee failed to compile for type %1%") % fnT->str()).str()) + AType fnT(loc, cenv.penv.sym("Fn"), &protT, cenv.type(this), 0); + Function* f = (Function*)c->funcs.find(&fnT); + THROW_IF(!f, loc, (format("callee failed to compile for type %1%") % fnT.str()).str()) vector<Value*> params(size() - 1); for (size_t i = 1; i < size(); ++i) @@ -557,6 +556,10 @@ eval(CEnv& cenv, const string& name, istream& is) resultType = cenv.type(result); result->lift(cenv); // Lift functions exprs.push_back(make_pair(exp, result)); + + // Add definitions as GC roots + if (result->to<ADefinition*>()) + cenv.lock(result); } const Type* ctype = lltype(resultType); @@ -576,6 +579,9 @@ eval(CEnv& cenv, const string& name, istream& is) cenv.out << call(resultType, llengine(cenv)->engine->getPointerToFunction(f)) << " : " << resultType << endl; + + AST::pool.collect(cenv, AST::pool.roots()); + } catch (Error& e) { cenv.err << e.what() << endl; return 1; @@ -624,7 +630,15 @@ repl(CEnv& cenv) cenv.out << "; " << cenv.compile(body); } cenv.out << " : " << cenv.type(body) << endl; + + // Add definitions as GC roots + if (body->to<ADefinition*>()) + cenv.lock(body); + + AST::pool.collect(cenv, AST::pool.roots()); + cenv.tsubst = oldSubst; + } catch (Error& e) { cenv.err << e.what() << endl; } @@ -646,3 +660,11 @@ newCenv(PEnv& penv, TEnv& tenv) return cenv; } +void +freeCenv(CEnv* cenv) +{ + AST::pool.collect(*cenv, GC::Roots()); + delete (LLVMEngine*)cenv->engine(); + delete cenv; +} + |