浏览代码

Everywhere: Add support for compilation under emscripten

Co-Authored-By: Andrew Kaster <akaster@serenityos.org>
Ali Mohammad Pur 2 年之前
父节点
当前提交
2110e7cf85

+ 8 - 0
AK/Platform.h

@@ -19,6 +19,10 @@
 #    define AK_ARCH_AARCH64 1
 #endif
 
+#ifdef __wasm32__
+#    define AK_ARCH_WASM32 1
+#endif
+
 #if (defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8) || defined(_WIN64)
 #    define AK_ARCH_64_BIT
 #else
@@ -83,6 +87,10 @@
 #endif
 // clang-format on
 
+#if defined(__EMSCRIPTEN__)
+#    define AK_OS_EMSCRIPTEN
+#endif
+
 #define ARCH(arch) (defined(AK_ARCH_##arch) && AK_ARCH_##arch)
 
 #if ARCH(I386) || ARCH(X86_64)

+ 3 - 1
AK/StackInfo.cpp

@@ -68,7 +68,9 @@ StackInfo::StackInfo()
     }
     m_base = top_of_stack - m_size;
 #else
-    VERIFY_NOT_REACHED();
+#    pragma message "StackInfo not supported on this platform! Recursion checks and stack scans may not work properly"
+    m_size = (size_t)~0;
+    m_base = 0;
 #endif
 
     m_top = m_base + m_size;

+ 17 - 7
Meta/Lagom/CMakeLists.txt

@@ -93,6 +93,12 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
 
 set(CMAKE_INSTALL_MESSAGE NEVER)
 
+if (EMSCRIPTEN)
+    set(CMAKE_EXECUTABLE_SUFFIX ".js")
+    add_compile_options(-gsource-map)
+    add_link_options(--emrun "SHELL:-s ALLOW_MEMORY_GROWTH")
+endif()
+
 if (ENABLE_ADDRESS_SANITIZER)
     add_compile_options(-fsanitize=address -fno-omit-frame-pointer)
     set(LINKER_FLAGS "${LINKER_FLAGS} -fsanitize=address")
@@ -290,7 +296,7 @@ endif()
 add_library(LibC INTERFACE)
 add_library(LibCrypt INTERFACE)
 add_library(LibSystem INTERFACE)
