Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:

test-wasm32-wasip1-threads:
name: Test wasm32-wasip1-threads
if: ${{ github.ref_name == 'main' }}
# if: ${{ github.ref_name == 'main' }}
runs-on: ubuntu-latest
env:
RUSTFLAGS: "--cfg tokio_unstable -C target-feature=+atomics,+bulk-memory,+mutable-globals,+simd128 -C link-args=--max-memory=67108864"
Expand All @@ -105,8 +105,12 @@ jobs:
with:
cache-key: wasi
save-cache: ${{ github.ref_name == 'main' }}
- uses: ./.github/actions/pnpm
- run: rustup target add wasm32-wasip1-threads
- uses: bytecodealliance/actions/wasmtime/setup@3b93676295fd6f7eaa7af2c2785539e052fa8349 # v1.1.1
- run: pnpm napi build --target wasm32-wasip1-threads --manifest-path ./napi/parser/Cargo.toml
- run: pnpm napi build --target wasm32-wasip1-threads --manifest-path ./napi/transform/Cargo.toml
- run: pnpm napi build --target wasm32-wasip1-threads --manifest-path ./napi/minify/Cargo.toml
- run: cargo test --target wasm32-wasip1-threads ${TEST_FLAGS}
- run: git diff --exit-code # Must commit everything

Expand Down
1 change: 1 addition & 0 deletions napi/parser/bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,4 +379,5 @@ module.exports.ImportNameKind = nativeBinding.ImportNameKind
module.exports.parseAsync = nativeBinding.parseAsync
module.exports.parseSync = nativeBinding.parseSync
module.exports.parseSyncRaw = nativeBinding.parseSyncRaw
module.exports.rawTransferSupported = nativeBinding.rawTransferSupported
module.exports.Severity = nativeBinding.Severity
3 changes: 3 additions & 0 deletions napi/parser/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ export declare function parseSync(filename: string, sourceText: string, options?
*/
export declare function parseSyncRaw(filename: string, buffer: Uint8Array, sourceLen: number, options?: ParserOptions | undefined | null): void

/** Returns `true` if raw transfer is supported on this platform. */
export declare function rawTransferSupported(): boolean

export declare const enum Severity {
Error = 'Error',
Warning = 'Warning',
Expand Down
15 changes: 15 additions & 0 deletions napi/parser/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ module.exports.parseSync = function parseSync(filename, sourceText, options) {
let buffer, encoder;

function parseSyncRaw(filename, sourceText, options) {
if (!rawTransferSupported()) {
throw new Error('`experimentalRawTransfer` option is not supported on 32-bit or big-endian systems');
}

// Delete `experimentalRawTransfer` option
let experimentalRawTransfer;
({ experimentalRawTransfer, ...options } = options);
Expand Down Expand Up @@ -138,3 +142,14 @@ function createBuffer() {
const offset = bindings.getBufferOffset(new Uint8Array(arrayBuffer));
return new Uint8Array(arrayBuffer, offset, TWO_GIB);
}

let rawTransferIsSupported = null;

// Returns `true` if `experimentalRawTransfer` is option is supported.
// Raw transfer is only available on 64-bit little-endian systems.
function rawTransferSupported() {
if (rawTransferIsSupported === null) rawTransferIsSupported = bindings.rawTransferSupported();
return rawTransferIsSupported;
}

module.exports.rawTransferSupported = rawTransferSupported;
18 changes: 15 additions & 3 deletions napi/parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,30 @@ use oxc::{
use oxc_napi::OxcError;

mod convert;
mod raw_transfer;
mod raw_transfer_types;
mod types;
pub use raw_transfer::{get_buffer_offset, parse_sync_raw};
pub use types::{Comment, EcmaScriptModule, ParseResult, ParserOptions};

// Only compile raw transfer APIs on 64-bit little-endian systems
#[cfg(all(target_pointer_width = "64", target_endian = "little"))]
mod raw_transfer;
#[cfg(all(target_pointer_width = "64", target_endian = "little"))]
mod raw_transfer_types;
#[cfg(all(target_pointer_width = "64", target_endian = "little"))]
pub use raw_transfer::*;

#[cfg(all(target_pointer_width = "64", target_endian = "little"))]
mod generated {
// Note: We intentionally don't import `generated/derive_estree.rs`. It's not needed.
#[cfg(debug_assertions)]
pub mod assert_layouts;
}

// Expose stubs on unsupported platforms
#[cfg(not(all(target_pointer_width = "64", target_endian = "little")))]
mod raw_transfer_stubs;
#[cfg(not(all(target_pointer_width = "64", target_endian = "little")))]
pub use raw_transfer_stubs::*;

#[derive(Clone, Copy, PartialEq, Eq)]
enum AstType {
JavaScript,
Expand Down
20 changes: 16 additions & 4 deletions napi/parser/src/raw_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ use crate::{
raw_transfer_types::{EcmaScriptModule, Error, RawTransferData},
};

const _: () = {
#[cfg(not(target_pointer_width = "64"))]
panic!("Only 64-bit systems are supported");
#[cfg(target_endian = "big")]
panic!("Little-endian systems are not supported");
};

// For raw transfer, use a buffer 4 GiB in size, with 4 GiB alignment.
// This ensures that all 64-bit pointers have the same value in upper 32 bits,
// so JS only needs to read the lower 32 bits to get an offset into the buffer.
Expand Down Expand Up @@ -69,15 +76,12 @@ pub fn get_buffer_offset(buffer: Uint8Array) -> u32 {
/// Panics if source text is too long, or AST takes more memory than is available in the buffer.
#[allow(clippy::items_after_statements, clippy::allow_attributes)]
#[napi]
pub unsafe fn parse_sync_raw(
pub fn parse_sync_raw(
filename: String,
mut buffer: Uint8Array,
source_len: u32,
options: Option<ParserOptions>,
) {
// 32-bit systems are not supported
const { assert!(std::mem::size_of::<usize>() >= 8) };

// Check buffer has expected size and alignment
let buffer = &mut *buffer;
assert_eq!(buffer.len(), BUFFER_SIZE);
Expand Down Expand Up @@ -176,6 +180,14 @@ pub unsafe fn parse_sync_raw(
}
}

/// Returns `true` if raw transfer is supported on this platform.
#[napi]
pub fn raw_transfer_supported() -> bool {
// On unsupported platforms, the stub function in `raw_transfer_stubs.rs` will be compiled instead.
// It returns `false`.
true
}

/// Returns `true` if `n` is a multiple of `divisor`.
const fn is_multiple_of(n: usize, divisor: usize) -> bool {
n % divisor == 0
Expand Down
29 changes: 29 additions & 0 deletions napi/parser/src/raw_transfer_stubs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//! Stubs for raw transfer functions on unsupported platforms.
//!
//! These exports are required to avoid type-checking errors.

#![expect(unused_variables, unused_mut)]

use napi::bindgen_prelude::Uint8Array;
use napi_derive::napi;

use crate::ParserOptions;

#[napi]
pub fn get_buffer_offset(buffer: Uint8Array) -> u32 {
0
}

#[napi]
pub fn parse_sync_raw(
filename: String,
mut buffer: Uint8Array,
source_len: u32,
options: Option<ParserOptions>,
) {
}

#[napi]
pub fn raw_transfer_supported() -> bool {
false
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
},
"devDependencies": {
"@napi-rs/cli": "catalog:",
"emnapi": "1.3.1",
"typescript": "catalog:",
"vitest": "catalog:"
}
Expand Down
18 changes: 16 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading