Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Redesign native functions and closures API #2499

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion boa_engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ ryu-js = "0.2.2"
chrono = "0.4.23"
fast-float = "0.2.0"
unicode-normalization = "0.1.22"
dyn-clone = "1.0.10"
once_cell = "1.17.0"
tap = "1.0.1"
sptr = "0.3.2"
Expand Down
16 changes: 9 additions & 7 deletions boa_engine/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ use crate::{
context::intrinsics::StandardConstructors,
error::JsNativeError,
js_string,
native_function::NativeFunction,
object::{
internal_methods::get_prototype_from_constructor, ConstructorBuilder, FunctionBuilder,
JsFunction, JsObject, ObjectData,
internal_methods::get_prototype_from_constructor, ConstructorBuilder,
FunctionObjectBuilder, JsFunction, JsObject, ObjectData,
},
property::{Attribute, PropertyDescriptor, PropertyNameKind},
symbol::WellKnownSymbols,
Expand All @@ -50,10 +51,11 @@ impl BuiltIn for Array {
let symbol_iterator = WellKnownSymbols::iterator();
let symbol_unscopables = WellKnownSymbols::unscopables();

let get_species = FunctionBuilder::native(context, Self::get_species)
.name("get [Symbol.species]")
.constructor(false)
.build();
let get_species =
FunctionObjectBuilder::new(context, NativeFunction::from_fn_ptr(Self::get_species))
.name("get [Symbol.species]")
.constructor(false)
.build();

let values_function = context.intrinsics().objects().array_prototype_values();
let unscopables_object = Self::unscopables_intrinsic(context);
Expand Down Expand Up @@ -2847,7 +2849,7 @@ impl Array {

/// Creates an `Array.prototype.values( )` function object.
pub(crate) fn create_array_prototype_values(context: &mut Context<'_>) -> JsFunction {
FunctionBuilder::native(context, Self::values)
FunctionObjectBuilder::new(context, NativeFunction::from_fn_ptr(Self::values))
.name("values")
.length(0)
.constructor(false)
Expand Down
21 changes: 12 additions & 9 deletions boa_engine/src/builtins/array_buffer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ use crate::{
builtins::{typed_array::TypedArrayKind, BuiltIn, JsArgs},
context::intrinsics::StandardConstructors,
error::JsNativeError,
native_function::NativeFunction,
object::{
internal_methods::get_prototype_from_constructor, ConstructorBuilder, FunctionBuilder,
JsObject, ObjectData,
internal_methods::get_prototype_from_constructor, ConstructorBuilder,
FunctionObjectBuilder, JsObject, ObjectData,
},
property::Attribute,
symbol::WellKnownSymbols,
Expand Down Expand Up @@ -55,14 +56,16 @@ impl BuiltIn for ArrayBuffer {

let flag_attributes = Attribute::CONFIGURABLE | Attribute::NON_ENUMERABLE;

let get_species = FunctionBuilder::native(context, Self::get_species)
.name("get [Symbol.species]")
.constructor(false)
.build();
let get_species =
FunctionObjectBuilder::new(context, NativeFunction::from_fn_ptr(Self::get_species))
.name("get [Symbol.species]")
.constructor(false)
.build();

let get_byte_length = FunctionBuilder::native(context, Self::get_byte_length)
.name("get byteLength")
.build();
let get_byte_length =
FunctionObjectBuilder::new(context, NativeFunction::from_fn_ptr(Self::get_byte_length))
.name("get byteLength")
.build();

ConstructorBuilder::with_standard_constructor(
context,
Expand Down
3 changes: 2 additions & 1 deletion boa_engine/src/builtins/async_function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
function::{ConstructorKind, Function},
BuiltIn,
},
native_function::NativeFunction,
object::ObjectData,
property::PropertyDescriptor,
symbol::WellKnownSymbols,
Expand Down Expand Up @@ -62,7 +63,7 @@ impl BuiltIn for AsyncFunction {
.configurable(false);
constructor.borrow_mut().insert("prototype", property);
constructor.borrow_mut().data = ObjectData::function(Function::Native {
function: Self::constructor,
function: NativeFunction::from_fn_ptr(Self::constructor),
constructor: Some(ConstructorKind::Base),
});

Expand Down
87 changes: 46 additions & 41 deletions boa_engine/src/builtins/async_generator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ use crate::{
promise::if_abrupt_reject_promise, promise::PromiseCapability, BuiltIn, JsArgs, Promise,
},
error::JsNativeError,
object::{ConstructorBuilder, FunctionBuilder, JsObject, ObjectData},
native_function::NativeFunction,
object::{ConstructorBuilder, FunctionObjectBuilder, JsObject, ObjectData},
property::{Attribute, PropertyDescriptor},
symbol::WellKnownSymbols,
value::JsValue,
Expand Down Expand Up @@ -627,65 +628,69 @@ impl AsyncGenerator {

// 7. Let fulfilledClosure be a new Abstract Closure with parameters (value) that captures generator and performs the following steps when called:
// 8. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 1, "", « »).
let on_fulfilled = FunctionBuilder::closure_with_captures(
let on_fulfilled = FunctionObjectBuilder::new(
context,
|_this, args, generator, context| {
let mut generator_borrow_mut = generator.borrow_mut();
let gen = generator_borrow_mut
.as_async_generator_mut()
.expect("already checked before");
NativeFunction::from_copy_closure_with_captures(
|_this, args, generator, context| {
let mut generator_borrow_mut = generator.borrow_mut();
let gen = generator_borrow_mut
.as_async_generator_mut()
.expect("already checked before");

// a. Set generator.[[AsyncGeneratorState]] to completed.
gen.state = AsyncGeneratorState::Completed;
// a. Set generator.[[AsyncGeneratorState]] to completed.
gen.state = AsyncGeneratorState::Completed;

// b. Let result be NormalCompletion(value).
let result = Ok(args.get_or_undefined(0).clone());
// b. Let result be NormalCompletion(value).
let result = Ok(args.get_or_undefined(0).clone());

// c. Perform AsyncGeneratorCompleteStep(generator, result, true).
let next = gen.queue.pop_front().expect("must have one entry");
drop(generator_borrow_mut);
Self::complete_step(&next, result, true, context);
// c. Perform AsyncGeneratorCompleteStep(generator, result, true).
let next = gen.queue.pop_front().expect("must have one entry");
drop(generator_borrow_mut);
Self::complete_step(&next, result, true, context);

// d. Perform AsyncGeneratorDrainQueue(generator).
Self::drain_queue(generator, context);
// d. Perform AsyncGeneratorDrainQueue(generator).
Self::drain_queue(generator, context);

// e. Return undefined.
Ok(JsValue::undefined())
},
generator.clone(),
// e. Return undefined.
Ok(JsValue::undefined())
},
generator.clone(),
),
)
.name("")
.length(1)
.build();

// 9. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures generator and performs the following steps when called:
// 10. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »).
let on_rejected = FunctionBuilder::closure_with_captures(
let on_rejected = FunctionObjectBuilder::new(
context,
|_this, args, generator, context| {
let mut generator_borrow_mut = generator.borrow_mut();
let gen = generator_borrow_mut
.as_async_generator_mut()
.expect("already checked before");
NativeFunction::from_copy_closure_with_captures(
|_this, args, generator, context| {
let mut generator_borrow_mut = generator.borrow_mut();
let gen = generator_borrow_mut
.as_async_generator_mut()
.expect("already checked before");

// a. Set generator.[[AsyncGeneratorState]] to completed.
gen.state = AsyncGeneratorState::Completed;
// a. Set generator.[[AsyncGeneratorState]] to completed.
gen.state = AsyncGeneratorState::Completed;

// b. Let result be ThrowCompletion(reason).
let result = Err(JsError::from_opaque(args.get_or_undefined(0).clone()));
// b. Let result be ThrowCompletion(reason).
let result = Err(JsError::from_opaque(args.get_or_undefined(0).clone()));

// c. Perform AsyncGeneratorCompleteStep(generator, result, true).
let next = gen.queue.pop_front().expect("must have one entry");
drop(generator_borrow_mut);
Self::complete_step(&next, result, true, context);
// c. Perform AsyncGeneratorCompleteStep(generator, result, true).
let next = gen.queue.pop_front().expect("must have one entry");
drop(generator_borrow_mut);
Self::complete_step(&next, result, true, context);

// d. Perform AsyncGeneratorDrainQueue(generator).
Self::drain_queue(generator, context);
// d. Perform AsyncGeneratorDrainQueue(generator).
Self::drain_queue(generator, context);

// e. Return undefined.
Ok(JsValue::undefined())
},
generator,
// e. Return undefined.
Ok(JsValue::undefined())
},
generator,
),
)
.name("")
.length(1)
Expand Down
3 changes: 2 additions & 1 deletion boa_engine/src/builtins/async_generator_function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{
function::{BuiltInFunctionObject, ConstructorKind, Function},
BuiltIn,
},
native_function::NativeFunction,
object::ObjectData,
property::PropertyDescriptor,
symbol::WellKnownSymbols,
Expand Down Expand Up @@ -67,7 +68,7 @@ impl BuiltIn for AsyncGeneratorFunction {
.configurable(false);
constructor.borrow_mut().insert("prototype", property);
constructor.borrow_mut().data = ObjectData::function(Function::Native {
function: Self::constructor,
function: NativeFunction::from_fn_ptr(Self::constructor),
constructor: Some(ConstructorKind::Base),
});

Expand Down
26 changes: 15 additions & 11 deletions boa_engine/src/builtins/dataview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ use crate::{
builtins::{array_buffer::SharedMemoryOrder, typed_array::TypedArrayKind, BuiltIn, JsArgs},
context::intrinsics::StandardConstructors,
error::JsNativeError,
native_function::NativeFunction,
object::{
internal_methods::get_prototype_from_constructor, ConstructorBuilder, FunctionBuilder,
JsObject, ObjectData,
internal_methods::get_prototype_from_constructor, ConstructorBuilder,
FunctionObjectBuilder, JsObject, ObjectData,
},
property::Attribute,
symbol::WellKnownSymbols,
Expand All @@ -37,17 +38,20 @@ impl BuiltIn for DataView {
fn init(context: &mut Context<'_>) -> Option<JsValue> {
let flag_attributes = Attribute::CONFIGURABLE | Attribute::NON_ENUMERABLE;

let get_buffer = FunctionBuilder::native(context, Self::get_buffer)
.name("get buffer")
.build();
let get_buffer =
FunctionObjectBuilder::new(context, NativeFunction::from_fn_ptr(Self::get_buffer))
.name("get buffer")
.build();

let get_byte_length = FunctionBuilder::native(context, Self::get_byte_length)
.name("get byteLength")
.build();
let get_byte_length =
FunctionObjectBuilder::new(context, NativeFunction::from_fn_ptr(Self::get_byte_length))
.name("get byteLength")
.build();

let get_byte_offset = FunctionBuilder::native(context, Self::get_byte_offset)
.name("get byteOffset")
.build();
let get_byte_offset =
FunctionObjectBuilder::new(context, NativeFunction::from_fn_ptr(Self::get_byte_offset))
.name("get byteOffset")
.build();

ConstructorBuilder::with_standard_constructor(
context,
Expand Down
3 changes: 2 additions & 1 deletion boa_engine/src/builtins/error/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::{
builtins::{function::Function, BuiltIn, JsArgs},
context::intrinsics::StandardConstructors,
error::JsNativeError,
native_function::NativeFunction,
object::{
internal_methods::get_prototype_from_constructor, ConstructorBuilder, JsObject, ObjectData,
},
Expand Down Expand Up @@ -103,7 +104,7 @@ pub(crate) fn create_throw_type_error(context: &mut Context<'_>) -> JsObject {
let function = JsObject::from_proto_and_data(
context.intrinsics().constructors().function().prototype(),
ObjectData::function(Function::Native {
function: throw_type_error,
function: NativeFunction::from_fn_ptr(throw_type_error),
constructor: None,
}),
);
Expand Down
5 changes: 3 additions & 2 deletions boa_engine/src/builtins/eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use crate::{
builtins::{BuiltIn, JsArgs},
environments::DeclarativeEnvironment,
error::JsNativeError,
object::FunctionBuilder,
native_function::NativeFunction,
object::FunctionObjectBuilder,
property::Attribute,
Context, JsResult, JsString, JsValue,
};
Expand All @@ -37,7 +38,7 @@ impl BuiltIn for Eval {
fn init(context: &mut Context<'_>) -> Option<JsValue> {
let _timer = Profiler::global().start_event(Self::NAME, "init");

let object = FunctionBuilder::native(context, Self::eval)
let object = FunctionObjectBuilder::new(context, NativeFunction::from_fn_ptr(Self::eval))
.name("eval")
.length(1)
.constructor(false)
Expand Down
Loading