-if (NOT APPLE AND NOT ANDROID AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD")
+if (NOT APPLE AND NOT ANDROID AND NOT EMSCRIPTEN AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD")
     target_link_libraries(LibCrypt INTERFACE crypt) # LibCore::Account uses crypt() but it's not in libcrypt on macOS
 endif()
 if (SERENITYOS)
@@ -395,7 +401,7 @@ if (BUILD_LAGOM)
 
     # FIXME: Excluding arm64 is a temporary hack to circumvent a build problem
     #        for Lagom on Apple M1
-    if (NOT CMAKE_SYSTEM_PROCESSOR MATCHES "arm64")
+    if (NOT CMAKE_SYSTEM_PROCESSOR MATCHES "arm64" AND NOT EMSCRIPTEN)
         # FIXME: Create a LIBELF_SOURCES macro similar to AK
         file(GLOB LIBELF_SOURCES CONFIGURE_DEPENDS "../../Userland/Libraries/LibELF/*.cpp")
         # There's no way we can reliably make the dynamic loading classes cross platform
@@ -446,12 +452,14 @@ if (BUILD_LAGOM)
         target_link_libraries(TestJson LibCore)
 
         # Lagom Utilities
-        add_executable(adjtime ../../Userland/Utilities/adjtime.cpp)
-        target_link_libraries(adjtime LibCore LibMain)
+        if (NOT EMSCRIPTEN)
+            add_executable(adjtime ../../Userland/Utilities/adjtime.cpp)
+            target_link_libraries(adjtime LibCore LibMain)
+        endif()
 
         # FIXME: Excluding arm64 is a temporary hack to circumvent a build problem
         #        for Lagom on Apple M1
-        if (NOT CMAKE_SYSTEM_PROCESSOR MATCHES "arm64")
+        if (NOT CMAKE_SYSTEM_PROCESSOR MATCHES "arm64" AND NOT EMSCRIPTEN)
             add_executable(disasm ../../Userland/Utilities/disasm.cpp)
             target_link_libraries(disasm LibCore LibELF LibX86 LibMain)
         endif()
@@ -470,8 +478,10 @@ if (BUILD_LAGOM)
         add_executable(markdown-check ../../Userland/Utilities/markdown-check.cpp)
         target_link_libraries(markdown-check LibMarkdown LibMain)
 
-        add_executable(ntpquery ../../Userland/Utilities/ntpquery.cpp)
-        target_link_libraries(ntpquery LibCore LibMain)
+        if (NOT EMSCRIPTEN)
+            add_executable(ntpquery ../../Userland/Utilities/ntpquery.cpp)
+            target_link_libraries(ntpquery LibCore LibMain)
+        endif()
 
         add_executable(test262-runner ../../Tests/LibJS/test262-runner.cpp)
         target_link_libraries(test262-runner LibJS LibCore)

+ 6 - 2
Tests/LibJS/test262-runner.cpp

@@ -26,7 +26,7 @@
 #include <signal.h>
 #include <unistd.h>
 
-#ifndef AK_OS_MACOS
+#if !defined(AK_OS_MACOS) && !defined(AK_OS_EMSCRIPTEN)
 // Only used to disable core dumps
 #    include <sys/prctl.h>
 #endif
@@ -560,7 +560,11 @@ void __assertion_failed(char const* assertion)
     handle_failed_assert(assertion);
 }
 #else
+#    if AK_OS_EMSCRIPTEN
+extern "C" __attribute__((__noreturn__)) void __assert_fail(char const* assertion, char const* file, int line, char const* function)
+#    else
 extern "C" __attribute__((__noreturn__)) void __assert_fail(char const* assertion, char const* file, unsigned int line, char const* function)
+#    endif
 {
     auto full_message = String::formatted("{}:{}: {}: Assertion `{}' failed.", file, line, function, assertion);
     handle_failed_assert(full_message.characters());
@@ -588,7 +592,7 @@ int main(int argc, char** argv)
     args_parser.add_option(disable_core_dumping, "Disable core dumping", "disable-core-dump", 0);
     args_parser.parse(argc, argv);
 
-#ifndef AK_OS_MACOS
+#if !defined(AK_OS_MACOS) && !defined(AK_OS_EMSCRIPTEN)
     if (disable_core_dumping && prctl(PR_SET_DUMPABLE, 0, 0) < 0) {
         perror("prctl(PR_SET_DUMPABLE)");
         return exit_wrong_arguments;

+ 8 - 0
Userland/Libraries/LibCompress/BrotliDictionary.cpp

@@ -13,13 +13,21 @@ extern u8 const brotli_dictionary_data[];
 asm(".const_data\n"
     ".globl _brotli_dictionary_data\n"
     "_brotli_dictionary_data:\n");
+#elif defined(AK_OS_EMSCRIPTEN)
+asm(".section .data, \"\",@\n"
+    ".global brotli_dictionary_data\n"
+    "brotli_dictionary_data:\n");
 #else
 asm(".section .rodata\n"
     ".global brotli_dictionary_data\n"
     "brotli_dictionary_data:\n");
 #endif
 asm(".incbin \"LibCompress/BrotliDictionaryData.bin\"\n"
+#if (!defined(AK_OS_WINDOWS) && !defined(AK_OS_EMSCRIPTEN))
     ".previous\n");
+#else
+);
+#endif
 
 namespace Compress {
 

+ 1 - 1
Userland/Libraries/LibCore/CMakeLists.txt

@@ -34,7 +34,7 @@ set(SOURCES
     UDPServer.cpp
     Version.cpp
 )
-if (NOT ANDROID AND NOT WIN32)
+if (NOT ANDROID AND NOT WIN32 AND NOT EMSCRIPTEN)
     list(APPEND SOURCES
         Account.cpp
         FilePermissionsMask.cpp

+ 3 - 1
Userland/Libraries/LibCore/MappedFile.cpp

@@ -44,7 +44,9 @@ MappedFile::MappedFile(void* ptr, size_t size)
 
 MappedFile::~MappedFile()
 {
-    MUST(Core::System::munmap(m_data, m_size));
+    auto res = Core::System::munmap(m_data, m_size);
+    if (res.is_error())
+        dbgln("Failed to unmap MappedFile (@ {:p}): {}", m_data, res.error());
 }
 
 }

+ 2 - 2
Userland/Libraries/LibCore/System.cpp

@@ -20,7 +20,6 @@
 #include <stdlib.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
-#include <sys/ptrace.h>
 #include <sys/time.h>
 #include <termios.h>
 #include <unistd.h>
@@ -29,6 +28,7 @@
 #    include <LibCore/Account.h>
 #    include <LibSystem/syscall.h>
 #    include <serenity.h>
+#    include <sys/ptrace.h>
 #endif
 
 #if defined(AK_OS_LINUX) && !defined(MFD_CLOEXEC)
@@ -319,7 +319,7 @@ ErrorOr<int> anon_create([[maybe_unused]] size_t size, [[maybe_unused]] int opti
         TRY(close(fd));
         return Error::from_errno(saved_errno);
     }
-#elif defined(AK_OS_MACOS)
+#elif defined(AK_OS_MACOS) || defined(AK_OS_EMSCRIPTEN)
     struct timespec time;
     clock_gettime(CLOCK_REALTIME, &time);
     auto name = String::formatted("/shm-{}{}", (unsigned long)time.tv_sec, (unsigned long)time.tv_nsec);

+ 2 - 2
Userland/Libraries/LibTest/CrashTest.cpp

@@ -12,7 +12,7 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
-#ifndef AK_OS_MACOS
+#if !defined(AK_OS_MACOS) && !defined(AK_OS_EMSCRIPTEN)
 #    include <sys/prctl.h>
 #endif
 
@@ -38,7 +38,7 @@ bool Crash::run(RunType run_type)
             perror("fork");
             VERIFY_NOT_REACHED();
         } else if (pid == 0) {
-#ifndef AK_OS_MACOS
+#if !defined(AK_OS_MACOS) && !defined(AK_OS_EMSCRIPTEN)
             if (prctl(PR_SET_DUMPABLE, 0, 0) < 0)
                 perror("prctl(PR_SET_DUMPABLE)");
 #endif