Skip to content

Commit

Permalink
Fix some errors, change sepecies_constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
raskad committed Oct 2, 2021
1 parent 5af3e23 commit bab142c
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 87 deletions.
11 changes: 5 additions & 6 deletions boa/src/builtins/array_buffer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ impl ArrayBuffer {
} else {
return context.throw_type_error("ArrayBuffer.byteLength called with non-object value");
};
let obj_borrow = obj.borrow();
let o = if let Some(o) = obj_borrow.as_array_buffer() {
let obj = obj.borrow();
let o = if let Some(o) = obj.as_array_buffer() {
o
} else {
return context.throw_type_error("ArrayBuffer.byteLength called with invalid object");
Expand Down Expand Up @@ -227,11 +227,10 @@ impl ArrayBuffer {
let new_len = std::cmp::max(r#final - first, 0) as usize;

// 15. Let ctor be ? SpeciesConstructor(O, %ArrayBuffer%).
let ctor =
obj.species_constructor(context.global_object().get(Self::NAME, context)?, context)?;
let ctor = obj.species_constructor(StandardObjects::array_buffer_object, context)?;

// 16. Let new be ? Construct(ctor, « 𝔽(newLen) »).
let new = Self::constructor(&ctor, &[new_len.into()], context)?;
let new = Self::constructor(&ctor.into(), &[new_len.into()], context)?;

// 17. Perform ? RequireInternalSlot(new, [[ArrayBufferData]]).
let new_obj = if let Some(obj) = new.as_object() {
Expand Down Expand Up @@ -441,7 +440,7 @@ impl ArrayBuffer {

// 2. If ! IsBigIntElementType(type) is true and order is not Init or Unordered, return true.
if Self::is_big_int_element_type(t)
&& matches!(
&& !matches!(
order,
SharedMemoryOrder::Init | SharedMemoryOrder::Unordered
)
Expand Down
27 changes: 12 additions & 15 deletions boa/src/builtins/regexp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1211,16 +1211,17 @@ impl RegExp {
let c = this
.as_object()
.unwrap_or_default()
.species_constructor(context.global_object().get(RegExp::NAME, context)?, context)?;
.species_constructor(StandardObjects::regexp_object, context)?;

// 5. Let flags be ? ToString(? Get(R, "flags")).
let flags = this.get_field("flags", context)?.to_string(context)?;

// 6. Let matcher be ? Construct(C, « R, flags »).
let matcher = c
.as_object()
.expect("SpeciesConstructor returned non Object")
.construct(&[this.clone(), flags.clone().into()], &c, context)?;
let matcher = c.construct(
&[this.clone(), flags.clone().into()],
&c.clone().into(),
context,
)?;

// 7. Let lastIndex be ? ToLength(? Get(R, "lastIndex")).
let last_index = this.get_field("lastIndex", context)?.to_length(context)?;
Expand Down Expand Up @@ -1582,8 +1583,7 @@ impl RegExp {
.to_string(context)?;

// 4. Let C be ? SpeciesConstructor(rx, %RegExp%).
let constructor =
rx.species_constructor(context.global_object().get(RegExp::NAME, context)?, context)?;
let constructor = rx.species_constructor(StandardObjects::regexp_object, context)?;

// 5. Let flags be ? ToString(? Get(rx, "flags")).
let flags = rx.get("flags", context)?.to_string(context)?;
Expand All @@ -1601,14 +1601,11 @@ impl RegExp {
};

// 10. Let splitter be ? Construct(C, « rx, newFlags »).
let splitter = constructor
.as_object()
.expect("SpeciesConstructor returned non Object")
.construct(
&[JsValue::from(rx), new_flags.into()],
&constructor,
context,
)?;
let splitter = constructor.construct(
&[rx.into(), new_flags.into()],
&constructor.clone().into(),
context,
)?;

// 11. Let A be ! ArrayCreate(0).
let a = Array::array_create(0, None, context).unwrap();
Expand Down
74 changes: 17 additions & 57 deletions boa/src/builtins/typed_array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2801,63 +2801,24 @@ impl TypedArray {
) -> JsResult<JsObject> {
// 1. Let defaultConstructor be the intrinsic object listed in column one of Table 73 for exemplar.[[TypedArrayName]].
let default_constructor = match typed_array_name {
TypedArrayName::Int8Array => context
.standard_objects()
.typed_int8_array_object()
.constructor(),
TypedArrayName::Uint8Array => context
.standard_objects()
.typed_uint8_array_object()
.constructor(),
TypedArrayName::Uint8ClampedArray => context
.standard_objects()
.typed_uint8clamped_array_object()
.constructor(),
TypedArrayName::Int16Array => context
.standard_objects()
.typed_int16_array_object()
.constructor(),
TypedArrayName::Uint16Array => context
.standard_objects()
.typed_uint16_array_object()
.constructor(),
TypedArrayName::Int32Array => context
.standard_objects()
.typed_int32_array_object()
.constructor(),
TypedArrayName::Uint32Array => context
.standard_objects()
.typed_uint32_array_object()
.constructor(),
TypedArrayName::BigInt64Array => context
.standard_objects()
.typed_bigint64_array_object()
.constructor(),
TypedArrayName::BigUint64Array => context
.standard_objects()
.typed_biguint64_array_object()
.constructor(),
TypedArrayName::Float32Array => context
.standard_objects()
.typed_float32_array_object()
.constructor(),
TypedArrayName::Float64Array => context
.standard_objects()
.typed_float64_array_object()
.constructor(),
TypedArrayName::Int8Array => StandardObjects::typed_int8_array_object,
TypedArrayName::Uint8Array => StandardObjects::typed_uint8_array_object,
TypedArrayName::Uint8ClampedArray => StandardObjects::typed_uint8clamped_array_object,
TypedArrayName::Int16Array => StandardObjects::typed_int16_array_object,
TypedArrayName::Uint16Array => StandardObjects::typed_uint16_array_object,
TypedArrayName::Int32Array => StandardObjects::typed_int32_array_object,
TypedArrayName::Uint32Array => StandardObjects::typed_uint32_array_object,
TypedArrayName::BigInt64Array => StandardObjects::typed_bigint64_array_object,
TypedArrayName::BigUint64Array => StandardObjects::typed_biguint64_array_object,
TypedArrayName::Float32Array => StandardObjects::typed_float32_array_object,
TypedArrayName::Float64Array => StandardObjects::typed_float64_array_object,
};

// 2. Let constructor be ? SpeciesConstructor(exemplar, defaultConstructor).
let constructor = exemplar.species_constructor(default_constructor.into(), context)?;
let constructor = exemplar.species_constructor(default_constructor, context)?;

// 3. Let result be ? TypedArrayCreate(constructor, argumentList).
let result = Self::create(
&constructor
.as_object()
.expect("Constructor must be an object"),
args,
context,
)?;
let result = Self::create(&constructor, args, context)?;

// 4. Assert: result has [[TypedArrayName]] and [[ContentType]] internal slots.
// 5. If result.[[ContentType]] ≠ exemplar.[[ContentType]], throw a TypeError exception.
Expand Down Expand Up @@ -3054,7 +3015,6 @@ impl TypedArray {
src_array: JsObject,
context: &mut Context,
) -> JsResult<()> {
// TODO: change parameters?
let o_obj = o.borrow();
let src_array_obj = src_array.borrow();
let o_array = o_obj.as_typed_array().expect("this must be a typed array");
Expand Down Expand Up @@ -3101,22 +3061,22 @@ impl TypedArray {
// TODO: Shared Array Buffer
// 13. Else,
// a. Let bufferConstructor be %ArrayBuffer%.
let buffer_constructor = src_data_obj
.species_constructor(context.global_object().get(Self::NAME, context)?, context)?;
let buffer_constructor =
src_data_obj.species_constructor(StandardObjects::array_buffer_object, context)?;

// 14. If elementType is the same as srcType, then
let data = if constructor_name == src_name {
// a. Let data be ? CloneArrayBuffer(srcData, srcByteOffset, byteLength, bufferConstructor).
src_data.clone_array_buffer(
src_byte_offset,
byte_length,
&buffer_constructor,
&buffer_constructor.into(),
context,
)?
// 15. Else,
} else {
// a. Let data be ? AllocateArrayBuffer(bufferConstructor, byteLength).
let data_obj = ArrayBuffer::allocate(&buffer_constructor, byte_length, context)?;
let data_obj = ArrayBuffer::allocate(&buffer_constructor.into(), byte_length, context)?;
let mut data_obj_b = data_obj.borrow_mut();
let data = data_obj_b
.as_array_buffer_mut()
Expand Down
22 changes: 13 additions & 9 deletions boa/src/object/operations.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
builtins::Array,
context::{StandardConstructor, StandardObjects},
object::JsObject,
property::{PropertyDescriptor, PropertyKey, PropertyNameKind},
symbol::WellKnownSymbols,
Expand Down Expand Up @@ -423,44 +424,47 @@ impl JsObject {
/// - [ECMAScript reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-speciesconstructor
pub(crate) fn species_constructor(
pub(crate) fn species_constructor<F>(
&self,
default_constructor: JsValue,
default_constructor: F,
context: &mut Context,
) -> JsResult<JsValue> {
) -> JsResult<JsObject>
where
F: FnOnce(&StandardObjects) -> &StandardConstructor,
{
// 1. Assert: Type(O) is Object.

// 2. Let C be ? Get(O, "constructor").
let c = self.clone().get("constructor", context)?;

// 3. If C is undefined, return defaultConstructor.
if c.is_undefined() {
return Ok(default_constructor);
return Ok(default_constructor(context.standard_objects()).constructor());
}

// 4. If Type(C) is not Object, throw a TypeError exception.
if !c.is_object() {
return context.throw_type_error("property 'constructor' is not an object");
return Err(context.construct_type_error("property 'constructor' is not an object"));
}

// 5. Let S be ? Get(C, @@species).
let s = c.get_field(WellKnownSymbols::species(), context)?;

// 6. If S is either undefined or null, return defaultConstructor.
if s.is_null_or_undefined() {
return Ok(default_constructor);
return Ok(default_constructor(context.standard_objects()).constructor());
}

// 7. If IsConstructor(S) is true, return S.
// 8. Throw a TypeError exception.
if let Some(obj) = s.as_object() {
if obj.is_constructable() {
Ok(s)
Ok(obj)
} else {
context.throw_type_error("property 'constructor' is not a constructor")
Err(context.construct_type_error("property 'constructor' is not a constructor"))
}
} else {
context.throw_type_error("property 'constructor' is not an object")
Err(context.construct_type_error("property 'constructor' is not an object"))
}
}

Expand Down

0 comments on commit bab142c

Please sign in to comment.