aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorwhitequark <whitequark@whitequark.org>2019-11-11 09:23:06 +0000
committerwhitequark <whitequark@whitequark.org>2020-04-30 18:56:25 +0000
commitb43c282e4e0de53b9323a5d8d85b07bc73324a17 (patch)
treeab7a0beb69f8f4cb7588128fbe248343665b1d7d /kernel
parentbc380b0b56e0fa269a0d5844280cc4419d438d3a (diff)
downloadyosys-b43c282e4e0de53b9323a5d8d85b07bc73324a17.tar.gz
yosys-b43c282e4e0de53b9323a5d8d85b07bc73324a17.tar.bz2
yosys-b43c282e4e0de53b9323a5d8d85b07bc73324a17.zip
Add WASI platform support.
This includes the following significant changes: * Patching ezsat and minisat to disable resource limiting code on WASM/WASI, since the POSIX functions they use are unavailable. * Adding a new definition, YOSYS_DISABLE_SPAWN, present if platform does not support spawning subprocesses (i.e. Emscripten or WASI). This definition hides the definition of `run_command()`. * Adding a new Makefile flag, DISABLE_SPAWN, present in the same condition. This flag disables all passes that require spawning subprocesses for their function.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/driver.cc17
-rw-r--r--kernel/register.cc4
-rw-r--r--kernel/yosys.cc27
-rw-r--r--kernel/yosys.h2
4 files changed, 40 insertions, 10 deletions
diff --git a/kernel/driver.cc b/kernel/driver.cc
index 5f0959776..57ed7b8b4 100644
--- a/kernel/driver.cc
+++ b/kernel/driver.cc
@@ -155,6 +155,19 @@ int yosys_history_offset = 0;
std::string yosys_history_file;
#endif
+#if defined(__wasm)
+extern "C" {
+ // FIXME: WASI does not currently support exceptions.
+ void* __cxa_allocate_exception(size_t thrown_size) throw() {
+ return malloc(thrown_size);
+ }
+ bool __cxa_uncaught_exception() throw();
+ void __cxa_throw(void* thrown_exception, struct std::type_info * tinfo, void (*dest)(void*)) {
+ std::terminate();
+ }
+}
+#endif
+
void yosys_atexit()
{
#if defined(YOSYS_ENABLE_READLINE) || defined(YOSYS_ENABLE_EDITLINE)
@@ -587,9 +600,11 @@ int main(int argc, char **argv)
ru_buffer.ru_utime.tv_usec += ru_buffer_children.ru_utime.tv_usec;
ru_buffer.ru_stime.tv_sec += ru_buffer_children.ru_stime.tv_sec;
ru_buffer.ru_stime.tv_usec += ru_buffer_children.ru_stime.tv_usec;
+#if defined(__linux__) || defined(__FreeBSD__)
ru_buffer.ru_maxrss = std::max(ru_buffer.ru_maxrss, ru_buffer_children.ru_maxrss);
+#endif
}
-# if defined(__linux__) || defined(__FreeBSD__)
+#if defined(__linux__) || defined(__FreeBSD__)
meminfo = stringf(", MEM: %.2f MB peak",
ru_buffer.ru_maxrss / 1024.0);
#endif
diff --git a/kernel/register.cc b/kernel/register.cc
index 925d0d776..02974e534 100644
--- a/kernel/register.cc
+++ b/kernel/register.cc
@@ -238,6 +238,7 @@ void Pass::call(RTLIL::Design *design, std::string command)
return;
if (tok[0] == '!') {
+#if !defined(YOSYS_DISABLE_SPAWN)
cmd_buf = command.substr(command.find('!') + 1);
while (!cmd_buf.empty() && (cmd_buf.back() == ' ' || cmd_buf.back() == '\t' ||
cmd_buf.back() == '\r' || cmd_buf.back() == '\n'))
@@ -247,6 +248,9 @@ void Pass::call(RTLIL::Design *design, std::string command)
if (retCode != 0)
log_cmd_error("Shell command returned error code %d.\n", retCode);
return;
+#else
+ log_cmd_error("Shell is not available.\n");
+#endif
}
while (!tok.empty()) {
diff --git a/kernel/yosys.cc b/kernel/yosys.cc
index 01131601f..2ec3dca0c 100644
--- a/kernel/yosys.cc
+++ b/kernel/yosys.cc
@@ -45,8 +45,10 @@
# include <unistd.h>
# include <dirent.h>
# include <sys/types.h>
-# include <sys/wait.h>
# include <sys/stat.h>
+# if !defined(YOSYS_DISABLE_SPAWN)
+# include <sys/wait.h>
+# endif
#endif
#if !defined(_WIN32) && defined(YOSYS_ENABLE_GLOB)
@@ -336,16 +338,13 @@ bool patmatch(const char *pattern, const char *string)
return false;
}
+#if !defined(YOSYS_DISABLE_SPAWN)
int run_command(const std::string &command, std::function<void(const std::string&)> process_line)
{
if (!process_line)
return system(command.c_str());
-#ifdef EMSCRIPTEN
- FILE *f = nullptr;
-#else
FILE *f = popen(command.c_str(), "r");
-#endif
if (f == nullptr)
return -1;
@@ -368,10 +367,16 @@ int run_command(const std::string &command, std::function<void(const std::string
return WEXITSTATUS(ret);
#endif
}
+#endif
std::string make_temp_file(std::string template_str)
{
-#ifdef _WIN32
+#if defined(__wasm)
+ size_t pos = template_str.rfind("XXXXXX");
+ log_assert(pos != std::string::npos);
+ static size_t index = 0;
+ template_str.replace(pos, 6, stringf("%06zu", index++));
+#elif defined(_WIN32)
if (template_str.rfind("/tmp/", 0) == 0) {
# ifdef __MINGW32__
char longpath[MAX_PATH + 1];
@@ -420,10 +425,14 @@ std::string make_temp_file(std::string template_str)
std::string make_temp_dir(std::string template_str)
{
-#ifdef _WIN32
+#if defined(_WIN32)
template_str = make_temp_file(template_str);
mkdir(template_str.c_str());
return template_str;
+#elif defined(__wasm)
+ template_str = make_temp_file(template_str);
+ mkdir(template_str.c_str(), 0777);
+ return template_str;
#else
# ifndef NDEBUG
size_t pos = template_str.rfind("XXXXXX");
@@ -806,7 +815,7 @@ std::string proc_self_dirname()
path += char(shortpath[i]);
return path;
}
-#elif defined(EMSCRIPTEN)
+#elif defined(EMSCRIPTEN) || defined(__wasm)
std::string proc_self_dirname()
{
return "/";
@@ -815,7 +824,7 @@ std::string proc_self_dirname()
#error "Don't know how to determine process executable base path!"
#endif
-#ifdef EMSCRIPTEN
+#if defined(EMSCRIPTEN) || defined(__wasm)
std::string proc_share_dirname()
{
return "/share/";
diff --git a/kernel/yosys.h b/kernel/yosys.h
index ed48eec09..af1e376b1 100644
--- a/kernel/yosys.h
+++ b/kernel/yosys.h
@@ -264,7 +264,9 @@ int readsome(std::istream &f, char *s, int n);
std::string next_token(std::string &text, const char *sep = " \t\r\n", bool long_strings = false);
std::vector<std::string> split_tokens(const std::string &text, const char *sep = " \t\r\n");
bool patmatch(const char *pattern, const char *string);
+#if !defined(YOSYS_DISABLE_SPAWN)
int run_command(const std::string &command, std::function<void(const std::string&)> process_line = std::function<void(const std::string&)>());
+#endif
std::string make_temp_file(std::string template_str = "/tmp/yosys_XXXXXX");
std::string make_temp_dir(std::string template_str = "/tmp/yosys_XXXXXX");
bool check_file_exists(std::string filename, bool is_exec = false);