mirror of https://github.com/exaloop/codon.git
Update plugin errors
parent
ddca5263a9
commit
8f827da254
|
@ -136,12 +136,15 @@ std::unique_ptr<codon::Compiler> processSource(const std::vector<const char *> &
|
|||
|
||||
// load plugins
|
||||
for (const auto &plugin : plugins) {
|
||||
std::string errMsg;
|
||||
if (!compiler->load(plugin, &errMsg)) {
|
||||
codon::compilationError(errMsg, /*file=*/"", /*line=*/0, /*col=*/0,
|
||||
/*terminate=*/false);
|
||||
bool failed = false;
|
||||
llvm::handleAllErrors(
|
||||
compiler->load(plugin), [&failed](const codon::error::PluginErrorInfo &e) {
|
||||
codon::compilationError(e.getMessage(), /*file=*/"", /*line=*/0, /*col=*/0,
|
||||
/*terminate=*/false);
|
||||
failed = true;
|
||||
});
|
||||
if (failed)
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
bool failed = false;
|
||||
|
@ -155,7 +158,7 @@ std::unique_ptr<codon::Compiler> processSource(const std::vector<const char *> &
|
|||
|
||||
{
|
||||
TIME("compile");
|
||||
compiler->compile();
|
||||
llvm::cantFail(compiler->compile());
|
||||
}
|
||||
return compiler;
|
||||
}
|
||||
|
|
|
@ -25,21 +25,23 @@ Compiler::Compiler(const std::string &argv0, bool debug,
|
|||
llvisitor->setPluginManager(plm.get());
|
||||
}
|
||||
|
||||
bool Compiler::load(const std::string &plugin, std::string *errMsg) {
|
||||
if (auto *p = plm->load(plugin, errMsg)) {
|
||||
if (!p->info.stdlibPath.empty()) {
|
||||
cache->pluginImportPaths.push_back(p->info.stdlibPath);
|
||||
}
|
||||
for (auto &kw : p->dsl->getExprKeywords()) {
|
||||
cache->customExprStmts[kw.keyword] = kw.callback;
|
||||
}
|
||||
for (auto &kw : p->dsl->getBlockKeywords()) {
|
||||
cache->customBlockStmts[kw.keyword] = {kw.hasExpr, kw.callback};
|
||||
}
|
||||
p->dsl->addIRPasses(pm.get(), debug);
|
||||
return true;
|
||||
llvm::Error Compiler::load(const std::string &plugin) {
|
||||
auto result = plm->load(plugin);
|
||||
if (auto err = result.takeError())
|
||||
return err;
|
||||
|
||||
auto *p = *result;
|
||||
if (!p->info.stdlibPath.empty()) {
|
||||
cache->pluginImportPaths.push_back(p->info.stdlibPath);
|
||||
}
|
||||
return false;
|
||||
for (auto &kw : p->dsl->getExprKeywords()) {
|
||||
cache->customExprStmts[kw.keyword] = kw.callback;
|
||||
}
|
||||
for (auto &kw : p->dsl->getBlockKeywords()) {
|
||||
cache->customBlockStmts[kw.keyword] = {kw.hasExpr, kw.callback};
|
||||
}
|
||||
p->dsl->addIRPasses(pm.get(), debug);
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
llvm::Error
|
||||
|
@ -95,9 +97,10 @@ Compiler::parseCode(const std::string &file, const std::string &code, int startL
|
|||
return parse(/*isCode=*/true, file, code, startLine, testFlags, defines);
|
||||
}
|
||||
|
||||
void Compiler::compile() {
|
||||
llvm::Error Compiler::compile() {
|
||||
pm->run(module.get());
|
||||
llvisitor->visit(module.get());
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
llvm::Expected<std::string> Compiler::docgen(const std::vector<std::string> &files) {
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
ir::transform::PassManager *getPassManager() const { return pm.get(); }
|
||||
ir::LLVMVisitor *getLLVMVisitor() const { return llvisitor.get(); }
|
||||
|
||||
bool load(const std::string &plugin, std::string *errMsg);
|
||||
llvm::Error load(const std::string &plugin);
|
||||
llvm::Error
|
||||
parseFile(const std::string &file, int testFlags = 0,
|
||||
const std::unordered_map<std::string, std::string> &defines = {});
|
||||
|
@ -48,7 +48,7 @@ public:
|
|||
parseCode(const std::string &file, const std::string &code, int startLine = 0,
|
||||
int testFlags = 0,
|
||||
const std::unordered_map<std::string, std::string> &defines = {});
|
||||
void compile();
|
||||
llvm::Error compile();
|
||||
llvm::Expected<std::string> docgen(const std::vector<std::string> &files);
|
||||
};
|
||||
|
||||
|
|
|
@ -7,5 +7,7 @@ char ParserErrorInfo::ID = 0;
|
|||
|
||||
char RuntimeErrorInfo::ID = 0;
|
||||
|
||||
char PluginErrorInfo::ID = 0;
|
||||
|
||||
} // namespace error
|
||||
} // namespace codon
|
||||
|
|
|
@ -104,5 +104,23 @@ public:
|
|||
static char ID;
|
||||
};
|
||||
|
||||
class PluginErrorInfo : public llvm::ErrorInfo<PluginErrorInfo> {
|
||||
private:
|
||||
std::string message;
|
||||
|
||||
public:
|
||||
explicit PluginErrorInfo(const std::string &message) : message(message) {}
|
||||
|
||||
std::string getMessage() const { return message; }
|
||||
|
||||
void log(llvm::raw_ostream &out) const override { out << message; }
|
||||
|
||||
std::error_code convertToErrorCode() const override {
|
||||
return llvm::inconvertibleErrorCode();
|
||||
}
|
||||
|
||||
static char ID;
|
||||
};
|
||||
|
||||
} // namespace error
|
||||
} // namespace codon
|
||||
|
|
|
@ -10,10 +10,8 @@
|
|||
|
||||
namespace codon {
|
||||
namespace {
|
||||
Plugin *error(const std::string &msg, std::string *errMsg) {
|
||||
if (!msg.empty() && errMsg)
|
||||
*errMsg = msg;
|
||||
return nullptr;
|
||||
llvm::Expected<Plugin *> pluginError(const std::string &msg) {
|
||||
return llvm::make_error<error::PluginErrorInfo>(msg);
|
||||
}
|
||||
|
||||
typedef std::unique_ptr<DSL> LoadFunc();
|
||||
|
@ -21,7 +19,7 @@ typedef std::unique_ptr<DSL> LoadFunc();
|
|||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
Plugin *PluginManager::load(const std::string &path, std::string *errMsg) {
|
||||
llvm::Expected<Plugin *> PluginManager::load(const std::string &path) {
|
||||
#if __APPLE__
|
||||
const std::string libExt = "dylib";
|
||||
#else
|
||||
|
@ -40,9 +38,8 @@ Plugin *PluginManager::load(const std::string &path, std::string *errMsg) {
|
|||
try {
|
||||
tml = toml::parse_file(tomlPath.string());
|
||||
} catch (const toml::parse_error &e) {
|
||||
return error(
|
||||
fmt::format("[toml::parse_file(\"{}\")] {}", tomlPath.string(), e.what()),
|
||||
errMsg);
|
||||
return pluginError(
|
||||
fmt::format("[toml::parse_file(\"{}\")] {}", tomlPath.string(), e.what()));
|
||||
}
|
||||
auto about = tml["about"];
|
||||
auto library = tml["library"];
|
||||
|
@ -70,31 +67,26 @@ Plugin *PluginManager::load(const std::string &path, std::string *errMsg) {
|
|||
semver::version(CODON_VERSION_MAJOR, CODON_VERSION_MINOR, CODON_VERSION_PATCH),
|
||||
info.supported);
|
||||
} catch (const std::invalid_argument &e) {
|
||||
return error(fmt::format("[semver::range::satisfies(..., \"{}\")] {}",
|
||||
info.supported, e.what()),
|
||||
errMsg);
|
||||
return pluginError(fmt::format("[semver::range::satisfies(..., \"{}\")] {}",
|
||||
info.supported, e.what()));
|
||||
}
|
||||
if (!versionOk)
|
||||
return error(fmt::format("unsupported version {} (supported: {})", CODON_VERSION,
|
||||
info.supported),
|
||||
errMsg);
|
||||
return pluginError(fmt::format("unsupported version {} (supported: {})",
|
||||
CODON_VERSION, info.supported));
|
||||
|
||||
if (!dylibPath.empty()) {
|
||||
std::string libLoadErrorMsg;
|
||||
auto handle = llvm::sys::DynamicLibrary::getPermanentLibrary(dylibPath.c_str(),
|
||||
&libLoadErrorMsg);
|
||||
if (!handle.isValid())
|
||||
return error(
|
||||
fmt::format(
|
||||
"[llvm::sys::DynamicLibrary::getPermanentLibrary(\"{}\", ...)] {}",
|
||||
dylibPath, libLoadErrorMsg),
|
||||
errMsg);
|
||||
return pluginError(fmt::format(
|
||||
"[llvm::sys::DynamicLibrary::getPermanentLibrary(\"{}\", ...)] {}", dylibPath,
|
||||
libLoadErrorMsg));
|
||||
|
||||
auto *entry = (LoadFunc *)handle.getAddressOfSymbol("load");
|
||||
if (!entry)
|
||||
return error(
|
||||
fmt::format("could not find 'load' in plugin shared library: {}", dylibPath),
|
||||
errMsg);
|
||||
return pluginError(
|
||||
fmt::format("could not find 'load' in plugin shared library: {}", dylibPath));
|
||||
|
||||
auto dsl = (*entry)();
|
||||
plugins.push_back(std::make_unique<Plugin>(std::move(dsl), info, handle));
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "codon/compiler/error.h"
|
||||
#include "codon/dsl/dsl.h"
|
||||
#include "codon/sir/util/iterators.h"
|
||||
#include "llvm/Support/DynamicLibrary.h"
|
||||
|
@ -45,9 +46,8 @@ public:
|
|||
|
||||
/// Loads the plugin at the given load path.
|
||||
/// @param path path to plugin directory containing "plugin.toml" file
|
||||
/// @param errMsg where to store potential error messages, if non-null
|
||||
/// @return plugin pointer if successful, null otherwise
|
||||
Plugin *load(const std::string &path, std::string *errMsg = nullptr);
|
||||
/// @return plugin pointer if successful, plugin error otherwise
|
||||
llvm::Expected<Plugin *> load(const std::string &path);
|
||||
};
|
||||
|
||||
} // namespace codon
|
||||
|
|
|
@ -201,7 +201,7 @@ public:
|
|||
pm->registerPass(std::make_unique<TestOutliner>());
|
||||
pm->registerPass(std::make_unique<TestInliner>());
|
||||
|
||||
compiler->compile();
|
||||
llvm::cantFail(compiler->compile());
|
||||
compiler->getLLVMVisitor()->run({file});
|
||||
fflush(stdout);
|
||||
exit(EXIT_SUCCESS);
|
||||
|
|
Loading…
Reference in New Issue