diff options
Diffstat (limited to 'src/yue.cpp')
| -rw-r--r-- | src/yue.cpp | 47 |
1 files changed, 42 insertions, 5 deletions
diff --git a/src/yue.cpp b/src/yue.cpp index fc57767..2722c55 100644 --- a/src/yue.cpp +++ b/src/yue.cpp | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* Copyright (c) 2017-2025 Li Jin <dragon-fly@qq.com> | 1 | /* Copyright (c) 2017-2026 Li Jin <dragon-fly@qq.com> |
| 2 | 2 | ||
| 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: |
| 4 | 4 | ||
| @@ -30,6 +30,38 @@ using namespace std::chrono_literals; | |||
| 30 | #include "ghc/fs_std.hpp" | 30 | #include "ghc/fs_std.hpp" |
| 31 | #include "linenoise.hpp" | 31 | #include "linenoise.hpp" |
| 32 | 32 | ||
| 33 | #if __has_include(<pthread.h>) | ||
| 34 | #include <pthread.h> | ||
| 35 | template<class R> | ||
| 36 | std::future<R> async(const std::function<R()>& f) { | ||
| 37 | using Fn = std::packaged_task<R()>; | ||
| 38 | auto task = new Fn(f); | ||
| 39 | std::future<R> fut = task->get_future(); | ||
| 40 | |||
| 41 | pthread_attr_t attr; | ||
| 42 | pthread_attr_init(&attr); | ||
| 43 | pthread_attr_setstacksize(&attr, 8 * 1024 * 1024); | ||
| 44 | |||
| 45 | pthread_t th; | ||
| 46 | pthread_create(&th, &attr, | ||
| 47 | [](void* p)->void* { | ||
| 48 | std::unique_ptr<Fn> fn(static_cast<Fn*>(p)); | ||
| 49 | (*fn)(); | ||
| 50 | return nullptr; | ||
| 51 | }, | ||
| 52 | task); | ||
| 53 | pthread_attr_destroy(&attr); | ||
| 54 | pthread_detach(th); | ||
| 55 | return fut; | ||
| 56 | } | ||
| 57 | #else | ||
| 58 | template<class R> | ||
| 59 | std::future<R> async(const std::function<R()>& f) { | ||
| 60 | // fallback: ignore stack size | ||
| 61 | return std::async(std::launch::async, f); | ||
| 62 | } | ||
| 63 | #endif | ||
| 64 | |||
| 33 | #if not(defined YUE_NO_MACRO && defined YUE_COMPILER_ONLY) | 65 | #if not(defined YUE_NO_MACRO && defined YUE_COMPILER_ONLY) |
| 34 | #define _DEFER(code, line) std::shared_ptr<void> _defer_##line(nullptr, [&](auto) { \ | 66 | #define _DEFER(code, line) std::shared_ptr<void> _defer_##line(nullptr, [&](auto) { \ |
| 35 | code; \ | 67 | code; \ |
| @@ -40,18 +72,23 @@ extern "C" { | |||
| 40 | #include "lua.h" | 72 | #include "lua.h" |
| 41 | #include "lualib.h" | 73 | #include "lualib.h" |
| 42 | int luaopen_yue(lua_State* L); | 74 | int luaopen_yue(lua_State* L); |
| 75 | int luaopen_colibc_json(lua_State* L); | ||
| 43 | } // extern "C" | 76 | } // extern "C" |
| 44 | 77 | ||
| 45 | static void openlibs(void* state) { | 78 | static void openlibs(void* state) { |
| 46 | lua_State* L = static_cast<lua_State*>(state); | 79 | lua_State* L = static_cast<lua_State*>(state); |
| 80 | int top = lua_gettop(L); | ||
| 81 | DEFER(lua_settop(L, top)); | ||
| 47 | luaL_openlibs(L); | 82 | luaL_openlibs(L); |
| 48 | #if LUA_VERSION_NUM > 501 | 83 | #if LUA_VERSION_NUM > 501 |
| 49 | luaL_requiref(L, "yue", luaopen_yue, 0); | 84 | luaL_requiref(L, "yue", luaopen_yue, 0); |
| 85 | luaL_requiref(L, "cojson", luaopen_colibc_json, 0); | ||
| 50 | #else | 86 | #else |
| 51 | lua_pushcfunction(L, luaopen_yue); | 87 | lua_pushcfunction(L, luaopen_yue); |
| 52 | lua_call(L, 0, 0); | 88 | lua_call(L, 0, 0); |
| 89 | lua_pushcfunction(L, luaopen_colibc_json); | ||
| 90 | lua_call(L, 0, 0); | ||
| 53 | #endif | 91 | #endif |
| 54 | lua_pop(L, 1); | ||
| 55 | } | 92 | } |
| 56 | 93 | ||
| 57 | void pushYue(lua_State* L, std::string_view name) { | 94 | void pushYue(lua_State* L, std::string_view name) { |
| @@ -304,7 +341,7 @@ int main(int narg, const char** args) { | |||
| 304 | " -- Read from standard in, print to standard out\n" | 341 | " -- Read from standard in, print to standard out\n" |
| 305 | " (Must be first and only argument)\n\n" | 342 | " (Must be first and only argument)\n\n" |
| 306 | " --target=version Specify the Lua version that codes will be generated to\n" | 343 | " --target=version Specify the Lua version that codes will be generated to\n" |
| 307 | " (version can only be 5.1, 5.2, 5.3 or 5.4)\n" | 344 | " (version can only be 5.1 to 5.5)\n" |
| 308 | " --path=path_str Append an extra Lua search path string to package.path\n\n" | 345 | " --path=path_str Append an extra Lua search path string to package.path\n\n" |
| 309 | " Execute without options to enter REPL, type symbol '$'\n" | 346 | " Execute without options to enter REPL, type symbol '$'\n" |
| 310 | " in a single line to start/stop multi-line mode\n" | 347 | " in a single line to start/stop multi-line mode\n" |
| @@ -699,7 +736,7 @@ int main(int narg, const char** args) { | |||
| 699 | } | 736 | } |
| 700 | std::list<std::future<std::string>> results; | 737 | std::list<std::future<std::string>> results; |
| 701 | for (const auto& file : files) { | 738 | for (const auto& file : files) { |
| 702 | auto task = std::async(std::launch::async, [=]() { | 739 | auto task = async<std::string>([=]() { |
| 703 | #ifndef YUE_COMPILER_ONLY | 740 | #ifndef YUE_COMPILER_ONLY |
| 704 | return compileFile(fs::absolute(file.first), config, fullWorkPath, fullTargetPath, minify, rewrite); | 741 | return compileFile(fs::absolute(file.first), config, fullWorkPath, fullTargetPath, minify, rewrite); |
| 705 | #else | 742 | #else |
| @@ -737,7 +774,7 @@ int main(int narg, const char** args) { | |||
| 737 | #endif // YUE_NO_WATCHER | 774 | #endif // YUE_NO_WATCHER |
| 738 | std::list<std::future<std::tuple<int, std::string, std::string>>> results; | 775 | std::list<std::future<std::tuple<int, std::string, std::string>>> results; |
| 739 | for (const auto& file : files) { | 776 | for (const auto& file : files) { |
| 740 | auto task = std::async(std::launch::async, [=]() { | 777 | auto task = async<std::tuple<int, std::string, std::string>>([=]() { |
| 741 | std::ifstream input(file.first, std::ios::in); | 778 | std::ifstream input(file.first, std::ios::in); |
| 742 | if (input) { | 779 | if (input) { |
| 743 | std::string s( | 780 | std::string s( |
