mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 10:47:35 +00:00
LibJS: Add "name" property to functions
This commit is contained in:
parent
d007e8d00f
commit
99be27b4a1
16 changed files with 118 additions and 16 deletions
|
@ -51,6 +51,7 @@ void FunctionPrototype::initialize()
|
|||
put_native_function("call", call, 1, attr);
|
||||
put_native_function("toString", to_string, 0, attr);
|
||||
put("length", Value(0), Attribute::Configurable);
|
||||
put("name", js_string(heap(), ""), Attribute::Configurable);
|
||||
}
|
||||
|
||||
FunctionPrototype::~FunctionPrototype()
|
||||
|
|
|
@ -61,6 +61,7 @@ template<typename ConstructorType>
|
|||
void GlobalObject::add_constructor(const FlyString& property_name, ConstructorType*& constructor, Object& prototype)
|
||||
{
|
||||
constructor = heap().allocate<ConstructorType>();
|
||||
constructor->put("name", js_string(heap(), property_name), Attribute::Configurable);
|
||||
prototype.put("constructor", constructor);
|
||||
put(property_name, constructor, Attribute::Writable | Attribute::Configurable);
|
||||
}
|
||||
|
|
|
@ -48,6 +48,9 @@ public:
|
|||
protected:
|
||||
virtual void visit_children(Visitor&) override;
|
||||
|
||||
template<typename ConstructorType>
|
||||
void add_constructor(const FlyString& property_name, ConstructorType*&, Object& prototype);
|
||||
|
||||
private:
|
||||
virtual const char* class_name() const override { return "GlobalObject"; }
|
||||
|
||||
|
@ -55,9 +58,6 @@ private:
|
|||
static Value is_nan(Interpreter&);
|
||||
static Value is_finite(Interpreter&);
|
||||
|
||||
template<typename ConstructorType>
|
||||
void add_constructor(const FlyString& property_name, ConstructorType*&, Object& prototype);
|
||||
|
||||
Shape* m_empty_object_shape { nullptr };
|
||||
|
||||
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName) \
|
||||
|
|
|
@ -397,6 +397,7 @@ bool Object::put_native_function(const FlyString& property_name, AK::Function<Va
|
|||
{
|
||||
auto* function = NativeFunction::create(interpreter(), interpreter().global_object(), property_name, move(native_function));
|
||||
function->put("length", Value(length), Attribute::Configurable);
|
||||
function->put("name", js_string(heap(), property_name), Attribute::Configurable);
|
||||
return put(property_name, function, attributes);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,18 @@
|
|||
|
||||
namespace JS {
|
||||
|
||||
static ScriptFunction* script_function_from(Interpreter& interpreter)
|
||||
{
|
||||
auto* this_object = interpreter.this_value().to_object(interpreter.heap());
|
||||
if (!this_object)
|
||||
return nullptr;
|
||||
if (!this_object->is_function()) {
|
||||
interpreter.throw_exception<TypeError>("Not a function");
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<ScriptFunction*>(this_object);
|
||||
}
|
||||
|
||||
ScriptFunction* ScriptFunction::create(GlobalObject& global_object, const FlyString& name, const Statement& body, Vector<FlyString> parameters, LexicalEnvironment* parent_environment)
|
||||
{
|
||||
return global_object.heap().allocate<ScriptFunction>(name, body, move(parameters), parent_environment, *global_object.function_prototype());
|
||||
|
@ -47,7 +59,8 @@ ScriptFunction::ScriptFunction(const FlyString& name, const Statement& body, Vec
|
|||
, m_parent_environment(parent_environment)
|
||||
{
|
||||
put("prototype", Object::create_empty(interpreter(), interpreter().global_object()), 0);
|
||||
put_native_property("length", length_getter, length_setter, Attribute::Configurable);
|
||||
put_native_property("length", length_getter, nullptr, Attribute::Configurable);
|
||||
put_native_property("name", name_getter, nullptr, Attribute::Configurable);
|
||||
}
|
||||
|
||||
ScriptFunction::~ScriptFunction()
|
||||
|
@ -101,16 +114,18 @@ Value ScriptFunction::construct(Interpreter& interpreter)
|
|||
|
||||
Value ScriptFunction::length_getter(Interpreter& interpreter)
|
||||
{
|
||||
auto* this_object = interpreter.this_value().to_object(interpreter.heap());
|
||||
if (!this_object)
|
||||
auto* function = script_function_from(interpreter);
|
||||
if (!function)
|
||||
return {};
|
||||
if (!this_object->is_function())
|
||||
return interpreter.throw_exception<TypeError>("Not a function");
|
||||
return Value(static_cast<i32>(static_cast<const ScriptFunction*>(this_object)->parameters().size()));
|
||||
return Value(static_cast<i32>(function->parameters().size()));
|
||||
}
|
||||
|
||||
void ScriptFunction::length_setter(Interpreter&, Value)
|
||||
Value ScriptFunction::name_getter(Interpreter& interpreter)
|
||||
{
|
||||
auto* function = script_function_from(interpreter);
|
||||
if (!function)
|
||||
return {};
|
||||
return js_string(interpreter, function->name().is_null() ? "" : function->name());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ private:
|
|||
virtual void visit_children(Visitor&) override;
|
||||
|
||||
static Value length_getter(Interpreter&);
|
||||
static void length_setter(Interpreter&, Value);
|
||||
static Value name_getter(Interpreter&);
|
||||
|
||||
FlyString m_name;
|
||||
NonnullRefPtr<Statement> m_body;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue