LibJS: Initial class implementation; allow super expressions in object

literal methods; add EnvrionmentRecord fields and methods to
LexicalEnvironment

Adding EnvrionmentRecord's fields and methods lets us throw an exception
when |this| is not initialized, which occurs when the super constructor
in a derived class has not yet been called, or when |this| has already
been initialized (the super constructor was already called).
This commit is contained in:
Jack Karamanian 2020-06-08 13:31:21 -05:00 committed by Andreas Kling
parent a535d58cac
commit 7533fd8b02
Notes: sideshowbarker 2024-07-19 05:19:30 +09:00
18 changed files with 967 additions and 92 deletions

View file

@ -66,8 +66,8 @@ ScriptFunction::ScriptFunction(GlobalObject& global_object, const FlyString& nam
void ScriptFunction::initialize(Interpreter& interpreter, GlobalObject& global_object)
{
Function::initialize(interpreter, global_object);
if (!is_arrow_function) {
Object* prototype = Object::create_empty(interpreter(), interpreter().global_object());
if (!m_is_arrow_function) {
Object* prototype = Object::create_empty(interpreter, global_object);
prototype->define_property("constructor", this, Attribute::Writable | Attribute::Configurable);
define_property("prototype", prototype, 0);
}
@ -99,9 +99,11 @@ LexicalEnvironment* ScriptFunction::create_environment()
}
}
}
if (variables.is_empty())
return m_parent_environment;
return heap().allocate<LexicalEnvironment>(global_object(), move(variables), m_parent_environment);
auto* environment = heap().allocate<LexicalEnvironment>(global_object(), move(variables), m_parent_environment, LexicalEnvironment::EnvironmentRecordType::Function);
environment->set_home_object(home_object());
environment->set_current_function(*this);
return environment;
}
Value ScriptFunction::call(Interpreter& interpreter)
@ -134,7 +136,7 @@ Value ScriptFunction::call(Interpreter& interpreter)
Value ScriptFunction::construct(Interpreter& interpreter)
{
if (m_is_arrow_function)
return interpreter.throw_exception<TypeError>(ErrorType::NotACtor, m_name.characters());
return interpreter.throw_exception<TypeError>(ErrorType::NotAConstructor, m_name.characters());
return call(interpreter);
}