@@ -114,6 +114,7 @@ use boa_gc::{custom_trace, Finalize, Trace};
114
114
use boa_string:: JsString ;
115
115
use core:: fmt;
116
116
use static_assertions:: const_assert;
117
+ use std:: sync:: Arc ;
117
118
118
119
// We cannot NaN-box pointers larger than 64 bits.
119
120
const_assert ! ( size_of:: <usize >( ) <= size_of:: <u64 >( ) ) ;
@@ -128,6 +129,7 @@ mod bits {
128
129
use boa_engine:: { JsBigInt , JsObject , JsSymbol } ;
129
130
use boa_string:: JsString ;
130
131
use std:: ptr:: NonNull ;
132
+ use std:: sync:: Arc ;
131
133
132
134
/// Undefined value in `u64`.
133
135
pub ( super ) const UNDEFINED : u64 = 0x7FF4_0000_0000_0000 ;
@@ -296,8 +298,8 @@ mod bits {
296
298
/// by calling `[Self::drop_pointer]`.
297
299
#[ inline( always) ]
298
300
#[ allow( clippy:: identity_op) ]
299
- pub ( super ) unsafe fn tag_bigint ( value : Box < JsBigInt > ) -> u64 {
300
- let value = Box :: into_raw ( value) as u64 ;
301
+ pub ( super ) unsafe fn tag_bigint ( value : Arc < JsBigInt > ) -> u64 {
302
+ let value = Arc :: into_raw ( value) as u64 ;
301
303
let value_masked: u64 = value & POINTER_MASK ;
302
304
303
305
// Assert alignment and location of the pointer.
@@ -321,8 +323,8 @@ mod bits {
321
323
/// The box is forgotten after this operation. It must be dropped separately,
322
324
/// by calling `[Self::drop_pointer]`.
323
325
#[ inline( always) ]
324
- pub ( super ) unsafe fn tag_object ( value : Box < JsObject > ) -> u64 {
325
- let value = Box :: into_raw ( value) as u64 ;
326
+ pub ( super ) unsafe fn tag_object ( value : Arc < JsObject > ) -> u64 {
327
+ let value = Arc :: into_raw ( value) as u64 ;
326
328
let value_masked: u64 = value & POINTER_MASK ;
327
329
328
330
// Assert alignment and location of the pointer.
@@ -346,8 +348,8 @@ mod bits {
346
348
/// The box is forgotten after this operation. It must be dropped separately,
347
349
/// by calling `[Self::drop_pointer]`.
348
350
#[ inline( always) ]
349
- pub ( super ) unsafe fn tag_symbol ( value : Box < JsSymbol > ) -> u64 {
350
- let value = Box :: into_raw ( value) as u64 ;
351
+ pub ( super ) unsafe fn tag_symbol ( value : Arc < JsSymbol > ) -> u64 {
352
+ let value = Arc :: into_raw ( value) as u64 ;
351
353
let value_masked: u64 = value & POINTER_MASK ;
352
354
353
355
// Assert alignment and location of the pointer.
@@ -371,8 +373,8 @@ mod bits {
371
373
/// The box is forgotten after this operation. It must be dropped separately,
372
374
/// by calling `[Self::drop_pointer]`.
373
375
#[ inline( always) ]
374
- pub ( super ) unsafe fn tag_string ( value : Box < JsString > ) -> u64 {
375
- let value = Box :: into_raw ( value) as u64 ;
376
+ pub ( super ) unsafe fn tag_string ( value : Arc < JsString > ) -> u64 {
377
+ let value = Arc :: into_raw ( value) as u64 ;
376
378
let value_masked: u64 = value & POINTER_MASK ;
377
379
378
380
// Assert alignment and location of the pointer.
@@ -455,17 +457,17 @@ unsafe impl Trace for NanBoxedValue {
455
457
impl Clone for NanBoxedValue {
456
458
#[ inline( always) ]
457
459
fn clone ( & self ) -> Self {
458
- if let Some ( o) = self . as_object ( ) {
459
- Self :: object ( o. clone ( ) )
460
- } else if let Some ( b) = self . as_bigint ( ) {
461
- Self :: bigint ( b. clone ( ) )
462
- } else if let Some ( s) = self . as_symbol ( ) {
463
- Self :: symbol ( s. clone ( ) )
464
- } else if let Some ( s) = self . as_string ( ) {
465
- Self :: string ( s. clone ( ) )
466
- } else {
467
- Self ( self . 0 )
460
+ let maybe_ptr = self . 0 & bits:: POINTER_MASK ;
461
+ if self . is_object ( ) {
462
+ unsafe { Arc :: increment_strong_count ( maybe_ptr as * const JsObject ) } ;
463
+ } else if self . is_bigint ( ) {
464
+ unsafe { Arc :: increment_strong_count ( maybe_ptr as * const JsBigInt ) } ;
465
+ } else if self . is_symbol ( ) {
466
+ unsafe { Arc :: increment_strong_count ( maybe_ptr as * const JsSymbol ) } ;
467
+ } else if self . is_string ( ) {
468
+ unsafe { Arc :: increment_strong_count ( maybe_ptr as * const JsString ) } ;
468
469
}
470
+ Self ( self . 0 )
469
471
}
470
472
}
471
473
@@ -518,28 +520,28 @@ impl NanBoxedValue {
518
520
#[ must_use]
519
521
#[ inline( always) ]
520
522
pub ( crate ) fn bigint ( value : JsBigInt ) -> Self {
521
- Self :: from_inner_unchecked ( unsafe { bits:: tag_bigint ( Box :: new ( value) ) } )
523
+ Self :: from_inner_unchecked ( unsafe { bits:: tag_bigint ( Arc :: new ( value) ) } )
522
524
}
523
525
524
526
/// Returns a `InnerValue` from a boxed `[JsObject]`.
525
527
#[ must_use]
526
528
#[ inline( always) ]
527
529
pub ( crate ) fn object ( value : JsObject ) -> Self {
528
- Self :: from_inner_unchecked ( unsafe { bits:: tag_object ( Box :: new ( value) ) } )
530
+ Self :: from_inner_unchecked ( unsafe { bits:: tag_object ( Arc :: new ( value) ) } )
529
531
}
530
532
531
533
/// Returns a `InnerValue` from a boxed `[JsSymbol]`.
532
534
#[ must_use]
533
535
#[ inline( always) ]
534
536
pub ( crate ) fn symbol ( value : JsSymbol ) -> Self {
535
- Self :: from_inner_unchecked ( unsafe { bits:: tag_symbol ( Box :: new ( value) ) } )
537
+ Self :: from_inner_unchecked ( unsafe { bits:: tag_symbol ( Arc :: new ( value) ) } )
536
538
}
537
539
538
540
/// Returns a `InnerValue` from a boxed `[JsString]`.
539
541
#[ must_use]
540
542
#[ inline( always) ]
541
543
pub ( crate ) fn string ( value : JsString ) -> Self {
542
- Self :: from_inner_unchecked ( unsafe { bits:: tag_string ( Box :: new ( value) ) } )
544
+ Self :: from_inner_unchecked ( unsafe { bits:: tag_string ( Arc :: new ( value) ) } )
543
545
}
544
546
545
547
/// Returns true if a value is undefined.
@@ -725,14 +727,14 @@ impl Drop for NanBoxedValue {
725
727
726
728
// Drop the pointer if it is a pointer.
727
729
if self . is_pointer ( ) {
728
- if self . is_string ( ) {
729
- drop ( unsafe { Box :: from_raw ( maybe_ptr as * mut JsString ) } ) ;
730
- } else if self . is_object ( ) {
731
- drop ( unsafe { Box :: from_raw ( maybe_ptr as * mut JsObject ) } ) ;
730
+ if self . is_object ( ) {
731
+ unsafe { Arc :: decrement_strong_count ( maybe_ptr as * const JsObject ) } ;
732
732
} else if self . is_bigint ( ) {
733
- drop ( unsafe { Box :: from_raw ( maybe_ptr as * mut JsBigInt ) } ) ;
733
+ unsafe { Arc :: decrement_strong_count ( maybe_ptr as * const JsBigInt ) } ;
734
734
} else if self . is_symbol ( ) {
735
- drop ( unsafe { Box :: from_raw ( maybe_ptr as * mut JsSymbol ) } ) ;
735
+ unsafe { Arc :: decrement_strong_count ( maybe_ptr as * const JsSymbol ) } ;
736
+ } else if self . is_string ( ) {
737
+ unsafe { Arc :: decrement_strong_count ( maybe_ptr as * const JsString ) } ;
736
738
}
737
739
}
738
740
}
0 commit comments