Skip to content

Commit

Permalink
Value refactor
Browse files Browse the repository at this point in the history
 - Refactor `String` => `Rc<str>`
 - Refactor `Symbol` => `Rc<Symbol>`
 - Refactor `BigInt` => `RcBigInt`
 - Changed function signature, from `&mut Value` to `&Value`
 - Removed `Interpreter::value_to_rust_number()
 - Abstracted `Gc<GcCell<Object>>` to `GcObject`
 - Removed unnecessary `Box`s in global environment
  • Loading branch information
HalidOdat committed Jun 19, 2020
1 parent a7cffe3 commit 1d179d5
Show file tree
Hide file tree
Showing 36 changed files with 872 additions and 796 deletions.
113 changes: 41 additions & 72 deletions boa/src/builtins/array/mod.rs

Large diffs are not rendered by default.

43 changes: 15 additions & 28 deletions boa/src/builtins/bigint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
builtins::{
function::{make_builtin_fn, make_constructor_fn},
object::ObjectData,
value::{ResultValue, Value, ValueData},
value::{RcBigInt, ResultValue, Value},
},
exec::Interpreter,
BoaProfiler,
Expand Down Expand Up @@ -61,15 +61,15 @@ impl BigInt {
///
/// [spec]: https://tc39.es/ecma262/#sec-thisbigintvalue
#[inline]
fn this_bigint_value(value: &Value, ctx: &mut Interpreter) -> Result<Self, Value> {
match value.data() {
fn this_bigint_value(value: &Value, ctx: &mut Interpreter) -> Result<RcBigInt, Value> {
match value {
// 1. If Type(value) is BigInt, return value.
ValueData::BigInt(ref bigint) => return Ok(bigint.clone()),
Value::BigInt(ref bigint) => return Ok(bigint.clone()),

// 2. If Type(value) is Object and value has a [[BigIntData]] internal slot, then
// a. Assert: Type(value.[[BigIntData]]) is BigInt.
// b. Return value.[[BigIntData]].
ValueData::Object(ref object) => {
Value::Object(ref object) => {
if let ObjectData::BigInt(ref bigint) = object.borrow().data {
return Ok(bigint.clone());
}
Expand All @@ -91,10 +91,10 @@ impl BigInt {
///
/// [spec]: https://tc39.es/ecma262/#sec-bigint-objects
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/BigInt
pub(crate) fn make_bigint(_: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
pub(crate) fn make_bigint(_: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let data = match args.get(0) {
Some(ref value) => ctx.to_bigint(value)?,
None => Self::from(0),
None => RcBigInt::from(Self::from(0)),
};
Ok(Value::from(data))
}
Expand All @@ -110,11 +110,7 @@ impl BigInt {
/// [spec]: https://tc39.es/ecma262/#sec-bigint.prototype.tostring
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/toString
#[allow(clippy::wrong_self_convention)]
pub(crate) fn to_string(
this: &mut Value,
args: &[Value],
ctx: &mut Interpreter,
) -> ResultValue {
pub(crate) fn to_string(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let radix = if !args.is_empty() {
args[0].to_integer()
} else {
Expand All @@ -139,11 +135,7 @@ impl BigInt {
///
/// [spec]: https://tc39.es/ecma262/#sec-bigint.prototype.valueof
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/valueOf
pub(crate) fn value_of(
this: &mut Value,
_args: &[Value],
ctx: &mut Interpreter,
) -> ResultValue {
pub(crate) fn value_of(this: &Value, _args: &[Value], ctx: &mut Interpreter) -> ResultValue {
Ok(Value::from(Self::this_bigint_value(this, ctx)?))
}

Expand All @@ -154,11 +146,7 @@ impl BigInt {
/// [spec]: https://tc39.es/ecma262/#sec-bigint.asintn
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asIntN
#[allow(clippy::wrong_self_convention)]
pub(crate) fn as_int_n(
_this: &mut Value,
args: &[Value],
ctx: &mut Interpreter,
) -> ResultValue {
pub(crate) fn as_int_n(_this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let (modulo, bits) = Self::calculate_as_uint_n(args, ctx)?;

if bits > 0 && modulo >= BigInt::from(2).pow(&BigInt::from(bits as i64 - 1)) {
Expand All @@ -177,11 +165,7 @@ impl BigInt {
/// [spec]: https://tc39.es/ecma262/#sec-bigint.asuintn
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt/asUintN
#[allow(clippy::wrong_self_convention)]
pub(crate) fn as_uint_n(
_this: &mut Value,
args: &[Value],
ctx: &mut Interpreter,
) -> ResultValue {
pub(crate) fn as_uint_n(_this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let (modulo, _) = Self::calculate_as_uint_n(args, ctx)?;

Ok(Value::from(modulo))
Expand All @@ -206,7 +190,10 @@ impl BigInt {
let bigint = ctx.to_bigint(bigint_arg)?;

Ok((
bigint.mod_floor(&BigInt::from(2).pow(&BigInt::from(bits as i64))),
bigint
.as_inner()
.clone()
.mod_floor(&BigInt::from(2).pow(&BigInt::from(bits as i64))),
bits,
))
}
Expand Down
14 changes: 7 additions & 7 deletions boa/src/builtins/boolean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use super::function::{make_builtin_fn, make_constructor_fn};
use crate::{
builtins::{
object::ObjectData,
value::{ResultValue, Value, ValueData},
value::{ResultValue, Value},
},
exec::Interpreter,
BoaProfiler,
Expand All @@ -40,9 +40,9 @@ impl Boolean {
///
/// [spec]: https://tc39.es/ecma262/#sec-thisbooleanvalue
fn this_boolean_value(value: &Value, ctx: &mut Interpreter) -> Result<bool, Value> {
match value.data() {
ValueData::Boolean(boolean) => return Ok(*boolean),
ValueData::Object(ref object) => {
match value {
Value::Boolean(boolean) => return Ok(*boolean),
Value::Object(ref object) => {
let object = object.borrow();
if let Some(boolean) = object.as_boolean() {
return Ok(boolean);
Expand All @@ -58,7 +58,7 @@ impl Boolean {
///
/// `[[Call]]` Creates a new boolean primitive
pub(crate) fn construct_boolean(
this: &mut Value,
this: &Value,
args: &[Value],
_: &mut Interpreter,
) -> ResultValue {
Expand All @@ -78,7 +78,7 @@ impl Boolean {
/// [spec]: https://tc39.es/ecma262/#sec-boolean-object
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean/toString
#[allow(clippy::wrong_self_convention)]
pub(crate) fn to_string(this: &mut Value, _: &[Value], ctx: &mut Interpreter) -> ResultValue {
pub(crate) fn to_string(this: &Value, _: &[Value], ctx: &mut Interpreter) -> ResultValue {
let boolean = Self::this_boolean_value(this, ctx)?;
Ok(Value::from(boolean.to_string()))
}
Expand All @@ -92,7 +92,7 @@ impl Boolean {
/// [spec]: https://tc39.es/ecma262/#sec-boolean.prototype.valueof
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean/valueOf
#[inline]
pub(crate) fn value_of(this: &mut Value, _: &[Value], ctx: &mut Interpreter) -> ResultValue {
pub(crate) fn value_of(this: &Value, _: &[Value], ctx: &mut Interpreter) -> ResultValue {
Ok(Value::from(Self::this_boolean_value(this, ctx)?))
}

Expand Down
52 changes: 26 additions & 26 deletions boa/src/builtins/console/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::{
builtins::{
function::make_builtin_fn,
object::InternalState,
value::{display_obj, ResultValue, Value},
value::{display_obj, RcString, ResultValue, Value},
},
exec::Interpreter,
BoaProfiler,
Expand All @@ -31,8 +31,8 @@ use std::time::SystemTime;
/// This is the internal console object state.
#[derive(Debug, Default)]
pub struct ConsoleState {
count_map: FxHashMap<String, u32>,
timer_map: FxHashMap<String, u128>,
count_map: FxHashMap<RcString, u32>,
timer_map: FxHashMap<RcString, u128>,
groups: Vec<String>,
}

Expand Down Expand Up @@ -74,7 +74,7 @@ pub fn formatter(data: &[Value], ctx: &mut Interpreter) -> Result<String, Value>
let target = ctx.to_string(&data.get(0).cloned().unwrap_or_default())?;
match data.len() {
0 => Ok(String::new()),
1 => Ok(target),
1 => Ok(target.to_string()),
_ => {
let mut formatted = String::new();
let mut arg_index = 1;
Expand Down Expand Up @@ -141,7 +141,7 @@ pub fn formatter(data: &[Value], ctx: &mut Interpreter) -> Result<String, Value>
///
/// [spec]: https://console.spec.whatwg.org/#assert
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/assert
pub fn assert(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
pub fn assert(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let assertion = get_arg_at_index::<bool>(args, 0).unwrap_or_default();

if !assertion {
Expand Down Expand Up @@ -175,7 +175,7 @@ pub fn assert(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> Result
///
/// [spec]: https://console.spec.whatwg.org/#clear
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/clear
pub fn clear(this: &mut Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
pub fn clear(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
this.with_internal_state_mut(|state: &mut ConsoleState| {
state.groups.clear();
});
Expand All @@ -193,7 +193,7 @@ pub fn clear(this: &mut Value, _: &[Value], _: &mut Interpreter) -> ResultValue
///
/// [spec]: https://console.spec.whatwg.org/#debug
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/debug
pub fn debug(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
pub fn debug(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
this.with_internal_state_ref::<_, Result<(), Value>, _>(|state| {
logger(LogMessage::Log(formatter(args, ctx)?), state);
Ok(())
Expand All @@ -211,7 +211,7 @@ pub fn debug(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultV
///
/// [spec]: https://console.spec.whatwg.org/#error
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/error
pub fn error(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
pub fn error(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
this.with_internal_state_ref::<_, Result<(), Value>, _>(|state| {
logger(LogMessage::Error(formatter(args, ctx)?), state);
Ok(())
Expand All @@ -229,7 +229,7 @@ pub fn error(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultV
///
/// [spec]: https://console.spec.whatwg.org/#info
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/info
pub fn info(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
pub fn info(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
this.with_internal_state_ref::<_, Result<(), Value>, _>(|state| {
logger(LogMessage::Info(formatter(args, ctx)?), state);
Ok(())
Expand All @@ -247,7 +247,7 @@ pub fn info(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultVa
///
/// [spec]: https://console.spec.whatwg.org/#log
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/log
pub fn log(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
pub fn log(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
this.with_internal_state_ref::<_, Result<(), Value>, _>(|state| {
logger(LogMessage::Log(formatter(args, ctx)?), state);
Ok(())
Expand All @@ -265,7 +265,7 @@ pub fn log(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultVal
///
/// [spec]: https://console.spec.whatwg.org/#trace
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/trace
pub fn trace(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
pub fn trace(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
if !args.is_empty() {
this.with_internal_state_ref::<_, Result<(), Value>, _>(|state| {
logger(LogMessage::Log(formatter(args, ctx)?), state);
Expand Down Expand Up @@ -294,7 +294,7 @@ pub fn trace(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultV
///
/// [spec]: https://console.spec.whatwg.org/#warn
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/warn
pub fn warn(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
pub fn warn(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
this.with_internal_state_ref::<_, Result<(), Value>, _>(|state| {
logger(LogMessage::Warn(formatter(args, ctx)?), state);
Ok(())
Expand All @@ -312,10 +312,10 @@ pub fn warn(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultVa
///
/// [spec]: https://console.spec.whatwg.org/#count
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/count
pub fn count(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
pub fn count(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let label = match args.get(0) {
Some(value) => ctx.to_string(value)?,
None => "default".to_owned(),
None => "default".into(),
};

this.with_internal_state_mut(|state: &mut ConsoleState| {
Expand All @@ -339,10 +339,10 @@ pub fn count(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultV
///
/// [spec]: https://console.spec.whatwg.org/#countreset
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/countReset
pub fn count_reset(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
pub fn count_reset(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let label = match args.get(0) {
Some(value) => ctx.to_string(value)?,
None => "default".to_owned(),
None => "default".into(),
};

this.with_internal_state_mut(|state: &mut ConsoleState| {
Expand Down Expand Up @@ -372,10 +372,10 @@ fn system_time_in_ms() -> u128 {
///
/// [spec]: https://console.spec.whatwg.org/#time
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/time
pub fn time(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
pub fn time(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let label = match args.get(0) {
Some(value) => ctx.to_string(value)?,
None => "default".to_owned(),
None => "default".into(),
};

this.with_internal_state_mut(|state: &mut ConsoleState| {
Expand Down Expand Up @@ -403,10 +403,10 @@ pub fn time(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultVa
///
/// [spec]: https://console.spec.whatwg.org/#timelog
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/timeLog
pub fn time_log(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
pub fn time_log(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let label = match args.get(0) {
Some(value) => ctx.to_string(value)?,
None => "default".to_owned(),
None => "default".into(),
};

this.with_internal_state_mut(|state: &mut ConsoleState| {
Expand Down Expand Up @@ -438,14 +438,14 @@ pub fn time_log(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> Resu
///
/// [spec]: https://console.spec.whatwg.org/#timeend
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/timeEnd
pub fn time_end(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
pub fn time_end(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let label = match args.get(0) {
Some(value) => ctx.to_string(value)?,
None => "default".to_owned(),
None => "default".into(),
};

this.with_internal_state_mut(|state: &mut ConsoleState| {
if let Some(t) = state.timer_map.remove(&label) {
if let Some(t) = state.timer_map.remove(label.as_str()) {
let time = system_time_in_ms();
logger(
LogMessage::Info(format!("{}: {} ms - timer removed", label, time - t)),
Expand All @@ -472,7 +472,7 @@ pub fn time_end(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> Resu
///
/// [spec]: https://console.spec.whatwg.org/#group
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/group
pub fn group(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
pub fn group(this: &Value, args: &[Value], ctx: &mut Interpreter) -> ResultValue {
let group_label = formatter(args, ctx)?;

this.with_internal_state_mut(|state: &mut ConsoleState| {
Expand All @@ -493,7 +493,7 @@ pub fn group(this: &mut Value, args: &[Value], ctx: &mut Interpreter) -> ResultV
///
/// [spec]: https://console.spec.whatwg.org/#groupend
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/groupEnd
pub fn group_end(this: &mut Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
pub fn group_end(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
this.with_internal_state_mut(|state: &mut ConsoleState| {
state.groups.pop();
});
Expand All @@ -511,7 +511,7 @@ pub fn group_end(this: &mut Value, _: &[Value], _: &mut Interpreter) -> ResultVa
///
/// [spec]: https://console.spec.whatwg.org/#dir
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/console/dir
pub fn dir(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
pub fn dir(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
this.with_internal_state_mut(|state: &mut ConsoleState| {
let undefined = Value::undefined();
logger(
Expand Down
4 changes: 2 additions & 2 deletions boa/src/builtins/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl Error {
pub(crate) const LENGTH: usize = 1;

/// Create a new error object.
pub(crate) fn make_error(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
pub(crate) fn make_error(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
if !args.is_empty() {
this.set_field(
"message",
Expand Down Expand Up @@ -71,7 +71,7 @@ impl Error {
/// [spec]: https://tc39.es/ecma262/#sec-error.prototype.tostring
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/toString
#[allow(clippy::wrong_self_convention)]
pub(crate) fn to_string(this: &mut Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
pub(crate) fn to_string(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
let name = this.get_field("name");
let message = this.get_field("message");
Ok(Value::from(format!("{}: {}", name, message)))
Expand Down
4 changes: 2 additions & 2 deletions boa/src/builtins/error/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl RangeError {
pub(crate) const LENGTH: usize = 1;

/// Create a new error object.
pub(crate) fn make_error(this: &mut Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
pub(crate) fn make_error(this: &Value, args: &[Value], _: &mut Interpreter) -> ResultValue {
if !args.is_empty() {
this.set_field(
"message",
Expand Down Expand Up @@ -60,7 +60,7 @@ impl RangeError {
/// [spec]: https://tc39.es/ecma262/#sec-error.prototype.tostring
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/toString
#[allow(clippy::wrong_self_convention)]
pub(crate) fn to_string(this: &mut Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
pub(crate) fn to_string(this: &Value, _: &[Value], _: &mut Interpreter) -> ResultValue {
let name = this.get_field("name");
let message = this.get_field("message");
Ok(Value::from(format!("{}: {}", name, message)))
Expand Down
Loading

0 comments on commit 1d179d5

Please sign in to comment.