Merge remote-tracking branch 'origin/incoming' into stable
This commit is contained in:
commit
acbbb7da37
|
@ -78,16 +78,20 @@ if (${IS_GNU} OR ${IS_CLANG})
|
||||||
else()
|
else()
|
||||||
set(IS_HOST_NOT_ANDROID 0)
|
set(IS_HOST_NOT_ANDROID 0)
|
||||||
endif()
|
endif()
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "--closure 1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=${IS_HOST_NOT_ANDROID} -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sSTRICT=1 -sMINIMAL_RUNTIME=0 -sDISABLE_EXCEPTION_CATCHING=0 -sALLOW_MEMORY_GROWTH=1 -Wno-pthreads-mem-growth -sMEMORY_GROWTH_GEOMETRIC_STEP=0 -sDECLARE_ASM_MODULE_EXPORTS=0 ${CMAKE_EXE_LINKER_FLAGS}")
|
set(CMAKE_EXE_LINKER_FLAGS "--closure 1 --closure-args=\"--compilation_level SIMPLE\" -lnodefs.js -lembind -sDYNAMIC_EXECUTION=0 -sFORCE_FILESYSTEM=1 -sWASM=0 --memory-init-file 0 -sEXPORTED_FUNCTIONS=_main -sEXIT_RUNTIME=1 -sSINGLE_FILE=1 -sSAFE_HEAP=${IS_HOST_NOT_ANDROID} -sMALLOC='emmalloc' -sABORTING_MALLOC=0 -sJS_MATH=1 -sENVIRONMENT='web,webview,worker,node,shell' -sNODEJS_CATCH_EXIT=0 -sSTRICT=1 -sMINIMAL_RUNTIME=0 -sDISABLE_EXCEPTION_CATCHING=0 -sSTACK_SIZE=8MB -sALLOW_MEMORY_GROWTH=1 -Wno-pthreads-mem-growth -sMEMORY_GROWTH_GEOMETRIC_STEP=0 -sDECLARE_ASM_MODULE_EXPORTS=1 -sDEMANGLE_SUPPORT=1 ${CMAKE_EXE_LINKER_FLAGS}")
|
||||||
if (CMAKE_USE_PTHREADS_INIT)
|
if (CMAKE_USE_PTHREADS_INIT)
|
||||||
set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS}") # Emscripten requires the -pthread flag
|
set(CMAKE_CXX_FLAGS "-pthread ${CMAKE_CXX_FLAGS}") # Emscripten requires the -pthread flag
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "--closure-args=\"--compilation_level SIMPLE\" -sPROXY_TO_PTHREAD=1 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706
|
set(CMAKE_EXE_LINKER_FLAGS "-sPROXY_TO_PTHREAD=0 -sPTHREAD_POOL_SIZE=3 ${CMAKE_EXE_LINKER_FLAGS}") # See https://github.com/emscripten-core/emscripten/issues/16706
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-s")
|
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-Wl,--gc-sections -s")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstrict-enums -pipe -funwind-tables -fasynchronous-unwind-tables -frtti -fexceptions")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstrict-enums -pipe -funwind-tables -fasynchronous-unwind-tables -frtti -fexceptions")
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections -fmerge-all-constants -ftree-vectorize -fno-math-errno")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections -fmerge-all-constants -ftree-vectorize -fno-math-errno")
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
|
check_cxx_compiler_flag("-Oz" Z_OPTIMIZATION_SUPPORTED)
|
||||||
|
if (Z_OPTIMIZATION_SUPPORTED OR EMSCRIPTEN)
|
||||||
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Oz")
|
||||||
|
endif()
|
||||||
set(CF_PROTECTION "-fcf-protection")
|
set(CF_PROTECTION "-fcf-protection")
|
||||||
check_cxx_compiler_flag("${CF_PROTECTION}" CF_PROTECTION_SUPPORTED)
|
check_cxx_compiler_flag("${CF_PROTECTION}" CF_PROTECTION_SUPPORTED)
|
||||||
if (CF_PROTECTION_SUPPORTED)
|
if (CF_PROTECTION_SUPPORTED)
|
||||||
|
|
|
@ -7,8 +7,7 @@ boolean use_yarn_or_npm() { return fileExists('/usr/bin/yarn') || fileExists('/u
|
||||||
- Sidebar Link
|
- Sidebar Link
|
||||||
- Workspace Cleanup
|
- Workspace Cleanup
|
||||||
Required Compilers:
|
Required Compilers:
|
||||||
- G++ cross-compiler for riscv64
|
- Musl cross-compiling toolchains (archives ending in "-cross" from https://musl.cc/#binaries) for x86_64, i686, armel, armhf, aarch64 and riscv64, unzipped into /usr/, along with soft links from /usr/bin/ to the binaries
|
||||||
- Musl cross-compiling toolchains (archives ending in "-cross" from https://musl.cc/#binaries) for x86_64, i686, armel, armhf and aarch64, unzipped into /usr/, along with soft links from /usr/bin/ to the binaries
|
|
||||||
- Emscripten Clang (https://github.com/emscripten-core/emsdk) in /usr/share/
|
- Emscripten Clang (https://github.com/emscripten-core/emsdk) in /usr/share/
|
||||||
- MinGW32 G++/Clang (https://github.com/mstorsjo/llvm-mingw) for x86_64, i686, armhf and aarch64, (unzip the content of the folder in the tar.xz file) in /usr/, along with soft links from /usr/bin/ to the binaries
|
- MinGW32 G++/Clang (https://github.com/mstorsjo/llvm-mingw) for x86_64, i686, armhf and aarch64, (unzip the content of the folder in the tar.xz file) in /usr/, along with soft links from /usr/bin/ to the binaries
|
||||||
Optional Tools:
|
Optional Tools:
|
||||||
|
@ -44,7 +43,7 @@ pipeline {
|
||||||
'armel-linux-musleabi (RPM=armv4l, DEB=armel)',
|
'armel-linux-musleabi (RPM=armv4l, DEB=armel)',
|
||||||
'armv7l-linux-musleabihf (RPM=armv7hl, DEB=armhf)',
|
'armv7l-linux-musleabihf (RPM=armv7hl, DEB=armhf)',
|
||||||
'aarch64-linux-musl (RPM=aarch64, DEB=arm64)',
|
'aarch64-linux-musl (RPM=aarch64, DEB=arm64)',
|
||||||
'riscv64-linux-gnu (RPM=riscv64, DEB=riscv64)',
|
'riscv64-linux-musl (RPM=riscv64, DEB=riscv64)',
|
||||||
'x86_64-w64-mingw32 (RPM=x86_64, DEB=amd64)',
|
'x86_64-w64-mingw32 (RPM=x86_64, DEB=amd64)',
|
||||||
'i686-w64-mingw32 (RPM=i386, DEB=i386)',
|
'i686-w64-mingw32 (RPM=i386, DEB=i386)',
|
||||||
'armv7-w64-mingw32 (RPM=armv7hl, DEB=armhf)',
|
'armv7-w64-mingw32 (RPM=armv7hl, DEB=armhf)',
|
||||||
|
|
|
@ -32,6 +32,35 @@
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#ifdef EMSCRIPTEN
|
||||||
|
#include <emscripten.h>
|
||||||
|
static bool is_node;
|
||||||
|
void emscripten_exit(int status) {
|
||||||
|
MAIN_THREAD_EM_ASM("yerbacon_output = Module.get_cout();");
|
||||||
|
if (not is_node) emscripten_exit_with_live_runtime();
|
||||||
|
std::exit(status);
|
||||||
|
}
|
||||||
|
#define exit(status) emscripten_exit(status)
|
||||||
|
#include <sstream>
|
||||||
|
static std::ostringstream string_cout;
|
||||||
|
#define cout (is_node ? std::cout : string_cout)
|
||||||
|
#define cerr (is_node ? std::cerr : string_cout)
|
||||||
|
std::string get_cout() {
|
||||||
|
static size_t previous_cout_size = 0;
|
||||||
|
std::string output = string_cout.str();
|
||||||
|
const size_t current_size = output.size();
|
||||||
|
output = output.substr(previous_cout_size, current_size);
|
||||||
|
previous_cout_size = current_size;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
#include <emscripten/bind.h>
|
||||||
|
EMSCRIPTEN_BINDINGS() {
|
||||||
|
emscripten::function("get_cout", &get_cout);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
using std::exit;
|
||||||
|
using std::cout;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Yerbacon {
|
namespace Yerbacon {
|
||||||
consteval const char* getVersion() noexcept { return YBCON_VERSION; }
|
consteval const char* getVersion() noexcept { return YBCON_VERSION; }
|
||||||
|
@ -43,10 +72,10 @@ namespace Yerbacon {
|
||||||
}
|
}
|
||||||
static void fail(const std::initializer_list<const char*> reason) {
|
static void fail(const std::initializer_list<const char*> reason) {
|
||||||
std::for_each(reason.begin(), reason.end(), [](const char* current_string){
|
std::for_each(reason.begin(), reason.end(), [](const char* current_string){
|
||||||
std::cout << current_string;
|
cout << current_string;
|
||||||
});
|
});
|
||||||
std::cout << std::endl;
|
cout << std::endl;
|
||||||
std::exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
inline void fail(const char* reason) { fail({reason}); }
|
inline void fail(const char* reason) { fail({reason}); }
|
||||||
class Exception: public std::exception {
|
class Exception: public std::exception {
|
||||||
|
|
|
@ -19,7 +19,9 @@ inline const char* ID(const ReservedIdentifier& identifier) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool reserved(const string_view words) {
|
bool reserved(const string_view words) {
|
||||||
return find(identifiers.cbegin(), identifiers.cend(), words) != identifiers.cend();
|
return any_of(identifiers.cbegin(), identifiers.cend(), [&words](const auto& identifier) {
|
||||||
|
return words == identifier;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //YERBACON_RESERVEDIDENTIFIERS_HPP
|
#endif //YERBACON_RESERVEDIDENTIFIERS_HPP
|
||||||
|
|
50
src/main.cpp
50
src/main.cpp
|
@ -19,6 +19,9 @@ int main(int argc, char* argv[]) {
|
||||||
using unit_result = pair<string, optional<Yerbacon::Exception>>;
|
using unit_result = pair<string, optional<Yerbacon::Exception>>;
|
||||||
using unit = future<unit_result>;
|
using unit = future<unit_result>;
|
||||||
map<string_view, unit> Units;
|
map<string_view, unit> Units;
|
||||||
|
#ifdef EMSCRIPTEN
|
||||||
|
is_node = MAIN_THREAD_EM_ASM_INT({ return ENVIRONMENT_IS_NODE; });
|
||||||
|
#endif
|
||||||
for (signed int i = 1; i < argc; ++i)
|
for (signed int i = 1; i < argc; ++i)
|
||||||
{
|
{
|
||||||
const string_view currentArgument (argv[i]);
|
const string_view currentArgument (argv[i]);
|
||||||
|
@ -42,24 +45,41 @@ int main(int argc, char* argv[]) {
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
if (not parallel) omp_set_num_threads(1);
|
if (not parallel) omp_set_num_threads(1);
|
||||||
#endif
|
#endif
|
||||||
Units.insert_or_assign(currentArgument, async(not parallel ? launch::deferred : launch::async, [currentArgument, &text_provided, &target, &newLines]() {
|
optional file_path = make_optional<filesystem::path>();
|
||||||
|
if (not text_provided) {
|
||||||
|
file_path = filesystem::path(currentArgument);
|
||||||
|
#ifdef EMSCRIPTEN
|
||||||
|
if (currentArgument.size() >= 2 and currentArgument[1] == ':') {
|
||||||
|
auto path = string(currentArgument).erase(0, 2);
|
||||||
|
replace(path.begin(), path.end(), '\\', '/');
|
||||||
|
file_path = path;
|
||||||
|
}
|
||||||
|
const string directory = filesystem::path(file_path.value()).remove_filename();
|
||||||
|
for (unsigned int character = 1; character < directory.size(); ++character) {
|
||||||
|
const string sub_directory = directory.substr(0, character);
|
||||||
|
if (is_node and (directory[character] == '/') and not filesystem::is_directory(sub_directory)) {
|
||||||
|
MAIN_THREAD_EM_ASM({
|
||||||
|
const sub_directory = UTF8ToString($0);
|
||||||
|
if (!FS.isMountpoint(sub_directory)) {
|
||||||
|
try {
|
||||||
|
FS.mkdir(sub_directory);
|
||||||
|
FS.mount(NODEFS, {root: sub_directory}, sub_directory);
|
||||||
|
} catch (exception) {}
|
||||||
|
};
|
||||||
|
}, sub_directory.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Units.insert_or_assign(currentArgument, async(not parallel ? launch::deferred : launch::async, [&, currentArgument, file_path]() {
|
||||||
unit_result resultingPair;
|
unit_result resultingPair;
|
||||||
try {
|
try {
|
||||||
resultingPair.first = Target::forName(target, newLines)->transpileWithTree(
|
resultingPair.first = Target::forName(target, newLines)->transpileWithTree(
|
||||||
parseString(text_provided ? currentArgument : getFileContent(currentArgument.data()))
|
parseString(text_provided ? currentArgument : getFileContent(file_path->string()))
|
||||||
);
|
);
|
||||||
if (not text_provided) outputFileContent(string(currentArgument.substr(0, currentArgument.size() - 6)) + '.' + target, resultingPair.first);
|
if (not text_provided) outputFileContent(filesystem::path(file_path.value()).replace_extension(target).string(), resultingPair.first);
|
||||||
} catch (const Yerbacon::Exception& error) {
|
} catch (const Yerbacon::Exception& error) {
|
||||||
size_t lastSlash = 0;
|
resultingPair.first = file_path.has_value() ? file_path->filename().string() : string();
|
||||||
const size_t position1 = currentArgument.find_last_of('/');
|
|
||||||
if (cmp_not_equal(position1, string_view::npos)) lastSlash = position1;
|
|
||||||
if constexpr(filesystem::path::preferred_separator != '/') {
|
|
||||||
const size_t position2 = currentArgument.find_last_of(filesystem::path::preferred_separator);
|
|
||||||
if (cmp_not_equal(position2, string_view::npos)) {
|
|
||||||
lastSlash = max(lastSlash, position2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resultingPair.first = currentArgument.substr(lastSlash + 1);
|
|
||||||
resultingPair.second.emplace(error);
|
resultingPair.second.emplace(error);
|
||||||
}
|
}
|
||||||
return resultingPair;
|
return resultingPair;
|
||||||
|
@ -89,9 +109,9 @@ int main(int argc, char* argv[]) {
|
||||||
} else {
|
} else {
|
||||||
cout << "Compilation"; if (not text_provided) cout << " of " << result.first; cout << " has failed with the following error:" << endl;
|
cout << "Compilation"; if (not text_provided) cout << " of " << result.first; cout << " has failed with the following error:" << endl;
|
||||||
cerr << result.second.value().what() << '\n';
|
cerr << result.second.value().what() << '\n';
|
||||||
return EXIT_FAILURE;
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else cout << (!text_provided ? "No valid file provided" : "No text was provided") << ".\n";
|
} else cout << (!text_provided ? "No valid file provided" : "No text was provided") << ".\n";
|
||||||
return EXIT_SUCCESS;
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
Loading…
Reference in New Issue