mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 04:27:44 +00:00
LibJS: Implement the CreateUnmappedArgumentsObject abstract operation
This commit is contained in:
parent
63a1275378
commit
9eed7444de
4 changed files with 46 additions and 5 deletions
|
@ -11,6 +11,8 @@
|
||||||
#include <LibJS/Interpreter.h>
|
#include <LibJS/Interpreter.h>
|
||||||
#include <LibJS/Parser.h>
|
#include <LibJS/Parser.h>
|
||||||
#include <LibJS/Runtime/AbstractOperations.h>
|
#include <LibJS/Runtime/AbstractOperations.h>
|
||||||
|
#include <LibJS/Runtime/Array.h>
|
||||||
|
#include <LibJS/Runtime/ArrayPrototype.h>
|
||||||
#include <LibJS/Runtime/BoundFunction.h>
|
#include <LibJS/Runtime/BoundFunction.h>
|
||||||
#include <LibJS/Runtime/DeclarativeEnvironmentRecord.h>
|
#include <LibJS/Runtime/DeclarativeEnvironmentRecord.h>
|
||||||
#include <LibJS/Runtime/ErrorTypes.h>
|
#include <LibJS/Runtime/ErrorTypes.h>
|
||||||
|
@ -204,4 +206,36 @@ Value perform_eval(Value x, GlobalObject& caller_realm, CallerMode strict_caller
|
||||||
return interpreter.execute_statement(caller_realm, program).value_or(js_undefined());
|
return interpreter.execute_statement(caller_realm, program).value_or(js_undefined());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 10.4.4.6 CreateUnmappedArgumentsObject ( argumentsList ), https://tc39.es/ecma262/#sec-createunmappedargumentsobject
|
||||||
|
Object* create_unmapped_arguments_object(GlobalObject& global_object, Vector<Value> const& arguments)
|
||||||
|
{
|
||||||
|
auto& vm = global_object.vm();
|
||||||
|
// FIXME: This should use OrdinaryObjectCreate
|
||||||
|
auto* object = Object::create(global_object, global_object.object_prototype());
|
||||||
|
if (vm.exception())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// 4. Perform DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
|
||||||
|
auto length = arguments.size();
|
||||||
|
object->define_property(vm.names.length, Value(length), Attribute::Writable | Attribute::Configurable);
|
||||||
|
if (vm.exception())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
object->define_property(*vm.well_known_symbol_iterator(), global_object.array_prototype()->get(vm.names.values), Attribute::Writable | Attribute::Configurable);
|
||||||
|
|
||||||
|
for (auto& argument : arguments)
|
||||||
|
object->indexed_properties().append(argument);
|
||||||
|
|
||||||
|
// FIXME: 8. Perform ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Get]]: %ThrowTypeError%, [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false }).
|
||||||
|
PropertyAttributes attributes;
|
||||||
|
attributes.set_has_configurable();
|
||||||
|
attributes.set_has_enumerable();
|
||||||
|
|
||||||
|
object->define_property(vm.names.callee, js_undefined(), attributes);
|
||||||
|
if (vm.exception())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ MarkedValueList create_list_from_array_like(GlobalObject&, Value, Function<Resul
|
||||||
FunctionObject* species_constructor(GlobalObject&, Object const&, FunctionObject& default_constructor);
|
FunctionObject* species_constructor(GlobalObject&, Object const&, FunctionObject& default_constructor);
|
||||||
GlobalObject* get_function_realm(GlobalObject&, FunctionObject const&);
|
GlobalObject* get_function_realm(GlobalObject&, FunctionObject const&);
|
||||||
Object* get_prototype_from_constructor(GlobalObject&, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)());
|
Object* get_prototype_from_constructor(GlobalObject&, FunctionObject const& constructor, Object* (GlobalObject::*intrinsic_default_prototype)());
|
||||||
|
Object* create_unmapped_arguments_object(GlobalObject&, Vector<Value> const& arguments);
|
||||||
|
|
||||||
enum class CallerMode {
|
enum class CallerMode {
|
||||||
Strict,
|
Strict,
|
||||||
|
|
|
@ -369,10 +369,16 @@ Value VM::get_variable(const FlyString& name, GlobalObject& global_object)
|
||||||
if (possible_match.has_value())
|
if (possible_match.has_value())
|
||||||
return possible_match.value().value;
|
return possible_match.value().value;
|
||||||
if (!context.arguments_object) {
|
if (!context.arguments_object) {
|
||||||
context.arguments_object = Array::create(global_object);
|
if (context.function->is_strict_mode()) {
|
||||||
context.arguments_object->put(names.callee, context.function);
|
context.arguments_object = create_unmapped_arguments_object(global_object, context.arguments);
|
||||||
for (auto argument : context.arguments) {
|
} else {
|
||||||
context.arguments_object->indexed_properties().append(argument);
|
// FIXME: This code path is completely ad-hoc.
|
||||||
|
context.arguments_object = Array::create(global_object);
|
||||||
|
context.arguments_object->put(names.callee, context.function);
|
||||||
|
|
||||||
|
for (auto argument : context.arguments) {
|
||||||
|
context.arguments_object->indexed_properties().append(argument);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return context.arguments_object;
|
return context.arguments_object;
|
||||||
|
|
|
@ -48,7 +48,7 @@ struct ExecutionContext {
|
||||||
FunctionObject* function { nullptr };
|
FunctionObject* function { nullptr };
|
||||||
Value this_value;
|
Value this_value;
|
||||||
Vector<Value> arguments;
|
Vector<Value> arguments;
|
||||||
Array* arguments_object { nullptr };
|
Object* arguments_object { nullptr };
|
||||||
EnvironmentRecord* lexical_environment { nullptr };
|
EnvironmentRecord* lexical_environment { nullptr };
|
||||||
EnvironmentRecord* variable_environment { nullptr };
|
EnvironmentRecord* variable_environment { nullptr };
|
||||||
bool is_strict_mode { false };
|
bool is_strict_mode { false };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue