@ 261027.7

261018.1 · 4caa87cda978f25211499266fcc99e637c582ebc

chore: update swc to v1.16.18

reading declarations

Changes to deps/swc/bindings/binding_native_addon/. All files

deps/swc/bindings/binding_native_addon/Cargo.toml

new file mode 100644@@ -0,0 +1,36 @@+[package]+name = "binding_native_addon"+version = "0.1.0"+edition = "2021"+rust-version = "1.85"+license = "Apache-2.0"+publish = false+build = "build.rs"++[lib]+crate-type = ["cdylib", "rlib"]++[features]+embedded-payload = []++[dependencies]+swc_native_addon = { path = "../../crates/swc_native_addon" }+libloading = "=0.8.9"+tracing = { version = "=0.1.44", default-features = false, features = ["std"] }++[build-dependencies]+swc_native_addon = { path = "../../crates/swc_native_addon" }+tempfile = "=3.12.0"++[dev-dependencies]+tempfile = "=3.12.0"++[package.metadata.cargo-shear]+# The carrier imports the shared ACL fixture with #[path] from swc_native_addon.+# cargo-shear does not scan that external source, which uses windows-sys.+ignored = ["windows-sys"]++[target.'cfg(windows)'.dev-dependencies]+windows-sys = { version = "=0.52.0", features = [+  "Win32_Foundation", "Win32_Security", "Win32_Security_Authorization",+] }

deps/swc/bindings/binding_native_addon/NOTICE

new file mode 100644@@ -0,0 +1,24 @@+The registration descriptor and constructor contract in src/legacy.rs follow+the public N-API NAPI_MODULE_X interface in Node.js v10.0.0's src/node_api.h.+The following Node.js attribution is retained for that interface adaptation.+No implementation from SWC PR #12000 or the napi-rs compression PoC is used.++Copyright Node.js contributors. All rights reserved.++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to+deal in the Software without restriction, including without limitation the+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or+sell copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS+IN THE SOFTWARE.

deps/swc/bindings/binding_native_addon/build.rs

