1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 23:47:45 +00:00

LibJS: Implement constructor/non-constructor function calls

This adds Function::construct() for constructor function calls via `new`
keyword. NativeFunction doesn't have constructor behaviour by default,
ScriptFunction simply calls call() in construct()
This commit is contained in:
Linus Groh 2020-04-01 18:31:24 +01:00 committed by Andreas Kling
parent a27884e4be
commit 849e2c77e4
11 changed files with 66 additions and 1 deletions

View file

@ -46,6 +46,14 @@ DateConstructor::~DateConstructor()
}
Value DateConstructor::call(Interpreter& interpreter)
{
auto* date = static_cast<Date*>(construct(interpreter).as_object());
if (!date)
return {};
return js_string(interpreter.heap(), date->string());
}
Value DateConstructor::construct(Interpreter& interpreter)
{
// TODO: Support args
struct timeval tv;

View file

@ -36,8 +36,10 @@ public:
virtual ~DateConstructor() override;
virtual Value call(Interpreter&) override;
virtual Value construct(Interpreter&) override;
private:
virtual bool has_constructor() const override { return true; }
virtual const char* class_name() const override { return "DateConstructor"; }
static Value now(Interpreter&);

View file

@ -36,6 +36,7 @@ public:
virtual ~Function();
virtual Value call(Interpreter&) = 0;
virtual Value construct(Interpreter&) = 0;
protected:
Function();

View file

@ -44,4 +44,9 @@ Value NativeFunction::call(Interpreter& interpreter)
return m_native_function(interpreter);
}
Value NativeFunction::construct(Interpreter&)
{
return {};
}
}

View file

@ -37,6 +37,9 @@ public:
virtual ~NativeFunction() override;
virtual Value call(Interpreter&) override;
virtual Value construct(Interpreter&) override;
virtual bool has_constructor() const { return false; }
protected:
NativeFunction() {}

View file

@ -50,6 +50,11 @@ Value ObjectConstructor::call(Interpreter& interpreter)
return interpreter.heap().allocate<Object>();
}
Value ObjectConstructor::construct(Interpreter& interpreter)
{
return call(interpreter);
}
Value ObjectConstructor::get_own_property_names(Interpreter& interpreter)
{
if (interpreter.call_frame().arguments.size() < 1)

View file

@ -36,8 +36,10 @@ public:
virtual ~ObjectConstructor() override;
virtual Value call(Interpreter&) override;
virtual Value construct(Interpreter&) override;
private:
virtual bool has_constructor() const override { return true; }
virtual const char* class_name() const override { return "ObjectConstructor"; }
static Value get_own_property_names(Interpreter&);

View file

@ -55,4 +55,9 @@ Value ScriptFunction::call(Interpreter& interpreter)
return interpreter.run(m_body, arguments, ScopeType::Function);
}
Value ScriptFunction::construct(Interpreter& interpreter)
{
return call(interpreter);
}
}

View file

@ -39,6 +39,7 @@ public:
const Vector<FlyString>& parameters() const { return m_parameters; };
virtual Value call(Interpreter&) override;
virtual Value construct(Interpreter&) override;
private:
virtual bool is_script_function() const final { return true; }