Skip to content

Commit

Permalink
feat(target): add support for s390x-unknown-linux-gnu (#2028)
Browse files Browse the repository at this point in the history
* feat(target): add support for s390x-unknown-linux-gnu

* chore: rerun CI
  • Loading branch information
sapphi-red committed Apr 9, 2024
1 parent 0fa755d commit 2e0f983
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 37 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/test-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,10 @@ jobs:
setup: |
sudo apt-get update
sudo apt-get install -y gcc-powerpc64le-linux-gnu
- target: s390x-unknown-linux-gnu
setup: |
sudo apt-get update
sudo apt-get install -y gcc-s390x-linux-gnu
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -383,6 +387,12 @@ jobs:
arch: 'ppc64'
libc: 'gnu'
without-lerna: true
- image: 'node:{:version}-slim'
target: s390x-unknown-linux-gnu
args: '--platform linux/s390x'
arch: 's390x'
libc: 'gnu'
without-lerna: true
- image: 'node:{:version}-alpine'
target: x86_64-unknown-linux-musl
args: ''
Expand Down
6 changes: 6 additions & 0 deletions cli/src/api/templates/ci-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ jobs:
sudo apt-get update
sudo apt-get install gcc-powerpc64le-linux-gnu -y
build: ${packageManager} build --platform --target powerpc64le-unknown-linux-gnu
- host: ubuntu-latest
target: 's390x-unknown-linux-gnu'
setup: |
sudo apt-get update
sudo apt-get install gcc-s390x-linux-gnu -y
build: ${packageManager} build --platform --target s390x-unknown-linux-gnu
- host: ubuntu-latest
target: 'wasm32-wasi-preview1-threads'
build: ${packageManager} build --platform --target wasm32-wasi-preview1-threads
Expand Down
7 changes: 7 additions & 0 deletions cli/src/utils/__tests__/__snapshots__/target.spec.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,13 @@ Generated by [AVA](https://avajs.dev).
platformArchABI: 'linux-ppc64-gnu',
triple: 'powerpc64le-unknown-linux-gnu',
},
{
abi: 'gnu',
arch: 's390x',
platform: 'linux',
platformArchABI: 'linux-s390x-gnu',
triple: 's390x-unknown-linux-gnu',
},
{
abi: 'wasi',
arch: 'wasm32',
Expand Down
Binary file modified cli/src/utils/__tests__/__snapshots__/target.spec.ts.snap
Binary file not shown.
2 changes: 2 additions & 0 deletions cli/src/utils/target.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const AVAILABLE_TARGETS = [
'universal-apple-darwin',
'riscv64gc-unknown-linux-gnu',
'powerpc64le-unknown-linux-gnu',
's390x-unknown-linux-gnu',
'wasm32-wasi-preview1-threads',
] as const

Expand All @@ -40,6 +41,7 @@ export const TARGET_LINKER: Record<string, string> = {
'aarch64-unknown-linux-musl': 'aarch64-linux-musl-gcc',
'riscv64gc-unknown-linux-gnu': 'riscv64-linux-gnu-gcc',
'powerpc64le-unknown-linux-gnu': 'powerpc64le-linux-gnu-gcc',
's390x-unknown-linux-gnu': 's390x-linux-gnu-gcc',
}

// https://nodejs.org/api/process.html#process_process_arch
Expand Down
33 changes: 23 additions & 10 deletions crates/napi/src/bindgen_runtime/js_values/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,7 @@ impl BigInt {
if len == 1 {
(self.words[0] as i128, false)
} else {
let i128_words: [i64; 2] = [self.words[0] as _, self.words[1] as _];
let mut val = unsafe { ptr::read(i128_words.as_ptr() as *const i128) };
let mut val = self.words[0] as i128 + ((self.words[1] as i128) << 64);
if self.sign_bit {
val = -val;
}
Expand All @@ -125,8 +124,7 @@ impl BigInt {
if len == 1 {
(self.sign_bit, self.words[0] as u128, false)
} else {
let u128_words: [u64; 2] = [self.words[0], self.words[1]];
let val = unsafe { ptr::read(u128_words.as_ptr() as *const u128) };
let val = self.words[0] as u128 + ((self.words[1] as u128) << 64);
(self.sign_bit, val, len > 2)
}
}
Expand Down Expand Up @@ -156,7 +154,16 @@ impl ToNapiValue for i128 {
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> crate::Result<sys::napi_value> {
let mut raw_value = ptr::null_mut();
let sign_bit = i32::from(val <= 0);
let words = &val as *const i128 as *const u64;
if cfg!(target_endian = "little") {
let words = &val as *const i128 as *const u64;
check_status!(unsafe {
sys::napi_create_bigint_words(env, sign_bit, 2, words, &mut raw_value)
})?;
return Ok(raw_value);
}

let arr: [u64; 2] = [val as _, (val >> 64) as _];
let words = &arr as *const u64;
check_status!(unsafe {
sys::napi_create_bigint_words(env, sign_bit, 2, words, &mut raw_value)
})?;
Expand All @@ -167,7 +174,14 @@ impl ToNapiValue for i128 {
impl ToNapiValue for u128 {
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> crate::Result<sys::napi_value> {
let mut raw_value = ptr::null_mut();
let words = &val as *const u128 as *const u64;
if cfg!(target_endian = "little") {
let words = &val as *const u128 as *const u64;
check_status!(unsafe { sys::napi_create_bigint_words(env, 0, 2, words, &mut raw_value) })?;
return Ok(raw_value);
}

let arr: [u64; 2] = [val as _, (val >> 64) as _];
let words = &arr as *const u64;
check_status!(unsafe { sys::napi_create_bigint_words(env, 0, 2, words, &mut raw_value) })?;
Ok(raw_value)
}
Expand Down Expand Up @@ -226,20 +240,19 @@ impl From<u64> for BigInt {
impl From<i128> for BigInt {
fn from(val: i128) -> Self {
let sign_bit = val < 0;
let words = (if sign_bit { -val } else { val }).to_ne_bytes();
let val = if sign_bit { -val } else { val };
BigInt {
sign_bit,
words: unsafe { std::slice::from_raw_parts(words.as_ptr() as *mut _, 2).to_vec() },
words: vec![val as _, (val >> 64) as _],
}
}
}

impl From<u128> for BigInt {
fn from(val: u128) -> Self {
let words = val.to_ne_bytes();
BigInt {
sign_bit: false,
words: unsafe { std::slice::from_raw_parts(words.as_ptr() as *mut _, 2).to_vec() },
words: vec![val as _, (val >> 64) as _],
}
}
}
20 changes: 18 additions & 2 deletions crates/napi/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,16 @@ impl Env {
pub fn create_bigint_from_i128(&self, value: i128) -> Result<JsBigInt> {
let mut raw_value = ptr::null_mut();
let sign_bit = i32::from(value <= 0);
let words = &value as *const i128 as *const u64;
if cfg!(target_endian = "little") {
let words = &value as *const i128 as *const u64;
check_status!(unsafe {
sys::napi_create_bigint_words(self.0, sign_bit, 2, words, &mut raw_value)
})?;
return Ok(JsBigInt::from_raw_unchecked(self.0, raw_value, 2));
}

let arr: [u64; 2] = [value as _, (value >> 64) as _];
let words = &arr as *const u64;
check_status!(unsafe {
sys::napi_create_bigint_words(self.0, sign_bit, 2, words, &mut raw_value)
})?;
Expand All @@ -129,7 +138,14 @@ impl Env {
#[cfg(feature = "napi6")]
pub fn create_bigint_from_u128(&self, value: u128) -> Result<JsBigInt> {
let mut raw_value = ptr::null_mut();
let words = &value as *const u128 as *const u64;
if cfg!(target_endian = "little") {
let words = &value as *const u128 as *const u64;
check_status!(unsafe { sys::napi_create_bigint_words(self.0, 0, 2, words, &mut raw_value) })?;
return Ok(JsBigInt::from_raw_unchecked(self.0, raw_value, 2));
}

let arr: [u64; 2] = [value as _, (value >> 64) as _];
let words = &arr as *const u64;
check_status!(unsafe { sys::napi_create_bigint_words(self.0, 0, 2, words, &mut raw_value) })?;
Ok(JsBigInt::from_raw_unchecked(self.0, raw_value, 2))
}
Expand Down
33 changes: 22 additions & 11 deletions crates/napi/src/js_values/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,17 +246,22 @@ impl JsBigInt {
pub fn get_i128(&mut self) -> Result<(i128, bool)> {
let (signed, words) = self.get_words()?;

let high_part = words.first().copied().unwrap_or(0).to_le_bytes();
let low_part = words.get(1).copied().unwrap_or(0).to_le_bytes();
let low_part = words.first().copied().unwrap_or(0).to_ne_bytes();
let high_part = words.get(1).copied().unwrap_or(0).to_ne_bytes();

let mut val = [0_u8; std::mem::size_of::<i128>()];

let (high_val, low_val) = val.split_at_mut(low_part.len());
let high_val: &mut [u8];
let low_val: &mut [u8];
if cfg!(target_endian = "little") {
(low_val, high_val) = val.split_at_mut(low_part.len());
} else {
(high_val, low_val) = val.split_at_mut(low_part.len());
}

high_val.copy_from_slice(&high_part);
low_val.copy_from_slice(&low_part);

let mut val = i128::from_le_bytes(val);
let mut val = i128::from_ne_bytes(val);

let mut loss = words.len() > 2;
let mut overflow = false;
Expand All @@ -275,17 +280,23 @@ impl JsBigInt {
pub fn get_u128(&mut self) -> Result<(bool, u128, bool)> {
let (signed, words) = self.get_words()?;

let high_part = words.first().copied().unwrap_or(0).to_le_bytes();
let low_part = words.get(1).copied().unwrap_or(0).to_le_bytes();

let mut val = [0_u8; std::mem::size_of::<u128>()];
let low_part = words.first().copied().unwrap_or(0).to_ne_bytes();
let high_part = words.get(1).copied().unwrap_or(0).to_ne_bytes();

let (high_val, low_val) = val.split_at_mut(low_part.len());
let mut val = [0_u8; std::mem::size_of::<i128>()];
let high_val: &mut [u8];
let low_val: &mut [u8];
if cfg!(target_endian = "little") {
(low_val, high_val) = val.split_at_mut(low_part.len());
} else {
(high_val, low_val) = val.split_at_mut(low_part.len());
}

high_val.copy_from_slice(&high_part);
low_val.copy_from_slice(&low_part);

let val = u128::from_le_bytes(val);
let val = u128::from_ne_bytes(val);

let len = words.len();

Ok((signed, val, len > 2))
Expand Down
16 changes: 2 additions & 14 deletions crates/napi/src/js_values/ser.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use std::result::Result as StdResult;
#[cfg(feature = "napi6")]
use std::slice;

use serde::{ser, Serialize, Serializer};

Expand Down Expand Up @@ -124,12 +122,7 @@ impl<'env> Serializer for Ser<'env> {

#[cfg(feature = "napi6")]
fn serialize_u128(self, v: u128) -> Result<Self::Ok> {
let words_ref = &v as *const _;
let words = unsafe { slice::from_raw_parts(words_ref as *const u64, 2) };
self
.0
.create_bigint_from_words(false, words.to_vec())
.map(|v| v.raw)
self.0.create_bigint_from_u128(v).map(|v| v.raw)
}

#[cfg(all(
Expand All @@ -147,12 +140,7 @@ impl<'env> Serializer for Ser<'env> {

#[cfg(feature = "napi6")]
fn serialize_i128(self, v: i128) -> Result<Self::Ok> {
let words_ref = &(v as u128) as *const _;
let words = unsafe { slice::from_raw_parts(words_ref as *const u64, 2) };
self
.0
.create_bigint_from_words(v < 0, words.to_vec())
.map(|v| v.raw)
self.0.create_bigint_from_i128(v).map(|v| v.raw)
}

fn serialize_unit(self) -> Result<Self::Ok> {
Expand Down

0 comments on commit 2e0f983

Please sign in to comment.