mirror of
https://github.com/oven-sh/bun
synced 2026-02-27 03:57:23 +01:00
# JavaScriptCore Upstream Changes: 1b6f54d1c872..upstream/main **Date range**: Feb 5 -- Feb 11, 2026 **Total JSC commits**: 38 --- ## 1. New Features ### WebAssembly JSPI (JavaScript Promise Integration) **Commit**: `53e97afd3421` -- [JSC] JSPI Implementation **Files changed**: 59 files, +3879/-148 lines Full implementation of the [WebAssembly JSPI proposal](https://github.com/WebAssembly/js-promise-integration). Adds two new APIs: - `WebAssembly.promising(wasmFun)` -- wraps a wasm function so it returns a Promise - `new WebAssembly.Suspending(jsFun)` -- wraps a JS function so wasm can suspend on its result Controlled by `useJSPI` feature flag (disabled by default). This is a large change that introduces: - New classes: `EvacuatedStack`, `PinballCompletion`, `JSPIContext`, `WebAssemblySuspending`, `WebAssemblyPromising`, `JSWebAssemblySuspendError` - New `JSPIContext` struct added to `VM` (field `topJSPIContext`) - New `pinballCompletionStructure` in VM - New `WebAssemblySuspendError` and `WebAssemblySuspending` lazy class structures in JSGlobalObject - New methods on VM: `addEvacuatedStackSlice`, `removeEvacuatedStackSlice`, `gatherEvacuatedStackRoots` - New iso subspace: `pinballCompletionSpace` **Follow-up**: `f67441012b90` -- JSPI cages should only generate JIT code when JITCage is enabled ### WebAssembly Memory64 in BBQ Tier **Commit**: `7b98e4b17594` -- Add support for Memory64 in BBQ Tier Extends Memory64 support from the interpreter to the BBQ JIT tier, allowing wasm modules to address >4GB of memory. ### WebAssembly Multi-Memory (instantiation only) **Commit**: `bdf26416947e` -- Support instantiating multiple wasm memories Adds support for instantiating multiple memories in wasm modules (but not executing instructions that use memories other than index 0). Gated behind `useWasmMultiMemory` flag. ### LOL (Lightweight Optimizing Language) JIT -- New Tier (In Progress) A new JIT compilation tier "LOL" is being built incrementally across multiple commits: - `dd56e0f5b991` -- Add get_argument/argument_count bytecodes - `fb43184a0a77` -- Add to_primitive-like bytecodes - `f52fa4a30c76` -- Add switch/throw bytecodes - `7fd04c82d291` -- Add support for this/prototype bytecodes - `11127b8a61e0` -- Add support for op_ret These commits add new files under `Source/JavaScriptCore/lol/` (LOLJIT.cpp, LOLJIT.h, LOLRegisterAllocator.h). This appears to be a new lightweight JIT tier between Baseline and DFG. --- ## 2. Performance Improvements ### Deep Rope String Slicing -- 168x faster **Commit**: `93f2fd68619b` -- [JSC] Limit rope traversal depth in `tryJSSubstringImpl` Limits rope traversal depth to 16 in `tryJSSubstringImpl`. Deep rope strings from repeated concatenation (`s += 'A'`) previously caused O(n^2) behavior. When the depth limit is exceeded, it falls back to `resolveRope` to flatten the string. This directly addresses a performance issue reported against Bun where it was significantly slower than Node.js. ### String#endsWith DFG/FTL Optimization -- up to 10.5x faster **Commit**: `901865149859` -- [JSC] Optimize `String#endsWith` in DFG/FTL Adds a new DFG/FTL intrinsic `StringPrototypeEndsWithIntrinsic` for `String.prototype.endsWith`. Constant folding case is 10.5x faster; general case is 1.45x faster. ### RegExp Flag Getters in DFG/FTL and IC -- 1.6x faster **Commit**: `1fe86a244d00` -- [JSC] Handle RegExp flag getters in DFG/FTL and IC Adds DFG/FTL and inline cache support for RegExp flag property getters (`.global`, `.ignoreCase`, `.multiline`, `.dotAll`, `.sticky`, `.unicode`, `.unicodeSets`, `.hasIndices`). ### String#@@iterator as NewInternalFieldObject in DFG/FTL **Commit**: `44cba41d8eef` -- [JSC] Handle `String#@@iterator` as `NewInternalFieldObject` in DFG/FTL Optimizes string iterator creation in DFG/FTL by treating it as a `NewInternalFieldObject`, enabling allocation sinking. ### ArithMod(Int52) in DFG/FTL **Commit**: `49a21e7ff327` -- [JSC] Add ArithMod(Int52Use, Int52Use) in DFG / FTL **Follow-ups**: `f96be6066671` (constant folding fix), `c8f283248f3f` (NaNOrInfinity fix) Adds Int52 modulo support in DFG/FTL, avoiding expensive `fmod` double operations when inputs are integer-like doubles. ### ArithDiv(Int52) in DFG/FTL -- REVERTED **Commit**: `582cb0306b7c` -- [JSC] Add ArithDiv(Int52Use, Int52Use) in DFG / FTL **Revert**: `2e967edd1dc0` -- Reverted due to JetStream3 regressions ### Intl formatToParts Pre-built Structure -- up to 1.15x faster **Commit**: `a5dd9753d23c` -- [JSC] Optimize Intl formatToParts methods with pre-built Structure Optimizes Intl's `formatToParts` methods by using pre-built Structures for the returned part objects. ### JSBigInt Inline Storage **Commit**: `dbc50284d4cf` -- [JSC] Inline storage into JSBigInt **Related**: `304cf0713b9d` -- Remove JSBigInt::rightTrim and JSBigInt::tryRightTrim Major structural change to JSBigInt: digits are now stored inline (trailing storage) instead of via a separate `CagedBarrierPtr`. This eliminates the separate allocation and pointer indirection. `tryRightTrim` and `rightTrim` removed; `createFrom` renamed to `tryCreateFrom` with span-based API. ### WYHash Always Enabled for Strings **Commit**: `14ba1421ca08` -- [JSC] Always use WYHash for strings Previously, WYHash had a threshold (disabled for short strings on weak devices). Now it's enabled regardless of string size. ### JIT Worklist Thread Count: 3 -> 4 **Commit**: `453c578cadf6` -- [JSC] Bump JIT worklist thread number from 3 to 4 ### Greedy Register Allocator Improvements **Commit**: `b642ae17aade` -- [JSC] Proactively coalesce spill slots during register allocation **Commit**: `a78705db7c08` -- [JSC] GreedyRegAlloc: amortize cost of clearing the visited set in the evict loop --- ## 3. Bug Fixes ### RegExp (YARR) Fixes - `dea6808af40e` -- **Fix stale captures in FixedCount groups in MatchOnly mode**: `.test()` was not clearing captures between FixedCount iterations, causing stale values visible to backreferences. - `437e137889ea` -- **Fix infinite loop in JIT for non-greedy backreference to zero-width capture**: A non-greedy backreference like `\1*?` could loop forever when the referenced capture was undefined or empty. - `d4f884d21c0e` -- **Fix backtracking in NestedAlternativeEnd**: Wrong jump target was used when backtracking from NestedAlternativeEnd. ### ARM64 Cached Immediate Fix **Commit**: `8396ad321ad0` -- [JSC] Fix edge case issue of cached imm in ARM64 TrustedImm32(-1) was not zero-extended when cached, causing wrong reuse when followed by TrustedImm64(-1). ### Wasm Fixes - `cea8513d43ef` -- **Fix RefCast/RefTest folding in B3**: The condition was inverted, causing wrong cast results. - `629632da96e1` -- **Fix debugger races with idle and active VMs in stop-the-world** - `e5391ad90f47` -- **Stack check on IPInt->BBQ loop OSR entry** - `fd15e0d70ab1` -- **Use FrameTracer in wasm table_init operations** ### Structure Heap Alignment Assert Fix **Commit**: `47b52526fd42` -- [JSC] Fix startOfStructureHeap alignment RELEASE_ASSERT --- ## 4. Bun-side Changes - Updated `WEBKIT_VERSION` to `f03492d0636f` - Updated `SerializedScriptValue.cpp`: replaced removed `JSBigInt::tryRightTrim` with `JSBigInt::tryCreateFrom` span-based API - Fixed `CloneSerializer`/`CloneDeserializer` inheritance (`private` -> `public CloneBase`) - Explicitly disabled `ENABLE_MEDIA_SOURCE`, `ENABLE_MEDIA_STREAM`, `ENABLE_WEB_RTC` in `build.ts` and `SetupWebKit.cmake` for JSCOnly port --- ## 5. Summary by Component | Component | Commits | Key Changes | |-----------|---------|-------------| | **WASM** | 9 | JSPI implementation, Memory64 BBQ, multi-memory, RefCast fix, stack checks, debugger races | | **DFG/FTL** | 6 | String#endsWith opt, RegExp flags opt, String@@iterator opt, ArithMod(Int52) | | **YARR (RegExp)** | 3 | Stale captures fix, infinite loop fix, NestedAlternativeEnd backtracking fix | | **B3/Air** | 3 | Spill slot coalescing, generational set for eviction, RefCast/RefTest fix | | **LOL JIT** | 5 | New JIT tier being built incrementally | | **Runtime** | 6 | BigInt inline storage, WYHash always-on, Intl formatToParts opt, ARM64 imm fix, rope depth limit | --------- Co-authored-by: Sosuke Suzuki <sosuke@bun.com>
263 lines
8.4 KiB
CMake
263 lines
8.4 KiB
CMake
# NOTE: Changes to this file trigger QEMU JIT stress tests in CI.
|
|
# See scripts/verify-jit-stress-qemu.sh for details.
|
|
|
|
option(WEBKIT_VERSION "The version of WebKit to use")
|
|
option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading")
|
|
option(WEBKIT_BUILD_TYPE "The build type for local WebKit (defaults to CMAKE_BUILD_TYPE)")
|
|
|
|
if(NOT WEBKIT_VERSION)
|
|
set(WEBKIT_VERSION 4a6a32c32c11ffb9f5a94c310b10f50130bfe6de)
|
|
endif()
|
|
|
|
|
|
string(SUBSTRING ${WEBKIT_VERSION} 0 16 WEBKIT_VERSION_PREFIX)
|
|
string(SUBSTRING ${WEBKIT_VERSION} 0 8 WEBKIT_VERSION_SHORT)
|
|
|
|
if(WEBKIT_LOCAL)
|
|
if(NOT WEBKIT_BUILD_TYPE)
|
|
set(WEBKIT_BUILD_TYPE ${CMAKE_BUILD_TYPE})
|
|
endif()
|
|
set(DEFAULT_WEBKIT_PATH ${VENDOR_PATH}/WebKit/WebKitBuild/${WEBKIT_BUILD_TYPE})
|
|
else()
|
|
set(DEFAULT_WEBKIT_PATH ${CACHE_PATH}/webkit-${WEBKIT_VERSION_PREFIX})
|
|
endif()
|
|
|
|
option(WEBKIT_PATH "The path to the WebKit directory")
|
|
|
|
if(NOT WEBKIT_PATH)
|
|
set(WEBKIT_PATH ${DEFAULT_WEBKIT_PATH})
|
|
endif()
|
|
|
|
set(WEBKIT_INCLUDE_PATH ${WEBKIT_PATH}/include)
|
|
set(WEBKIT_LIB_PATH ${WEBKIT_PATH}/lib)
|
|
|
|
if(WEBKIT_LOCAL)
|
|
set(WEBKIT_SOURCE_DIR ${VENDOR_PATH}/WebKit)
|
|
|
|
if(WIN32)
|
|
# --- Build ICU from source (Windows only) ---
|
|
# On macOS, ICU is found automatically (Homebrew icu4c for headers, system for libs).
|
|
# On Linux, ICU is found automatically from system packages (e.g. libicu-dev).
|
|
# On Windows, there is no system ICU, so we build it from source.
|
|
set(ICU_LOCAL_ROOT ${VENDOR_PATH}/WebKit/WebKitBuild/icu)
|
|
if(NOT EXISTS ${ICU_LOCAL_ROOT}/lib/sicudt.lib)
|
|
message(STATUS "Building ICU from source...")
|
|
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|ARM64|aarch64|AARCH64")
|
|
set(ICU_PLATFORM "ARM64")
|
|
else()
|
|
set(ICU_PLATFORM "x64")
|
|
endif()
|
|
execute_process(
|
|
COMMAND powershell -ExecutionPolicy Bypass -File
|
|
${WEBKIT_SOURCE_DIR}/build-icu.ps1
|
|
-Platform ${ICU_PLATFORM}
|
|
-BuildType ${WEBKIT_BUILD_TYPE}
|
|
-OutputDir ${ICU_LOCAL_ROOT}
|
|
RESULT_VARIABLE ICU_BUILD_RESULT
|
|
)
|
|
if(NOT ICU_BUILD_RESULT EQUAL 0)
|
|
message(FATAL_ERROR "Failed to build ICU (exit code: ${ICU_BUILD_RESULT}).")
|
|
endif()
|
|
endif()
|
|
|
|
# Copy ICU libs to WEBKIT_LIB_PATH with the names BuildBun.cmake expects.
|
|
# Prebuilt WebKit uses 's' prefix (static) and 'd' suffix (debug).
|
|
file(MAKE_DIRECTORY ${WEBKIT_LIB_PATH})
|
|
if(WEBKIT_BUILD_TYPE STREQUAL "Debug")
|
|
set(ICU_SUFFIX "d")
|
|
else()
|
|
set(ICU_SUFFIX "")
|
|
endif()
|
|
file(COPY_FILE ${ICU_LOCAL_ROOT}/lib/sicudt.lib ${WEBKIT_LIB_PATH}/sicudt${ICU_SUFFIX}.lib ONLY_IF_DIFFERENT)
|
|
file(COPY_FILE ${ICU_LOCAL_ROOT}/lib/icuin.lib ${WEBKIT_LIB_PATH}/sicuin${ICU_SUFFIX}.lib ONLY_IF_DIFFERENT)
|
|
file(COPY_FILE ${ICU_LOCAL_ROOT}/lib/icuuc.lib ${WEBKIT_LIB_PATH}/sicuuc${ICU_SUFFIX}.lib ONLY_IF_DIFFERENT)
|
|
endif()
|
|
|
|
# --- Configure JSC ---
|
|
message(STATUS "Configuring JSC from local WebKit source at ${WEBKIT_SOURCE_DIR}...")
|
|
|
|
set(JSC_CMAKE_ARGS
|
|
-S ${WEBKIT_SOURCE_DIR}
|
|
-B ${WEBKIT_PATH}
|
|
-G ${CMAKE_GENERATOR}
|
|
-DPORT=JSCOnly
|
|
-DENABLE_STATIC_JSC=ON
|
|
-DUSE_THIN_ARCHIVES=OFF
|
|
-DENABLE_FTL_JIT=ON
|
|
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
|
-DUSE_BUN_JSC_ADDITIONS=ON
|
|
-DUSE_BUN_EVENT_LOOP=ON
|
|
-DENABLE_BUN_SKIP_FAILING_ASSERTIONS=ON
|
|
-DALLOW_LINE_AND_COLUMN_NUMBER_IN_BUILTINS=ON
|
|
-DCMAKE_BUILD_TYPE=${WEBKIT_BUILD_TYPE}
|
|
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
|
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
|
-DENABLE_REMOTE_INSPECTOR=ON
|
|
-DENABLE_MEDIA_SOURCE=OFF
|
|
-DENABLE_MEDIA_STREAM=OFF
|
|
-DENABLE_WEB_RTC=OFF
|
|
)
|
|
|
|
if(WIN32)
|
|
# ICU paths and Windows-specific compiler/linker settings
|
|
list(APPEND JSC_CMAKE_ARGS
|
|
-DICU_ROOT=${ICU_LOCAL_ROOT}
|
|
-DICU_LIBRARY=${ICU_LOCAL_ROOT}/lib
|
|
-DICU_INCLUDE_DIR=${ICU_LOCAL_ROOT}/include
|
|
-DCMAKE_LINKER=lld-link
|
|
)
|
|
# Static CRT and U_STATIC_IMPLEMENTATION
|
|
if(WEBKIT_BUILD_TYPE STREQUAL "Debug")
|
|
set(JSC_MSVC_RUNTIME "MultiThreadedDebug")
|
|
else()
|
|
set(JSC_MSVC_RUNTIME "MultiThreaded")
|
|
endif()
|
|
list(APPEND JSC_CMAKE_ARGS
|
|
-DCMAKE_MSVC_RUNTIME_LIBRARY=${JSC_MSVC_RUNTIME}
|
|
"-DCMAKE_C_FLAGS=/DU_STATIC_IMPLEMENTATION"
|
|
"-DCMAKE_CXX_FLAGS=/DU_STATIC_IMPLEMENTATION /clang:-fno-c++-static-destructors"
|
|
)
|
|
endif()
|
|
|
|
if(ENABLE_ASAN)
|
|
list(APPEND JSC_CMAKE_ARGS -DENABLE_SANITIZERS=address)
|
|
endif()
|
|
|
|
# Pass through ccache if available
|
|
if(CMAKE_C_COMPILER_LAUNCHER)
|
|
list(APPEND JSC_CMAKE_ARGS -DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER})
|
|
endif()
|
|
if(CMAKE_CXX_COMPILER_LAUNCHER)
|
|
list(APPEND JSC_CMAKE_ARGS -DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER})
|
|
endif()
|
|
|
|
execute_process(
|
|
COMMAND ${CMAKE_COMMAND} ${JSC_CMAKE_ARGS}
|
|
RESULT_VARIABLE JSC_CONFIGURE_RESULT
|
|
)
|
|
if(NOT JSC_CONFIGURE_RESULT EQUAL 0)
|
|
message(FATAL_ERROR "Failed to configure JSC (exit code: ${JSC_CONFIGURE_RESULT}). "
|
|
"Check the output above for errors.")
|
|
endif()
|
|
|
|
if(WIN32)
|
|
set(JSC_BYPRODUCTS
|
|
${WEBKIT_LIB_PATH}/JavaScriptCore.lib
|
|
${WEBKIT_LIB_PATH}/WTF.lib
|
|
${WEBKIT_LIB_PATH}/bmalloc.lib
|
|
)
|
|
else()
|
|
set(JSC_BYPRODUCTS
|
|
${WEBKIT_LIB_PATH}/libJavaScriptCore.a
|
|
${WEBKIT_LIB_PATH}/libWTF.a
|
|
${WEBKIT_LIB_PATH}/libbmalloc.a
|
|
)
|
|
endif()
|
|
|
|
if(WIN32)
|
|
add_custom_target(jsc ALL
|
|
COMMAND ${CMAKE_COMMAND} --build ${WEBKIT_PATH} --config ${WEBKIT_BUILD_TYPE} --target jsc
|
|
BYPRODUCTS ${JSC_BYPRODUCTS}
|
|
COMMENT "Building JSC (${WEBKIT_PATH})"
|
|
)
|
|
else()
|
|
add_custom_target(jsc ALL
|
|
COMMAND ${CMAKE_COMMAND} --build ${WEBKIT_PATH} --config ${WEBKIT_BUILD_TYPE} --target jsc
|
|
BYPRODUCTS ${JSC_BYPRODUCTS}
|
|
COMMENT "Building JSC (${WEBKIT_PATH})"
|
|
USES_TERMINAL
|
|
)
|
|
endif()
|
|
|
|
include_directories(
|
|
${WEBKIT_PATH}
|
|
${WEBKIT_PATH}/JavaScriptCore/Headers
|
|
${WEBKIT_PATH}/JavaScriptCore/Headers/JavaScriptCore
|
|
${WEBKIT_PATH}/JavaScriptCore/PrivateHeaders
|
|
${WEBKIT_PATH}/bmalloc/Headers
|
|
${WEBKIT_PATH}/WTF/Headers
|
|
${WEBKIT_PATH}/JavaScriptCore/PrivateHeaders/JavaScriptCore
|
|
)
|
|
|
|
# On Windows, add ICU headers from the local ICU build
|
|
if(WIN32)
|
|
include_directories(${ICU_LOCAL_ROOT}/include)
|
|
endif()
|
|
|
|
# After this point, only prebuilt WebKit is supported
|
|
return()
|
|
endif()
|
|
|
|
if(WIN32)
|
|
set(WEBKIT_OS "windows")
|
|
elseif(APPLE)
|
|
set(WEBKIT_OS "macos")
|
|
elseif(UNIX)
|
|
set(WEBKIT_OS "linux")
|
|
else()
|
|
message(FATAL_ERROR "Unsupported operating system: ${CMAKE_SYSTEM_NAME}")
|
|
endif()
|
|
|
|
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|ARM64|aarch64|AARCH64")
|
|
set(WEBKIT_ARCH "arm64")
|
|
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|x64|AMD64")
|
|
set(WEBKIT_ARCH "amd64")
|
|
else()
|
|
message(FATAL_ERROR "Unsupported architecture: ${CMAKE_SYSTEM_PROCESSOR}")
|
|
endif()
|
|
|
|
if(LINUX AND ABI STREQUAL "musl")
|
|
set(WEBKIT_SUFFIX "-musl")
|
|
endif()
|
|
|
|
if(DEBUG)
|
|
set(WEBKIT_SUFFIX "${WEBKIT_SUFFIX}-debug")
|
|
elseif(ENABLE_LTO)
|
|
set(WEBKIT_SUFFIX "${WEBKIT_SUFFIX}-lto")
|
|
else()
|
|
set(WEBKIT_SUFFIX "${WEBKIT_SUFFIX}")
|
|
endif()
|
|
|
|
if(ENABLE_ASAN)
|
|
# We cannot mix and match ASan Bun + non-ASan WebKit, or vice versa, because some WebKit classes
|
|
# change their layout according to whether ASan is used, for example:
|
|
# https://github.com/oven-sh/WebKit/blob/eda8b0fb4fb1aa23db9c2b00933df8b58bcdd289/Source/WTF/wtf/Vector.h#L682
|
|
set(WEBKIT_SUFFIX "${WEBKIT_SUFFIX}-asan")
|
|
endif()
|
|
|
|
setx(WEBKIT_NAME bun-webkit-${WEBKIT_OS}-${WEBKIT_ARCH}${WEBKIT_SUFFIX})
|
|
set(WEBKIT_FILENAME ${WEBKIT_NAME}.tar.gz)
|
|
|
|
if(WEBKIT_VERSION MATCHES "^autobuild-")
|
|
set(WEBKIT_TAG ${WEBKIT_VERSION})
|
|
else()
|
|
set(WEBKIT_TAG autobuild-${WEBKIT_VERSION})
|
|
endif()
|
|
|
|
setx(WEBKIT_DOWNLOAD_URL https://github.com/oven-sh/WebKit/releases/download/${WEBKIT_TAG}/${WEBKIT_FILENAME})
|
|
|
|
if(EXISTS ${WEBKIT_PATH}/package.json)
|
|
file(READ ${WEBKIT_PATH}/package.json WEBKIT_PACKAGE_JSON)
|
|
|
|
if(WEBKIT_PACKAGE_JSON MATCHES ${WEBKIT_VERSION})
|
|
return()
|
|
endif()
|
|
endif()
|
|
|
|
file(
|
|
DOWNLOAD ${WEBKIT_DOWNLOAD_URL} ${CACHE_PATH}/${WEBKIT_FILENAME} SHOW_PROGRESS
|
|
STATUS WEBKIT_DOWNLOAD_STATUS
|
|
)
|
|
if(NOT "${WEBKIT_DOWNLOAD_STATUS}" MATCHES "^0;")
|
|
message(FATAL_ERROR "Failed to download WebKit: ${WEBKIT_DOWNLOAD_STATUS}")
|
|
endif()
|
|
|
|
file(ARCHIVE_EXTRACT INPUT ${CACHE_PATH}/${WEBKIT_FILENAME} DESTINATION ${CACHE_PATH} TOUCH)
|
|
file(REMOVE ${CACHE_PATH}/${WEBKIT_FILENAME})
|
|
file(REMOVE_RECURSE ${WEBKIT_PATH})
|
|
file(RENAME ${CACHE_PATH}/bun-webkit ${WEBKIT_PATH})
|
|
|
|
if(APPLE)
|
|
file(REMOVE_RECURSE ${WEBKIT_INCLUDE_PATH}/unicode)
|
|
endif()
|