From a5e38133c240b4a72d36c68f25dc044f278cb0d8 Mon Sep 17 00:00:00 2001 From: Halid Odat Date: Sat, 22 May 2021 11:14:16 +0200 Subject: [PATCH] Fix `Context::register_global_function()` (#1270) --- boa/src/context.rs | 55 ++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/boa/src/context.rs b/boa/src/context.rs index ca7f2ed887..b1e21eb760 100644 --- a/boa/src/context.rs +++ b/boa/src/context.rs @@ -8,7 +8,7 @@ use crate::{ }, class::{Class, ClassBuilder}, exec::Interpreter, - object::{GcObject, Object, PROTOTYPE}, + object::{FunctionBuilder, GcObject, Object, PROTOTYPE}, property::{Attribute, DataDescriptor, PropertyKey}, realm::Realm, symbol::{RcSymbol, Symbol}, @@ -503,34 +503,18 @@ impl Context { Ok(val) } - /// Create a new builin function. - pub fn create_builtin_function( - &mut self, - name: &str, - length: usize, - body: NativeFunction, - ) -> Result { - let function_prototype: Value = self.standard_objects().object_object().prototype().into(); - - // Every new function has a prototype property pre-made - let proto = Value::new_object(self); - let mut function = GcObject::new(Object::function( - Function::BuiltIn(body.into(), FunctionFlags::CALLABLE), - function_prototype, - )); - function.set(PROTOTYPE.into(), proto, function.clone().into(), self)?; - function.set( - "length".into(), - length.into(), - function.clone().into(), - self, - )?; - function.set("name".into(), name.into(), function.clone().into(), self)?; - - Ok(function) - } - /// Register a global function. + /// + /// The function will be both `callable` and `constructable` (call with `new`). + /// + /// The function will be bound to the global object with `writable`, `non-enumerable` + /// and `configurable` attributes. The same as when you create a function in JavaScript. + /// + /// # Note + /// + /// If you want to make a function only `callable` or `constructable`, or wish to bind it differently + /// to the global object, you can create the function object with [`FunctionBuilder`](crate::object::FunctionBuilder). + /// And bind it to the global object with [`Context::register_global_property`](Context::register_global_property) method. #[inline] pub fn register_global_function( &mut self, @@ -538,9 +522,18 @@ impl Context { length: usize, body: NativeFunction, ) -> Result<()> { - let function = self.create_builtin_function(name, length, body)?; - let mut global = self.global_object(); - global.insert_property(name, function, Attribute::all()); + let function = FunctionBuilder::new(self, body) + .name(name) + .length(length) + .callable(true) + .constructable(true) + .build(); + + self.global_object().insert_property( + name, + function, + Attribute::WRITABLE | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE, + ); Ok(()) }