feat(target): add support for s390x-unknown-linux-gnu (#2028)

* feat(target): add support for s390x-unknown-linux-gnu

* chore: rerun CI
This commit is contained in:
翠 / green 2024-04-09 15:16:09 +09:00 committed by GitHub
parent 0fa755d30a
commit 2e0f983ccf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 90 additions and 37 deletions

View file

@ -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
@ -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: ''

View file

@ -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

View file

@ -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',

View file

@ -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
@ -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

View file

@ -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;
}
@ -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)
}
}
@ -156,10 +154,19 @@ 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);
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)
})?;
Ok(raw_value)
}
}
@ -167,8 +174,15 @@ 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();
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)
}
}
@ -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 _],
}
}
}

View file

@ -119,18 +119,34 @@ 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);
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)
})?;
Ok(JsBigInt::from_raw_unchecked(self.0, raw_value, 2))
}
#[cfg(feature = "napi6")]
pub fn create_bigint_from_u128(&self, value: u128) -> Result<JsBigInt> {
let mut raw_value = ptr::null_mut();
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))
}

View file

@ -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;
@ -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 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::<u128>()];
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))

View file

@ -1,6 +1,4 @@
use std::result::Result as StdResult;
#[cfg(feature = "napi6")]
use std::slice;
use serde::{ser, Serialize, Serializer};
@ -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(
@ -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> {