Update JIT API to return outputs as string

pull/6/head
A. R. Shajii 2021-11-06 11:02:19 -04:00
parent e83c3e8fd6
commit f88d491144
3 changed files with 33 additions and 14 deletions

View File

@ -179,10 +179,15 @@ int runMode(const std::vector<const char *> &args) {
} }
namespace { namespace {
void jitExec(codon::jit::JIT *jit, const std::string &code) { std::string jitExec(codon::jit::JIT *jit, const std::string &code) {
auto result = jit->exec(code);
if (auto err = result.takeError()) {
llvm::handleAllErrors( llvm::handleAllErrors(
jit->exec(code), [](const codon::error::ParserErrorInfo &e) { display(e); }, std::move(err), [](const codon::error::ParserErrorInfo &e) { display(e); },
[](const codon::error::RuntimeErrorInfo &e) { /* nothing */ }); [](const codon::error::RuntimeErrorInfo &e) { /* nothing */ });
return "";
}
return *result;
} }
} // namespace } // namespace
@ -195,14 +200,13 @@ int jitMode(const std::vector<const char *> &args) {
if (line != "#%%") { if (line != "#%%") {
code += line + "\n"; code += line + "\n";
} else { } else {
jitExec(&jit, code); fmt::print("{}\n\n[done]\n\n", jitExec(&jit, code));
code = ""; code = "";
fmt::print("\n\n[done]\n\n");
fflush(stdout); fflush(stdout);
} }
} }
if (!code.empty()) if (!code.empty())
jitExec(&jit, code); fmt::print("{}\n\n[done]\n\n", jitExec(&jit, code));
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -1,5 +1,7 @@
#include "jit.h" #include "jit.h"
#include <sstream>
#include "codon/parser/peg/peg.h" #include "codon/parser/peg/peg.h"
#include "codon/parser/visitors/doc/doc.h" #include "codon/parser/visitors/doc/doc.h"
#include "codon/parser/visitors/format/format.h" #include "codon/parser/visitors/format/format.h"
@ -15,6 +17,15 @@ typedef int MainFunc(int, char **);
typedef void InputFunc(); typedef void InputFunc();
const std::string JIT_FILENAME = "<jit>"; const std::string JIT_FILENAME = "<jit>";
class CaptureOutput {
private:
std::streambuf *orig;
public:
CaptureOutput(std::streambuf *buf) : orig(std::cout.rdbuf(buf)) {}
~CaptureOutput() { std::cout.rdbuf(orig); }
};
} // namespace } // namespace
JIT::JIT(const std::string &argv0) JIT::JIT(const std::string &argv0)
@ -56,7 +67,8 @@ llvm::Error JIT::init() {
return llvm::Error::success(); return llvm::Error::success();
} }
llvm::Error JIT::run(const ir::Func *input, const std::vector<ir::Var *> &newGlobals) { llvm::Expected<std::string> JIT::run(const ir::Func *input,
const std::vector<ir::Var *> &newGlobals) {
auto *llvisitor = compiler->getLLVMVisitor(); auto *llvisitor = compiler->getLLVMVisitor();
const std::string name = ir::LLVMVisitor::getNameForFunction(input); const std::string name = ir::LLVMVisitor::getNameForFunction(input);
llvisitor->registerGlobal(input); llvisitor->registerGlobal(input);
@ -72,20 +84,22 @@ llvm::Error JIT::run(const ir::Func *input, const std::vector<ir::Var *> &newGlo
llvm::StripDebugInfo(*pair.first); // TODO: needed? llvm::StripDebugInfo(*pair.first); // TODO: needed?
if (auto err = engine->addModule({std::move(pair.first), std::move(pair.second)})) if (auto err = engine->addModule({std::move(pair.first), std::move(pair.second)}))
return err; return std::move(err);
auto func = engine->lookup(name); auto func = engine->lookup(name);
if (auto err = func.takeError()) if (auto err = func.takeError())
return err; return std::move(err);
auto *repl = (InputFunc *)func->getAddress(); auto *repl = (InputFunc *)func->getAddress();
std::stringstream buffer;
try { try {
CaptureOutput(buffer.rdbuf());
(*repl)(); (*repl)();
} catch (const seq_jit_error &err) { } catch (const seq_jit_error &err) {
return llvm::make_error<error::RuntimeErrorInfo>( return llvm::make_error<error::RuntimeErrorInfo>(
err.getType(), err.what(), err.getFile(), err.getLine(), err.getCol()); err.getType(), err.what(), err.getFile(), err.getLine(), err.getCol());
} }
return llvm::Error::success(); return buffer.str();
} }
std::pair<ir::Func *, std::vector<ir::Var *>> std::pair<ir::Func *, std::vector<ir::Var *>>
@ -124,7 +138,7 @@ JIT::transformSimplified(const ast::StmtPtr &simplified) {
return {func, globalVars}; return {func, globalVars};
} }
llvm::Error JIT::exec(const std::string &code) { llvm::Expected<std::string> JIT::exec(const std::string &code) {
auto *cache = compiler->getCache(); auto *cache = compiler->getCache();
ast::StmtPtr node = ast::parseCode(cache, JIT_FILENAME, code, /*startLine=*/0); ast::StmtPtr node = ast::parseCode(cache, JIT_FILENAME, code, /*startLine=*/0);

View File

@ -23,8 +23,9 @@ private:
public: public:
explicit JIT(const std::string &argv0); explicit JIT(const std::string &argv0);
llvm::Error init(); llvm::Error init();
llvm::Error run(const ir::Func *input, const std::vector<ir::Var *> &newGlobals = {}); llvm::Expected<std::string> run(const ir::Func *input,
llvm::Error exec(const std::string &code); const std::vector<ir::Var *> &newGlobals = {});
llvm::Expected<std::string> exec(const std::string &code);
private: private:
std::pair<ir::Func *, std::vector<ir::Var *>> std::pair<ir::Func *, std::vector<ir::Var *>>