aboutsummaryrefslogtreecommitdiffstats
path: root/llvm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm.cpp')
-rw-r--r--llvm.cpp54
1 files changed, 38 insertions, 16 deletions
diff --git a/llvm.cpp b/llvm.cpp
index 9597236..407e8f2 100644
--- a/llvm.cpp
+++ b/llvm.cpp
@@ -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;
+}
+