use crate::{object::JsObject, Context, JsResult, JsValue};
use super::{InternalObjectMethods, ORDINARY_INTERNAL_METHODS};
pub(crate) static BOUND_FUNCTION_EXOTIC_INTERNAL_METHODS: InternalObjectMethods =
InternalObjectMethods {
__call__: Some(bound_function_exotic_call),
..ORDINARY_INTERNAL_METHODS
};
pub(crate) static BOUND_CONSTRUCTOR_EXOTIC_INTERNAL_METHODS: InternalObjectMethods =
InternalObjectMethods {
__call__: Some(bound_function_exotic_call),
__construct__: Some(bound_function_exotic_construct),
..ORDINARY_INTERNAL_METHODS
};
#[track_caller]
#[inline]
fn bound_function_exotic_call(
obj: &JsObject,
_: &JsValue,
arguments_list: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
let obj = obj.borrow();
let bound_function = obj
.as_bound_function()
.expect("bound function exotic method should only be callable from bound function objects");
let target = bound_function.target_function();
let bound_this = bound_function.this();
let bound_args = bound_function.args();
let mut args = bound_args.to_vec();
args.extend_from_slice(arguments_list);
target.call(bound_this, &args, context)
}
#[track_caller]
#[inline]
fn bound_function_exotic_construct(
obj: &JsObject,
arguments_list: &[JsValue],
new_target: &JsObject,
context: &mut Context,
) -> JsResult<JsObject> {
let object = obj.borrow();
let bound_function = object
.as_bound_function()
.expect("bound function exotic method should only be callable from bound function objects");
let target = bound_function.target_function();
let bound_args = bound_function.args();
let mut args = bound_args.to_vec();
args.extend_from_slice(arguments_list);
let new_target = if JsObject::equals(obj, new_target) {
target
} else {
new_target
};
target.construct(&args, Some(new_target), context)
}