diff --git a/.github/actions/cleanup-linux-disk-space/action.yml b/.github/actions/cleanup-linux-disk-space/action.yml index 0e823f22..daee2402 100644 --- a/.github/actions/cleanup-linux-disk-space/action.yml +++ b/.github/actions/cleanup-linux-disk-space/action.yml @@ -13,13 +13,37 @@ runs: run: | echo 'Disk space before cleanup' df -aH - sudo apt-get remove -y --purge '^mysql-.*' '^mongodb-.*' '^mssql-.*' '^postgresql-.*' '^aspnetcore-*' '^dotnet-.*' '^php.*-.*' 'mono-complete' '^llvm-.*' 'powershell' 'google-chrome-*' 'microsoft-edge-*' 'firefox' 'nginx' 'apache2' + + # Regular package cleanup + sudo apt-get remove -y --purge '^mysql-.*' '^mongodb-.*' '^mssql-.*' '^postgresql-.*' '^aspnetcore-*' '^dotnet-.*' '^php.*-.*' 'mono-complete' '^llvm-.*' 'powershell' 'google-chrome-*' 'microsoft-edge-*' 'firefox' 'nginx' 'apache2' 'ghc' '^ghc-*' sudo apt-get autoremove -y + + # Remove unnecessary large directories sudo rm -rf /usr/share/dotnet - echo 'Showing Android SDKs' - ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager --list - ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager --uninstall 'ndk;24.0.8215888' 'ndk;25.2.9519653' 'ndk;26.2.11394342' + sudo rm -rf /usr/local/.ghcup /opt/ghc + + # Android SDK cleanup + echo 'Showing installed Android SDKs' + ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager --list_installed + + echo 'Cleaning unnecessary Android SDK components...' + echo 'Removing old build tools...' + ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager --uninstall "build-tools;31.0.0" "build-tools;32.0.0" "build-tools;33.0.0" "build-tools;33.0.1" "build-tools;33.0.2" "build-tools;33.0.3" "build-tools;34.0.0" + + echo 'Removing old platforms...' + ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager --uninstall "platforms;android-31" "platforms;android-32" "platforms;android-33" "platforms;android-33-ext4" "platforms;android-33-ext5" "platforms;android-34" "platforms;android-34-ext8" "platforms;android-34-ext10" "platforms;android-34-ext11" "platforms;android-34-ext12" + + echo 'Removing NDKs...' + ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager --uninstall "ndk;26.3.11579264" + + echo 'Removing extras...' + ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager --uninstall "extras;android;m2repository" "extras;google;google_play_services" "extras;google;m2repository" + + # Docker cleanup + echo 'Cleaning up Docker resources' + docker system prune -af || true echo 'Removing all Docker images' - docker rmi -f $(docker images -aq) + docker rmi -f $(docker images -aq) || true + echo 'Disk space after cleanup' df -aH diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 74959699..0c4118c2 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -16,6 +16,9 @@ jobs: steps: - uses: actions/checkout@v4 + - name: 🧹 Cleanup GitHub Linux runner disk space + uses: ./.github/actions/cleanup-linux-disk-space + - name: 🔨 Use JDK 17 uses: actions/setup-java@v4 with: diff --git a/lib/jsc-android/build.gradle b/lib/jsc-android/build.gradle index fab7dbb2..7e71b48c 100644 --- a/lib/jsc-android/build.gradle +++ b/lib/jsc-android/build.gradle @@ -28,6 +28,10 @@ android { versionCode 1 versionName "1.0" + ndk { + abiFilters 'arm64-v8a', 'x86_64' + } + externalNativeBuild { cmake { arguments '-DANDROID_STL=c++_shared', diff --git a/package.json b/package.json index 3abd6d9c..8de68b87 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,10 @@ "start": "./scripts/start.sh" }, "config": { - "webkitGTK": "2.26.4", - "chromiumICUCommit": "64e5d7d43a1ff205e3787ab6150bbc1a1837332b" + "bunWebKitRepo": "https://github.com/oven-sh/WebKit.git", + "bunWebKitCommit": "26e6460697dab3e8681489ce67857434b2180e6f", + "icuRelease": "release-74-2", + "icuArchive": "icu4c-74_2-src.tgz" }, "devDependencies": { "commander": "^12.1.0", diff --git a/patches/jsc_android_collator_static.patch b/patches/jsc_android_collator_static.patch new file mode 100644 index 00000000..215afffa --- /dev/null +++ b/patches/jsc_android_collator_static.patch @@ -0,0 +1,30 @@ +diff --git a/webkit/Source/WTF/wtf/unicode/CollatorDefault.cpp b/webkit/Source/WTF/wtf/unicode/CollatorDefault.cpp +index 9a45990fa7..b709f02052 100644 +--- a/webkit/Source/WTF/wtf/unicode/CollatorDefault.cpp ++++ b/webkit/Source/WTF/wtf/unicode/CollatorDefault.cpp +@@ -27,13 +27,15 @@ + */ + + #include "config.h" ++#include ++#include + #include + + #if UCONFIG_NO_COLLATION + + namespace WTF { + +-int Collator::collate(StringView a, StringView b) const ++int Collator::collate(StringView a, StringView b) + { + unsigned commonLength = std::min(a.length(), b.length()); + for (unsigned i = 0; i < commonLength; ++i) { +@@ -51,7 +53,7 @@ int Collator::collate(StringView a, StringView b) const + return 0; + } + +-int Collator::collate(const char8_t* a, const char8_t* b) const ++int Collator::collate(const char8_t* a, const char8_t* b) + { + return collate(String::fromUTF8(byteCast(a)), String::fromUTF8(byteCast(b))); + } diff --git a/patches/jsc_android_define_bun_macros.patch b/patches/jsc_android_define_bun_macros.patch new file mode 100644 index 00000000..bef6648b --- /dev/null +++ b/patches/jsc_android_define_bun_macros.patch @@ -0,0 +1,15 @@ +diff --git a/webkit/Source/WTF/wtf/posix/OSAllocatorPOSIX.cpp b/webkit/Source/WTF/wtf/posix/OSAllocatorPOSIX.cpp +index 483d333b83..1612e84271 100644 +--- a/webkit/Source/WTF/wtf/posix/OSAllocatorPOSIX.cpp ++++ b/webkit/Source/WTF/wtf/posix/OSAllocatorPOSIX.cpp +@@ -63,6 +63,10 @@ + + #endif + ++#ifndef BUN_MACOSX ++#define BUN_MACOSX 0 ++#endif ++ + #ifdef MADV_DONTFORK + #define BUN_MADV_DONTFORK MADV_DONTFORK + #else diff --git a/patches/jsc_android_jit_guards.patch b/patches/jsc_android_jit_guards.patch new file mode 100644 index 00000000..abe8af33 --- /dev/null +++ b/patches/jsc_android_jit_guards.patch @@ -0,0 +1,36 @@ +diff --git a/webkit/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h b/webkit/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h +index 8b89733b83..9c1d93c23f 100644 +--- a/webkit/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h ++++ b/webkit/Source/JavaScriptCore/jit/JITInlineCacheGenerator.h +@@ -53,7 +53,11 @@ enum class AccessType : int8_t; + enum class CacheType : int8_t; + enum class JITType : uint8_t; + ++#if ENABLE(DFG_JIT) + using CompileTimeStructureStubInfo = Variant; ++#else ++using CompileTimeStructureStubInfo = Variant; ++#endif + + class JITInlineCacheGenerator { + protected: +diff --git a/webkit/Source/JavaScriptCore/jit/PCToCodeOriginMap.h b/webkit/Source/JavaScriptCore/jit/PCToCodeOriginMap.h +index 196e0516a9..572f6a4444 100644 +--- a/webkit/Source/JavaScriptCore/jit/PCToCodeOriginMap.h ++++ b/webkit/Source/JavaScriptCore/jit/PCToCodeOriginMap.h +@@ -41,6 +41,7 @@ namespace B3 { + class PCToOriginMap; + } + ++#if ENABLE(WEBASSEMBLY) + namespace Wasm { + class WasmOrigin { + MAKE_VALIDATED_REINTERPRET_CAST +@@ -59,6 +60,7 @@ public: + MAKE_VALIDATED_REINTERPRET_CAST_IMPL("WasmOrigin", WasmOrigin) + + } // namespace Wasm ++#endif + + class LinkBuffer; + class PCToCodeOriginMapBuilder; diff --git a/patches/jsc_android_jsc_wait.patch b/patches/jsc_android_jsc_wait.patch new file mode 100644 index 00000000..4c667da9 --- /dev/null +++ b/patches/jsc_android_jsc_wait.patch @@ -0,0 +1,22 @@ +diff --git a/webkit/Source/JavaScriptCore/jsc.cpp b/webkit/Source/JavaScriptCore/jsc.cpp +index 2b3b231e54..6b861fd1fe 100644 +--- a/webkit/Source/JavaScriptCore/jsc.cpp ++++ b/webkit/Source/JavaScriptCore/jsc.cpp +@@ -3649,7 +3649,7 @@ int main(int argc, char** argv) + WTF::fastDisableScavenger(); + fprintf(stdout, "\njs shell waiting for input to exit\n"); + fflush(stdout); +- getc(stdin); ++ (void)getc(stdin); + } + + #if OS(UNIX) +@@ -3658,7 +3658,7 @@ int main(int argc, char** argv) + fprintf(stdout, "\njs shell waiting for `kill -USR2 [pid]` to exit\n"); + fflush(stdout); + +- waitToExit.wait(); ++ (void)waitToExit.wait(); + + fprintf(stdout, "\njs shell exiting\n"); + fflush(stdout); diff --git a/patches/jsc_android_log_version.patch b/patches/jsc_android_log_version.patch new file mode 100644 index 00000000..483a6bb0 --- /dev/null +++ b/patches/jsc_android_log_version.patch @@ -0,0 +1,29 @@ +diff --git a/webkit/Source/JavaScriptCore/API/JSBase.cpp b/webkit/Source/JavaScriptCore/API/JSBase.cpp +index f0b01ec79a..1c9869b40b 100644 +--- a/webkit/Source/JavaScriptCore/API/JSBase.cpp ++++ b/webkit/Source/JavaScriptCore/API/JSBase.cpp +@@ -37,6 +37,12 @@ + #include "OpaqueJSString.h" + #include "SourceCode.h" + ++#if OS(ANDROID) ++#include ++#ifndef JSC_VERSION ++#define JSC_VERSION "unknown" ++#endif ++#endif + #if ENABLE(REMOTE_INSPECTOR) + #include "JSGlobalObjectInspectorController.h" + #endif +@@ -220,3 +226,11 @@ JSObjectRef JSGetMemoryUsageStatistics(JSContextRef ctx) + + return toRef(object); + } ++ ++#if OS(ANDROID) ++__attribute__((constructor)) ++static void logJSCVersion() ++{ ++ __android_log_print(ANDROID_LOG_INFO, "JavaScriptCore.Version", "%s", JSC_VERSION); ++} ++#endif diff --git a/patches/jsc_android_logging_property.patch b/patches/jsc_android_logging_property.patch new file mode 100644 index 00000000..7e65e2fc --- /dev/null +++ b/patches/jsc_android_logging_property.patch @@ -0,0 +1,30 @@ +diff --git a/webkit/Source/WTF/wtf/android/LoggingAndroid.cpp b/webkit/Source/WTF/wtf/android/LoggingAndroid.cpp +--- a/webkit/Source/WTF/wtf/android/LoggingAndroid.cpp ++++ b/webkit/Source/WTF/wtf/android/LoggingAndroid.cpp +@@ -32,20 +32,15 @@ + + String logLevelString() + { +- const char* propertyValue = nullptr; ++ constexpr auto propertyName = "debug." LOG_CHANNEL_WEBKIT_SUBSYSTEM ".log"; ++ char propertyValue[PROP_VALUE_MAX] { }; ++ int length = __system_property_get(propertyName, propertyValue); + +- if (const auto* propertyInfo = __system_property_find("debug." LOG_CHANNEL_WEBKIT_SUBSYSTEM ".log")) { +- __system_property_read_callback(propertyInfo, [](void *userData, const char*, const char* value, unsigned) { +- auto **propertyValue = static_cast(userData); +- *propertyValue = value; +- }, &propertyValue); +- } +- + // Disable all log channels if the property is unset or empty. +- if (!propertyValue || !*propertyValue) +- return makeString("-all"_s); ++ if (length <= 0) ++ return "-all"_s; + +- return String::fromLatin1(propertyValue); ++ return String::fromLatin1(propertyValue); + } + + } // namespace WTF diff --git a/patches/jsc_android_release_flags.patch b/patches/jsc_android_release_flags.patch new file mode 100644 index 00000000..50a84027 --- /dev/null +++ b/patches/jsc_android_release_flags.patch @@ -0,0 +1,17 @@ +diff --git a/webkit/Source/cmake/OptionsCommon.cmake b/webkit/Source/cmake/OptionsCommon.cmake +index ea7d508967d6..b4de9ef50bbf 100644 +--- a/webkit/Source/cmake/OptionsCommon.cmake ++++ b/webkit/Source/cmake/OptionsCommon.cmake +@@ -1,7 +1,11 @@ +-set(CMAKE_CXX_STANDARD 23) ++set(CMAKE_CXX_STANDARD 20) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) + set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP OFF) ++ ++# Android builds rely on downstream flags, so keep CMake from adding -O3 automatically. ++set(CMAKE_C_COMPILE_OPTIONS_RELEASE -DNDEBUG CACHE STRING "" FORCE) ++set(CMAKE_CXX_COMPILE_OPTIONS_RELEASE -DNDEBUG CACHE STRING "" FORCE) + + add_definitions(-DBUILDING_WITH_CMAKE=1) + add_definitions(-DBUILDING_WEBKIT=1) diff --git a/patches/jsc_android_silence_unused.patch b/patches/jsc_android_silence_unused.patch new file mode 100644 index 00000000..94799666 --- /dev/null +++ b/patches/jsc_android_silence_unused.patch @@ -0,0 +1,78 @@ +diff --git a/webkit/Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp b/webkit/Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp +index 2e2203099e..9c8917096d 100644 +--- a/webkit/Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp ++++ b/webkit/Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp +@@ -45,6 +45,7 @@ void JSModuleNamespaceObject::finishCreation(JSGlobalObject* globalObject, Abstr + { + VM& vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); ++ UNUSED_PARAM(shouldPreventExtensions); + Base::finishCreation(vm); + ASSERT(inherits(info())); + +@@ -208,6 +209,9 @@ bool JSModuleNamespaceObject::put(JSCell* cell, JSGlobalObject* globalObject, Pr + { + VM& vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); ++ UNUSED_PARAM(cell); ++ UNUSED_PARAM(propertyName); ++ UNUSED_PARAM(value); + + #if USE(BUN_JSC_ADDITIONS) + auto* thisObject = jsCast(cell); +diff --git a/webkit/Source/JavaScriptCore/runtime/JSModuleRecord.cpp b/webkit/Source/JavaScriptCore/runtime/JSModuleRecord.cpp +index 24cea00a3f..41ccae3c5e 100644 +--- a/webkit/Source/JavaScriptCore/runtime/JSModuleRecord.cpp ++++ b/webkit/Source/JavaScriptCore/runtime/JSModuleRecord.cpp +@@ -63,18 +63,18 @@ JSModuleRecord::JSModuleRecord(VM& vm, Structure* structure, const Identifier& m + { + } + +-#if USE(BUN_JSC_ADDITIONS) + size_t JSModuleRecord::estimatedSize(JSCell* cell, VM& vm) + { +- const auto& thisObject = jsCast(cell); + size_t size = Base::estimatedSize(cell, vm); ++#if USE(BUN_JSC_ADDITIONS) ++ const auto& thisObject = jsCast(cell); + const SourceCode& sourceCode = thisObject->sourceCode(); + StringView view = sourceCode.provider() ? sourceCode.provider()->source() : StringView(); + size += view.length() * (view.is8Bit() ? sizeof(Latin1Character) : sizeof(UChar)); + size += sourceCode.memoryCost(); ++#endif + return size; + } +-#endif + void JSModuleRecord::destroy(JSCell* cell) + { + JSModuleRecord* thisObject = static_cast(cell); +diff --git a/webkit/Source/JavaScriptCore/runtime/JSPromise.cpp b/webkit/Source/JavaScriptCore/runtime/JSPromise.cpp +index 09b051775b..a0a4a6b10f 100644 +--- a/webkit/Source/JavaScriptCore/runtime/JSPromise.cpp ++++ b/webkit/Source/JavaScriptCore/runtime/JSPromise.cpp +@@ -219,6 +219,7 @@ void JSPromise::fulfillWithNonPromise(JSGlobalObject* lexicalGlobalObject, JSVal + { + VM& vm = lexicalGlobalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); ++ UNUSED_PARAM(scope); + uint32_t flags = this->flags(); + ASSERT_WITH_MESSAGE(!value.inherits(), "Promise fulfilled with exception"); + ASSERT_WITH_MESSAGE(!value.inherits(), "Promise fulfilled with another promise"); +diff --git a/webkit/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp b/webkit/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp +index be5602f0b7..2f26538268 100644 +--- a/webkit/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp ++++ b/webkit/Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp +@@ -37,10 +37,11 @@ ModuleProgramExecutable::ModuleProgramExecutable(JSGlobalObject* globalObject, c + { + SourceProviderSourceType sourceType = source.provider()->sourceType(); + ASSERT(sourceType == SourceProviderSourceType::Module +- #if USE(BUN_JSC_ADDITIONS) ++#if USE(BUN_JSC_ADDITIONS) + || sourceType == SourceProviderSourceType::BunTranspiledModule +- #endif ++#endif + ); ++ UNUSED_PARAM(sourceType); + VM& vm = globalObject->vm(); + if (vm.typeProfiler() || vm.controlFlowProfiler()) + vm.functionHasExecutedCache()->insertUnexecutedRange(sourceID(), typeProfilingStartOffset(), typeProfilingEndOffset()); diff --git a/patches/jsc_android_systemheap_posix_memalign.patch b/patches/jsc_android_systemheap_posix_memalign.patch new file mode 100644 index 00000000..a02e93e6 --- /dev/null +++ b/patches/jsc_android_systemheap_posix_memalign.patch @@ -0,0 +1,18 @@ +diff --git a/webkit/Source/bmalloc/bmalloc/SystemHeap.cpp b/webkit/Source/bmalloc/bmalloc/SystemHeap.cpp +--- a/webkit/Source/bmalloc/bmalloc/SystemHeap.cpp ++++ b/webkit/Source/bmalloc/bmalloc/SystemHeap.cpp +@@ -210,7 +210,13 @@ void* SystemHeap::malloc(size_t size, FailureAction action) + + void* SystemHeap::memalign(size_t alignment, size_t size, FailureAction action) + { +- void* result = ::aligned_alloc(alignment, size); ++ void* result = nullptr; ++#if PAS_OS(ANDROID) ++ if (::posix_memalign(&result, alignment, size)) ++ result = nullptr; ++#else ++ result = ::aligned_alloc(alignment, size); ++#endif + RELEASE_BASSERT(action == FailureAction::ReturnNull || result); + return result; + } diff --git a/patches/jsc_android_thread_name_guard.patch b/patches/jsc_android_thread_name_guard.patch new file mode 100644 index 00000000..9689e62b --- /dev/null +++ b/patches/jsc_android_thread_name_guard.patch @@ -0,0 +1,17 @@ +diff --git a/webkit/Source/bmalloc/libpas/src/libpas/pas_thread_local_cache.c b/webkit/Source/bmalloc/libpas/src/libpas/pas_thread_local_cache.c +--- a/webkit/Source/bmalloc/libpas/src/libpas/pas_thread_local_cache.c ++++ b/webkit/Source/bmalloc/libpas/src/libpas/pas_thread_local_cache.c +@@ -221,9 +221,13 @@ static void dump_thread_diagnostics(pthread_t thread) + #endif + #if PAS_PLATFORM(PLAYSTATION) + getname_result = pthread_get_name_np(thread, thread_name); ++#else ++#if PAS_OS(ANDROID) ++ getname_result = -1; + #else + getname_result = pthread_getname_np(thread, thread_name, sizeof(thread_name)); + #endif ++#endif + if (!getname_result) + pas_log("[%d] thread %p has name %s\n", getpid(), (void*)thread, thread_name); + else diff --git a/patches/jsc_android_timezone_validate.patch b/patches/jsc_android_timezone_validate.patch new file mode 100644 index 00000000..e45b2cd1 --- /dev/null +++ b/patches/jsc_android_timezone_validate.patch @@ -0,0 +1,48 @@ +diff --git a/webkit/Source/JavaScriptCore/runtime/JSDateMath.cpp b/webkit/Source/JavaScriptCore/runtime/JSDateMath.cpp +index cbd32cefe0..16df1ec5a0 100644 +--- a/webkit/Source/JavaScriptCore/runtime/JSDateMath.cpp ++++ b/webkit/Source/JavaScriptCore/runtime/JSDateMath.cpp +@@ -502,6 +502,12 @@ static std::tuple> retrieveTimeZoneInformation() + getTimeZoneOverride(timeZoneID); + String canonical; + UErrorCode status = U_ZERO_ERROR; ++#if (defined(UCONFIG_NO_FORMATTING) && UCONFIG_NO_FORMATTING) || !defined(ucal_getCanonicalTimeZoneID) ++ if (!timeZoneID.isEmpty()) ++ canonical = String(timeZoneID.span()); ++ else ++ canonical = "UTC"_s; ++#else + if (timeZoneID.isEmpty()) { + status = callBufferProducingFunction(ucal_getHostTimeZone, timeZoneID); + ASSERT_UNUSED(status, U_SUCCESS(status)); +@@ -514,6 +520,7 @@ static std::tuple> retrieveTimeZoneInformation() + } + if (canonical.isNull() || isUTCEquivalent(canonical)) + canonical = "UTC"_s; ++#endif + + globalCache.get() = std::tuple { canonical.isolatedCopy(), WTFMove(timeZoneID), currentID }; + } +diff --git a/webkit/Source/WTF/wtf/DateMath.cpp b/webkit/Source/WTF/wtf/DateMath.cpp +index d4551c78ef..37b2ef6fc2 100644 +--- a/webkit/Source/WTF/wtf/DateMath.cpp ++++ b/webkit/Source/WTF/wtf/DateMath.cpp +@@ -1008,6 +1008,10 @@ String makeRFC2822DateString(unsigned dayOfWeek, unsigned day, unsigned month, u + + static std::optional> validateTimeZone(StringView timeZone) + { ++#if defined(UCONFIG_NO_FORMATTING) && UCONFIG_NO_FORMATTING ++ UNUSED_PARAM(timeZone); ++ return std::nullopt; ++#else + auto buffer = timeZone.upconvertedCharacters(); + const char16_t* characters = buffer; + Vector canonicalBuffer; +@@ -1015,6 +1019,7 @@ static std::optional> validateTimeZone(StringView timeZone) + if (!U_SUCCESS(status)) + return std::nullopt; + return canonicalBuffer; ++#endif + } + + bool isTimeZoneValid(StringView timeZone) diff --git a/patches/jsc_android_uv_pri64.patch b/patches/jsc_android_uv_pri64.patch new file mode 100644 index 00000000..684edd13 --- /dev/null +++ b/patches/jsc_android_uv_pri64.patch @@ -0,0 +1,16 @@ +diff --git a/webkit/Source/bmalloc/bmalloc/uv_get_constrained_memory.cpp b/webkit/Source/bmalloc/bmalloc/uv_get_constrained_memory.cpp +index e39afda511..48f46d76fc 100644 +--- a/webkit/Source/bmalloc/bmalloc/uv_get_constrained_memory.cpp ++++ b/webkit/Source/bmalloc/bmalloc/uv_get_constrained_memory.cpp +@@ -21,11 +21,12 @@ + + #include "BPlatform.h" + #include ++#include + + #if BOS(LINUX) + + #ifndef PRIu64 +-#define PRIu64 "lu" ++#define PRIu64 "llu" + #endif diff --git a/patches/jsc_android_wtf_sources.patch b/patches/jsc_android_wtf_sources.patch new file mode 100644 index 00000000..0d1c18a6 --- /dev/null +++ b/patches/jsc_android_wtf_sources.patch @@ -0,0 +1,45 @@ +diff --git a/webkit/Source/WTF/wtf/PlatformJSCOnly.cmake b/webkit/Source/WTF/wtf/PlatformJSCOnly.cmake +index 0ab58fe2a2..4b94606617 100644 +--- a/webkit/Source/WTF/wtf/PlatformJSCOnly.cmake ++++ b/webkit/Source/WTF/wtf/PlatformJSCOnly.cmake +@@ -36,8 +36,16 @@ else () + text/unix/TextBreakIteratorInternalICUUnix.cpp + + unix/LanguageUnix.cpp +- unix/LoggingUnix.cpp + ) ++ if (CMAKE_SYSTEM_NAME MATCHES "Android") ++ list(APPEND WTF_SOURCES ++ android/LoggingAndroid.cpp ++ ) ++ else () ++ list(APPEND WTF_SOURCES ++ unix/LoggingUnix.cpp ++ ) ++ endif () + if (WTF_OS_FUCHSIA) + list(APPEND WTF_SOURCES + fuchsia/CPUTimeFuchsia.cpp +@@ -97,6 +105,22 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "Linux") + + unix/MemoryPressureHandlerUnix.cpp + ) ++ list(APPEND WTF_PUBLIC_HEADERS ++ linux/CurrentProcessMemoryStatus.h ++ linux/ProcessMemoryFootprint.h ++ ) ++elseif (CMAKE_SYSTEM_NAME MATCHES "Android") ++ list(APPEND WTF_SOURCES ++ linux/CurrentProcessMemoryStatus.cpp ++ linux/MemoryFootprintLinux.cpp ++ linux/RealTimeThreads.cpp ++ ++ unix/MemoryPressureHandlerUnix.cpp ++ ) ++ list(APPEND WTF_PUBLIC_HEADERS ++ linux/CurrentProcessMemoryStatus.h ++ linux/ProcessMemoryFootprint.h ++ ) + elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + list(APPEND WTF_SOURCES + generic/MemoryFootprintGeneric.cpp diff --git a/patches/jsc_async_frame_guard.patch b/patches/jsc_async_frame_guard.patch new file mode 100644 index 00000000..20435d3c --- /dev/null +++ b/patches/jsc_async_frame_guard.patch @@ -0,0 +1,16 @@ +diff --git a/webkit/Source/JavaScriptCore/runtime/StackFrame.h b/webkit/Source/JavaScriptCore/runtime/StackFrame.h +index b689e68d58..5578051a6b 100644 +--- a/webkit/Source/JavaScriptCore/runtime/StackFrame.h ++++ b/webkit/Source/JavaScriptCore/runtime/StackFrame.h +@@ -100,7 +100,11 @@ public: + + bool isAsyncFrameWithoutCodeBlock() const + { ++#if USE(BUN_JSC_ADDITIONS) + return isAsyncFrame() && !codeBlock(); ++#else ++ return false; ++#endif + } + + #if USE(BUN_JSC_ADDITIONS) diff --git a/patches/jsc_disable_api_tests.patch b/patches/jsc_disable_api_tests.patch new file mode 100644 index 00000000..f808ea81 --- /dev/null +++ b/patches/jsc_disable_api_tests.patch @@ -0,0 +1,16 @@ +diff --git a/webkit/Source/cmake/OptionsJSCOnly.cmake b/webkit/Source/cmake/OptionsJSCOnly.cmake +index f00830dd41..f9e131cfa3 100644 +--- a/webkit/Source/cmake/OptionsJSCOnly.cmake ++++ b/webkit/Source/cmake/OptionsJSCOnly.cmake +@@ -101,10 +101,8 @@ else () + endif () + WEBKIT_OPTION_END() + +-if (WIN32) ++if (NOT DEFINED ENABLE_API_TESTS) + set(ENABLE_API_TESTS OFF) +-else () +- set(ENABLE_API_TESTS ON) + endif () + + if (WTF_CPU_ARM OR WTF_CPU_MIPS) diff --git a/patches/jsc_fix_external_string_tests.patch b/patches/jsc_fix_external_string_tests.patch new file mode 100644 index 00000000..d13d8180 --- /dev/null +++ b/patches/jsc_fix_external_string_tests.patch @@ -0,0 +1,40 @@ +diff --git a/webkit/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp b/webkit/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp +index 72339a29d7..cfaac6b233 100644 +--- a/webkit/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp ++++ b/webkit/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp +@@ -758,7 +758,7 @@ TEST(WTF, ExternalStringImplCreate8bit) + bool freeFunctionCalled = false; + + { +- auto external = ExternalStringImpl::create({ buffer, bufferStringLength }, [&freeFunctionCalled](ExternalStringImpl* externalStringImpl, void* buffer, unsigned bufferSize) mutable { ++ auto external = ExternalStringImpl::create({ buffer, bufferStringLength }, nullptr, [&freeFunctionCalled](void*, void*, unsigned) mutable { + freeFunctionCalled = true; + }); + +@@ -780,7 +780,7 @@ TEST(WTF, ExternalStringImplCreate16bit) + bool freeFunctionCalled = false; + + { +- auto external = ExternalStringImpl::create({ buffer, bufferStringLength }, [&freeFunctionCalled](ExternalStringImpl* externalStringImpl, void* buffer, unsigned bufferSize) mutable { ++ auto external = ExternalStringImpl::create({ buffer, bufferStringLength }, nullptr, [&freeFunctionCalled](void*, void*, unsigned) mutable { + freeFunctionCalled = true; + }); + +@@ -809,7 +809,7 @@ TEST(WTF, ExternalStringAtom) + bool freeFunctionCalled = false; + + { +- auto external = ExternalStringImpl::create({ buffer, bufferStringLength }, [&freeFunctionCalled](ExternalStringImpl* externalStringImpl, void* buffer, unsigned bufferSize) mutable { ++ auto external = ExternalStringImpl::create({ buffer, bufferStringLength }, nullptr, [&freeFunctionCalled](void*, void*, unsigned) mutable { + freeFunctionCalled = true; + }); + +@@ -845,7 +845,7 @@ TEST(WTF, ExternalStringToSymbol) + bool freeFunctionCalled = false; + + { +- auto external = ExternalStringImpl::create(buffer.span8(), [&freeFunctionCalled](ExternalStringImpl* externalStringImpl, void* buffer, unsigned bufferSize) mutable { ++ auto external = ExternalStringImpl::create(buffer.span8(), nullptr, [&freeFunctionCalled](void*, void*, unsigned) mutable { + freeFunctionCalled = true; + }); + diff --git a/patches/jsc_guard_error_instance.patch b/patches/jsc_guard_error_instance.patch new file mode 100644 index 00000000..7cb15732 --- /dev/null +++ b/patches/jsc_guard_error_instance.patch @@ -0,0 +1,58 @@ +diff --git a/webkit/Source/JavaScriptCore/runtime/ErrorInstance.cpp b/webkit/Source/JavaScriptCore/runtime/ErrorInstance.cpp +index 07999a9b28..e694388e2e 100644 +--- a/webkit/Source/JavaScriptCore/runtime/ErrorInstance.cpp ++++ b/webkit/Source/JavaScriptCore/runtime/ErrorInstance.cpp +@@ -108,6 +108,7 @@ String appendSourceToErrorMessage(CodeBlock* codeBlock, BytecodeIndex bytecodeIn + return appender(message, codeBlock->source().provider()->getRange(start, stop), type, ErrorInstance::FoundApproximateSource); + } + ++#if USE(BUN_JSC_ADDITIONS) + void ErrorInstance::setStackFrames(VM& vm, WTF::Vector&& stackFrames) + { + std::unique_ptr> stackTrace = makeUnique>(WTFMove(stackFrames)); +@@ -116,6 +117,7 @@ void ErrorInstance::setStackFrames(VM& vm, WTF::Vector&& stackFrames + m_stackTrace = WTFMove(stackTrace); + vm.writeBarrier(this); + } ++#endif + + size_t ErrorInstance::estimatedSize(JSCell* cell, VM& vm) + { +@@ -370,11 +372,16 @@ void ErrorInstance::computeErrorInfo(VM& vm, bool allocationAllowed) + UNUSED_PARAM(allocationAllowed); + + if (m_stackTrace && !m_stackTrace->isEmpty()) { +- auto& fn = vm.onComputeErrorInfo(); + WTF::String stackString; +- if (fn) { +- stackString = fn(vm, *m_stackTrace.get(), m_lineColumn.line, m_lineColumn.column, m_sourceURL, this->bunErrorData()); +- } else { ++ bool handled = false; ++#if USE(BUN_JSC_ADDITIONS) ++ auto& computeErrorInfo = vm.onComputeErrorInfo(); ++ if (computeErrorInfo) { ++ stackString = computeErrorInfo(vm, *m_stackTrace.get(), m_lineColumn.line, m_lineColumn.column, m_sourceURL, this->bunErrorData()); ++ handled = true; ++ } ++#endif ++ if (!handled) { + getLineColumnAndSource(vm, m_stackTrace.get(), m_lineColumn, m_sourceURL); + stackString = Interpreter::stackTraceAsString(vm, *m_stackTrace.get()); + } +@@ -394,13 +401,12 @@ bool ErrorInstance::materializeErrorInfoIfNeeded(VM& vm) + return false; + + #if USE(BUN_JSC_ADDITIONS) +- +- auto& fn = vm.onComputeErrorInfoJSValue(); +- if (fn && m_stackTrace && !m_stackTrace->isEmpty()) { ++ auto& computeErrorInfoJSValue = vm.onComputeErrorInfoJSValue(); ++ if (computeErrorInfoJSValue && m_stackTrace && !m_stackTrace->isEmpty()) { + m_errorInfoMaterialized = true; + DeferGCForAWhile deferGC(vm); + +- JSValue stack = fn(vm, *m_stackTrace.get(), m_lineColumn.line, m_lineColumn.column, m_sourceURL, this, this->bunErrorData()); ++ JSValue stack = computeErrorInfoJSValue(vm, *m_stackTrace.get(), m_lineColumn.line, m_lineColumn.column, m_sourceURL, this, this->bunErrorData()); + + { + Locker locker { cellLock() }; diff --git a/patches/jsc_stub_dfg_abstract_heap.patch b/patches/jsc_stub_dfg_abstract_heap.patch new file mode 100644 index 00000000..d4027a2a --- /dev/null +++ b/patches/jsc_stub_dfg_abstract_heap.patch @@ -0,0 +1,23 @@ +diff --git a/webkit/Source/JavaScriptCore/domjit/DOMJITEffect.h b/webkit/Source/JavaScriptCore/domjit/DOMJITEffect.h +index 6ba85116d1..91c6f4dc26 100644 +--- a/webkit/Source/JavaScriptCore/domjit/DOMJITEffect.h ++++ b/webkit/Source/JavaScriptCore/domjit/DOMJITEffect.h +@@ -25,7 +25,18 @@ + + #pragma once + ++#if ENABLE(DFG_JIT) + #include "DFGAbstractHeap.h" ++#else ++namespace JSC { ++namespace DFG { ++enum AbstractHeapKind : unsigned { ++ Heap, ++ InvalidAbstractHeap ++}; ++} ++} ++#endif + #include "DOMJITHeapRange.h" + + WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN diff --git a/scripts/compile/all.sh b/scripts/compile/all.sh index 1a6e29c0..5c5bc744 100755 --- a/scripts/compile/all.sh +++ b/scripts/compile/all.sh @@ -15,12 +15,14 @@ compile_arch() { } compile() { - for arch in arm x86 - do - export ANDROID_API=$ANDROID_API_FOR_ABI_32 - export JSC_ARCH=$arch - compile_arch - done + if [[ "${INCLUDE_32_BIT_ABIS:-0}" == "1" ]]; then + for arch in arm x86 + do + export ANDROID_API=$ANDROID_API_FOR_ABI_32 + export JSC_ARCH=$arch + compile_arch + done + fi for arch in arm64 x86_64 do diff --git a/scripts/compile/common.sh b/scripts/compile/common.sh index 7eb3b3d5..7b7f43a6 100755 --- a/scripts/compile/common.sh +++ b/scripts/compile/common.sh @@ -53,6 +53,7 @@ PLATFORM_CFLAGS_arm="" PLATFORM_LDFLAGS_arm="" JNI_ARCH_arm=armeabi-v7a +PLATFORM_CFLAGS_arm64="-mtune=cortex-a77" PLATFORM_LDFLAGS_arm64="" JNI_ARCH_arm64=arm64-v8a @@ -74,7 +75,7 @@ JNI_ARCH=${!var} # options flags # INTL -SWITCH_COMMON_CFLAGS_INTL_OFF="-DUCONFIG_NO_COLLATION=1 -DUCONFIG_NO_FORMATTING=1" +SWITCH_COMMON_CFLAGS_INTL_OFF="" SWITCH_BUILD_WEBKIT_OPTIONS_INTL_OFF="--no-intl" SWITCH_BUILD_WEBKIT_OPTIONS_INTL_ON="--intl" @@ -82,9 +83,10 @@ SWITCH_BUILD_WEBKIT_OPTIONS_INTL_ON="--intl" fix_zero_value_flag "INTL" process_switch_options "INTL" + # checks err=false -if ! [[ $ANDROID_API_FOR_ABI_32 ]]; then echo "set ANDROID_API_FOR_ABI_32 to the minimum supported Android platform version for arm and x86 (e.g. 16)"; err=true; fi +if [[ "${INCLUDE_32_BIT_ABIS:-0}" == "1" ]] && ! [[ $ANDROID_API_FOR_ABI_32 ]]; then echo "set ANDROID_API_FOR_ABI_32 to the minimum supported Android platform version for arm and x86 (e.g. 16)"; err=true; fi if ! [[ $ANDROID_API_FOR_ABI_64 ]]; then echo "set ANDROID_API_FOR_ABI_64 to the minimum supported Android platform version for arm64 and x86_64 (e.g. 21)"; err=true; fi if ! [[ $FLAVOR ]]; then echo "set FLAVOR to the name of the flavor"; err=true; fi if ! [[ $CROSS_COMPILE_PLATFORM ]]; then echo "set JSC_ARCH to one of {arm,arm64,x86,x86_64}"; err=true; fi @@ -99,8 +101,8 @@ DEBUG_SYMBOL_LEVEL="-g2" if [[ "$BUILD_TYPE" = "Release" ]] then FRAME_POINTER_FLAG="-fomit-frame-pointer" - CFLAGS_BUILD_TYPE="-DNDEBUG -g0 -Oz -flto=full" - ICU_CFLAGS_BUILD_TYPE="-Oz" + CFLAGS_BUILD_TYPE="-DNDEBUG -g0 -O2 -flto=thin" + ICU_CFLAGS_BUILD_TYPE="-O2 -flto=thin" else FRAME_POINTER_FLAG="-fno-omit-frame-pointer" CFLAGS_BUILD_TYPE="" @@ -115,6 +117,7 @@ COMMON_LDFLAGS=" \ -Wl,--exclude-libs,libgcc.a \ -Wl,--no-undefined \ -Wl,-z,max-page-size=16384 \ +-flto=thin \ " COMMON_CFLAGS=" \ @@ -129,17 +132,23 @@ $FRAME_POINTER_FLAG \ -DCUSTOMIZE_REACT_NATIVE \ $SWITCH_COMMON_CFLAGS_INTL \ $CFLAGS_BUILD_TYPE \ +-Wno-pass-failed=loop-vectorize \ -D__ANDROID_MIN_SDK_VERSION__=${ANDROID_API} \ " COMMON_CXXFLAGS=" \ +-std=c++20 \ " ICU_CFLAGS="$COMMON_CFLAGS $PLATFORM_CFLAGS $ICU_CFLAGS_BUILD_TYPE" -ICU_CXXFLAGS="$COMMON_CXXFLAGS $ICU_CFLAGS $ICU_CFLAGS_BUILD_TYPE" +ICU_CXXFLAGS="$COMMON_CXXFLAGS $ICU_CFLAGS" ICU_LDFLAGS="$COMMON_LDFLAGS \ $PLATFORM_LDFLAGS \ " -JSC_LDFLAGS="$COMMON_LDFLAGS" +JSC_LDFLAGS="$COMMON_LDFLAGS -llog" JSC_CFLAGS="$COMMON_CFLAGS -Wno-implicit-const-int-float-conversion -DU_STATIC_IMPLEMENTATION=1 -DU_SHOW_CPLUSPLUS_API=0 -DTRUE=1 -DFALSE=0" + +if [[ -n "$JSC_VERSION" ]]; then + JSC_CFLAGS="$JSC_CFLAGS -DJSC_VERSION=\\\"${JSC_VERSION}\\\"" +fi diff --git a/scripts/compile/icu.sh b/scripts/compile/icu.sh index 1696958d..1029d7cf 100755 --- a/scripts/compile/icu.sh +++ b/scripts/compile/icu.sh @@ -26,8 +26,16 @@ else BUILD_TYPE_CONFIG="--enable-debug=yes" fi -ICU_DATA_FILTER_FILE="${TARGETDIR}/icu/filters/android.json" \ -$TARGETDIR/icu/source/configure --prefix=${INSTALL_DIR} \ +ICU_FILTER_FILE="${TARGETDIR}/icu/filters/android.json" +if [[ -f "$ICU_FILTER_FILE" ]]; then + echo "Using ICU data filter: ${ICU_FILTER_FILE}" + CONFIGURE_PREFIX=(env ICU_DATA_FILTER_FILE="$ICU_FILTER_FILE") +else + echo "ICU data filter not found at ${ICU_FILTER_FILE}; building without data pruning" + CONFIGURE_PREFIX=() +fi + +"${CONFIGURE_PREFIX[@]}" $TARGETDIR/icu/source/configure --prefix=${INSTALL_DIR} \ $BUILD_TYPE_CONFIG \ --host=$CROSS_COMPILE_PLATFORM \ --enable-static=yes \ diff --git a/scripts/compile/jsc.sh b/scripts/compile/jsc.sh index d8eb4716..302ac49e 100755 --- a/scripts/compile/jsc.sh +++ b/scripts/compile/jsc.sh @@ -10,20 +10,6 @@ rm -rf $TARGETDIR/webkit/$CROSS_COMPILE_PLATFORM-${FLAVOR} rm -rf $TARGETDIR/webkit/WebKitBuild cd $TARGETDIR/webkit/Tools/Scripts -CMAKE_CXX_FLAGS=" \ -$SWITCH_JSC_CFLAGS_COMPAT \ -$JSC_CFLAGS \ -$PLATFORM_CFLAGS \ -" - -CMAKE_LD_FLAGS=" \ --latomic \ --lm \ --lc++_shared \ -$JSC_LDFLAGS \ -$PLATFORM_LDFLAGS \ -" - ARCH_NAME_PLATFORM_arm="armv7-a" ARCH_NAME_PLATFORM_arm64="aarch64" ARCH_NAME_PLATFORM_x86="i686" @@ -31,6 +17,13 @@ ARCH_NAME_PLATFORM_x86_64="x86_64" var="ARCH_NAME_PLATFORM_$JSC_ARCH" export ARCH_NAME=${!var} +BASE_C_FLAGS="$COMMON_CFLAGS $PLATFORM_CFLAGS" +BASE_CXX_FLAGS="$COMMON_CXXFLAGS $BASE_C_FLAGS" +BASE_LD_FLAGS="-latomic -lm -lc++_shared $JSC_LDFLAGS $PLATFORM_LDFLAGS" + +export CFLAGS="$BASE_C_FLAGS" +export CXXFLAGS="$BASE_CXX_FLAGS" +export LDFLAGS="$BASE_LD_FLAGS" if [[ "$BUILD_TYPE" = "Release" ]] then @@ -41,25 +34,17 @@ else BUILD_TYPE_FLAGS="-DDEBUG_FISSION=OFF" fi -if [[ "$ARCH_NAME" = "i686" ]] -then - JSC_FEATURE_FLAGS=" \ - -DENABLE_JIT=OFF \ - -DENABLE_C_LOOP=ON \ - " -else - JSC_FEATURE_FLAGS=" \ - -DENABLE_JIT=ON \ - -DENABLE_C_LOOP=OFF \ - " -fi +JSC_FEATURE_FLAGS=" \ + -DENABLE_JIT=OFF \ + -DENABLE_C_LOOP=ON \ + -DENABLE_WEBASSEMBLY=OFF \ +" $TARGETDIR/webkit/Tools/Scripts/build-webkit \ --jsc-only \ $BUILD_TYPE_CONFIG \ - --jit \ + --no-fatal-warnings \ "$SWITCH_BUILD_WEBKIT_OPTIONS_INTL" \ - --no-webassembly \ --no-xslt \ --no-netscape-plugin-api \ --no-tools \ @@ -67,15 +52,28 @@ $TARGETDIR/webkit/Tools/Scripts/build-webkit \ -DUSE_LD_GOLD=OFF \ -DANDROID_ABI=${JNI_ARCH} \ -DANDROID_PLATFORM=${ANDROID_API} \ + -DANDROID_TARGET_SDK_VERSION=${ANDROID_TARGET_API:-${ANDROID_API}} \ + -DENABLE_JIT=OFF \ + -DENABLE_WEBASSEMBLY=OFF \ -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=BOTH \ -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=BOTH \ -DICU_ROOT=${TARGETDIR}/icu/${CROSS_COMPILE_PLATFORM}-${FLAVOR}/prebuilts \ - -DCMAKE_CXX_FLAGS='${CMAKE_CXX_FLAGS} $COMMON_CXXFLAGS $CMAKE_CXX_FLAGS' \ - -DCMAKE_C_FLAGS='${CMAKE_C_FLAGS} $CMAKE_CXX_FLAGS' \ - -DCMAKE_C_FLAGS_DEBUG='${DEBUG_SYMBOL_LEVEL}' \ - -DCMAKE_CXX_FLAGS_DEBUG='${DEBUG_SYMBOL_LEVEL}' \ - -DCMAKE_SHARED_LINKER_FLAGS='${CMAKE_SHARED_LINKER_FLAGS} $CMAKE_LD_FLAGS' \ - -DCMAKE_EXE_LINKER_FLAGS='${CMAKE_MODULE_LINKER_FLAGS} $CMAKE_LD_FLAGS' \ + -DICU_INCLUDE_DIR=${TARGETDIR}/icu/${CROSS_COMPILE_PLATFORM}-${FLAVOR}/prebuilts/include \ + -DENABLE_API_TESTS=OFF \ + -DCMAKE_C_FLAGS=\"$BASE_C_FLAGS\" \ + -DCMAKE_CXX_FLAGS=\"$BASE_CXX_FLAGS\" \ + -DCMAKE_C_FLAGS_RELEASE=\"$BASE_C_FLAGS\" \ + -DCMAKE_CXX_FLAGS_RELEASE=\"$BASE_CXX_FLAGS\" \ + -DCMAKE_C_FLAGS_RELWITHDEBINFO=\"$BASE_C_FLAGS\" \ + -DCMAKE_CXX_FLAGS_RELWITHDEBINFO=\"$BASE_CXX_FLAGS\" \ + -DCMAKE_C_FLAGS_DEBUG=\"$BASE_C_FLAGS $DEBUG_SYMBOL_LEVEL\" \ + -DCMAKE_CXX_FLAGS_DEBUG=\"$BASE_CXX_FLAGS $DEBUG_SYMBOL_LEVEL\" \ + -DCMAKE_SHARED_LINKER_FLAGS=\"$BASE_LD_FLAGS\" \ + -DCMAKE_MODULE_LINKER_FLAGS=\"$BASE_LD_FLAGS\" \ + -DCMAKE_EXE_LINKER_FLAGS=\"$BASE_LD_FLAGS\" \ + -DCMAKE_CXX_STANDARD=20 \ + -DCMAKE_CXX_STANDARD_REQUIRED=ON \ + -DCMAKE_CXX_EXTENSIONS=OFF \ -DCMAKE_VERBOSE_MAKEFILE=on \ -DENABLE_API_TESTS=OFF \ -DENABLE_SAMPLING_PROFILER=OFF \ @@ -89,9 +87,16 @@ $TARGETDIR/webkit/Tools/Scripts/build-webkit \ mkdir -p $INSTALL_UNSTRIPPED_DIR_I18N/$JNI_ARCH mkdir -p $INSTALL_DIR_I18N/$JNI_ARCH -cp $TARGETDIR/webkit/WebKitBuild/$BUILD_TYPE/lib/libjsc.so $INSTALL_UNSTRIPPED_DIR_I18N/$JNI_ARCH -cp $TARGETDIR/webkit/WebKitBuild/$BUILD_TYPE/lib/libjsc.so $INSTALL_DIR_I18N/$JNI_ARCH -$TOOLCHAIN_DIR/bin/llvm-strip $INSTALL_DIR_I18N/$JNI_ARCH/libjsc.so +BUILT_LIB_PATH=$TARGETDIR/webkit/WebKitBuild/JSCOnly/$BUILD_TYPE/lib/libJavaScriptCore.so +OUTPUT_LIB_NAME=libjsc.so +if [[ ! -f $BUILT_LIB_PATH ]] +then + echo "Failed to find expected JavaScriptCore shared library at $BUILT_LIB_PATH" >&2 + exit 1 +fi +cp $BUILT_LIB_PATH $INSTALL_UNSTRIPPED_DIR_I18N/$JNI_ARCH/$OUTPUT_LIB_NAME +cp $BUILT_LIB_PATH $INSTALL_DIR_I18N/$JNI_ARCH/$OUTPUT_LIB_NAME +$TOOLCHAIN_DIR/bin/llvm-strip $INSTALL_DIR_I18N/$JNI_ARCH/$OUTPUT_LIB_NAME mv $TARGETDIR/webkit/WebKitBuild $TARGETDIR/webkit/${CROSS_COMPILE_PLATFORM}-${FLAVOR} mkdir -p $INSTALL_CPPRUNTIME_DIR/$JNI_ARCH diff --git a/scripts/download.sh b/scripts/download.sh index e0b92980..d94fa9eb 100755 --- a/scripts/download.sh +++ b/scripts/download.sh @@ -1,13 +1,40 @@ #!/bin/bash -e +ROOTDIR=$PWD + # download sources -rm -rf $PWD/build -TARGET_DIR=$PWD/build/download -REPO_URL="https://github.com/WebKit/WebKit.git" +rm -rf "$ROOTDIR/build" +TARGET_DIR="$ROOTDIR/build/download" +WEBKIT_DIR="$TARGET_DIR/webkit" + +REPO_URL="${npm_package_config_bunWebKitRepo:-https://github.com/oven-sh/WebKit.git}" +WEBKIT_COMMIT="${npm_package_config_bunWebKitCommit}" +ICU_RELEASE="${npm_package_config_icuRelease}" +ICU_ARCHIVE="${npm_package_config_icuArchive}" + +if [[ -z "$WEBKIT_COMMIT" ]]; then + echo "Missing bunWebKitCommit in package.json config." >&2 + exit 1 +fi + +mkdir -p "$TARGET_DIR" +mkdir -p "$WEBKIT_DIR" -mkdir -p $TARGET_DIR -# FIXME: hardcoded branch because WebKitGTK 2.26 does not have tag -git clone $REPO_URL --branch 'webkitgtk/2.26' --depth 1 $TARGET_DIR/webkit +pushd "$WEBKIT_DIR" > /dev/null +git init +git remote add origin "$REPO_URL" +git fetch --depth 1 origin "$WEBKIT_COMMIT" +git checkout --detach FETCH_HEAD +popd > /dev/null -mkdir -p $TARGET_DIR/icu -curl "https://chromium.googlesource.com/chromium/deps/icu/+archive/${npm_package_config_chromiumICUCommit}.tar.gz" | tar xzf - -C $TARGET_DIR/icu +mkdir -p "$TARGET_DIR/icu" +if [[ -n "$ICU_RELEASE" ]]; then + if [[ -z "$ICU_ARCHIVE" ]]; then + echo "Missing icuArchive for release ${ICU_RELEASE}" >&2 + exit 1 + fi + curl -L "https://github.com/unicode-org/icu/releases/download/${ICU_RELEASE}/${ICU_ARCHIVE}" | tar xzf - --strip-components=1 -C "$TARGET_DIR/icu" +else + echo "No ICU release configured for download." >&2 + exit 1 +fi diff --git a/scripts/info.sh b/scripts/info.sh index fdf737c4..3ec6b58f 100755 --- a/scripts/info.sh +++ b/scripts/info.sh @@ -1,24 +1,31 @@ #!/bin/bash -e -WEBKITGTK_VERSION="${npm_package_config_webkitGTK}" -# URL="https://github.com/WebKit/WebKit/tree/webkitgtk-${WEBKITGTK_VERSION}" -# FIXME: hardcoded branch because WebKitGTK 2.26 does not have tag -URL="https://github.com/WebKit/WebKit/tree/webkitgtk/2.26" -RAW_URL="https://raw.githubusercontent.com/WebKit/WebKit/refs/heads/webkitgtk/2.26" ROOTDIR=$PWD +WEBKIT_REPO="${npm_package_config_bunWebKitRepo:-https://github.com/oven-sh/WebKit.git}" +WEBKIT_COMMIT="${npm_package_config_bunWebKitCommit}" + export REVISION=$(node -e "console.log(require('./package.json').version.split('.')[0])") -CONFIG=$(node -e "console.log(require('$ROOTDIR/package.json').config)") -APPLE_VERSION=$(wget -q -O - "${RAW_URL}/Source/WebCore/Configurations/Version.xcconfig" | grep 'MAJOR_VERSION\s=\|MINOR_VERSION\s=\|TINY_VERSION\s=\|MICRO_VERSION\s=\|NANO_VERSION\s=') +CONFIG=$(node -e "console.log(JSON.stringify(require('$ROOTDIR/package.json').config, null, 2))") + +if [[ -n "$WEBKIT_COMMIT" ]]; then + WEBKIT_URL="https://github.com/oven-sh/WebKit/tree/${WEBKIT_COMMIT}" + RAW_URL="https://raw.githubusercontent.com/oven-sh/WebKit/${WEBKIT_COMMIT}" + APPLE_VERSION=$(curl -fsSL "${RAW_URL}/Configurations/Version.xcconfig" | grep 'MAJOR_VERSION\s=\|MINOR_VERSION\s=\|TINY_VERSION\s=\|MICRO_VERSION\s=\|NANO_VERSION\s=' || true) +else + WEBKIT_URL="$WEBKIT_REPO" + APPLE_VERSION="unknown" +fi if [ -d "$INSTALL_DIR_I18N_false" ]; then - SIZE=$(du -ah $INSTALL_DIR_I18N_false) + SIZE=$(du -ah "$INSTALL_DIR_I18N_false") else SIZE="0" fi printf "\n\n\n\n\n\t\t\tRevision: \x1B[32m$REVISION\x1B[0m\n\n\n" -printf "WebKitGTK version:\n$WEBKITGTK_VERSION\n\n" -printf "Config:\n$CONFIG\n\n" -printf "AppleWebkit:\n$APPLE_VERSION\n\n" +printf "WebKit repository:\n%s @ %s\n\n" "$WEBKIT_REPO" "${WEBKIT_COMMIT:-unknown}" +printf "Upstream URL:\n%s\n\n" "$WEBKIT_URL" +printf "Config:\n%s\n\n" "$CONFIG" +printf "AppleWebKit version components:\n%s\n\n" "$APPLE_VERSION" printf "Size:\n$SIZE\n\n" diff --git a/scripts/patch.sh b/scripts/patch.sh index 82178529..9452ca5d 100755 --- a/scripts/patch.sh +++ b/scripts/patch.sh @@ -9,51 +9,60 @@ ICU_PATCHSET=( ) JSC_PATCHSET=( - # Basic build setup, e.g. libjsc.so output name - "jsc.patch" + # Android-specific logging for version identification + "jsc_android_log_version.patch" - # Feature toggles, e.g. disable unnecessary build or JIT settings - "jsc_features.patch" + # Ensure PRIu64 fallback matches 64-bit width on Android builds + "jsc_android_uv_pri64.patch" - # NDK does not support backtrace and execinfo.h - "jsc_fix_build_error_execinfo.patch" + # Fix Collator stub implementation for builds without ICU collation + "jsc_android_collator_static.patch" - # Fix build error which related to C++StringView - "jsc_fix_build_error_stringview.patch" + # Provide defaults for Bun-specific macros on non-Bun platforms + "jsc_android_define_bun_macros.patch" - # Integrate with Chromium ICU - "jsc_icu_integrate.patch" + # Update TestWTF to match new ExternalStringImpl signature + "jsc_fix_external_string_tests.patch" - # Support getting correct locale setting in Android system - "jsc_locale_support.patch" + # Disable building TestWebKitAPI when consuming JSC only + "jsc_disable_api_tests.patch" - # Will print current JSC version in adb log during initialization - "jsc_startup_log_version.patch" + # Provide stubs for DFG abstract heap when DFG JIT is disabled + "jsc_stub_dfg_abstract_heap.patch" - # Misc errors - "jsc_fix_build_error_miss_headers.patch" + # Guard async frame helper when Bun additions disabled + "jsc_async_frame_guard.patch" - # Workaround JIT crash on arm64, especially for Saumsung S7 Edge - "jsc_fix_arm64_jit_crash.patch" + # Guard Bun-specific error helpers when Bun additions are disabled + "jsc_guard_error_instance.patch" - # Intl default timezone with Android integration - "jsc_intl_timezone.patch" + # Silence unused parameter warnings in modules and promise helpers + "jsc_android_silence_unused.patch" - # Improve heap GC mechanism like iOS - "jsc_heap_gc_like_ios.patch" + # Include Android-specific WTF sources for logging and real-time threads + "jsc_android_wtf_sources.patch" - # GC concurrent issue potential fix - # https://trac.webkit.org/changeset/251307/webkit - "jsc_fix_concurrent_gc_issue.patch" -) + # Avoid unused-result warning in CLI wait helper + "jsc_android_jsc_wait.patch" -if [[ "$I18N" = false ]] -then - JSC_PATCHSET+=( - # Disable i18n for non-i18n build - "jsc_disable_icu.patch" - ) -fi + # Guard JIT helpers when DFG/WebAssembly are disabled + "jsc_android_jit_guards.patch" + + # Avoid ICU formatting dependencies when validating time zones + "jsc_android_timezone_validate.patch" + + # Force Android builds to use C++20 and drop toolchain -O3 defaults + "jsc_android_release_flags.patch" + + # Avoid pthread_getname_np usage on Android where it's unavailable + "jsc_android_thread_name_guard.patch" + + # Use posix_memalign when aligned_alloc is missing on older Android + "jsc_android_systemheap_posix_memalign.patch" + + # Use legacy system property getter on older Android + "jsc_android_logging_property.patch" +) ###################################################################################### # Patchset management end diff --git a/scripts/start.sh b/scripts/start.sh index f03eb65c..a8dacdab 100755 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -2,8 +2,35 @@ export ANDROID_API_FOR_ABI_32=24 export ANDROID_API_FOR_ABI_64=24 +export ANDROID_TARGET_API=35 export ROOTDIR=$PWD +# Default toolchain locations when not provided. +DEFAULT_ANDROID_HOME="$HOME/Library/Android/sdk" +if [[ -z "$ANDROID_HOME" || ! -d "$ANDROID_HOME" ]]; then + export ANDROID_HOME="$DEFAULT_ANDROID_HOME" +fi + +DEFAULT_ANDROID_NDK="$ANDROID_HOME/ndk/28.2.13676358" +if [[ -z "$ANDROID_NDK" || ! -d "$ANDROID_NDK" ]]; then + export ANDROID_NDK="$DEFAULT_ANDROID_NDK" +fi + +if [[ -z "$JAVA_HOME" || ! -x "$JAVA_HOME/bin/java" ]]; then + if [[ "$(uname -s)" == "Darwin" ]]; then + if command -v brew >/dev/null 2>&1; then + HOMEBREW_JAVA_ROOT="$(brew --prefix openjdk@17 2>/dev/null)/libexec/openjdk.jdk/Contents/Home" + if [[ -x "$HOMEBREW_JAVA_ROOT/bin/java" ]]; then + export JAVA_HOME="$HOMEBREW_JAVA_ROOT" + fi + fi + fi +fi + +if [[ -n "$JAVA_HOME" && -x "$JAVA_HOME/bin/java" ]]; then + export PATH="$JAVA_HOME/bin:$PATH" +fi + source $ROOTDIR/scripts/env.sh source $ROOTDIR/scripts/info.sh export JSC_VERSION=${npm_package_version} @@ -17,27 +44,69 @@ patchAndMakeICU() { ICU_VERSION_MAJOR="$(awk '/ICU_VERSION_MAJOR_NUM/ {print $3}' $TARGETDIR/icu/source/common/unicode/uvernum.h)" printf "ICU version: ${ICU_VERSION_MAJOR}\n" $SCRIPT_DIR/patch.sh icu - rm -rf $TARGETDIR/icu/host mkdir -p $TARGETDIR/icu/host cd $TARGETDIR/icu/host + local HAS_CLANG=0 + if command -v clang >/dev/null 2>&1 && command -v clang++ >/dev/null 2>&1; then + HAS_CLANG=1 + fi + if [[ "$BUILD_TYPE" = "Release" ]] then - CFLAGS="-Os" + local LTO_FLAG + local EXTRA_FLAGS="" + if [[ $HAS_CLANG -eq 1 ]]; then + LTO_FLAG="-flto=thin" + EXTRA_FLAGS="-Wno-pass-failed=loop-vectorize" + else + LTO_FLAG="-flto" + fi + + local OPT_FLAGS="-O2 $LTO_FLAG" + if [[ -n "$EXTRA_FLAGS" ]]; then + OPT_FLAGS="$OPT_FLAGS $EXTRA_FLAGS" + fi + + CFLAGS="$OPT_FLAGS" + CXXFLAGS="-std=c++20 $OPT_FLAGS" + LDFLAGS="$LTO_FLAG" else CFLAGS="-g2" + CXXFLAGS="-std=c++20" + LDFLAGS="" fi - ICU_DATA_FILTER_FILE="${TARGETDIR}/icu/filters/android.json" \ - $TARGETDIR/icu/source/runConfigureICU Linux \ - --prefix=$PWD/prebuilts \ - CFLAGS="$CFLAGS" \ - CXXFLAGS="--std=c++11" \ - --disable-tests \ - --disable-samples \ - --disable-layout \ - --disable-layoutex + ICU_FILTER_FILE="${TARGETDIR}/icu/filters/android.json" + local CONFIG_ENV=(env "CFLAGS=$CFLAGS" "CXXFLAGS=$CXXFLAGS") + if [[ -n "$LDFLAGS" ]]; then + CONFIG_ENV+=("LDFLAGS=$LDFLAGS") + fi + if [[ $HAS_CLANG -eq 1 ]]; then + CONFIG_ENV+=("CC=clang" "CXX=clang++") + fi + + if [[ -f "$ICU_FILTER_FILE" ]]; then + printf "Using ICU data filter: %s\n" "$ICU_FILTER_FILE" + ICU_DATA_FILTER_FILE="$ICU_FILTER_FILE" \ + "${CONFIG_ENV[@]}" \ + $TARGETDIR/icu/source/runConfigureICU Linux \ + --prefix=$PWD/prebuilts \ + --disable-tests \ + --disable-samples \ + --disable-layout \ + --disable-layoutex + else + printf "ICU data filter not found at %s, building without data pruning\n" "$ICU_FILTER_FILE" + "${CONFIG_ENV[@]}" \ + $TARGETDIR/icu/source/runConfigureICU Linux \ + --prefix=$PWD/prebuilts \ + --disable-tests \ + --disable-samples \ + --disable-layout \ + --disable-layoutex + fi make -j5 cd $ROOTDIR @@ -98,13 +167,17 @@ copyHeaders() { cp -Rf $TARGETDIR/webkit/Source/JavaScriptCore/API/*.h ${distDir}/include } -export I18N=false -prep -compile - -export I18N=true -prep -compile +if [[ "${SKIP_NO_INTL}" != "1" ]]; then + export I18N=false + prep + compile +fi + +if [[ "${SKIP_INTL}" != "1" ]]; then + export I18N=true + prep + compile +fi printf "\n\n\t\t===================== create stripped distributions =====================\n\n" export DISTDIR=${ROOTDIR}/dist diff --git a/test/plugins/withJscAndroid.js b/test/plugins/withJscAndroid.js index 63c864fa..3143e6f1 100644 --- a/test/plugins/withJscAndroid.js +++ b/test/plugins/withJscAndroid.js @@ -1,6 +1,7 @@ const assert = require('assert'); const { withAppBuildGradle, + withGradleProperties, withProjectBuildGradle, } = require('expo/config-plugins'); @@ -47,6 +48,7 @@ afterEvaluate { `; config.modResults.contents += code; } + return config; }); }; @@ -73,6 +75,41 @@ const withJscAndroidProjectBuildGradle = (config) => { const withJscAndroid = (config) => { config = withJscAndroidAppBuildGradle(config); config = withJscAndroidProjectBuildGradle(config); + config = withGradleProperties(config, (config) => { + const DEFAULT_ARCHS = ['arm64-v8a', 'x86_64']; + const ARCHS_TO_REMOVE = new Set(['armeabi-v7a', 'x86']); + const propertyName = 'reactNativeArchitectures'; + const desiredValue = DEFAULT_ARCHS.join(','); + const existingProp = config.modResults.find( + (item) => item.type === 'property' && item.key === propertyName + ); + const cleanValue = (value) => { + if (!value) return desiredValue; + const archs = value + .split(',') + .map((arch) => arch.trim()) + .filter(Boolean); + if (!archs.length) return desiredValue; + const result = []; + archs.forEach((arch) => { + if (!ARCHS_TO_REMOVE.has(arch) && !result.includes(arch)) { + result.push(arch); + } + }); + if (!result.length) return desiredValue; + return result.join(','); + }; + if (existingProp) { + existingProp.value = cleanValue(existingProp.value); + } else { + config.modResults.push({ + type: 'property', + key: propertyName, + value: desiredValue, + }); + } + return config; + }); return config; };