diff --git a/CMakeLists.txt b/CMakeLists.txt index 35d7367489..b61ce51b3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_policy(SET CMP0067 NEW) set(CMAKE_POLICY_DEFAULT_CMP0069 NEW) set(Bun_VERSION "1.1.20") -set(WEBKIT_TAG b49be549da59347762aa83f849a65158d2a0d724) +set(WEBKIT_TAG dac47fbd5444cbd4e3568267099ae276c547e897) set(BUN_WORKDIR "${CMAKE_CURRENT_BINARY_DIR}") message(STATUS "Configuring Bun ${Bun_VERSION} in ${BUN_WORKDIR}") @@ -22,6 +22,7 @@ set(REPORTED_NODEJS_VERSION "22.3.0") # If we do not set this, it will crash at startup on the first memory allocation. if(NOT WIN32 AND NOT APPLE) set(CMAKE_CXX_EXTENSIONS ON) + set(CMAKE_POSITION_INDEPENDENT_CODE FALSE) endif() # --- Build Type --- @@ -645,16 +646,6 @@ file(GLOB BUN_CPP ${CONFIGURE_DEPENDS} ) list(APPEND BUN_RAW_SOURCES ${BUN_CPP}) -# -- Brotli -- -set(BROTLI_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/deps/brotli") -file(GLOB BROTLI_FILES ${CONFIGURE_DEPENDS} - "${BROTLI_SRC}/common/*.c" - "${BROTLI_SRC}/enc/*.c" - "${BROTLI_SRC}/dec/*.c" -) -list(APPEND BUN_RAW_SOURCES ${BROTLI_FILES}) -include_directories("${BUN_DEPS_DIR}/brotli/include") - # -- uSockets -- set(USOCKETS_SRC "${CMAKE_CURRENT_SOURCE_DIR}/packages/bun-usockets/src") file(GLOB USOCKETS_FILES ${CONFIGURE_DEPENDS} @@ -902,6 +893,7 @@ if(NOT BUN_LINK_ONLY AND NOT BUN_CPP_ONLY) "${ZIG_COMPILER}" "build" "obj" "--zig-lib-dir" "${ZIG_LIB_DIR}" "--prefix" "${BUN_ZIG_OBJ_DIR}" + "--verbose" "-Dgenerated-code=${BUN_WORKDIR}/codegen" "-freference-trace=10" "-Dversion=${Bun_VERSION}" @@ -1182,7 +1174,6 @@ if(WIN32) target_link_options(${bun} PUBLIC "/STACK:0x1200000,0x100000" "/DEF:${BUN_SRC}/symbols.def" "/errorlimit:0") else() target_compile_options(${bun} PUBLIC - -fPIC -mtune=${CPU_TARGET} -fconstexpr-steps=2542484 -fconstexpr-depth=54 @@ -1192,6 +1183,8 @@ else() -fno-rtti -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer + -fno-pic + -fno-pie -faddrsig ) endif() @@ -1208,10 +1201,11 @@ endif() if(UNIX AND NOT APPLE) target_link_options(${bun} PUBLIC - "-fuse-ld=lld" - "-static-libstdc++" - "-static-libgcc" - "-Wl,-z,now" + -fuse-ld=lld + -fno-pic + -static-libstdc++ + -static-libgcc + "-Wl,-no-pie" "-Wl,-icf=safe" "-Wl,--as-needed" "-Wl,--gc-sections" @@ -1241,6 +1235,8 @@ if(UNIX AND NOT APPLE) "-rdynamic" "-Wl,--dynamic-list=${BUN_SRC}/symbols.dyn" "-Wl,--version-script=${BUN_SRC}/linker.lds" + -Wl,-z,lazy + -Wl,-z,norelro ) target_link_libraries(${bun} PRIVATE "c") @@ -1274,11 +1270,12 @@ endif() # --- Stripped Binary "bun" if(CMAKE_BUILD_TYPE STREQUAL "Release" AND NOT WIN32 AND NOT ASSERT_ENABLED) - if(CI AND APPLE) + # if(CI AND APPLE) + if(APPLE) add_custom_command( TARGET ${bun} POST_BUILD - COMMAND ${DSYMUTIL} -z -o ${BUN_WORKDIR}/${bun}.dSYM ${BUN_WORKDIR}/${bun} + COMMAND ${DSYMUTIL} -o ${BUN_WORKDIR}/${bun}.dSYM ${BUN_WORKDIR}/${bun} COMMENT "Generating .dSYM" ) endif() @@ -1463,6 +1460,24 @@ else() target_compile_definitions(${bun} PRIVATE "LAZY_LOAD_SQLITE=1") endif() +# -- Brotli -- +set(BROTLI_SRC "${CMAKE_CURRENT_SOURCE_DIR}/src/deps/brotli") +file(GLOB BROTLI_FILES ${CONFIGURE_DEPENDS} + "${BROTLI_SRC}/common/*.c" + "${BROTLI_SRC}/enc/*.c" + "${BROTLI_SRC}/dec/*.c" +) +add_library(brotli STATIC ${BROTLI_FILES}) +target_include_directories(brotli PRIVATE "${BROTLI_SRC}/include") +target_compile_definitions(brotli PRIVATE "BROTLI_STATIC") + +if(WIN32) + target_compile_options(brotli PRIVATE /MT /U_DLL) +endif() + +target_link_libraries(${bun} PRIVATE brotli) +include_directories("${BUN_DEPS_DIR}/brotli/include") + if(USE_CUSTOM_LSHPACK) include_directories(${BUN_DEPS_DIR}/ls-hpack) diff --git a/Dockerfile b/Dockerfile index 843f8f0ef5..6fa2ddf48b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -54,10 +54,6 @@ ENV BUILDARCH=${BUILDARCH} ENV BUN_DEPS_OUT_DIR=${BUN_DEPS_OUT_DIR} ENV BUN_ENABLE_LTO 1 -ENV CXX=clang++-${LLVM_VERSION} -ENV CC=clang-${LLVM_VERSION} -ENV AR=/usr/bin/llvm-ar-${LLVM_VERSION} -ENV LD=lld-${LLVM_VERSION} ENV LC_CTYPE=en_US.UTF-8 ENV LC_ALL=en_US.UTF-8 @@ -94,6 +90,8 @@ RUN install_packages \ clangd-${LLVM_VERSION} \ libc++-${LLVM_VERSION}-dev \ libc++abi-${LLVM_VERSION}-dev \ + llvm-${LLVM_VERSION}-runtime \ + llvm-${LLVM_VERSION}-dev \ make \ cmake \ ninja-build \ @@ -120,6 +118,15 @@ RUN install_packages \ && ln -sf /usr/bin/lldb-${LLVM_VERSION} /usr/bin/lldb \ && ln -sf /usr/bin/clangd-${LLVM_VERSION} /usr/bin/clangd \ && ln -sf /usr/bin/llvm-ar-${LLVM_VERSION} /usr/bin/llvm-ar \ + && ln -sf /usr/bin/ld.lld /usr/bin/ld \ + && ln -sf /usr/bin/llvm-ranlib-${LLVM_VERSION} /usr/bin/ranlib \ + && ln -sf /usr/bin/clang /usr/bin/cc \ + && ln -sf /usr/bin/clang /usr/bin/c89 \ + && ln -sf /usr/bin/clang /usr/bin/c99 \ + && ln -sf /usr/bin/clang++ /usr/bin/c++ \ + && ln -sf /usr/bin/clang++ /usr/bin/g++ \ + && ln -sf /usr/bin/llvm-ar /usr/bin/ar \ + && ln -sf /usr/bin/clang /usr/bin/gcc \ && arch="$(dpkg --print-architecture)" \ && case "${arch##*-}" in \ amd64) variant="x64";; \ @@ -132,6 +139,7 @@ RUN install_packages \ && ln -s /usr/bin/bun /usr/bin/bunx \ && rm -rf bun-linux-${variant} bun-linux-${variant}.zip \ && mkdir -p ${BUN_DIR} ${BUN_DEPS_OUT_DIR} + # && if [ -n "${SCCACHE_BUCKET}" ]; then \ # echo "Setting up sccache" \ # && wget https://github.com/mozilla/sccache/releases/download/v0.5.4/sccache-v0.5.4-${BUILD_MACHINE_ARCH}-unknown-linux-musl.tar.gz \ @@ -168,13 +176,14 @@ ENV CCACHE_DIR=${CCACHE_DIR} COPY Makefile ${BUN_DIR}/Makefile COPY src/deps/c-ares ${BUN_DIR}/src/deps/c-ares +COPY scripts ${BUN_DIR}/scripts WORKDIR $BUN_DIR RUN --mount=type=cache,target=${CCACHE_DIR} \ cd $BUN_DIR \ - && make c-ares \ - && rm -rf ${BUN_DIR}/src/deps/c-ares ${BUN_DIR}/Makefile + && bash ./scripts/build-cares.sh \ + && rm -rf ${BUN_DIR}/src/deps/c-ares ${BUN_DIR}/Makefile ${BUN_DIR}/scripts FROM bun-base as lolhtml @@ -205,13 +214,14 @@ ENV CPU_TARGET=${CPU_TARGET} COPY Makefile ${BUN_DIR}/Makefile COPY src/deps/mimalloc ${BUN_DIR}/src/deps/mimalloc +COPY scripts ${BUN_DIR}/scripts ARG CCACHE_DIR=/ccache ENV CCACHE_DIR=${CCACHE_DIR} RUN --mount=type=cache,target=${CCACHE_DIR} \ cd ${BUN_DIR} \ - && make mimalloc \ + && bash ./scripts/build-mimalloc.sh \ && rm -rf src/deps/mimalloc Makefile FROM bun-base as mimalloc-debug @@ -241,14 +251,17 @@ ARG CCACHE_DIR=/ccache ENV CCACHE_DIR=${CCACHE_DIR} COPY Makefile ${BUN_DIR}/Makefile +COPY CMakeLists.txt ${BUN_DIR}/CMakeLists.txt +COPY scripts ${BUN_DIR}/scripts COPY src/deps/zlib ${BUN_DIR}/src/deps/zlib +COPY package.json bun.lockb Makefile .gitmodules ${BUN_DIR}/ WORKDIR $BUN_DIR RUN --mount=type=cache,target=${CCACHE_DIR} \ cd $BUN_DIR \ - && make zlib \ - && rm -rf src/deps/zlib Makefile + && bash ./scripts/build-zlib.sh && rm -rf src/deps/zlib scripts + FROM bun-base as libarchive @@ -287,6 +300,7 @@ ARG CPU_TARGET ENV CPU_TARGET=${CPU_TARGET} COPY Makefile ${BUN_DIR}/Makefile +COPY scripts ${BUN_DIR}/scripts COPY src/deps/boringssl ${BUN_DIR}/src/deps/boringssl WORKDIR $BUN_DIR @@ -296,7 +310,7 @@ ENV CCACHE_DIR=${CCACHE_DIR} RUN --mount=type=cache,target=${CCACHE_DIR} \ cd ${BUN_DIR} \ - && make boringssl \ + && bash ./scripts/build-boringssl.sh \ && rm -rf src/deps/boringssl Makefile @@ -312,12 +326,14 @@ ENV CCACHE_DIR=${CCACHE_DIR} COPY Makefile ${BUN_DIR}/Makefile COPY src/deps/zstd ${BUN_DIR}/src/deps/zstd +COPY scripts ${BUN_DIR}/scripts WORKDIR $BUN_DIR RUN --mount=type=cache,target=${CCACHE_DIR} \ cd $BUN_DIR \ - && make zstd + && bash ./scripts/build-zstd.sh \ + && rm -rf src/deps/zstd scripts FROM bun-base as ls-hpack @@ -331,12 +347,14 @@ ENV CCACHE_DIR=${CCACHE_DIR} COPY Makefile ${BUN_DIR}/Makefile COPY src/deps/ls-hpack ${BUN_DIR}/src/deps/ls-hpack +COPY scripts ${BUN_DIR}/scripts WORKDIR $BUN_DIR RUN --mount=type=cache,target=${CCACHE_DIR} \ cd $BUN_DIR \ - && make lshpack + && bash ./scripts/build-lshpack.sh \ + && rm -rf src/deps/ls-hpack scripts FROM bun-base-with-zig as bun-identifier-cache @@ -492,6 +510,7 @@ RUN mkdir -p build bun-webkit # lol COPY src/bun.js/bindings/sqlite/sqlite3.c ${BUN_DIR}/src/bun.js/bindings/sqlite/sqlite3.c +COPY src/deps/brotli ${BUN_DIR}/src/deps/brotli COPY src/symbols.dyn src/linker.lds ${BUN_DIR}/src/ @@ -506,7 +525,8 @@ COPY --from=tinycc ${BUN_DEPS_OUT_DIR}/* ${BUN_DEPS_OUT_DIR}/ COPY --from=c-ares ${BUN_DEPS_OUT_DIR}/* ${BUN_DEPS_OUT_DIR}/ COPY --from=ls-hpack ${BUN_DEPS_OUT_DIR}/* ${BUN_DEPS_OUT_DIR}/ COPY --from=bun-compile-zig-obj /tmp/bun-zig.o ${BUN_DIR}/build/bun-zig.o -COPY --from=bun-cpp-objects ${BUN_DIR}/build/bun-cpp-objects.a ${BUN_DIR}/build/bun-cpp-objects.a +COPY --from=bun-cpp-objects ${BUN_DIR}/build/*.a ${BUN_DIR}/build/ +COPY --from=bun-cpp-objects ${BUN_DIR}/build/*.o ${BUN_DIR}/build/ COPY --from=bun-cpp-objects ${BUN_DIR}/bun-webkit/lib ${BUN_DIR}/bun-webkit/lib WORKDIR $BUN_DIR/build diff --git a/Makefile b/Makefile index db8d717ec9..5f941249a9 100644 --- a/Makefile +++ b/Makefile @@ -157,7 +157,12 @@ CMAKE_FLAGS_WITHOUT_RELEASE = -DCMAKE_C_COMPILER=$(CC) \ -DCMAKE_OSX_DEPLOYMENT_TARGET=$(MIN_MACOS_VERSION) \ $(CMAKE_CXX_COMPILER_LAUNCHER_FLAG) \ -DCMAKE_AR=$(AR) \ - -DCMAKE_RANLIB=$(which llvm-16-ranlib 2>/dev/null || which llvm-ranlib 2>/dev/null) + -DCMAKE_RANLIB=$(which llvm-16-ranlib 2>/dev/null || which llvm-ranlib 2>/dev/null) \ + -DCMAKE_CXX_STANDARD=20 \ + -DCMAKE_C_STANDARD=17 \ + -DCMAKE_CXX_STANDARD_REQUIRED=ON \ + -DCMAKE_C_STANDARD_REQUIRED=ON \ + -DCMAKE_CXX_EXTENSIONS=ON @@ -184,8 +189,8 @@ endif OPTIMIZATION_LEVEL=-O3 $(MARCH_NATIVE) DEBUG_OPTIMIZATION_LEVEL= -O1 $(MARCH_NATIVE) -gdwarf-4 -CFLAGS_WITHOUT_MARCH = $(MACOS_MIN_FLAG) $(OPTIMIZATION_LEVEL) -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -BUN_CFLAGS = $(MACOS_MIN_FLAG) $(MARCH_NATIVE) $(OPTIMIZATION_LEVEL) -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden +CFLAGS_WITHOUT_MARCH = $(MACOS_MIN_FLAG) $(OPTIMIZATION_LEVEL) -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-pie -fno-pic +BUN_CFLAGS = $(MACOS_MIN_FLAG) $(MARCH_NATIVE) $(OPTIMIZATION_LEVEL) -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-pie -fno-pic BUN_TMP_DIR := /tmp/make-bun CFLAGS=$(CFLAGS_WITHOUT_MARCH) $(MARCH_NATIVE) diff --git a/build.zig b/build.zig index d6cae3fc03..20c65eff9e 100644 --- a/build.zig +++ b/build.zig @@ -338,10 +338,13 @@ pub fn addBunObject(b: *Build, opts: *BunBuildOptions) *Compile { }, .target = opts.target, .optimize = opts.optimize, + + // https://github.com/ziglang/zig/issues/17430 .pic = true, + + .omit_frame_pointer = false, .strip = false, // stripped at the end }); - obj.bundle_compiler_rt = false; obj.formatted_panics = true; obj.root_module.omit_frame_pointer = false; @@ -359,9 +362,10 @@ pub fn addBunObject(b: *Build, opts: *BunBuildOptions) *Compile { } if (opts.os == .linux) { - obj.link_emit_relocs = true; - obj.link_eh_frame_hdr = true; + obj.link_emit_relocs = false; + obj.link_eh_frame_hdr = false; obj.link_function_sections = true; + obj.link_data_sections = true; if (opts.optimize == .Debug) { obj.root_module.valgrind = true; diff --git a/scripts/build-cares.sh b/scripts/build-cares.sh index 266e4292b1..575a4da3d1 100755 --- a/scripts/build-cares.sh +++ b/scripts/build-cares.sh @@ -1,10 +1,12 @@ #!/usr/bin/env bash set -exo pipefail + +export FORCE_PIC=1 source $(dirname -- "${BASH_SOURCE[0]}")/env.sh cd $BUN_DEPS_DIR/c-ares -rm -rf build +rm -rf build CMakeCache.txt CMakeFiles mkdir -p build cd build @@ -12,8 +14,9 @@ cd build cmake "${CMAKE_FLAGS[@]}" .. \ -DCMAKE_INSTALL_LIBDIR=lib \ -DCARES_STATIC=ON \ - -DCARES_STATIC_PIC=ON \ + -DCARES_STATIC_PIC=OFF \ -DCARES_SHARED=OFF \ + -DCARES_BUILD_TOOLS=ON \ -G "Ninja" ninja diff --git a/scripts/build-libarchive.sh b/scripts/build-libarchive.sh index 464da3f338..d1ad80580b 100755 --- a/scripts/build-libarchive.sh +++ b/scripts/build-libarchive.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash set -exo pipefail +export FORCE_PIC=1 source $(dirname -- "${BASH_SOURCE[0]}")/env.sh mkdir -p $BUN_DEPS_OUT_DIR diff --git a/scripts/build-lshpack.sh b/scripts/build-lshpack.sh index e2b2011994..1a870efe56 100755 --- a/scripts/build-lshpack.sh +++ b/scripts/build-lshpack.sh @@ -2,11 +2,11 @@ set -exo pipefail source $(dirname -- "${BASH_SOURCE[0]}")/env.sh +rm -rf CMakeFiles CMakeCache build.ninja mkdir -p $BUN_DEPS_OUT_DIR cd $BUN_DEPS_DIR/ls-hpack - rm -rf CMakeCache* CMakeFiles cmake "${CMAKE_FLAGS[@]}" . \ @@ -15,6 +15,6 @@ cmake "${CMAKE_FLAGS[@]}" . \ -DSHARED=0 \ -GNinja -ninja +ninja libls-hpack.a cp ./libls-hpack.a $BUN_DEPS_OUT_DIR/liblshpack.a diff --git a/scripts/build-zlib.sh b/scripts/build-zlib.sh index c7cba5cf25..daedca9fb3 100755 --- a/scripts/build-zlib.sh +++ b/scripts/build-zlib.sh @@ -9,5 +9,5 @@ if [[ $(uname -s) == 'Darwin' ]]; then export CFLAGS="$CFLAGS -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}" fi CFLAGS="${CFLAGS}" ./configure --static -make -j${CPUS} +make -j${CPUS} libz.a cp ./libz.a $BUN_DEPS_OUT_DIR/libz.a diff --git a/scripts/build-zstd.sh b/scripts/build-zstd.sh index 2150d43204..3adb9fa764 100755 --- a/scripts/build-zstd.sh +++ b/scripts/build-zstd.sh @@ -7,5 +7,5 @@ mkdir -p $BUN_DEPS_OUT_DIR cd $BUN_DEPS_DIR/zstd rm -rf Release CMakeCache.txt CMakeFiles cmake "${CMAKE_FLAGS[@]}" -DZSTD_BUILD_STATIC=ON -B Release -S build/cmake -G Ninja -ninja -C Release +ninja libzstd_static -C Release cp Release/lib/libzstd.a $BUN_DEPS_OUT_DIR/libzstd.a diff --git a/scripts/env.sh b/scripts/env.sh index 012bd2be18..071ce4f989 100755 --- a/scripts/env.sh +++ b/scripts/env.sh @@ -27,8 +27,23 @@ export CPUS=${CPUS:-$(nproc || sysctl -n hw.ncpu || echo 1)} export CMAKE_CXX_COMPILER=${CXX} export CMAKE_C_COMPILER=${CC} -export CFLAGS='-O3 -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer' -export CXXFLAGS='-O3 -fno-exceptions -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer' +export CFLAGS='-O3 -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-asynchronous-unwind-tables -fno-unwind-tables -faddrsig ' +export CXXFLAGS='-O3 -fno-exceptions -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-asynchronous-unwind-tables -fno-unwind-tables -faddrsig ' + +if [[ $(uname -s) == 'Linux' ]]; then + export CFLAGS="$CFLAGS -ffunction-sections -fdata-sections" + export CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections" + export LDFLAGS="${LDFLAGS} -Wl,-z,norelro " +fi + +# libarchive needs position-independent executables to compile successfully +if [ -n "$FORCE_PIC" ]; then + export CFLAGS="$CFLAGS -fPIC " + export CXXFLAGS="$CXXFLAGS -fPIC " +else + export CFLAGS="$CFLAGS -fno-pie -fno-pic " + export CXXFLAGS="$CXXFLAGS -fno-pie -fno-pic " +fi if [[ $(uname -s) == 'Linux' && ($(uname -m) == 'aarch64' || $(uname -m) == 'arm64') ]]; then export CFLAGS="$CFLAGS -march=armv8-a+crc -mtune=ampere1 " diff --git a/src/bun.js/bindings/ProcessBindingUV.cpp b/src/bun.js/bindings/ProcessBindingUV.cpp index d62eefa3be..c6151ffefe 100644 --- a/src/bun.js/bindings/ProcessBindingUV.cpp +++ b/src/bun.js/bindings/ProcessBindingUV.cpp @@ -132,14 +132,15 @@ JSC_DEFINE_HOST_FUNCTION(jsGetErrorMap, (JSGlobalObject * globalObject, JSC::Cal auto& vm = globalObject->vm(); auto map = JSC::JSMap::create(vm, globalObject->mapStructure()); -#define PUT_PROPERTY(name, value, desc) \ - { \ - auto arr = JSC::constructEmptyArray(globalObject, static_cast(nullptr), 2); \ - arr->putDirectIndex(globalObject, 0, JSC::jsString(vm, String(#name##_s))); \ - arr->putDirectIndex(globalObject, 1, JSC::jsString(vm, String(desc##_s))); \ - map->set(globalObject, JSC::jsNumber(value), arr); \ - } + // Inlining each of these via macros costs like 300 KB. + const auto putProperty = [](JSC::VM& vm, JSC::JSMap* map, JSC::JSGlobalObject* globalObject, ASCIILiteral name, int value, ASCIILiteral desc) -> void { + auto arr = JSC::constructEmptyArray(globalObject, static_cast(nullptr), 2); + arr->putDirectIndex(globalObject, 0, JSC::jsString(vm, String(name))); + arr->putDirectIndex(globalObject, 1, JSC::jsString(vm, String(desc))); + map->set(globalObject, JSC::jsNumber(value), arr); + }; +#define PUT_PROPERTY(name, value, desc) putProperty(vm, map, globalObject, #name##_s, value, desc##_s); BUN_UV_ERRNO_MAP(PUT_PROPERTY) #undef PUT_PROPERTY @@ -152,9 +153,15 @@ JSObject* create(VM& vm, JSGlobalObject* globalObject) EnsureStillAliveScope ensureStillAlive(bindingObject); bindingObject->putDirect(vm, JSC::Identifier::fromString(vm, "errname"_s), JSC::JSFunction::create(vm, globalObject, 1, "errname"_s, jsErrname, ImplementationVisibility::Public)); -#define PUT_PROPERTY(name, value, desc) \ - bindingObject->putDirect(vm, JSC::Identifier::fromString(vm, "UV_" #name##_s), JSC::jsNumber(value)); + // Inlining each of these via macros costs like 300 KB. + // Before: 96305608 + // After: 95973832 + const auto putNamedProperty = [](JSC::VM& vm, JSObject* bindingObject, const ASCIILiteral name, int value) -> void { + bindingObject->putDirect(vm, JSC::Identifier::fromString(vm, makeString("UV_"_s, name)), JSC::jsNumber(value)); + }; +#define PUT_PROPERTY(name, value, desc) \ + putNamedProperty(vm, bindingObject, #name##_s, value); BUN_UV_ERRNO_MAP(PUT_PROPERTY) #undef PUT_PROPERTY diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig index 7c1e1e4724..5834f9dc8d 100644 --- a/src/bun.js/bindings/bindings.zig +++ b/src/bun.js/bindings/bindings.zig @@ -609,10 +609,10 @@ pub const ZigString = extern struct { pub fn static(comptime slice_: []const u8) *const ZigString { const Holder = struct { - pub const value = ZigString{ ._unsafe_ptr_do_not_use = slice_.ptr, .len = slice_.len }; + pub const value = &ZigString{ ._unsafe_ptr_do_not_use = slice_.ptr, .len = slice_.len }; }; - return &Holder.value; + return Holder.value; } pub const GithubActionFormatter = struct { diff --git a/src/bun.js/bindings/exports.zig b/src/bun.js/bindings/exports.zig index b2b46d7c91..dca4d934ec 100644 --- a/src/bun.js/bindings/exports.zig +++ b/src/bun.js/bindings/exports.zig @@ -954,6 +954,10 @@ comptime { /// Using characters16() does not seem to always have the sentinel. or something else /// broke when I just used it. Not sure. ... but this works! pub export fn Bun__LoadLibraryBunString(str: *bun.String) ?*anyopaque { + if (comptime !Environment.isWindows) { + unreachable; + } + var buf: bun.WPathBuffer = undefined; const data = switch (str.encoding()) { .utf8 => bun.strings.convertUTF8toUTF16InBuffer(&buf, str.utf8()), diff --git a/src/bun.js/bindings/workaround-missing-symbols.cpp b/src/bun.js/bindings/workaround-missing-symbols.cpp index 5db3610ca4..0b095e6c60 100644 --- a/src/bun.js/bindings/workaround-missing-symbols.cpp +++ b/src/bun.js/bindings/workaround-missing-symbols.cpp @@ -358,6 +358,10 @@ extern "C" int __ulock_wait2(uint32_t operation, void* addr, uint64_t value, #endif +#ifndef U_SHOW_CPLUSPLUS_API +#define U_SHOW_CPLUSPLUS_API 0 +#endif + #include extern "C" bool icu_hasBinaryProperty(UChar32 cp, unsigned int prop) diff --git a/src/bun.js/node/path.zig b/src/bun.js/node/path.zig index 9987cbf379..faa3d1df1c 100644 --- a/src/bun.js/node/path.zig +++ b/src/bun.js/node/path.zig @@ -117,7 +117,7 @@ pub const sep_str_windows = CHAR_STR_BACKWARD_SLASH; inline fn formatExtT(comptime T: type, ext: []const T, buf: []T) []const T { const len = ext.len; if (len == 0) { - return comptime L(T, ""); + return &.{}; } if (ext[0] == CHAR_DOT) { return ext; @@ -240,18 +240,18 @@ pub fn basenamePosixT(comptime T: type, path: []const T, suffix: ?[]const T) []c const len = path.len; // Exit early for easier number type use. if (len == 0) { - return comptime L(T, ""); + return &.{}; } var start: usize = 0; // We use an optional value instead of -1, as in Node code, for easier number type use. var end: ?usize = null; var matchedSlash: bool = true; - const _suffix = if (suffix) |_s| _s else comptime L(T, ""); + const _suffix = if (suffix) |_s| _s else &.{}; const _suffixLen = _suffix.len; if (suffix != null and _suffixLen > 0 and _suffixLen <= len) { if (std.mem.eql(T, _suffix, path)) { - return comptime L(T, ""); + return &.{}; } // We use an optional value instead of -1, as in Node code, for easier number type use. var extIdx: ?usize = _suffixLen - 1; @@ -328,7 +328,7 @@ pub fn basenamePosixT(comptime T: type, path: []const T, suffix: ?[]const T) []c return if (end) |_end| path[start.._end] else - comptime L(T, ""); + &.{}; } /// Based on Node v21.6.1 path.win32.basename: @@ -340,7 +340,7 @@ pub fn basenameWindowsT(comptime T: type, path: []const T, suffix: ?[]const T) [ const len = path.len; // Exit early for easier number type use. if (len == 0) { - return comptime L(T, ""); + return &.{}; } const isSepT = isSepWindowsT; @@ -357,11 +357,11 @@ pub fn basenameWindowsT(comptime T: type, path: []const T, suffix: ?[]const T) [ start = 2; } - const _suffix = if (suffix) |_s| _s else comptime L(T, ""); + const _suffix = if (suffix) |_s| _s else &.{}; const _suffixLen = _suffix.len; if (suffix != null and _suffixLen > 0 and _suffixLen <= len) { if (std.mem.eql(T, _suffix, path)) { - return comptime L(T, ""); + return &.{}; } // We use an optional value instead of -1, as in Node code, for easier number type use. var extIdx: ?usize = _suffixLen - 1; @@ -434,7 +434,7 @@ pub fn basenameWindowsT(comptime T: type, path: []const T, suffix: ?[]const T) [ return if (end) |_end| path[start.._end] else - comptime L(T, ""); + &.{}; } pub inline fn basenamePosixJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, path: []const T, suffix: ?[]const T) JSC.JSValue { @@ -685,7 +685,7 @@ pub fn extnamePosixT(comptime T: type, path: []const T) []const T { const len = path.len; // Exit early for easier number type use. if (len == 0) { - return comptime L(T, ""); + return &.{}; } // We use an optional value instead of -1, as in Node code, for easier number type use. var startDot: ?usize = null; @@ -746,7 +746,7 @@ pub fn extnamePosixT(comptime T: type, path: []const T) []const T { _startDot == _end - 1 and _startDot == startPart + 1)) { - return comptime L(T, ""); + return &.{}; } return path[_startDot.._end]; @@ -761,7 +761,7 @@ pub fn extnameWindowsT(comptime T: type, path: []const T) []const T { const len = path.len; // Exit early for easier number type use. if (len == 0) { - return comptime L(T, ""); + return &.{}; } var start: usize = 0; // We use an optional value instead of -1, as in Node code, for easier number type use. @@ -835,7 +835,7 @@ pub fn extnameWindowsT(comptime T: type, path: []const T) []const T { _startDot == _end - 1 and _startDot == startPart + 1)) { - return comptime L(T, ""); + return &.{}; } return path[_startDot.._end]; @@ -1085,7 +1085,7 @@ pub inline fn joinPosixT(comptime T: type, paths: []const []const T, buf: []T, b var bufOffset: usize = 0; // Back joined by expandable buf2 in case it is long. - var joined: []const T = comptime L(T, ""); + var joined: []const T = &.{}; for (paths) |path| { // validateString of `path is performed in pub fn join. @@ -1131,8 +1131,8 @@ pub fn joinWindowsT(comptime T: type, paths: []const []const T, buf: []T, buf2: var bufOffset: usize = 0; // Backed by expandable buf2 in case it is long. - var joined: []const T = comptime L(T, ""); - var firstPart: []const T = comptime L(T, ""); + var joined: []const T = &.{}; + var firstPart: []const T = &.{}; for (paths) |path| { // validateString of `path` is performed in pub fn join. @@ -1282,7 +1282,7 @@ fn normalizeStringT(comptime T: type, path: []const T, allowAboveRoot: bool, sep var bufOffset: usize = 0; var bufSize: usize = 0; - var res: []const T = comptime L(T, ""); + var res: []const T = &.{}; var lastSegmentLength: usize = 0; // We use an optional value instead of -1, as in Node code, for easier number type use. var lastSlash: ?usize = null; @@ -1317,7 +1317,7 @@ fn normalizeStringT(comptime T: type, path: []const T, allowAboveRoot: bool, sep if (bufSize > 2) { const lastSlashIndex = std.mem.lastIndexOfScalar(T, buf[0..bufSize], separator); if (lastSlashIndex == null) { - res = comptime L(T, ""); + res = &.{}; bufSize = 0; lastSegmentLength = 0; } else { @@ -1344,7 +1344,7 @@ fn normalizeStringT(comptime T: type, path: []const T, allowAboveRoot: bool, sep dots = 0; continue; } else if (bufSize != 0) { - res = comptime L(T, ""); + res = &.{}; bufSize = 0; lastSegmentLength = 0; lastSlash = i; @@ -1687,12 +1687,12 @@ pub fn parsePosixT(comptime T: type, path: []const T) PathParsed(T) { return .{}; } - var root: []const T = comptime L(T, ""); - var dir: []const T = comptime L(T, ""); - var base: []const T = comptime L(T, ""); - var ext: []const T = comptime L(T, ""); + var root: []const T = &.{}; + var dir: []const T = &.{}; + var base: []const T = &.{}; + var ext: []const T = &.{}; // Prefix with _ to avoid shadowing the identifier in the outer scope. - var _name: []const T = comptime L(T, ""); + var _name: []const T = &.{}; // Prefix with _ to avoid shadowing the identifier in the outer scope. const _isAbsolute = path[0] == CHAR_FORWARD_SLASH; var start: usize = 0; @@ -1786,12 +1786,12 @@ pub fn parseWindowsT(comptime T: type, path: []const T) PathParsed(T) { comptime validatePathT(T, "parseWindowsT"); // validateString of `path` is performed in pub fn parse. - var root: []const T = comptime L(T, ""); - var dir: []const T = comptime L(T, ""); - var base: []const T = comptime L(T, ""); - var ext: []const T = comptime L(T, ""); + var root: []const T = &.{}; + var dir: []const T = &.{}; + var base: []const T = &.{}; + var ext: []const T = &.{}; // Prefix with _ to avoid shadowing the identifier in the outer scope. - var _name: []const T = comptime L(T, ""); + var _name: []const T = &.{}; const len = path.len; if (len == 0) { @@ -2006,7 +2006,7 @@ pub fn relativePosixT(comptime T: type, from: []const T, to: []const T, buf: []T // validateString of `from` and `to` are performed in pub fn relative. if (std.mem.eql(T, from, to)) { - return MaybeSlice(T){ .result = comptime L(T, "") }; + return MaybeSlice(T){ .result = &.{} }; } // Trim leading forward slashes. @@ -2023,7 +2023,7 @@ pub fn relativePosixT(comptime T: type, from: []const T, to: []const T, buf: []T }; if (std.mem.eql(T, fromOrig, toOrig)) { - return MaybeSlice(T){ .result = comptime L(T, "") }; + return MaybeSlice(T){ .result = &.{} }; } const fromStart = 1; @@ -2081,7 +2081,7 @@ pub fn relativePosixT(comptime T: type, from: []const T, to: []const T, buf: []T var bufSize: usize = 0; // Backed by buf3. - var out: []const T = comptime L(T, ""); + var out: []const T = &.{}; // Add a block to isolate `i`. { // Generate the relative path based on the path difference between `to` @@ -2138,7 +2138,7 @@ pub fn relativeWindowsT(comptime T: type, from: []const T, to: []const T, buf: [ // validateString of `from` and `to` are performed in pub fn relative. if (std.mem.eql(T, from, to)) { - return MaybeSlice(T){ .result = comptime L(T, "") }; + return MaybeSlice(T){ .result = &.{} }; } // Backed by expandable buf2 because fromOrig may be long. @@ -2156,7 +2156,7 @@ pub fn relativeWindowsT(comptime T: type, from: []const T, to: []const T, buf: [ if (std.mem.eql(T, fromOrig, toOrig) or eqlIgnoreCaseT(T, fromOrig, toOrig)) { - return MaybeSlice(T){ .result = comptime L(T, "") }; + return MaybeSlice(T){ .result = &.{} }; } const toOrigLen = toOrig.len; @@ -2256,7 +2256,7 @@ pub fn relativeWindowsT(comptime T: type, from: []const T, to: []const T, buf: [ var bufSize: usize = 0; // Backed by buf3. - var out: []const T = comptime L(T, ""); + var out: []const T = &.{}; // Add a block to isolate `i`. { // Generate the relative path based on the path difference between `to` @@ -2374,7 +2374,7 @@ pub fn resolvePosixT(comptime T: type, paths: []const []const T, buf: []T, buf2: // Backed by expandable buf2 because resolvedPath may be long. // We use buf2 here because resolvePosixT is called by other methods and using // buf2 here avoids stepping on others' toes. - var resolvedPath: []const T = comptime L(T, ""); + var resolvedPath: []const T = &.{}; var resolvedPathLen: usize = 0; var resolvedAbsolute: bool = false; @@ -2383,7 +2383,7 @@ pub fn resolvePosixT(comptime T: type, paths: []const []const T, buf: []T, buf2: var i_i64: i64 = if (paths.len == 0) -1 else @as(i64, @intCast(paths.len - 1)); while (i_i64 > -2 and !resolvedAbsolute) : (i_i64 -= 1) { - var path: []const T = comptime L(T, ""); + var path: []const T = &.{}; if (i_i64 >= 0) { path = paths[@as(usize, @intCast(i_i64))]; } else { @@ -2460,12 +2460,12 @@ pub fn resolveWindowsT(comptime T: type, paths: []const []const T, buf: []T, buf var tmpBuf: [MAX_PATH_SIZE(T)]T = undefined; // Backed by tmpBuf. - var resolvedDevice: []const T = comptime L(T, ""); + var resolvedDevice: []const T = &.{}; var resolvedDeviceLen: usize = 0; // Backed by expandable buf2 because resolvedTail may be long. // We use buf2 here because resolvePosixT is called by other methods and using // buf2 here avoids stepping on others' toes. - var resolvedTail: []const T = comptime L(T, ""); + var resolvedTail: []const T = &.{}; var resolvedTailLen: usize = 0; var resolvedAbsolute: bool = false; @@ -2477,7 +2477,7 @@ pub fn resolveWindowsT(comptime T: type, paths: []const []const T, buf: []T, buf while (i_i64 > -2) : (i_i64 -= 1) { // Backed by expandable buf2, to not conflict with buf2 backed resolvedTail, // because path may be long. - var path: []const T = comptime L(T, ""); + var path: []const T = &.{}; if (i_i64 >= 0) { path = paths[@as(usize, @intCast(i_i64))]; // validateString of `path` is performed in pub fn resolve. @@ -2581,7 +2581,7 @@ pub fn resolveWindowsT(comptime T: type, paths: []const []const T, buf: []T, buf const len = path.len; var rootEnd: usize = 0; // Backed by tmpBuf or an anonymous buffer. - var device: []const T = comptime L(T, ""); + var device: []const T = &.{}; // Prefix with _ to avoid shadowing the identifier in the outer scope. var _isAbsolute: bool = false; const byte0 = if (len > 0) path[0] else 0; diff --git a/src/cli.zig b/src/cli.zig index 6c74ac63e1..f231501575 100644 --- a/src/cli.zig +++ b/src/cli.zig @@ -1210,13 +1210,7 @@ pub const Command = struct { }; var global_cli_ctx: Context = undefined; - - var context_data: ContextData = ContextData{ - .args = std.mem.zeroes(Api.TransformOptions), - .log = undefined, - .start_time = 0, - .allocator = undefined, - }; + var context_data: ContextData = undefined; pub const init = ContextData.create; @@ -1260,10 +1254,13 @@ pub const Command = struct { pub fn create(allocator: std.mem.Allocator, log: *logger.Log, comptime command: Command.Tag) anyerror!Context { Cli.cmd = command; + context_data = .{ + .args = std.mem.zeroes(Api.TransformOptions), + .log = log, + .start_time = start_time, + .allocator = allocator, + }; global_cli_ctx = &context_data; - global_cli_ctx.log = log; - global_cli_ctx.start_time = start_time; - global_cli_ctx.allocator = allocator; if (comptime Command.Tag.uses_global_options.get(command)) { global_cli_ctx.args = try Arguments.parse(allocator, global_cli_ctx, command); diff --git a/src/cli/package_manager_command.zig b/src/cli/package_manager_command.zig index 55631722ef..226d59d1c2 100644 --- a/src/cli/package_manager_command.zig +++ b/src/cli/package_manager_command.zig @@ -61,7 +61,8 @@ pub const PackageManagerCommand = struct { @memcpy(lockfile_buffer[0..lockfile_.len], lockfile_); lockfile_buffer[lockfile_.len] = 0; const lockfile = lockfile_buffer[0..lockfile_.len :0]; - var pm = try PackageManager.init(ctx, PackageManager.Subcommand.pm); + const cli = try PackageManager.CommandLineArguments.parse(ctx.allocator, .pm); + var pm = try PackageManager.init(ctx, cli, PackageManager.Subcommand.pm); const load_lockfile = pm.lockfile.loadFromDisk(pm, ctx.allocator, ctx.log, lockfile, true); handleLoadLockfileErrors(load_lockfile, pm); @@ -120,8 +121,8 @@ pub const PackageManagerCommand = struct { pub fn exec(ctx: Command.Context) !void { var args = try std.process.argsAlloc(ctx.allocator); args = args[1..]; - - var pm = PackageManager.init(ctx, PackageManager.Subcommand.pm) catch |err| { + const cli = try PackageManager.CommandLineArguments.parse(ctx.allocator, .pm); + var pm = PackageManager.init(ctx, cli, PackageManager.Subcommand.pm) catch |err| { if (err == error.MissingPackageJSON) { var cwd_buf: bun.PathBuffer = undefined; if (bun.getcwd(&cwd_buf)) |cwd| { diff --git a/src/generated_versions_list.zig b/src/generated_versions_list.zig index 6a39381135..6a28038a88 100644 --- a/src/generated_versions_list.zig +++ b/src/generated_versions_list.zig @@ -4,7 +4,7 @@ pub const boringssl = "29a2cd359458c9384694b75456026e4b57e3e567"; pub const libarchive = "898dc8319355b7e985f68a9819f182aaed61b53a"; pub const mimalloc = "4c283af60cdae205df5a872530c77e2a6a307d43"; pub const picohttpparser = "066d2b1e9ab820703db0837a7255d92d30f0c9f5"; -pub const webkit = "b49be549da59347762aa83f849a65158d2a0d724"; +pub const webkit = "dac47fbd5444cbd4e3568267099ae276c547e897"; pub const zig = @import("std").fmt.comptimePrint("{}", .{@import("builtin").zig_version}); pub const zlib = "886098f3f339617b4243b286f5ed364b9989e245"; pub const tinycc = "ab631362d839333660a265d3084d8ff060b96753"; diff --git a/src/install/install.zig b/src/install/install.zig index 00e4a06480..506d3c4995 100644 --- a/src/install/install.zig +++ b/src/install/install.zig @@ -8186,15 +8186,10 @@ pub const PackageManager = struct { } }; - pub fn init(ctx: Command.Context, comptime subcommand: Subcommand) !*PackageManager { - const cli = try CommandLineArguments.parse(ctx.allocator, subcommand); - return initWithCLI(ctx, cli, subcommand); - } - - fn initWithCLI( + pub fn init( ctx: Command.Context, cli: CommandLineArguments, - comptime subcommand: Subcommand, + subcommand: Subcommand, ) !*PackageManager { // assume that spawning a thread will take a lil so we do that asap HTTP.HTTPThread.init(); @@ -8286,7 +8281,7 @@ pub const PackageManager = struct { }; } - if (comptime subcommand == .install) { + if (subcommand == .install) { if (cli.positionals.len > 1) { // this is `bun add `. // @@ -8312,7 +8307,7 @@ pub const PackageManager = struct { // Check if this is a workspace; if so, use root package var found = false; - if (comptime subcommand != .link) { + if (subcommand != .link) { if (!created_package_json) { while (std.fs.path.dirname(this_cwd)) |parent| : (this_cwd = parent) { const parent_without_trailing_slash = strings.withoutTrailingSlash(parent); @@ -8680,29 +8675,29 @@ pub const PackageManager = struct { // parse dependency of positional arg string (may include name@version for example) // get the precise version from the lockfile (there may be multiple) // copy the contents into a temp folder - pub inline fn patch(ctx: Command.Context) !void { + pub fn patch(ctx: Command.Context) !void { try updatePackageJSONAndInstallCatchError(ctx, .patch); } - pub inline fn patchCommit(ctx: Command.Context) !void { + pub fn patchCommit(ctx: Command.Context) !void { try updatePackageJSONAndInstallCatchError(ctx, .@"patch-commit"); } - pub inline fn update(ctx: Command.Context) !void { + pub fn update(ctx: Command.Context) !void { try updatePackageJSONAndInstallCatchError(ctx, .update); } - pub inline fn add(ctx: Command.Context) !void { + pub fn add(ctx: Command.Context) !void { try updatePackageJSONAndInstallCatchError(ctx, .add); } - pub inline fn remove(ctx: Command.Context) !void { + pub fn remove(ctx: Command.Context) !void { try updatePackageJSONAndInstallCatchError(ctx, .remove); } pub fn updatePackageJSONAndInstallCatchError( ctx: Command.Context, - comptime subcommand: Subcommand, + subcommand: Subcommand, ) !void { updatePackageJSONAndInstall(ctx, subcommand) catch |err| { switch (err) { @@ -8719,11 +8714,12 @@ pub const PackageManager = struct { }; } - pub inline fn link(ctx: Command.Context) !void { - var manager = PackageManager.init(ctx, .link) catch |err| brk: { + pub fn link(ctx: Command.Context) !void { + const cli = try CommandLineArguments.parse(ctx.allocator, .link); + var manager = PackageManager.init(ctx, cli, .link) catch |err| brk: { if (err == error.MissingPackageJSON) { try attemptToCreatePackageJSON(); - break :brk try PackageManager.init(ctx, .link); + break :brk try PackageManager.init(ctx, cli, .link); } return err; @@ -8900,11 +8896,12 @@ pub const PackageManager = struct { } } - pub inline fn unlink(ctx: Command.Context) !void { - var manager = PackageManager.init(ctx, .unlink) catch |err| brk: { + pub fn unlink(ctx: Command.Context) !void { + const cli = try PackageManager.CommandLineArguments.parse(ctx.allocator, .unlink); + var manager = PackageManager.init(ctx, cli, .unlink) catch |err| brk: { if (err == error.MissingPackageJSON) { try attemptToCreatePackageJSON(); - break :brk try PackageManager.init(ctx, .unlink); + break :brk try PackageManager.init(ctx, cli, .unlink); } return err; @@ -9056,54 +9053,54 @@ pub const PackageManager = struct { clap.parseParam("-h, --help Print this help menu") catch unreachable, }; - pub const install_params = install_params_ ++ [_]ParamType{ + pub const install_params: []const ParamType = &(install_params_ ++ [_]ParamType{ clap.parseParam("-d, --dev Add dependency to \"devDependencies\"") catch unreachable, clap.parseParam("-D, --development") catch unreachable, clap.parseParam("--optional Add dependency to \"optionalDependencies\"") catch unreachable, clap.parseParam("-E, --exact Add the exact version instead of the ^range") catch unreachable, clap.parseParam(" ... ") catch unreachable, - }; + }); - pub const update_params = install_params_ ++ [_]ParamType{ + pub const update_params: []const ParamType = &(install_params_ ++ [_]ParamType{ clap.parseParam("--latest Update packages to their latest versions") catch unreachable, clap.parseParam(" ... \"name\" of packages to update") catch unreachable, - }; + }); - pub const pm_params = install_params_ ++ [_]ParamType{ + pub const pm_params: []const ParamType = &(install_params_ ++ [_]ParamType{ clap.parseParam("-a, --all") catch unreachable, clap.parseParam(" ... ") catch unreachable, - }; + }); - pub const add_params = install_params_ ++ [_]ParamType{ + pub const add_params: []const ParamType = &(install_params_ ++ [_]ParamType{ clap.parseParam("-d, --dev Add dependency to \"devDependencies\"") catch unreachable, clap.parseParam("-D, --development") catch unreachable, clap.parseParam("--optional Add dependency to \"optionalDependencies\"") catch unreachable, clap.parseParam("-E, --exact Add the exact version instead of the ^range") catch unreachable, clap.parseParam(" ... \"name\" or \"name@version\" of package(s) to install") catch unreachable, - }; + }); - pub const remove_params = install_params_ ++ [_]ParamType{ + pub const remove_params: []const ParamType = &(install_params_ ++ [_]ParamType{ clap.parseParam(" ... \"name\" of package(s) to remove from package.json") catch unreachable, - }; + }); - pub const link_params = install_params_ ++ [_]ParamType{ + pub const link_params: []const ParamType = &(install_params_ ++ [_]ParamType{ clap.parseParam(" ... \"name\" install package as a link") catch unreachable, - }; + }); - pub const unlink_params = install_params_ ++ [_]ParamType{ + pub const unlink_params: []const ParamType = &(install_params_ ++ [_]ParamType{ clap.parseParam(" ... \"name\" uninstall package as a link") catch unreachable, - }; + }); - const patch_params = install_params_ ++ [_]ParamType{ + const patch_params: []const ParamType = &(install_params_ ++ [_]ParamType{ clap.parseParam(" ... \"name\" of the package to patch") catch unreachable, clap.parseParam("--commit Install a package containing modifications in `dir`") catch unreachable, clap.parseParam("--patches-dir The directory to put the patch file in (only if --commit is used)") catch unreachable, - }; + }); - const patch_commit_params = install_params_ ++ [_]ParamType{ + const patch_commit_params: []const ParamType = &(install_params_ ++ [_]ParamType{ clap.parseParam(" ... \"dir\" containing changes to a package") catch unreachable, clap.parseParam("--patches-dir The directory to put the patch file") catch unreachable, - }; + }); pub const CommandLineArguments = struct { registry: string = "", @@ -9169,7 +9166,7 @@ pub const PackageManager = struct { } }; - pub fn printHelp(comptime subcommand: Subcommand) void { + pub fn printHelp(subcommand: Subcommand) void { switch (subcommand) { // fall back to HelpCommand.printWithReason Subcommand.install => { @@ -9192,7 +9189,7 @@ pub const PackageManager = struct { Output.flush(); Output.pretty("\n\nFlags:", .{}); Output.flush(); - clap.simpleHelp(&PackageManager.install_params); + clap.simpleHelp(PackageManager.install_params); Output.pretty("\n\n" ++ outro_text ++ "\n", .{}); Output.flush(); }, @@ -9219,7 +9216,7 @@ pub const PackageManager = struct { Output.flush(); Output.pretty("\nFlags:", .{}); Output.flush(); - clap.simpleHelp(&PackageManager.update_params); + clap.simpleHelp(PackageManager.update_params); Output.pretty("\n\n" ++ outro_text ++ "\n", .{}); Output.flush(); }, @@ -9235,7 +9232,7 @@ pub const PackageManager = struct { Output.flush(); Output.pretty("\nFlags:", .{}); Output.flush(); - clap.simpleHelp(&PackageManager.patch_params); + clap.simpleHelp(PackageManager.patch_params); // Output.pretty("\n\n" ++ outro_text ++ "\n", .{}); Output.flush(); }, @@ -9260,7 +9257,7 @@ pub const PackageManager = struct { Output.flush(); Output.pretty("\nFlags:", .{}); Output.flush(); - clap.simpleHelp(&PackageManager.patch_params); + clap.simpleHelp(PackageManager.patch_params); // Output.pretty("\n\n" ++ outro_text ++ "\n", .{}); Output.flush(); }, @@ -9290,7 +9287,7 @@ pub const PackageManager = struct { Output.flush(); Output.pretty("\n\nFlags:", .{}); Output.flush(); - clap.simpleHelp(&PackageManager.add_params); + clap.simpleHelp(PackageManager.add_params); Output.pretty("\n\n" ++ outro_text ++ "\n", .{}); Output.flush(); }, @@ -9312,7 +9309,7 @@ pub const PackageManager = struct { Output.flush(); Output.pretty("\nFlags:", .{}); Output.flush(); - clap.simpleHelp(&PackageManager.remove_params); + clap.simpleHelp(PackageManager.remove_params); Output.pretty("\n\n" ++ outro_text ++ "\n", .{}); Output.flush(); }, @@ -9336,7 +9333,7 @@ pub const PackageManager = struct { Output.flush(); Output.pretty("\nFlags:", .{}); Output.flush(); - clap.simpleHelp(&PackageManager.link_params); + clap.simpleHelp(PackageManager.link_params); Output.pretty("\n\n" ++ outro_text ++ "\n", .{}); Output.flush(); }, @@ -9357,7 +9354,7 @@ pub const PackageManager = struct { Output.flush(); Output.pretty("\nFlags:", .{}); Output.flush(); - clap.simpleHelp(&PackageManager.unlink_params); + clap.simpleHelp(PackageManager.unlink_params); Output.pretty("\n\n" ++ outro_text ++ "\n", .{}); Output.flush(); }, @@ -9367,7 +9364,7 @@ pub const PackageManager = struct { pub fn parse(allocator: std.mem.Allocator, comptime subcommand: Subcommand) !CommandLineArguments { Output.is_verbose = Output.isVerbose(); - const params: []const ParamType = &switch (subcommand) { + const params: []const ParamType = switch (subcommand) { .install => install_params, .update => update_params, .pm => pm_params, @@ -9681,9 +9678,12 @@ pub const PackageManager = struct { fn updatePackageJSONAndInstall( ctx: Command.Context, - comptime subcommand: Subcommand, + subcommand: Subcommand, ) !void { - var manager = init(ctx, subcommand) catch |err| brk: { + const cli = switch (subcommand) { + inline else => |cmd| try PackageManager.CommandLineArguments.parse(ctx.allocator, cmd), + }; + var manager = init(ctx, cli, subcommand) catch |err| brk: { if (err == error.MissingPackageJSON) { switch (subcommand) { .update => { @@ -9700,7 +9700,7 @@ pub const PackageManager = struct { }, else => { try attemptToCreatePackageJSON(); - break :brk try PackageManager.init(ctx, subcommand); + break :brk try PackageManager.init(ctx, cli, subcommand); }, } } @@ -9709,7 +9709,7 @@ pub const PackageManager = struct { }; if (manager.options.shouldPrintCommandName()) { - Output.prettyErrorln("bun " ++ @tagName(subcommand) ++ " v" ++ Global.package_json_version_with_sha ++ "\n", .{}); + Output.prettyErrorln("bun {s} v" ++ Global.package_json_version_with_sha ++ "\n", .{@tagName(subcommand)}); Output.flush(); } @@ -9882,21 +9882,19 @@ pub const PackageManager = struct { &[_]UpdateRequest{} else UpdateRequest.parse(ctx.allocator, ctx.log, manager.options.positionals[1..], &update_requests, manager.subcommand); - switch (manager.subcommand) { - inline else => |subcommand| try manager.updatePackageJSONAndInstallWithManagerWithUpdates( - ctx, - updates, - subcommand, - log_level, - ), - } + try manager.updatePackageJSONAndInstallWithManagerWithUpdates( + ctx, + updates, + manager.subcommand, + log_level, + ); } fn updatePackageJSONAndInstallWithManagerWithUpdates( manager: *PackageManager, ctx: Command.Context, updates: []UpdateRequest, - comptime subcommand: Subcommand, + subcommand: Subcommand, comptime log_level: Options.LogLevel, ) !void { if (manager.log.errors > 0) { @@ -9950,17 +9948,17 @@ pub const PackageManager = struct { if (subcommand == .remove) { if (current_package_json.root.data != .e_object) { - Output.errGeneric("package.json is not an Object {{}}, so there's nothing to " ++ @tagName(subcommand) ++ "!", .{}); + Output.errGeneric("package.json is not an Object {{}}, so there's nothing to {s}!", .{@tagName(subcommand)}); Global.crash(); } else if (current_package_json.root.data.e_object.properties.len == 0) { - Output.errGeneric("package.json is empty {{}}, so there's nothing to " ++ @tagName(subcommand) ++ "!", .{}); + Output.errGeneric("package.json is empty {{}}, so there's nothing to {s}!", .{@tagName(subcommand)}); Global.crash(); } else if (current_package_json.root.asProperty("devDependencies") == null and current_package_json.root.asProperty("dependencies") == null and current_package_json.root.asProperty("optionalDependencies") == null and current_package_json.root.asProperty("peerDependencies") == null) { - Output.prettyErrorln("package.json doesn't have dependencies, there's nothing to " ++ @tagName(subcommand) ++ "!", .{}); + Output.prettyErrorln("package.json doesn't have dependencies, there's nothing to {s}!", .{@tagName(subcommand)}); Global.exit(0); } } @@ -11443,8 +11441,9 @@ pub const PackageManager = struct { var package_json_cwd_buf: bun.PathBuffer = undefined; pub var package_json_cwd: string = ""; - pub inline fn install(ctx: Command.Context) !void { - var manager = try init(ctx, .install); + pub fn install(ctx: Command.Context) !void { + const cli = try CommandLineArguments.parse(ctx.allocator, .install); + var manager = try init(ctx, cli, .install); // switch to `bun add ` if (manager.options.positionals.len > 1) { diff --git a/src/resolver/resolve_path.zig b/src/resolver/resolve_path.zig index 2a80f5b7b2..01c87e1728 100644 --- a/src/resolver/resolve_path.zig +++ b/src/resolver/resolve_path.zig @@ -608,10 +608,10 @@ fn windowsVolumeNameLenT(comptime T: type, path: []const T) struct { usize, usiz } } } else { - if (bun.strings.indexAnyComptimeT(T, path[3..], comptime strings.literal(T, "/\\"))) |idx| { + if (bun.strings.indexAnyComptimeT(T, path[3..], strings.literal(T, "/\\"))) |idx| { // TODO: handle input "//abc//def" should be picked up as a unc path if (path.len > idx + 4 and !Platform.windows.isSeparatorT(T, path[idx + 4])) { - if (bun.strings.indexAnyComptimeT(T, path[idx + 4 ..], comptime strings.literal(T, "/\\"))) |idx2| { + if (bun.strings.indexAnyComptimeT(T, path[idx + 4 ..], strings.literal(T, "/\\"))) |idx2| { return .{ idx + idx2 + 4, idx + 3 }; } else { return .{ path.len, idx + 3 }; @@ -761,7 +761,7 @@ pub fn normalizeStringGenericTZ( // // since it is theoretically possible to get here in release // we will not do this check in release. - assert(!strings.hasPrefixComptimeType(T, path_, comptime strings.literal(T, ":\\"))); + assert(!strings.hasPrefixComptimeType(T, path_, strings.literal(T, ":\\"))); } var buf_i: usize = 0; @@ -776,16 +776,16 @@ pub fn normalizeStringGenericTZ( if (isWindows and !options.allow_above_root) { if (volLen > 0) { if (options.add_nt_prefix) { - @memcpy(buf[buf_i .. buf_i + 4], comptime strings.literal(T, "\\??\\")); + @memcpy(buf[buf_i .. buf_i + 4], strings.literal(T, "\\??\\")); buf_i += 4; } if (path_[1] != ':') { // UNC paths if (options.add_nt_prefix) { - @memcpy(buf[buf_i .. buf_i + 4], comptime strings.literal(T, "UNC" ++ sep_str)); + @memcpy(buf[buf_i .. buf_i + 4], strings.literal(T, "UNC" ++ sep_str)); buf_i += 2; } else { - @memcpy(buf[buf_i .. buf_i + 2], comptime strings.literal(T, sep_str ++ sep_str)); + @memcpy(buf[buf_i .. buf_i + 2], strings.literal(T, sep_str ++ sep_str)); } @memcpy(buf[buf_i + 2 .. buf_i + indexOfThirdUNCSlash + 1], path_[2 .. indexOfThirdUNCSlash + 1]); buf[buf_i + indexOfThirdUNCSlash] = options.separator; @@ -827,7 +827,7 @@ pub fn normalizeStringGenericTZ( if (isWindows and options.allow_above_root) { if (path_.len >= 2 and path_[1] == ':') { if (options.add_nt_prefix) { - @memcpy(buf[buf_i .. buf_i + 4], &comptime strings.literalBuf(T, "\\??\\")); + @memcpy(buf[buf_i .. buf_i + 4], &strings.literalBuf(T, "\\??\\")); buf_i += 4; } buf[buf_i] = path_[0]; @@ -884,10 +884,10 @@ pub fn normalizeStringGenericTZ( } } else if (options.allow_above_root) { if (buf_i > buf_start) { - buf[buf_i..][0..3].* = (comptime strings.literal(T, sep_str ++ "..")).*; + buf[buf_i..][0..3].* = (strings.literal(T, sep_str ++ "..")).*; buf_i += 3; } else { - buf[buf_i..][0..2].* = (comptime strings.literal(T, "..")).*; + buf[buf_i..][0..2].* = (strings.literal(T, "..")).*; buf_i += 2; } dotdot = buf_i; @@ -932,7 +932,7 @@ pub fn normalizeStringGenericTZ( const result = if (options.zero_terminate) buf[0..buf_i :0] else buf[0..buf_i]; if (bun.Environment.allow_assert and isWindows) { - assert(!strings.hasPrefixComptimeType(T, result, comptime strings.literal(T, "\\:\\"))); + assert(!strings.hasPrefixComptimeType(T, result, strings.literal(T, "\\:\\"))); } return result; @@ -1616,7 +1616,7 @@ pub fn lastIndexOfSeparatorWindows(slice: []const u8) ?usize { } pub fn lastIndexOfSeparatorWindowsT(comptime T: type, slice: []const T) ?usize { - return std.mem.lastIndexOfAny(T, slice, comptime strings.literal(T, "\\/")); + return std.mem.lastIndexOfAny(T, slice, strings.literal(T, "\\/")); } pub fn lastIndexOfSeparatorPosix(slice: []const u8) ?usize { diff --git a/src/string_immutable.zig b/src/string_immutable.zig index d6a6b82197..46bff268e9 100644 --- a/src/string_immutable.zig +++ b/src/string_immutable.zig @@ -51,21 +51,19 @@ pub inline fn removeLeadingDotSlash(slice: []const u8) []const u8 { pub const w = toUTF16Literal; pub fn toUTF16Literal(comptime str: []const u8) [:0]const u16 { - return comptime literal(u16, str); + return literal(u16, str); } pub fn literal(comptime T: type, comptime str: []const u8) *const [literalLength(T, str):0]T { - if (!@inComptime()) @compileError("strings.literal() must be called in a comptime context"); - return comptime switch (T) { - u8 => brk: { - var data: [str.len:0]u8 = undefined; - @memcpy(&data, str); - const final = data[0..].*; - break :brk &final; - }, - u16 => return std.unicode.utf8ToUtf16LeStringLiteral(str), - else => @compileError("unsupported type " ++ @typeName(T) ++ " in strings.literal() call."), + const Holder = struct { + pub const value = switch (T) { + u8 => (str[0..str.len].* ++ .{0})[0..str.len :0], + u16 => std.unicode.utf8ToUtf16LeStringLiteral(str), + else => @compileError("unsupported type " ++ @typeName(T) ++ " in strings.literal() call."), + }; }; + + return Holder.value; } fn literalLength(comptime T: type, comptime str: string) usize { @@ -173,7 +171,7 @@ pub inline fn containsAny(in: anytype, target: string) bool { /// - The name ends up being part of a URL, an argument on the command line, and /// a folder name. Therefore, the name can't contain any non-URL-safe /// characters. -pub inline fn isNPMPackageName(target: string) bool { +pub fn isNPMPackageName(target: string) bool { if (target.len == 0) return false; if (target.len > 214) return false; @@ -207,7 +205,7 @@ pub inline fn isNPMPackageName(target: string) bool { return !scoped or slash_index > 0 and slash_index + 1 < target.len; } -pub inline fn indexAnyComptime(target: string, comptime chars: string) ?usize { +pub fn indexAnyComptime(target: string, comptime chars: string) ?usize { for (target, 0..) |parent, i| { inline for (chars) |char| { if (char == parent) return i; @@ -216,7 +214,7 @@ pub inline fn indexAnyComptime(target: string, comptime chars: string) ?usize { return null; } -pub inline fn indexAnyComptimeT(comptime T: type, target: []const T, comptime chars: []const T) ?usize { +pub fn indexAnyComptimeT(comptime T: type, target: []const T, comptime chars: []const T) ?usize { for (target, 0..) |parent, i| { inline for (chars) |char| { if (char == parent) return i; @@ -225,7 +223,7 @@ pub inline fn indexAnyComptimeT(comptime T: type, target: []const T, comptime ch return null; } -pub inline fn indexEqualAny(in: anytype, target: string) ?usize { +pub fn indexEqualAny(in: anytype, target: string) ?usize { for (in, 0..) |str, i| if (eqlLong(str, target, true)) return i; return null; } @@ -795,8 +793,9 @@ pub fn hasSuffixComptime(self: string, comptime alt: anytype) bool { return self.len >= alt.len and eqlComptimeCheckLenWithType(u8, self[self.len - alt.len ..], alt, false); } -inline fn eqlComptimeCheckLenU8(a: []const u8, comptime b: []const u8, comptime check_len: bool) bool { +fn eqlComptimeCheckLenU8(a: []const u8, comptime b: []const u8, comptime check_len: bool) bool { @setEvalBranchQuota(9999); + if (comptime check_len) { if (a.len != b.len) return false; } @@ -833,7 +832,7 @@ inline fn eqlComptimeCheckLenU8(a: []const u8, comptime b: []const u8, comptime return true; } -inline fn eqlComptimeCheckLenWithKnownType(comptime Type: type, a: []const Type, comptime b: []const Type, comptime check_len: bool) bool { +fn eqlComptimeCheckLenWithKnownType(comptime Type: type, a: []const Type, comptime b: []const Type, comptime check_len: bool) bool { if (comptime Type != u8) { return eqlComptimeCheckLenU8(std.mem.sliceAsBytes(a), comptime std.mem.sliceAsBytes(b), comptime check_len); } @@ -844,18 +843,18 @@ inline fn eqlComptimeCheckLenWithKnownType(comptime Type: type, a: []const Type, /// /// strings.eqlComptime(input, "hello world"); /// strings.eqlComptime(input, "hai"); -pub inline fn eqlComptimeCheckLenWithType(comptime Type: type, a: []const Type, comptime b: anytype, comptime check_len: bool) bool { +pub fn eqlComptimeCheckLenWithType(comptime Type: type, a: []const Type, comptime b: anytype, comptime check_len: bool) bool { return eqlComptimeCheckLenWithKnownType(comptime Type, a, if (@typeInfo(@TypeOf(b)) != .Pointer) &b else b, comptime check_len); } -pub inline fn eqlCaseInsensitiveASCIIIgnoreLength( +pub fn eqlCaseInsensitiveASCIIIgnoreLength( a: string, b: string, ) bool { return eqlCaseInsensitiveASCII(a, b, false); } -pub inline fn eqlCaseInsensitiveASCIIICheckLength( +pub fn eqlCaseInsensitiveASCIIICheckLength( a: string, b: string, ) bool { @@ -886,7 +885,7 @@ pub fn eqlLong(a_str: string, b_str: string, comptime check_len: bool) bool { return false; } } else { - if (comptime Environment.allow_assert) assert(b_str.len == a_str.len); + if (comptime Environment.allow_assert) assert(b_str.len <= a_str.len); } const end = b_str.ptr + len; diff --git a/src/symbols.dyn b/src/symbols.dyn index 0be0db03ca..44160f2867 100644 --- a/src/symbols.dyn +++ b/src/symbols.dyn @@ -51,6 +51,7 @@ _napi_define_class; _napi_define_properties; _napi_delete_async_work; + _napi_delete_element; _napi_delete_property; _napi_delete_reference; _napi_detach_arraybuffer; @@ -67,7 +68,6 @@ _napi_get_dataview_info; _napi_get_date_value; _napi_get_element; - _napi_delete_element; _napi_get_global; _napi_get_instance_data; _napi_get_last_error_info; @@ -144,9 +144,14 @@ _napi_unref_threadsafe_function; _napi_unwrap; _napi_wrap; + _node_api_create_external_string_latin1; + _node_api_create_external_string_utf16; _node_api_create_syntax_error; _node_api_symbol_for; _node_api_throw_syntax_error; - _node_api_create_external_string_latin1; - _node_api_create_external_string_utf16; + __ZN2v87Isolate10GetCurrentEv; + __ZN2v87Isolate13TryGetCurrentEv; + __ZN2v87Isolate17GetCurrentContextEv; + __ZN4node25AddEnvironmentCleanupHookEPN2v87IsolateEPFvPvES3_; + __ZN4node28RemoveEnvironmentCleanupHookEPN2v87IsolateEPFvPvES3_; }; \ No newline at end of file