Browse Source

Fix compilation for targets without `AtomicU64` (#3399)

* Fix compilation for targets without `AtomicU64`

* Throw compilation error if `AtomicUsize` is not available

* Apply review pt. 1

* Apply review pt. 2

* fix comment
pull/3403/head
José Julián Espina 1 year ago committed by GitHub
parent
commit
f71039d9ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      boa_engine/src/lib.rs
  2. 31
      boa_engine/src/symbol.rs
  3. 33
      boa_gc/src/trace.rs

4
boa_engine/src/lib.rs

@ -123,9 +123,11 @@
// Add temporarily - Needs addressing // Add temporarily - Needs addressing
clippy::missing_panics_doc, clippy::missing_panics_doc,
clippy::arc_with_non_send_sync,
)] )]
#[cfg(not(target_has_atomic = "ptr"))]
compile_error!("Boa requires a lock free `AtomicUsize` in order to work properly.");
extern crate static_assertions as sa; extern crate static_assertions as sa;
pub mod bigint; pub mod bigint;

31
boa_engine/src/symbol.rs

@ -33,16 +33,15 @@ use num_enum::{IntoPrimitive, TryFromPrimitive};
use std::{ use std::{
hash::{Hash, Hasher}, hash::{Hash, Hasher},
sync::{ sync::{atomic::Ordering, Arc},
atomic::{AtomicU64, Ordering},
Arc,
},
}; };
use portable_atomic::AtomicU64;
/// Reserved number of symbols. /// Reserved number of symbols.
/// ///
/// This is where the well known symbol live /// This is the maximum number of well known and internal engine symbols
/// and internal engine symbols. /// that can be defined.
const RESERVED_SYMBOL_HASHES: u64 = 127; const RESERVED_SYMBOL_HASHES: u64 = 127;
fn get_id() -> Option<u64> { fn get_id() -> Option<u64> {
@ -118,21 +117,17 @@ impl WellKnown {
self as u64 self as u64
} }
const fn tag(self) -> usize {
self as usize
}
fn from_tag(tag: usize) -> Option<Self> { fn from_tag(tag: usize) -> Option<Self> {
Self::try_from_primitive(u8::try_from(tag).ok()?).ok() Self::try_from_primitive(u8::try_from(tag).ok()?).ok()
} }
} }
// TODO: Address below clippy::arc_with_non_send_sync below.
/// The inner representation of a JavaScript symbol. /// The inner representation of a JavaScript symbol.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct Inner { struct Inner {
hash: u64, hash: u64,
description: Option<JsString>, // must be a `Box`, since this needs to be shareable between many threads.
description: Option<Box<[u16]>>,
} }
/// This represents a JavaScript symbol primitive. /// This represents a JavaScript symbol primitive.
@ -158,7 +153,8 @@ macro_rules! well_known_symbols {
$( $(
$(#[$attr])* pub(crate) const fn $name() -> JsSymbol { $(#[$attr])* pub(crate) const fn $name() -> JsSymbol {
JsSymbol { JsSymbol {
repr: Tagged::from_tag($variant.tag()), // the cast shouldn't matter since we only have 127 const symbols
repr: Tagged::from_tag($variant.hash() as usize),
} }
} }
)+ )+
@ -173,7 +169,10 @@ impl JsSymbol {
#[must_use] #[must_use]
pub fn new(description: Option<JsString>) -> Option<Self> { pub fn new(description: Option<JsString>) -> Option<Self> {
let hash = get_id()?; let hash = get_id()?;
let arc = Arc::new(Inner { hash, description }); let arc = Arc::new(Inner {
hash,
description: description.map(|s| Box::from(&*s)),
});
Some(Self { Some(Self {
// SAFETY: Pointers returned by `Arc::into_raw` must be non-null. // SAFETY: Pointers returned by `Arc::into_raw` must be non-null.
@ -188,8 +187,8 @@ impl JsSymbol {
match self.repr.unwrap() { match self.repr.unwrap() {
UnwrappedTagged::Ptr(ptr) => { UnwrappedTagged::Ptr(ptr) => {
// SAFETY: `ptr` comes from `Arc`, which ensures the validity of the pointer // SAFETY: `ptr` comes from `Arc`, which ensures the validity of the pointer
// as long as we corrently call `Arc::from_raw` on `Drop`. // as long as we correctly call `Arc::from_raw` on `Drop`.
unsafe { ptr.as_ref().description.clone() } unsafe { ptr.as_ref().description.as_ref().map(|v| js_string!(&**v)) }
} }
UnwrappedTagged::Tag(tag) => { UnwrappedTagged::Tag(tag) => {
// SAFETY: All tagged reprs always come from `WellKnown` itself, making // SAFETY: All tagged reprs always come from `WellKnown` itself, making

33
boa_gc/src/trace.rs

@ -11,10 +11,7 @@ use std::{
}, },
path::{Path, PathBuf}, path::{Path, PathBuf},
rc::Rc, rc::Rc,
sync::atomic::{ sync::atomic,
AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, AtomicU32,
AtomicU64, AtomicU8, AtomicUsize,
},
}; };
/// Substitute for the [`Drop`] trait for garbage collected types. /// Substitute for the [`Drop`] trait for garbage collected types.
@ -161,20 +158,24 @@ simple_empty_finalize_trace![
NonZeroI64, NonZeroI64,
NonZeroU64, NonZeroU64,
NonZeroI128, NonZeroI128,
NonZeroU128, NonZeroU128
AtomicBool,
AtomicIsize,
AtomicUsize,
AtomicI8,
AtomicU8,
AtomicI16,
AtomicU16,
AtomicI32,
AtomicU32,
AtomicI64,
AtomicU64
]; ];
#[cfg(target_has_atomic = "8")]
simple_empty_finalize_trace![atomic::AtomicBool, atomic::AtomicI8, atomic::AtomicU8];
#[cfg(target_has_atomic = "16")]
simple_empty_finalize_trace![atomic::AtomicI16, atomic::AtomicU16];
#[cfg(target_has_atomic = "32")]
simple_empty_finalize_trace![atomic::AtomicI32, atomic::AtomicU32];
#[cfg(target_has_atomic = "64")]
simple_empty_finalize_trace![atomic::AtomicI64, atomic::AtomicU64];
#[cfg(target_has_atomic = "ptr")]
simple_empty_finalize_trace![atomic::AtomicIsize, atomic::AtomicUsize];
impl<T: Trace, const N: usize> Finalize for [T; N] {} impl<T: Trace, const N: usize> Finalize for [T; N] {}
// SAFETY: // SAFETY:
// All elements inside the array are correctly marked. // All elements inside the array are correctly marked.

Loading…
Cancel
Save