From 4584be7c53df3fdf53f973d0b091e2c98a19f445 Mon Sep 17 00:00:00 2001 From: Iban Eguia Moraza Date: Wed, 23 Feb 2022 19:04:38 +0100 Subject: [PATCH] Changes to allow cheap cloning of JsValues, still maintaining `StatementList` as `Send` --- boa_engine/src/bigint.rs | 40 +++++++++++++++++---------- boa_engine/src/bytecompiler.rs | 2 +- boa_engine/src/string.rs | 3 +- boa_engine/src/symbol.rs | 7 +++-- boa_engine/src/syntax/ast/constant.rs | 25 ++++++++++++----- boa_engine/src/syntax/lexer/number.rs | 6 ++-- boa_engine/src/syntax/lexer/token.rs | 10 +++---- 7 files changed, 59 insertions(+), 34 deletions(-) diff --git a/boa_engine/src/bigint.rs b/boa_engine/src/bigint.rs index 9d402ffc9f9..6c21e933057 100644 --- a/boa_engine/src/bigint.rs +++ b/boa_engine/src/bigint.rs @@ -5,6 +5,7 @@ use boa_gc::{unsafe_empty_trace, Finalize, Trace}; use num_integer::Integer; use num_traits::pow::Pow; use num_traits::{FromPrimitive, One, ToPrimitive, Zero}; +use std::rc::Rc; use std::{ fmt::{self, Display}, ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Rem, Shl, Shr, Sub}, @@ -20,7 +21,7 @@ use serde::{Deserialize, Serialize}; #[cfg_attr(feature = "deser", derive(Serialize, Deserialize))] #[derive(Debug, Finalize, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct JsBigInt { - inner: Box, + inner: Rc, } // Safety: BigInt does not contain any objects which needs to be traced, @@ -40,7 +41,7 @@ impl JsBigInt { #[inline] pub fn zero() -> Self { Self { - inner: Box::new(RawBigInt::zero()), + inner: Rc::new(RawBigInt::zero()), } } @@ -54,7 +55,7 @@ impl JsBigInt { #[inline] pub fn one() -> Self { Self { - inner: Box::new(RawBigInt::one()), + inner: Rc::new(RawBigInt::one()), } } @@ -82,7 +83,7 @@ impl JsBigInt { #[inline] pub fn from_string_radix(buf: &str, radix: u32) -> Option { Some(Self { - inner: Box::new(RawBigInt::parse_bytes(buf.as_bytes(), radix)?), + inner: Rc::new(RawBigInt::parse_bytes(buf.as_bytes(), radix)?), }) } @@ -284,7 +285,16 @@ impl From for JsBigInt { #[inline] fn from(value: RawBigInt) -> Self { Self { - inner: Box::new(value), + inner: Rc::new(value), + } + } +} + +impl From> for JsBigInt { + #[inline] + fn from(value: Box) -> Self { + Self { + inner: value.into(), } } } @@ -293,7 +303,7 @@ impl From for JsBigInt { #[inline] fn from(value: i8) -> Self { Self { - inner: Box::new(RawBigInt::from(value)), + inner: Rc::new(RawBigInt::from(value)), } } } @@ -302,7 +312,7 @@ impl From for JsBigInt { #[inline] fn from(value: u8) -> Self { Self { - inner: Box::new(RawBigInt::from(value)), + inner: Rc::new(RawBigInt::from(value)), } } } @@ -311,7 +321,7 @@ impl From for JsBigInt { #[inline] fn from(value: i16) -> Self { Self { - inner: Box::new(RawBigInt::from(value)), + inner: Rc::new(RawBigInt::from(value)), } } } @@ -320,7 +330,7 @@ impl From for JsBigInt { #[inline] fn from(value: u16) -> Self { Self { - inner: Box::new(RawBigInt::from(value)), + inner: Rc::new(RawBigInt::from(value)), } } } @@ -329,7 +339,7 @@ impl From for JsBigInt { #[inline] fn from(value: i32) -> Self { Self { - inner: Box::new(RawBigInt::from(value)), + inner: Rc::new(RawBigInt::from(value)), } } } @@ -338,7 +348,7 @@ impl From for JsBigInt { #[inline] fn from(value: u32) -> Self { Self { - inner: Box::new(RawBigInt::from(value)), + inner: Rc::new(RawBigInt::from(value)), } } } @@ -347,7 +357,7 @@ impl From for JsBigInt { #[inline] fn from(value: i64) -> Self { Self { - inner: Box::new(RawBigInt::from(value)), + inner: Rc::new(RawBigInt::from(value)), } } } @@ -356,7 +366,7 @@ impl From for JsBigInt { #[inline] fn from(value: u64) -> Self { Self { - inner: Box::new(RawBigInt::from(value)), + inner: Rc::new(RawBigInt::from(value)), } } } @@ -365,7 +375,7 @@ impl From for JsBigInt { #[inline] fn from(value: isize) -> Self { Self { - inner: Box::new(RawBigInt::from(value)), + inner: Rc::new(RawBigInt::from(value)), } } } @@ -374,7 +384,7 @@ impl From for JsBigInt { #[inline] fn from(value: usize) -> Self { Self { - inner: Box::new(RawBigInt::from(value)), + inner: Rc::new(RawBigInt::from(value)), } } } diff --git a/boa_engine/src/bytecompiler.rs b/boa_engine/src/bytecompiler.rs index 1f4550a98da..6f8b70749ff 100644 --- a/boa_engine/src/bytecompiler.rs +++ b/boa_engine/src/bytecompiler.rs @@ -554,7 +554,7 @@ impl<'b> ByteCompiler<'b> { )), Const::Int(v) => self.emit_push_integer(*v), Const::Num(v) => self.emit_push_rational(*v), - Const::BigInt(v) => self.emit_push_literal(Literal::BigInt(v.clone())), + Const::BigInt(v) => self.emit_push_literal(Literal::BigInt(v.clone().into())), Const::Bool(true) => self.emit(Opcode::PushTrue, &[]), Const::Bool(false) => self.emit(Opcode::PushFalse, &[]), Const::Null => self.emit(Opcode::PushNull, &[]), diff --git a/boa_engine/src/string.rs b/boa_engine/src/string.rs index c174c9e7ab4..53659fbc9e1 100644 --- a/boa_engine/src/string.rs +++ b/boa_engine/src/string.rs @@ -9,6 +9,7 @@ use std::{ marker::PhantomData, ops::Deref, ptr::{copy_nonoverlapping, NonNull}, + rc::Rc, }; const CONSTANTS_ARRAY: [&str; 127] = [ @@ -314,7 +315,7 @@ impl Inner { #[derive(Finalize)] pub struct JsString { inner: NonNull, - _marker: PhantomData>, + _marker: PhantomData>, } impl Default for JsString { diff --git a/boa_engine/src/symbol.rs b/boa_engine/src/symbol.rs index c1a010fe221..b35e18a2bc0 100644 --- a/boa_engine/src/symbol.rs +++ b/boa_engine/src/symbol.rs @@ -21,6 +21,7 @@ use std::{ cell::Cell, fmt::{self, Display}, hash::{Hash, Hasher}, + rc::Rc, }; /// A structure that contains the JavaScript well known symbols. @@ -249,7 +250,7 @@ struct Inner { /// This represents a JavaScript symbol primitive. #[derive(Debug, Clone)] pub struct JsSymbol { - inner: Box, + inner: Rc, } impl JsSymbol { @@ -263,7 +264,7 @@ impl JsSymbol { }); Self { - inner: Box::new(Inner { hash, description }), + inner: Rc::new(Inner { hash, description }), } } @@ -271,7 +272,7 @@ impl JsSymbol { #[inline] fn with_hash(hash: u64, description: Option) -> Self { Self { - inner: Box::new(Inner { hash, description }), + inner: Rc::new(Inner { hash, description }), } } diff --git a/boa_engine/src/syntax/ast/constant.rs b/boa_engine/src/syntax/ast/constant.rs index b1672492e7c..4fc1f3d20aa 100644 --- a/boa_engine/src/syntax/ast/constant.rs +++ b/boa_engine/src/syntax/ast/constant.rs @@ -7,10 +7,9 @@ //! [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 crate::JsBigInt; -use boa_gc::{Finalize, Trace}; +use boa_gc::{unsafe_empty_trace, Finalize, Trace}; use boa_interner::{Interner, Sym, ToInternedString}; - +use num_bigint::BigInt; #[cfg(feature = "deser")] use serde::{Deserialize, Serialize}; @@ -25,7 +24,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, Trace, Finalize, PartialEq)] +#[derive(Clone, Debug, Finalize, PartialEq)] pub enum Const { /// A string literal is zero or more characters enclosed in double (`"`) or single (`'`) quotation marks. /// @@ -74,7 +73,7 @@ pub enum Const { /// /// [spec]: https://tc39.es/ecma262/#sec-terms-and-definitions-bigint-value /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Numeric_literals - BigInt(JsBigInt), + BigInt(Box), /// The Boolean type has two literal values: `true` and `false`. /// @@ -113,6 +112,12 @@ 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 for Const { fn from(string: Sym) -> Self { Self::String(string) @@ -131,8 +136,14 @@ impl From for Const { } } -impl From for Const { - fn from(i: JsBigInt) -> Self { +impl From for Const { + fn from(i: BigInt) -> Self { + Self::BigInt(Box::new(i)) + } +} + +impl From> for Const { + fn from(i: Box) -> Self { Self::BigInt(i) } } diff --git a/boa_engine/src/syntax/lexer/number.rs b/boa_engine/src/syntax/lexer/number.rs index ff4171abb4e..540cf6e2f8a 100644 --- a/boa_engine/src/syntax/lexer/number.rs +++ b/boa_engine/src/syntax/lexer/number.rs @@ -9,6 +9,8 @@ use crate::{ }; use boa_interner::Interner; use boa_profiler::Profiler; +use num_bigint::BigInt; +use num_traits::Zero; use std::{io::Read, str}; /// Number literal lexing. @@ -251,7 +253,7 @@ impl Tokenizer for NumberLiteral { // DecimalBigIntegerLiteral '0n' return Ok(Token::new( - TokenKind::NumericLiteral(Numeric::BigInt(0.into())), + TokenKind::NumericLiteral(Numeric::BigInt(BigInt::zero().into())), Span::new(start_pos, cursor.pos()), )); } @@ -380,7 +382,7 @@ impl Tokenizer for NumberLiteral { let num = match kind { NumericKind::BigInt(base) => { Numeric::BigInt( - JsBigInt::from_string_radix(num_str, base).expect("Could not convert to BigInt") + BigInt::parse_bytes(num_str.as_bytes(), base).expect("Could not convert to BigInt").into() ) } NumericKind::Rational /* base: 10 */ => { diff --git a/boa_engine/src/syntax/lexer/token.rs b/boa_engine/src/syntax/lexer/token.rs index a394dc19d64..9e9bc51ebae 100644 --- a/boa_engine/src/syntax/lexer/token.rs +++ b/boa_engine/src/syntax/lexer/token.rs @@ -8,10 +8,10 @@ use crate::{ syntax::ast::{Keyword, Punctuator, Span}, syntax::lexer::template::TemplateString, - JsBigInt, }; use boa_interner::{Interner, Sym}; +use num_bigint::BigInt; #[cfg(feature = "deser")] use serde::{Deserialize, Serialize}; @@ -71,7 +71,7 @@ pub enum Numeric { Integer(i32), // A BigInt - BigInt(JsBigInt), + BigInt(Box), } impl From for Numeric { @@ -88,10 +88,10 @@ impl From for Numeric { } } -impl From for Numeric { +impl From for Numeric { #[inline] - fn from(n: JsBigInt) -> Self { - Self::BigInt(n) + fn from(n: BigInt) -> Self { + Self::BigInt(Box::new(n)) } }