Browse Source

Removed some unsafe_empty_trace!() calls to improve performance (#2233)

<!---
Thank you for contributing to Boa! Please fill out the template below, and remove or add any
information as you feel neccesary.
--->

This Pull Request fixes #1615.

It changes the following:

- Removes the `Trace` implementation from types that don't need it (except for `JsSymbol` and `JsString`, which are needed elsewere).
- Uses `#[unsafe_ignore_trace]` in places where we need to implement `Trace` for part of a structure.
- Implements a custom `Trace` in enums where deriving it is not possible, since `#[unsafe_ignore_trace]` doesn't work for enums.

Co-authored-by: raskad <32105367+raskad@users.noreply.github.com>
pull/2246/head
Iban Eguia 2 years ago
parent
commit
47ab7e0a80
  1. 9
      boa_engine/src/bigint.rs
  2. 1
      boa_engine/src/builtins/array/array_iterator.rs
  3. 9
      boa_engine/src/builtins/date/mod.rs
  4. 3
      boa_engine/src/builtins/function/mod.rs
  5. 1
      boa_engine/src/builtins/map/map_iterator.rs
  6. 8
      boa_engine/src/builtins/regexp/mod.rs
  7. 1
      boa_engine/src/builtins/set/set_iterator.rs
  8. 10
      boa_engine/src/builtins/typed_array/integer_indexed_object.rs
  9. 8
      boa_engine/src/builtins/typed_array/mod.rs
  10. 43
      boa_engine/src/object/mod.rs
  11. 11
      boa_engine/src/property/attribute/mod.rs
  12. 10
      boa_engine/src/property/mod.rs
  13. 12
      boa_engine/src/string.rs
  14. 16
      boa_engine/src/symbol.rs
  15. 9
      boa_engine/src/syntax/ast/constant.rs
  16. 7
      boa_engine/src/syntax/ast/node/identifier/mod.rs
  17. 7
      boa_engine/src/syntax/ast/node/iteration/break_node/mod.rs
  18. 43
      boa_engine/src/syntax/ast/op.rs
  19. 12
      boa_engine/src/value/mod.rs

9
boa_engine/src/bigint.rs

@ -1,7 +1,6 @@
//! This module implements the JavaScript bigint primitive rust type.
use crate::{builtins::Number, Context, JsValue};
use boa_gc::{unsafe_empty_trace, Finalize, Trace};
use num_integer::Integer;
use num_traits::{pow::Pow, FromPrimitive, One, ToPrimitive, Zero};
use std::{
@ -18,17 +17,11 @@ use serde::{Deserialize, Serialize};
/// JavaScript bigint primitive rust type.
#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
#[derive(Debug, Finalize, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct JsBigInt {
inner: Rc<RawBigInt>,
}
// Safety: BigInt does not contain any objects which needs to be traced,
// so this is safe.
unsafe impl Trace for JsBigInt {
unsafe_empty_trace!();
}
impl JsBigInt {
/// Create a new [`JsBigInt`].
#[inline]

1
boa_engine/src/builtins/array/array_iterator.rs

@ -18,6 +18,7 @@ use boa_profiler::Profiler;
pub struct ArrayIterator {
array: JsObject,
next_index: u64,
#[unsafe_ignore_trace]
kind: PropertyNameKind,
done: bool,
}

9
boa_engine/src/builtins/date/mod.rs

@ -12,7 +12,6 @@ use crate::{
value::{JsValue, PreferredType},
Context, JsResult, JsString,
};
use boa_gc::{unsafe_empty_trace, Finalize, Trace};
use boa_profiler::Profiler;
use chrono::{prelude::*, Duration, LocalResult};
use std::fmt::Display;
@ -61,7 +60,7 @@ macro_rules! getter_method {
}};
}
#[derive(Debug, Finalize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Date(Option<NaiveDateTime>);
impl Display for Date {
@ -73,12 +72,6 @@ impl Display for Date {
}
}
unsafe impl Trace for Date {
// Date is a stack value, it doesn't require tracing.
// only safe if `chrono` never implements `Trace` for `NaiveDateTime`
unsafe_empty_trace!();
}
impl Default for Date {
fn default() -> Self {
Self(Some(Utc::now().naive_utc()))

3
boa_engine/src/builtins/function/mod.rs

@ -153,8 +153,7 @@ pub enum ClassFieldDefinition {
unsafe impl Trace for ClassFieldDefinition {
custom_trace! {this, {
match this {
Self::Public(key, func) => {
mark(key);
Self::Public(_key, func) => {
mark(func);
}
Self::Private(_, func) => {

1
boa_engine/src/builtins/map/map_iterator.rs

@ -19,6 +19,7 @@ use boa_profiler::Profiler;
pub struct MapIterator {
iterated_map: Option<JsObject>,
map_next_index: usize,
#[unsafe_ignore_trace]
map_iteration_kind: PropertyNameKind,
lock: MapLock,
}

8
boa_engine/src/builtins/regexp/mod.rs

@ -26,7 +26,6 @@ use crate::{
value::{IntegerOrInfinity, JsValue},
Context, JsResult, JsString,
};
use boa_gc::{unsafe_empty_trace, Finalize, Trace};
use boa_profiler::Profiler;
use regress::Regex;
use std::str::FromStr;
@ -36,7 +35,7 @@ use tap::{Conv, Pipe};
mod tests;
/// The internal representation on a `RegExp` object.
#[derive(Debug, Clone, Finalize)]
#[derive(Debug, Clone)]
pub struct RegExp {
/// Regex matcher.
matcher: Regex,
@ -45,11 +44,6 @@ pub struct RegExp {
original_flags: JsString,
}
// Only safe while regress::Regex doesn't implement Trace itself.
unsafe impl Trace for RegExp {
unsafe_empty_trace!();
}
impl BuiltIn for RegExp {
const NAME: &'static str = "RegExp";

1
boa_engine/src/builtins/set/set_iterator.rs

@ -18,6 +18,7 @@ use boa_profiler::Profiler;
pub struct SetIterator {
iterated_set: JsValue,
next_index: usize,
#[unsafe_ignore_trace]
iteration_kind: PropertyNameKind,
}

10
boa_engine/src/builtins/typed_array/integer_indexed_object.rs

@ -13,24 +13,20 @@ use crate::{
object::{JsObject, ObjectData},
Context,
};
use boa_gc::{unsafe_empty_trace, Finalize, Trace};
use boa_gc::{Finalize, Trace};
/// Type of the array content.
#[derive(Debug, Clone, Copy, Finalize, PartialEq)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub(crate) enum ContentType {
Number,
BigInt,
}
unsafe impl Trace for ContentType {
// safe because `ContentType` is `Copy`
unsafe_empty_trace!();
}
/// <https://tc39.es/ecma262/#integer-indexed-exotic-object>
#[derive(Debug, Clone, Trace, Finalize)]
pub struct IntegerIndexed {
viewed_array_buffer: Option<JsObject>,
#[unsafe_ignore_trace]
typed_array_name: TypedArrayKind,
byte_offset: u64,
byte_length: u64,

8
boa_engine/src/builtins/typed_array/mod.rs

@ -29,7 +29,6 @@ use crate::{
value::{IntegerOrInfinity, JsValue},
Context, JsResult, JsString,
};
use boa_gc::{unsafe_empty_trace, Finalize, Trace};
use boa_profiler::Profiler;
use num_traits::{Signed, Zero};
use std::cmp::Ordering;
@ -3388,7 +3387,7 @@ impl TypedArray {
}
/// Names of all the typed arrays.
#[derive(Debug, Clone, Copy, Finalize, PartialEq)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub(crate) enum TypedArrayKind {
Int8,
Uint8,
@ -3403,11 +3402,6 @@ pub(crate) enum TypedArrayKind {
Float64,
}
unsafe impl Trace for TypedArrayKind {
// Safe because `TypedArrayName` is `Copy`
unsafe_empty_trace!();
}
impl TypedArrayKind {
/// Gets the element size of the given typed array name, as per the [spec].
///

43
boa_engine/src/object/mod.rs

@ -49,7 +49,7 @@ use crate::{
Context, JsBigInt, JsResult, JsString, JsSymbol, JsValue,
};
use boa_gc::{Finalize, Trace};
use boa_gc::{custom_trace, Finalize, Trace};
use boa_interner::Sym;
use rustc_hash::FxHashMap;
use std::{
@ -163,7 +163,7 @@ pub struct ObjectData {
}
/// Defines the different types of objects.
#[derive(Debug, Trace, Finalize)]
#[derive(Debug, Finalize)]
pub enum ObjectKind {
AsyncGenerator(AsyncGenerator),
AsyncGeneratorFunction(Function),
@ -201,6 +201,45 @@ pub enum ObjectKind {
Promise(Promise),
}
unsafe impl Trace for ObjectKind {
custom_trace! {this, {
match this {
Self::ArrayIterator(i) => mark(i),
Self::ArrayBuffer(b) => mark(b),
Self::Map(m) => mark(m),
Self::MapIterator(i) => mark(i),
Self::RegExpStringIterator(i) => mark(i),
Self::DataView(v) => mark(v),
Self::ForInIterator(i) => mark(i),
Self::Function(f) | Self::GeneratorFunction(f) | Self::AsyncGeneratorFunction(f) => mark(f),
Self::BoundFunction(f) => mark(f),
Self::Generator(g) => mark(g),
Self::Set(s) => mark(s),
Self::SetIterator(i) => mark(i),
Self::StringIterator(i) => mark(i),
Self::Proxy(p) => mark(p),
Self::Arguments(a) => mark(a),
Self::NativeObject(o) => mark(o),
Self::IntegerIndexed(i) => mark(i),
#[cfg(feature = "intl")]
Self::DateTimeFormat(f) => mark(f),
Self::Promise(p) => mark(p),
Self::AsyncGenerator(g) => mark(g),
Self::RegExp(_)
| Self::BigInt(_)
| Self::Boolean(_)
| Self::String(_)
| Self::Date(_)
| Self::Array
| Self::Error
| Self::Ordinary
| Self::Global
| Self::Number(_)
| Self::Symbol(_) => {}
}
}}
}
impl ObjectData {
/// Create the `AsyncGenerator` object data
pub fn async_generator(async_generator: AsyncGenerator) -> Self {

11
boa_engine/src/property/attribute/mod.rs

@ -1,7 +1,6 @@
//! This module implements the `Attribute` struct which contains the attibutes for property descriptors.
use bitflags::bitflags;
use boa_gc::{unsafe_empty_trace, Finalize, Trace};
#[cfg(test)]
mod tests;
@ -16,7 +15,6 @@ bitflags! {
/// - `[[Configurable]]` (`CONFIGURABLE`) - If `false`, attempts to delete the property,
/// change the property to be an `accessor property`, or change its attributes (other than `[[Value]]`,
/// or changing `[[Writable]]` to `false`) will fail.
#[derive(Finalize)]
pub struct Attribute: u8 {
/// The `Writable` attribute decides whether the value associated with the property can be changed or not, from its initial value.
const WRITABLE = 0b0000_0001;
@ -38,15 +36,6 @@ bitflags! {
}
}
// We implement `Trace` manualy rather that wih derive, beacuse `rust-gc`,
// derive `Trace` does not allow `Copy` and `Trace` to be both implemented.
//
// SAFETY: The `Attribute` struct only contains an `u8`
// and therefore it should be safe to implement an empty trace.
unsafe impl Trace for Attribute {
unsafe_empty_trace!();
}
impl Attribute {
/// Clear all flags.
#[inline]

10
boa_engine/src/property/mod.rs

@ -16,7 +16,7 @@
//! [section]: https://tc39.es/ecma262/#sec-property-attributes
use crate::{JsString, JsSymbol, JsValue};
use boa_gc::{unsafe_empty_trace, Finalize, Trace};
use boa_gc::{Finalize, Trace};
use std::fmt;
mod attribute;
@ -488,7 +488,7 @@ impl From<PropertyDescriptorBuilder> for PropertyDescriptor {
/// - [ECMAScript reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-ispropertykey
#[derive(Trace, Finalize, PartialEq, Debug, Clone, Eq, Hash)]
#[derive(PartialEq, Debug, Clone, Eq, Hash)]
pub enum PropertyKey {
String(JsString),
Symbol(JsSymbol),
@ -673,13 +673,9 @@ impl PartialEq<&str> for PropertyKey {
}
}
#[derive(Debug, Clone, Copy, Finalize)]
#[derive(Debug, Clone, Copy)]
pub(crate) enum PropertyNameKind {
Key,
Value,
KeyAndValue,
}
unsafe impl Trace for PropertyNameKind {
unsafe_empty_trace!();
}

12
boa_engine/src/string.rs

@ -635,6 +635,12 @@ pub struct JsString {
_marker: PhantomData<Rc<str>>,
}
// Safety: JsString does not contain any objects which needs to be traced,
// so this is safe.
unsafe impl Trace for JsString {
unsafe_empty_trace!();
}
/// This struct uses a technique called tagged pointer to benefit from the fact that newly
/// allocated pointers are always word aligned on 64-bits platforms, making it impossible
/// to have a LSB equal to 1. More details about this technique on the article of Wikipedia
@ -942,12 +948,6 @@ impl JsString {
}
}
// Safety: [`JsString`] does not contain any objects which recquire trace,
// so this is safe.
unsafe impl Trace for JsString {
unsafe_empty_trace!();
}
impl Clone for JsString {
#[inline]
fn clone(&self) -> Self {

16
boa_engine/src/symbol.rs

@ -248,11 +248,17 @@ struct Inner {
}
/// This represents a JavaScript symbol primitive.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Finalize)]
pub struct JsSymbol {
inner: Rc<Inner>,
}
// Safety: JsSymbol does not contain any objects which needs to be traced,
// so this is safe.
unsafe impl Trace for JsSymbol {
unsafe_empty_trace!();
}
impl JsSymbol {
/// Create a new symbol.
#[inline]
@ -301,14 +307,6 @@ impl JsSymbol {
}
}
impl Finalize for JsSymbol {}
// Safety: `JsSymbol` does not contain any object that require trace,
// so this is safe.
unsafe impl Trace for JsSymbol {
unsafe_empty_trace!();
}
impl Display for JsSymbol {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

9
boa_engine/src/syntax/ast/constant.rs

@ -7,7 +7,6 @@
//! [spec]: https://tc39.es/ecma262/#sec-primary-expression-literals
//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Literals
use boa_gc::{unsafe_empty_trace, Finalize, Trace};
use boa_interner::{Interner, Sym, ToInternedString};
use num_bigint::BigInt;
#[cfg(feature = "deser")]
@ -24,7 +23,7 @@ use serde::{Deserialize, Serialize};
/// [spec]: https://tc39.es/ecma262/#sec-primary-expression-literals
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Literals
#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Finalize, PartialEq)]
#[derive(Clone, Debug, PartialEq)]
pub enum Const {
/// A string literal is zero or more characters enclosed in double (`"`) or single (`'`) quotation marks.
///
@ -112,12 +111,6 @@ pub enum Const {
Undefined,
}
// Safety: Const does not contain any objects which needs to be traced,
// so this is safe.
unsafe impl Trace for Const {
unsafe_empty_trace!();
}
impl From<Sym> for Const {
fn from(string: Sym) -> Self {
Self::String(string)

7
boa_engine/src/syntax/ast/node/identifier/mod.rs

@ -4,7 +4,6 @@ use crate::syntax::{
ast::{node::Node, Position},
parser::ParseError,
};
use boa_gc::{unsafe_empty_trace, Finalize, Trace};
use boa_interner::{Interner, Sym, ToInternedString};
#[cfg(feature = "deser")]
@ -27,7 +26,7 @@ use serde::{Deserialize, Serialize};
/// [mdn]: https://developer.mozilla.org/en-US/docs/Glossary/Identifier
#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "deser", serde(transparent))]
#[derive(Debug, Clone, Copy, Finalize, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Identifier {
ident: Sym,
}
@ -68,10 +67,6 @@ impl ToInternedString for Identifier {
}
}
unsafe impl Trace for Identifier {
unsafe_empty_trace!();
}
impl From<Sym> for Identifier {
fn from(sym: Sym) -> Self {
Self { ident: sym }

7
boa_engine/src/syntax/ast/node/iteration/break_node/mod.rs

@ -1,5 +1,4 @@
use crate::syntax::ast::Node;
use boa_gc::{unsafe_empty_trace, Finalize, Trace};
use boa_interner::{Interner, Sym, ToInternedString};
#[cfg(feature = "deser")]
@ -23,7 +22,7 @@ mod tests;
/// [spec]: https://tc39.es/ecma262/#prod-BreakStatement
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/break
#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, Copy, Finalize, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Break {
label: Option<Sym>,
}
@ -45,10 +44,6 @@ impl Break {
}
}
unsafe impl Trace for Break {
unsafe_empty_trace!();
}
impl ToInternedString for Break {
fn to_interned_string(&self, interner: &Interner) -> String {
if let Some(label) = self.label {

43
boa_engine/src/syntax/ast/op.rs

@ -1,6 +1,5 @@
//! This module implements various structure for logic handling.
use boa_gc::{unsafe_empty_trace, Finalize, Trace};
use std::fmt::{Display, Formatter, Result};
#[cfg(feature = "deser")]
@ -14,7 +13,7 @@ use serde::{Deserialize, Serialize};
///
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Arithmetic
#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
#[derive(Clone, Copy, Debug, Finalize, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum NumOp {
/// The addition operator produces the sum of numeric operands or string concatenation.
///
@ -115,10 +114,6 @@ impl Display for NumOp {
}
}
unsafe impl Trace for NumOp {
unsafe_empty_trace!();
}
/// A unary operator is one that takes a single operand/argument and performs an operation.
///
/// A unary operation is an operation with only one operand. This operand comes either
@ -132,7 +127,7 @@ unsafe impl Trace for NumOp {
/// [spec]: https://tc39.es/ecma262/#prod-UnaryExpression
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Unary
#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
#[derive(Clone, Copy, Debug, Finalize, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum UnaryOp {
/// The increment operator increments (adds one to) its operand and returns a value.
///
@ -334,10 +329,6 @@ impl Display for UnaryOp {
}
}
unsafe impl Trace for UnaryOp {
unsafe_empty_trace!();
}
/// A bitwise operator is an operator used to perform bitwise operations
/// on bit patterns or binary numerals that involve the manipulation of individual bits.
///
@ -346,7 +337,7 @@ unsafe impl Trace for UnaryOp {
///
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise
#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
#[derive(Clone, Copy, Debug, Finalize, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BitOp {
/// Performs the AND operation on each pair of bits. a AND b yields 1 only if both a and b are 1.
///
@ -452,10 +443,6 @@ impl Display for BitOp {
}
}
unsafe impl Trace for BitOp {
unsafe_empty_trace!();
}
/// A comparison operator compares its operands and returns a logical value based on whether the comparison is true.
///
/// The operands can be numerical, string, logical, or object values. Strings are compared based on standard
@ -472,7 +459,7 @@ unsafe impl Trace for BitOp {
/// [spec]: tc39.es/ecma262/#sec-testing-and-comparison-operations
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Comparison
#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
#[derive(Clone, Copy, Debug, Finalize, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum CompOp {
/// The equality operator converts the operands if they are not of the same type, then applies
/// strict comparison.
@ -652,10 +639,6 @@ impl Display for CompOp {
}
}
unsafe impl Trace for CompOp {
unsafe_empty_trace!();
}
/// Logical operators are typically used with Boolean (logical) values; when they are, they return a Boolean value.
///
/// However, the `&&` and `||` operators actually return the value of one of the specified operands,
@ -668,7 +651,7 @@ unsafe impl Trace for CompOp {
/// [spec]: https://tc39.es/ecma262/#sec-binary-logical-operators
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Logical
#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
#[derive(Clone, Copy, Debug, Finalize, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum LogOp {
/// The logical AND operator returns the value of the first operand if it can be coerced into `false`;
/// otherwise, it returns the second operand.
@ -727,13 +710,9 @@ impl Display for LogOp {
}
}
unsafe impl Trace for LogOp {
unsafe_empty_trace!();
}
/// This represents a binary operation between two values.
#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
#[derive(Clone, Copy, Debug, Finalize, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BinOp {
/// Numeric operation.
///
@ -814,10 +793,6 @@ impl Display for BinOp {
}
}
unsafe impl Trace for BinOp {
unsafe_empty_trace!();
}
/// An assignment operator assigns a value to its left operand based on the value of its right operand.
///
/// The simple assignment operator is equal (`=`), which assigns the value of its right operand to its
@ -832,7 +807,7 @@ unsafe impl Trace for BinOp {
/// [spec]: https://tc39.es/ecma262/#prod-AssignmentOperator
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment
#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
#[derive(Clone, Copy, Debug, Finalize, PartialEq, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum AssignOp {
/// The addition assignment operator adds the value of the right operand to a variable and assigns the result to the variable.
///
@ -1020,10 +995,6 @@ pub enum AssignOp {
Coalesce,
}
unsafe impl Trace for AssignOp {
unsafe_empty_trace!();
}
impl AssignOp {
/// Retrieves the operation as a static string.
fn as_str(self) -> &'static str {

12
boa_engine/src/value/mod.rs

@ -15,7 +15,7 @@ use crate::{
symbol::{JsSymbol, WellKnownSymbols},
Context, JsBigInt, JsResult, JsString,
};
use boa_gc::{Finalize, Trace};
use boa_gc::{custom_trace, Finalize, Trace};
use boa_profiler::Profiler;
use num_bigint::BigInt;
use num_integer::Integer;
@ -56,7 +56,7 @@ static TWO_E_63: Lazy<BigInt> = Lazy::new(|| {
});
/// A Javascript value
#[derive(Trace, Finalize, Debug, Clone)]
#[derive(Finalize, Debug, Clone)]
pub enum JsValue {
/// `null` - A null value, for when a value doesn't exist.
Null,
@ -78,6 +78,14 @@ pub enum JsValue {
Symbol(JsSymbol),
}
unsafe impl Trace for JsValue {
custom_trace! {this, {
if let Self::Object(o) = this {
mark(o);
}
}}
}
impl JsValue {
/// Create a new [`JsValue`].
#[inline]

Loading…
Cancel
Save