new file mode 100644@@ -0,0 +1,81 @@+use std::{env, fs, path::PathBuf};++use swc_native_addon::{+    format::{NativeTarget, Payload},+    integrity::RuntimeIntegrity,+};++fn main() {+    println!("cargo:rerun-if-env-changed=SWC_NATIVE_BINDING_PAYLOAD");+    let output = PathBuf::from(env::var_os("OUT_DIR").unwrap()).join("payload.rs");+    if env::var_os("CARGO_FEATURE_EMBEDDED_PAYLOAD").is_none() {+        fs::write(+            output,+            "static PAYLOAD: &[u8] = &[];\nstatic INTEGRITY: &[u8] = &[];\n",+        )+        .unwrap();+        return;+    }+    let target = env::var("TARGET").unwrap();+    let target = NativeTarget::parse(&target).expect("native carrier target");+    let path = PathBuf::from(+        env::var_os("SWC_NATIVE_BINDING_PAYLOAD")+            .expect("embedded-payload requires SWC_NATIVE_BINDING_PAYLOAD=/absolute/payload.swcn"),+    );+    assert!(+        path.is_absolute(),+        "SWC_NATIVE_BINDING_PAYLOAD must be absolute"+    );+    println!("cargo:rerun-if-changed={}", path.display());+    let bytes = fs::read(&path).expect("read native addon payload");+    let payload = Payload::parse(&bytes).expect("validate native addon payload header");+    assert_eq!(+        payload.header.target, target,+        "embedded native addon payload target does not match Cargo TARGET"+    );+    let output_parent = output.parent().expect("OUT_DIR has a parent");+    let mut raw = tempfile::Builder::new()+        .prefix(".swc-native-addon-validate-")+        .tempfile_in(output_parent)+        .expect("stage decoded native addon validation");+    payload+        .decode_into(&mut raw)+        .expect("decode embedded native addon bytes");+    payload+        .verify_target(&mut raw)+        .expect("validate embedded native addon target");+    let integrity = RuntimeIntegrity::from_raw(&payload.header, &mut raw)+        .expect("derive runtime integrity from SHA-512 verified raw addon");+    let integrity_path = output.with_file_name("integrity.swcn");+    fs::write(&integrity_path, integrity.encode()).expect("snapshot native runtime integrity");+    // Copy to OUT_DIR so a later input replacement cannot change the validated+    // payload between build-script validation and rustc's include_bytes call.+    let embedded = output.with_file_name("payload.swcn");+    fs::write(&embedded, &bytes).expect("snapshot validated addon payload");+    // Retain a complete, mapped payload for final-artifact verification. LTO+    // may otherwise fold header reads and eliminate parts of include_bytes.+    // Section names fit the Mach-O (16-byte) and PE (8-byte) limits.+    fs::write(+        output,+        format!(+            r#"#[used]+#[cfg_attr(target_os = "linux", link_section = ".swc_native")]+#[cfg_attr(target_os = "macos", link_section = "__TEXT,__swc_native")]+#[cfg_attr(windows, link_section = ".swcn")]+static EMBEDDED_PAYLOAD: [u8; {}] = *include_bytes!({:?});+static PAYLOAD: &[u8] = &EMBEDDED_PAYLOAD;+#[used]+#[cfg_attr(target_os = "linux", link_section = ".swc_integrity")]+#[cfg_attr(target_os = "macos", link_section = "__TEXT,__swc_integrity")]+#[cfg_attr(windows, link_section = ".swci")]+static EMBEDDED_INTEGRITY: [u8; {}] = *include_bytes!({:?});+static INTEGRITY: &[u8] = &EMBEDDED_INTEGRITY;+"#,+            payload.header.compressed_len + swc_native_addon::format::HEADER_LEN as u64,+            embedded,+            swc_native_addon::integrity::INTEGRITY_LEN,+            integrity_path,+        ),+    )+    .unwrap();+}

deps/swc/bindings/binding_native_addon/src/legacy.rs

new file mode 100644@@ -0,0 +1,58 @@+//! Node 10.0 predates lookup of napi_register_module_v1 by symbol. Its original+//! napi_module_register entry point is required even though all APIs used by+//! the initializer itself exist there. New Node versions also accept this hook.+//!+//! Constructors only register metadata. Decompression, IO, and native loading+//! stay in the initializer, outside the Windows loader lock.+//! See ../NOTICE for the Node.js MIT attribution of this public ABI adaptation.++use std::{+    ffi::{c_char, c_void},+    ptr,+};++use crate::napi::Register;++#[repr(C)]+struct Module {+    version: i32,+    flags: u32,+    filename: *const c_char,+    register: Register,+    name: *const c_char,+    private: *mut c_void,+    reserved: [*mut c_void; 4],+}++static mut MODULE: Module = Module {+    version: 1,+    flags: 0,+    filename: b"swc-native-carrier\0".as_ptr().cast(),+    register: crate::napi_register_module_v1,+    name: b"swc_native_carrier\0".as_ptr().cast(),+    private: ptr::null_mut(),+    reserved: [ptr::null_mut(); 4],+};++unsafe extern "C" fn register() {+    #[cfg(unix)]+    let process = libloading::os::unix::Library::this();+    #[cfg(windows)]+    let process = match libloading::os::windows::Library::this() {+        Ok(process) => process,+        Err(_) => return,+    };+    // Test executables are not Node hosts. They can link the rlib without+    // registering anything; Node always exports this original N-API function.+    if let Ok(register) =+        process.get::<unsafe extern "C" fn(*mut Module)>(b"napi_module_register\0")+    {+        register(ptr::addr_of_mut!(MODULE));+    }+}++#[used]+#[cfg_attr(target_os = "linux", link_section = ".init_array")]+#[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]+#[cfg_attr(windows, link_section = ".CRT$XCU")]+static INITIALIZER: unsafe extern "C" fn() = register;

deps/swc/bindings/binding_native_addon/src/lib.rs

new file mode 100644@@ -0,0 +1,191 @@+//! Self-loading target carrier. All native image bytes are verified before the+//! OS loader sees them; N-API registration is forwarded without wrapping+//! exports.++mod legacy;+mod napi;++use std::sync::Mutex;++use libloading::Library;+use swc_native_addon::{+    cache::{self, CacheMode, Materialized},+    format::Payload,+    integrity::RuntimeIntegrity,+    platform, replacement, Error, ErrorKind, Result,+};++include!(concat!(env!("OUT_DIR"), "/payload.rs"));++struct Loaded {+    register: napi::Register,+    _library: Library,+    _materialized: Materialized,+}++// Statics are deliberately never dropped. Addon callbacks can survive the+// original registration call and other Node environments in the same process.+// A Windows temporary's cleanup pipe is closed by process teardown.+static LOADED: Mutex<Option<Loaded>> = Mutex::new(None);+static IMAGE_ANCHOR: u8 = 0;++fn replacement_carrier(+    mode: &CacheMode,+    resolve: impl FnOnce() -> Result<std::path::PathBuf>,+) -> Option<std::path::PathBuf> {+    // APFS self-replacement recompresses the decoded image with ditto and+    // decodes it again for this process. Keep macOS first loads on the verified+    // cache path, even for writable installations, before resolving the carrier.+    if cfg!(target_os = "macos") || *mode == CacheMode::Temporary {+        return None;+    }+    match resolve() {+        Ok(path) => Some(path),+        Err(error) => {+            tracing::debug!(%error, "native carrier path unavailable; using cache");+            None+        }+    }+}++fn initialize() -> Result<napi::Register> {+    let mut loaded = LOADED.lock().map_err(|_| {+        Error::new(+            ErrorKind::Load,+            "native loader initialization lock was poisoned",+        )+    })?;+    if let Some(loaded) = loaded.as_ref() {+        return Ok(loaded.register);+    }+    let payload = Payload::parse(PAYLOAD)?.with_integrity(RuntimeIntegrity::parse(INTEGRITY)?)?;+    let mode = CacheMode::from_env()?;+    let replacement = if let Some(carrier) = replacement_carrier(&mode, || unsafe {+        platform::carrier_path((&IMAGE_ANCHOR as *const u8).cast())+    }) {+        // Compression and replacement are optional. Integrity is rechecked in+        // the cache path; no fallback ever loads an unverified original buffer.+        match replacement::try_replace(&payload, &carrier) {+            Ok(replacement) => replacement,+            Err(error) => {+                tracing::debug!(path = %carrier.display(), %error, "native self-replacement unavailable; using cache");+                None+            }+        }+    } else {+        None+    };+    let mut materialized = match replacement {+        Some(file) => file,+        None => cache::materialize(&payload, &mode)?,+    };+    #[cfg(unix)]+    let library = unsafe {+        libloading::os::unix::Library::open(+            Some(materialized.path()),+            libloading::os::unix::RTLD_NOW | libloading::os::unix::RTLD_LOCAL,+        )+        .map(Library::from)+    };+    #[cfg(windows)]+    let library = unsafe { Library::new(materialized.path()) };+    let library = library.map_err(|e| {+        Error::new(+            ErrorKind::Load,+            format!("load verified addon {}: {e}", materialized.path().display()),+        )+    })?;+    let register = *unsafe { library.get::<napi::Register>(b"napi_register_module_v1\0") }+        .map_err(|e| {+            Error::new(+                ErrorKind::Load,+                format!("verified addon has no napi_register_module_v1: {e}"),+            )+        })?;+    if register as usize == napi_register_module_v1 as *const () as usize {+        return Err(Error::new(+            ErrorKind::Load,+            "raw addon registration resolved back to the carrier",+        ));+    }+    materialized.loaded()?;+    *loaded = Some(Loaded {+        register,+        _library: library,+        _materialized: materialized,+    });+    Ok(register)+}++/// The raw packages already target N-API 3, supported by their Node minimums.+#[no_mangle]+pub extern "C" fn node_api_module_get_api_version_v1() -> i32 {+    3+}++/// Forward each environment independently, including a raw initializer+/// returning a different exports value or null with a pending JavaScript+/// exception.+///+/// # Safety+/// Node must pass a live `napi_env` and its associated initial exports value.+#[no_mangle]+pub unsafe extern "C" fn napi_register_module_v1(+    env: napi::Env,+    exports: napi::Value,+) -> napi::Value {+    let error = match std::panic::catch_unwind(initialize) {+        Ok(Ok(register)) => return register(env, exports),+        Ok(Err(error)) => error,+        Err(_) => Error::new(ErrorKind::Load, "native loader initialization panicked"),+    };+    // Successful registration forwards the raw initializer directly. Resolving+    // exception helpers would open and close the process image unnecessarily on+    // every environment; only the failure path needs those symbols.+    let api = match napi::Api::load() {+        Ok(api) => api,+        Err(error) => {+            // This can only occur outside the supported Node ABI: without even+            // napi_throw_error there is no legal way to create a JS exception.+            eprintln!("SWC native addon cannot initialize its N-API host: {error}");+            std::process::abort();+        }+    };+    api.throw(env, &error)+}++#[cfg(test)]+mod tests {+    use super::*;++    #[test]+    fn temporary_mode_skips_carrier_resolution() {+        assert!(replacement_carrier(&CacheMode::Temporary, || -> Result<_> {+            panic!("temporary mode must not resolve the carrier")+        })+        .is_none());+    }++    #[test]+    #[cfg(not(target_os = "macos"))]+    fn unavailable_carrier_disables_replacement() {+        assert!(replacement_carrier(&CacheMode::Default, || {+            Err(Error::new(ErrorKind::Load, "carrier is unavailable"))+        })+        .is_none());+    }++    #[test]+    #[cfg(target_os = "macos")]+    fn macos_persistent_modes_skip_carrier_resolution() {+        for mode in [+            CacheMode::Default,+            CacheMode::Custom("/custom/cache".into()),+        ] {+            assert!(replacement_carrier(&mode, || -> Result<_> {+                panic!("macOS must not resolve the carrier for self-replacement")+            })+            .is_none());+        }+    }+}

deps/swc/bindings/binding_native_addon/src/napi.rs

new file mode 100644@@ -0,0 +1,70 @@+//! Only original N-API functions are used here. No generated napi-rs module+//! initialization or newer path-discovery API is linked into the carrier.++use std::ffi::{c_char, c_void, CString};++use swc_native_addon::{Error, ErrorKind, Result};++pub type Env = *mut c_void;+pub type Value = *mut c_void;+pub type Register = unsafe extern "C" fn(Env, Value) -> Value;+type ThrowError = unsafe extern "C" fn(Env, *const c_char, *const c_char) -> i32;+type FatalError = unsafe extern "C" fn(*const c_char, usize, *const c_char, usize);++pub struct Api {+    throw_error: ThrowError,+    fatal_error: FatalError,+}++impl Api {+    pub unsafe fn load() -> Result<Self> {+        #[cfg(unix)]+        let process = libloading::os::unix::Library::this();+        #[cfg(windows)]+        let process = libloading::os::windows::Library::this()+            .map_err(|e| Error::new(ErrorKind::Load, format!("open Node process symbols: {e}")))?;+        let throw_error = *process+            .get::<ThrowError>(b"napi_throw_error\0")+            .map_err(|e| {+                Error::new(+                    ErrorKind::Load,+                    format!("Node must expose napi_throw_error: {e}"),+                )+            })?;+        let fatal_error = *process+            .get::<FatalError>(b"napi_fatal_error\0")+            .map_err(|e| {+                Error::new(+                    ErrorKind::Load,+                    format!("Node must expose napi_fatal_error: {e}"),+                )+            })?;+        Ok(Self {+            throw_error,+            fatal_error,+        })+    }++    pub unsafe fn throw(&self, env: Env, error: &Error) -> Value {+        let code = CString::new(error.kind.code()).unwrap();+        let message = format!(+            "SWC native addon: {error}. Reinstall the native package if its payload is damaged; \+             check SWC_NATIVE_BINDING_CACHE and directory permissions for materialization \+             failures."+        );+        let message = CString::new(message.replace('\0', "?")).unwrap();+        if (self.throw_error)(env, code.as_ptr(), message.as_ptr()) != 0 {+            // A functioning Node host always provides the original throw API.+            // If it cannot create an exception, returning exports would falsely+            // report success. N-API's original fatal API is the last resort.+            let location = b"swc native loader";+            (self.fatal_error)(+                location.as_ptr().cast(),+                location.len(),+                message.as_ptr(),+                message.as_bytes().len(),+            );+        }+        std::ptr::null_mut()+    }+}