Skip to content

Commit

Permalink
Merge 0b39351 into 6ff36fb
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat authored Mar 7, 2022
2 parents 6ff36fb + 0b39351 commit ec8fdef
Show file tree
Hide file tree
Showing 56 changed files with 1,530 additions and 787 deletions.
2 changes: 1 addition & 1 deletion boa_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ struct Opt {
)]
dump_ast: Option<Option<DumpFormat>>,

/// Dump the AST to stdout with the given format.
/// Dump the compiled bytecode and trace the execution stack
#[structopt(long = "trace", short = "t")]
trace: bool,

Expand Down
13 changes: 12 additions & 1 deletion boa_engine/src/bigint.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
//! This module implements the JavaScript bigint primitive rust type.
use crate::{builtins::Number, Context, JsValue};
use crate::{builtins::Number, value::PointerType, 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::{
fmt::{self, Display},
mem::{self, ManuallyDrop},
ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Rem, Shl, Shr, Sub},
rc::Rc,
};
Expand All @@ -23,6 +24,16 @@ pub struct JsBigInt {
inner: Rc<RawBigInt>,
}

unsafe impl PointerType for JsBigInt {
unsafe fn from_void_ptr(ptr: *mut ()) -> ManuallyDrop<Self> {
ManuallyDrop::new(mem::transmute(ptr))
}

unsafe fn into_void_ptr(bigint: ManuallyDrop<Self>) -> *mut () {
mem::transmute(bigint)
}
}

// Safety: BigInt does not contain any objects which needs to be traced,
// so this is safe.
unsafe impl Trace for JsBigInt {
Expand Down
3 changes: 2 additions & 1 deletion boa_engine/src/builtins/array/array_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ impl ArrayIterator {
///
/// [spec]: https://tc39.es/ecma262/#sec-%arrayiteratorprototype%.next
pub(crate) fn next(this: &JsValue, _: &[JsValue], context: &mut Context) -> JsResult<JsValue> {
let mut array_iterator = this.as_object().map(JsObject::borrow_mut);
let array_iterator = this.as_object();
let mut array_iterator = array_iterator.as_deref().map(JsObject::borrow_mut);
let array_iterator = array_iterator
.as_mut()
.and_then(|obj| obj.as_array_iterator_mut())
Expand Down
17 changes: 9 additions & 8 deletions boa_engine/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use crate::{
},
property::{Attribute, PropertyDescriptor, PropertyNameKind},
symbol::WellKnownSymbols,
value::{IntegerOrInfinity, JsValue},
value::{IntegerOrInfinity, JsValue, JsVariant},
Context, JsResult, JsString,
};
use std::cmp::{max, min, Ordering};
Expand Down Expand Up @@ -413,6 +413,7 @@ impl Array {
Some(constructor) => constructor
.construct(&[len.into()], this, context)?
.as_object()
.as_deref()
.cloned()
.ok_or_else(|| {
context.construct_type_error("object constructor didn't return an object")
Expand Down Expand Up @@ -1534,7 +1535,7 @@ impl Array {
source_len as u64,
0,
1,
Some(mapper_function),
Some(&mapper_function),
args.get_or_undefined(1),
context,
)?;
Expand Down Expand Up @@ -1624,7 +1625,7 @@ impl Array {
// 4. Set targetIndex to ? FlattenIntoArray(target, element, elementLen, targetIndex, newDepth)
target_index = Self::flatten_into_array(
target,
element,
&element,
element_len as u64,
target_index,
new_depth,
Expand Down Expand Up @@ -2161,9 +2162,9 @@ impl Array {
context: &mut Context,
) -> JsResult<JsValue> {
// 1. If comparefn is not undefined and IsCallable(comparefn) is false, throw a TypeError exception.
let comparefn = match args.get_or_undefined(0) {
JsValue::Object(ref obj) if obj.is_callable() => Some(obj),
JsValue::Undefined => None,
let comparefn = match args.get_or_undefined(0).variant() {
JsVariant::Object(obj) if obj.is_callable() => Some(obj),
JsVariant::Undefined => None,
_ => {
return context.throw_type_error(
"The comparison function must be either a function or undefined",
Expand All @@ -2190,11 +2191,11 @@ impl Array {
}

// 4. If comparefn is not undefined, then
if let Some(cmp) = comparefn {
if let Some(ref cmp) = comparefn {
let args = [x.clone(), y.clone()];
// a. Let v be ? ToNumber(? Call(comparefn, undefined, « x, y »)).
let v = cmp
.call(&JsValue::Undefined, &args, context)?
.call(&JsValue::undefined(), &args, context)?
.to_number(context)?;
// b. If v is NaN, return +0𝔽.
// c. Return v.
Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/builtins/array_buffer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ impl ArrayBuffer {
let new = ctor.construct(&[new_len.into()], &ctor.clone().into(), context)?;

// 17. Perform ? RequireInternalSlot(new, [[ArrayBufferData]]).
let new_obj = new.as_object().cloned().ok_or_else(|| {
let new_obj = new.as_object().as_deref().cloned().ok_or_else(|| {
context.construct_type_error("ArrayBuffer constructor returned non-object value")
})?;

Expand Down Expand Up @@ -322,7 +322,7 @@ impl ArrayBuffer {
obj.borrow_mut().data = ObjectData::array_buffer(Self {
array_buffer_data: Some(block),
array_buffer_byte_length: byte_length,
array_buffer_detach_key: JsValue::Undefined,
array_buffer_detach_key: JsValue::undefined(),
});

// 5. Return obj.
Expand Down
1 change: 1 addition & 0 deletions boa_engine/src/builtins/bigint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ impl BigInt {
value
// 1. If Type(value) is BigInt, return value.
.as_bigint()
.as_deref()
.cloned()
// 2. If Type(value) is Object and value has a [[BigIntData]] internal slot, then
// a. Assert: Type(value.[[BigIntData]]) is BigInt.
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/boolean/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,6 @@ fn instances_have_correct_proto_set() {

assert_eq!(
&*bool_instance.as_object().unwrap().prototype(),
&bool_prototype.as_object().cloned()
&bool_prototype.as_object().as_deref().cloned()
);
}
15 changes: 10 additions & 5 deletions boa_engine/src/builtins/dataview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ impl DataView {
) -> JsResult<JsValue> {
// 1. Let O be the this value.
// 2. Perform ? RequireInternalSlot(O, [[DataView]]).
let dataview = this.as_object().map(JsObject::borrow);
let dataview = this.as_object();
let dataview = dataview.as_deref().map(JsObject::borrow);
let dataview = dataview
.as_ref()
.and_then(|obj| obj.as_data_view())
Expand Down Expand Up @@ -223,7 +224,8 @@ impl DataView {
) -> JsResult<JsValue> {
// 1. Let O be the this value.
// 2. Perform ? RequireInternalSlot(O, [[DataView]]).
let dataview = this.as_object().map(JsObject::borrow);
let dataview = this.as_object();
let dataview = dataview.as_deref().map(JsObject::borrow);
let dataview = dataview
.as_ref()
.and_then(|obj| obj.as_data_view())
Expand Down Expand Up @@ -262,7 +264,8 @@ impl DataView {
) -> JsResult<JsValue> {
// 1. Let O be the this value.
// 2. Perform ? RequireInternalSlot(O, [[DataView]]).
let dataview = this.as_object().map(JsObject::borrow);
let dataview = this.as_object();
let dataview = dataview.as_deref().map(JsObject::borrow);
let dataview = dataview
.as_ref()
.and_then(|obj| obj.as_data_view())
Expand Down Expand Up @@ -302,7 +305,8 @@ impl DataView {
) -> JsResult<JsValue> {
// 1. Perform ? RequireInternalSlot(view, [[DataView]]).
// 2. Assert: view has a [[ViewedArrayBuffer]] internal slot.
let view = view.as_object().map(JsObject::borrow);
let view = view.as_object();
let view = view.as_deref().map(JsObject::borrow);
let view = view
.as_ref()
.and_then(|obj| obj.as_data_view())
Expand Down Expand Up @@ -661,7 +665,8 @@ impl DataView {
) -> JsResult<JsValue> {
// 1. Perform ? RequireInternalSlot(view, [[DataView]]).
// 2. Assert: view has a [[ViewedArrayBuffer]] internal slot.
let view = view.as_object().map(JsObject::borrow);
let view = view.as_object();
let view = view.as_deref().map(JsObject::borrow);
let view = view
.as_ref()
.and_then(|obj| obj.as_data_view())
Expand Down
35 changes: 18 additions & 17 deletions boa_engine/src/builtins/date/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
internal_methods::get_prototype_from_constructor, ConstructorBuilder, JsObject, ObjectData,
},
symbol::WellKnownSymbols,
value::{JsValue, PreferredType},
value::{JsValue, JsVariant, PreferredType},
Context, JsResult, JsString,
};
use boa_gc::{unsafe_empty_trace, Finalize, Trace};
Expand Down Expand Up @@ -393,24 +393,25 @@ impl Date {
context: &mut Context,
) -> JsResult<JsObject> {
let value = &args[0];
let tv = match this_time_value(value, context) {
Ok(dt) => dt.0,
_ => match value.to_primitive(context, PreferredType::Default)? {
JsValue::String(ref str) => match chrono::DateTime::parse_from_rfc3339(str) {
let tv = if let Ok(dt) = this_time_value(value, context) {
dt.0
} else {
let tv = value.to_primitive(context, PreferredType::Default)?;
if let JsVariant::String(ref str) = tv.variant() {
match chrono::DateTime::parse_from_rfc3339(str) {
Ok(dt) => Some(dt.naive_utc()),
_ => None,
},
tv => {
let tv = tv.to_number(context)?;
if tv.is_nan() {
None
} else {
let secs = (tv / 1_000f64) as i64;
let nano_secs = ((tv % 1_000f64) * 1_000_000f64) as u32;
NaiveDateTime::from_timestamp_opt(secs, nano_secs)
}
}
},
} else {
let tv = tv.to_number(context)?;
if tv.is_nan() {
None
} else {
let secs = (tv / 1_000f64) as i64;
let nano_secs = ((tv % 1_000f64) * 1_000_000f64) as u32;
NaiveDateTime::from_timestamp_opt(secs, nano_secs)
}
}
};

let tv = tv.filter(|time| Self::time_clip(time.timestamp_millis() as f64).is_some());
Expand Down Expand Up @@ -515,7 +516,7 @@ impl Date {

let hint = args.get_or_undefined(0);

let try_first = match hint.as_string().map(JsString::as_str) {
let try_first = match hint.as_string().as_deref().map(JsString::as_str) {
// 3. If hint is "string" or "default", then
// a. Let tryFirst be string.
Some("string" | "default") => PreferredType::String,
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/date/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn forward_dt_utc(context: &mut Context, src: &str) -> Option<NaiveDateTime> {
panic!("expected success")
};

if let JsValue::Object(ref date_time) = date_time {
if let Some(date_time) = date_time.as_object() {
if let Some(date_time) = date_time.borrow().as_date() {
date_time.0
} else {
Expand Down
1 change: 0 additions & 1 deletion boa_engine/src/builtins/function/arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,6 @@ impl Arguments {
// In the case of duplicate parameter names, the last one is bound as the environment binding.
//
// The following logic implements the steps 17-19 adjusted for our environment structure.

let mut bindings = FxHashMap::default();
let mut property_index = 0;
'outer: for formal in formals.parameters.iter() {
Expand Down
7 changes: 5 additions & 2 deletions boa_engine/src/builtins/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,9 @@ impl BuiltInFunctionObject {
// 9. If Type(targetName) is not String, set targetName to the empty String.
let target_name = target_name
.as_string()
.map_or(JsString::new(""), Clone::clone);
.as_deref()
.cloned()
.unwrap_or_default();

// 10. Perform SetFunctionName(F, targetName, "bound").
set_function_name(&f, &target_name.into(), Some("bound"), context);
Expand Down Expand Up @@ -435,7 +437,8 @@ impl BuiltInFunctionObject {

#[allow(clippy::wrong_self_convention)]
fn to_string(this: &JsValue, _: &[JsValue], context: &mut Context) -> JsResult<JsValue> {
let object = this.as_object().map(JsObject::borrow);
let object = this.as_object();
let object = object.as_deref().map(JsObject::borrow);
let function = object
.as_deref()
.and_then(Object::as_function)
Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/builtins/function/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ fn function_prototype_call() {
"#;
let value = forward_val(&mut context, func).unwrap();
assert!(value.is_string());
assert_eq!(value.as_string().unwrap(), "[object Error]");
assert_eq!(*value.as_string().unwrap(), "[object Error]");
}

#[test]
Expand Down Expand Up @@ -246,7 +246,7 @@ fn closure_capture_clone() {
object
.__get_own_property__(&"key".into(), context)?
.and_then(|prop| prop.value().cloned())
.and_then(|val| val.as_string().cloned())
.and_then(|val| val.as_string().as_deref().cloned())
.ok_or_else(|| context.construct_type_error("invalid `key` property"))?,
);
Ok(hw.into())
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/generator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ impl Generator {
) -> JsResult<JsValue> {
// 1. Return ? GeneratorResume(this value, value, empty).
match this.as_object() {
Some(obj) if obj.is_generator() => {
Some(ref obj) if obj.is_generator() => {
Self::generator_resume(obj, args.get_or_undefined(0), context)
}
_ => context.throw_type_error("Generator.prototype.next called on non generator"),
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/intl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl Intl {
// 1. Let ll be ? CanonicalizeLocaleList(locales).
let ll = Self::canonicalize_locale_list(args, context)?;
// 2. Return CreateArrayFromList(ll).
Ok(JsValue::Object(Array::create_array_from_list(
Ok(JsValue::new(Array::create_array_from_list(
ll.into_iter().map(Into::into),
context,
)))
Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/builtins/iterable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ impl JsValue {
// 1. Let syncMethod be ? GetMethod(obj, @@iterator).
let sync_method = self
.get_method(WellKnownSymbols::iterator(), context)?
.map_or(Self::Undefined, Self::from);
.map_or(Self::undefined(), Self::from);
// 2. Let syncIteratorRecord be ? GetIterator(obj, sync, syncMethod).
let _sync_iterator_record =
self.get_iterator(context, Some(IteratorHint::Sync), Some(sync_method));
Expand All @@ -154,7 +154,7 @@ impl JsValue {
} else {
// b. Otherwise, set method to ? GetMethod(obj, @@iterator).
self.get_method(WellKnownSymbols::iterator(), context)?
.map_or(Self::Undefined, Self::from)
.map_or(Self::undefined(), Self::from)
}
};

Expand Down
10 changes: 5 additions & 5 deletions boa_engine/src/builtins/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl Json {
let unfiltered = context.eval(script_string.as_bytes())?;

// 11. If IsCallable(reviver) is true, then
if let Some(obj) = args.get_or_undefined(1).as_callable() {
if let Some(ref obj) = args.get_or_undefined(1).as_callable() {
// a. Let root be ! OrdinaryObjectCreate(%Object.prototype%).
let root = context.construct_object();

Expand Down Expand Up @@ -129,7 +129,7 @@ impl Json {
let val = holder.get(name.clone(), context)?;

// 2. If Type(val) is Object, then
if let Some(obj) = val.as_object() {
if let Some(ref obj) = val.as_object() {
// a. Let isArray be ? IsArray(val).
// b. If isArray is true, then
if obj.is_array_abstract(context)? {
Expand Down Expand Up @@ -388,7 +388,7 @@ impl Json {
}

// 4. If Type(value) is Object, then
if let Some(obj) = value.as_object().cloned() {
if let Some(obj) = value.as_object().as_deref().cloned() {
// a. If value has a [[NumberData]] internal slot, then
if obj.is_number() {
// i. Set value to ? ToNumber(value).
Expand Down Expand Up @@ -427,7 +427,7 @@ impl Json {
}

// 8. If Type(value) is String, return QuoteJSONString(value).
if let Some(s) = value.as_string() {
if let Some(ref s) = value.as_string() {
return Ok(Some(Self::quote_json_string(s)));
}

Expand All @@ -452,7 +452,7 @@ impl Json {
}

// 11. If Type(value) is Object and IsCallable(value) is false, then
if let Some(obj) = value.as_object() {
if let Some(ref obj) = value.as_object() {
if !obj.is_callable() {
// a. Let isArray be ? IsArray(value).
// b. If isArray is true, return ? SerializeJSONArray(state, value).
Expand Down
Loading

0 comments on commit ec8fdef

Please sign in to comment.