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: | setup: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y gcc-powerpc64le-linux-gnu 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: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -383,6 +387,12 @@ jobs:
arch: 'ppc64' arch: 'ppc64'
libc: 'gnu' libc: 'gnu'
without-lerna: true 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' - image: 'node:{:version}-alpine'
target: x86_64-unknown-linux-musl target: x86_64-unknown-linux-musl
args: '' args: ''

View file

@ -85,6 +85,12 @@ jobs:
sudo apt-get update sudo apt-get update
sudo apt-get install gcc-powerpc64le-linux-gnu -y sudo apt-get install gcc-powerpc64le-linux-gnu -y
build: ${packageManager} build --platform --target powerpc64le-unknown-linux-gnu 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 - host: ubuntu-latest
target: 'wasm32-wasi-preview1-threads' target: 'wasm32-wasi-preview1-threads'
build: ${packageManager} build --platform --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', platformArchABI: 'linux-ppc64-gnu',
triple: 'powerpc64le-unknown-linux-gnu', triple: 'powerpc64le-unknown-linux-gnu',
}, },
{
abi: 'gnu',
arch: 's390x',
platform: 'linux',
platformArchABI: 'linux-s390x-gnu',
triple: 's390x-unknown-linux-gnu',
},
{ {
abi: 'wasi', abi: 'wasi',
arch: 'wasm32', arch: 'wasm32',

View file

@ -24,6 +24,7 @@ export const AVAILABLE_TARGETS = [
'universal-apple-darwin', 'universal-apple-darwin',
'riscv64gc-unknown-linux-gnu', 'riscv64gc-unknown-linux-gnu',
'powerpc64le-unknown-linux-gnu', 'powerpc64le-unknown-linux-gnu',
's390x-unknown-linux-gnu',
'wasm32-wasi-preview1-threads', 'wasm32-wasi-preview1-threads',
] as const ] as const
@ -40,6 +41,7 @@ export const TARGET_LINKER: Record<string, string> = {
'aarch64-unknown-linux-musl': 'aarch64-linux-musl-gcc', 'aarch64-unknown-linux-musl': 'aarch64-linux-musl-gcc',
'riscv64gc-unknown-linux-gnu': 'riscv64-linux-gnu-gcc', 'riscv64gc-unknown-linux-gnu': 'riscv64-linux-gnu-gcc',
'powerpc64le-unknown-linux-gnu': 'powerpc64le-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 // https://nodejs.org/api/process.html#process_process_arch

View file

@ -107,8 +107,7 @@ impl BigInt {
if len == 1 { if len == 1 {
(self.words[0] as i128, false) (self.words[0] as i128, false)
} else { } else {
let i128_words: [i64; 2] = [self.words[0] as _, self.words[1] as _]; let mut val = self.words[0] as i128 + ((self.words[1] as i128) << 64);
let mut val = unsafe { ptr::read(i128_words.as_ptr() as *const i128) };
if self.sign_bit { if self.sign_bit {
val = -val; val = -val;
} }
@ -125,8 +124,7 @@ impl BigInt {
if len == 1 { if len == 1 {
(self.sign_bit, self.words[0] as u128, false) (self.sign_bit, self.words[0] as u128, false)
} else { } else {
let u128_words: [u64; 2] = [self.words[0], self.words[1]]; let val = self.words[0] as u128 + ((self.words[1] as u128) << 64);
let val = unsafe { ptr::read(u128_words.as_ptr() as *const u128) };
(self.sign_bit, val, len > 2) (self.sign_bit, val, len > 2)
} }
} }
@ -156,7 +154,16 @@ impl ToNapiValue for i128 {
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> crate::Result<sys::napi_value> { unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> crate::Result<sys::napi_value> {
let mut raw_value = ptr::null_mut(); let mut raw_value = ptr::null_mut();
let sign_bit = i32::from(val <= 0); 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 { check_status!(unsafe {
sys::napi_create_bigint_words(env, sign_bit, 2, words, &mut raw_value) sys::napi_create_bigint_words(env, sign_bit, 2, words, &mut raw_value)
})?; })?;
@ -167,7 +174,14 @@ impl ToNapiValue for i128 {
impl ToNapiValue for u128 { impl ToNapiValue for u128 {
unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> crate::Result<sys::napi_value> { unsafe fn to_napi_value(env: sys::napi_env, val: Self) -> crate::Result<sys::napi_value> {
let mut raw_value = ptr::null_mut(); 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) })?; check_status!(unsafe { sys::napi_create_bigint_words(env, 0, 2, words, &mut raw_value) })?;
Ok(raw_value) Ok(raw_value)
} }
@ -226,20 +240,19 @@ impl From<u64> for BigInt {
impl From<i128> for BigInt { impl From<i128> for BigInt {
fn from(val: i128) -> Self { fn from(val: i128) -> Self {
let sign_bit = val < 0; 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 { BigInt {
sign_bit, 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 { impl From<u128> for BigInt {
fn from(val: u128) -> Self { fn from(val: u128) -> Self {
let words = val.to_ne_bytes();
BigInt { BigInt {
sign_bit: false, 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,7 +119,16 @@ impl Env {
pub fn create_bigint_from_i128(&self, value: i128) -> Result<JsBigInt> { pub fn create_bigint_from_i128(&self, value: i128) -> Result<JsBigInt> {
let mut raw_value = ptr::null_mut(); let mut raw_value = ptr::null_mut();
let sign_bit = i32::from(value <= 0); 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 { check_status!(unsafe {
sys::napi_create_bigint_words(self.0, sign_bit, 2, words, &mut raw_value) sys::napi_create_bigint_words(self.0, sign_bit, 2, words, &mut raw_value)
})?; })?;
@ -129,7 +138,14 @@ impl Env {
#[cfg(feature = "napi6")] #[cfg(feature = "napi6")]
pub fn create_bigint_from_u128(&self, value: u128) -> Result<JsBigInt> { pub fn create_bigint_from_u128(&self, value: u128) -> Result<JsBigInt> {
let mut raw_value = ptr::null_mut(); 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) })?; 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)) 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)> { pub fn get_i128(&mut self) -> Result<(i128, bool)> {
let (signed, words) = self.get_words()?; let (signed, words) = self.get_words()?;
let high_part = words.first().copied().unwrap_or(0).to_le_bytes(); let low_part = words.first().copied().unwrap_or(0).to_ne_bytes();
let low_part = words.get(1).copied().unwrap_or(0).to_le_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 mut val = [0_u8; std::mem::size_of::<i128>()];
let high_val: &mut [u8];
let (high_val, low_val) = val.split_at_mut(low_part.len()); 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); high_val.copy_from_slice(&high_part);
low_val.copy_from_slice(&low_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 loss = words.len() > 2;
let mut overflow = false; let mut overflow = false;
@ -275,17 +280,23 @@ impl JsBigInt {
pub fn get_u128(&mut self) -> Result<(bool, u128, bool)> { pub fn get_u128(&mut self) -> Result<(bool, u128, bool)> {
let (signed, words) = self.get_words()?; let (signed, words) = self.get_words()?;
let high_part = words.first().copied().unwrap_or(0).to_le_bytes(); let low_part = words.first().copied().unwrap_or(0).to_ne_bytes();
let low_part = words.get(1).copied().unwrap_or(0).to_le_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 mut val = [0_u8; std::mem::size_of::<i128>()];
let high_val: &mut [u8];
let (high_val, low_val) = val.split_at_mut(low_part.len()); 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); high_val.copy_from_slice(&high_part);
low_val.copy_from_slice(&low_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(); let len = words.len();
Ok((signed, val, len > 2)) Ok((signed, val, len > 2))

View file

@ -1,6 +1,4 @@
use std::result::Result as StdResult; use std::result::Result as StdResult;
#[cfg(feature = "napi6")]
use std::slice;
use serde::{ser, Serialize, Serializer}; use serde::{ser, Serialize, Serializer};
@ -124,12 +122,7 @@ impl<'env> Serializer for Ser<'env> {
#[cfg(feature = "napi6")] #[cfg(feature = "napi6")]
fn serialize_u128(self, v: u128) -> Result<Self::Ok> { fn serialize_u128(self, v: u128) -> Result<Self::Ok> {
let words_ref = &v as *const _; self.0.create_bigint_from_u128(v).map(|v| v.raw)
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)
} }
#[cfg(all( #[cfg(all(
@ -147,12 +140,7 @@ impl<'env> Serializer for Ser<'env> {
#[cfg(feature = "napi6")] #[cfg(feature = "napi6")]
fn serialize_i128(self, v: i128) -> Result<Self::Ok> { fn serialize_i128(self, v: i128) -> Result<Self::Ok> {
let words_ref = &(v as u128) as *const _; self.0.create_bigint_from_i128(v).map(|v| v.raw)
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)
} }
fn serialize_unit(self) -> Result<Self::Ok> { fn serialize_unit(self) -> Result<Self::Ok> {