LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
/*
|
2022-05-01 00:47:55 +02:00
|
|
|
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <LibJS/Runtime/Error.h>
|
|
|
|
#include <LibJS/Runtime/FunctionObject.h>
|
|
|
|
#include <LibJS/Runtime/GlobalObject.h>
|
|
|
|
#include <LibJS/Runtime/Object.h>
|
|
|
|
#include <LibJS/Runtime/PropertyDescriptor.h>
|
|
|
|
#include <LibJS/Runtime/Value.h>
|
2023-10-06 17:54:21 +02:00
|
|
|
#include <LibJS/Runtime/ValueInlines.h>
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
|
|
|
|
namespace JS {
|
|
|
|
|
|
|
|
// 6.2.5.1 IsAccessorDescriptor ( Desc ), https://tc39.es/ecma262/#sec-isaccessordescriptor
|
|
|
|
bool PropertyDescriptor::is_accessor_descriptor() const
|
|
|
|
{
|
|
|
|
// 1. If Desc is undefined, return false.
|
|
|
|
|
2022-05-01 01:38:21 +02:00
|
|
|
// 2. If Desc has a [[Get]] field, return true.
|
|
|
|
if (get.has_value())
|
|
|
|
return true;
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
|
2022-05-01 01:38:21 +02:00
|
|
|
// 3. If Desc has a [[Set]] field, return true.
|
|
|
|
if (set.has_value())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// 4. Return false.
|
|
|
|
return false;
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// 6.2.5.2 IsDataDescriptor ( Desc ), https://tc39.es/ecma262/#sec-isdatadescriptor
|
|
|
|
bool PropertyDescriptor::is_data_descriptor() const
|
|
|
|
{
|
|
|
|
// 1. If Desc is undefined, return false.
|
|
|
|
|
2022-05-01 01:38:21 +02:00
|
|
|
// 2. If Desc has a [[Value]] field, return true.
|
|
|
|
if (value.has_value())
|
|
|
|
return true;
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
|
2022-05-01 01:38:21 +02:00
|
|
|
// 3. If Desc has a [[Writable]] field, return true.
|
|
|
|
if (writable.has_value())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// 4. Return false.
|
|
|
|
return false;
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// 6.2.5.3 IsGenericDescriptor ( Desc ), https://tc39.es/ecma262/#sec-isgenericdescriptor
|
|
|
|
bool PropertyDescriptor::is_generic_descriptor() const
|
|
|
|
{
|
|
|
|
// 1. If Desc is undefined, return false.
|
|
|
|
|
2022-05-01 01:38:21 +02:00
|
|
|
// 2. If IsAccessorDescriptor(Desc) is true, return false.
|
|
|
|
if (is_accessor_descriptor())
|
|
|
|
return false;
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
|
2022-05-01 01:38:21 +02:00
|
|
|
// 3. If IsDataDescriptor(Desc) is true, return false.
|
|
|
|
if (is_data_descriptor())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// 4. Return true.
|
|
|
|
return true;
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// 6.2.5.4 FromPropertyDescriptor ( Desc ), https://tc39.es/ecma262/#sec-frompropertydescriptor
|
2022-08-21 20:38:35 +01:00
|
|
|
Value from_property_descriptor(VM& vm, Optional<PropertyDescriptor> const& property_descriptor)
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
{
|
2022-08-21 20:38:35 +01:00
|
|
|
auto& realm = *vm.current_realm();
|
|
|
|
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
if (!property_descriptor.has_value())
|
|
|
|
return js_undefined();
|
2022-12-13 20:49:50 +00:00
|
|
|
auto object = Object::create(realm, realm.intrinsics().object_prototype());
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
if (property_descriptor->value.has_value())
|
2021-10-03 01:18:46 +01:00
|
|
|
MUST(object->create_data_property_or_throw(vm.names.value, *property_descriptor->value));
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
if (property_descriptor->writable.has_value())
|
2021-10-03 01:18:46 +01:00
|
|
|
MUST(object->create_data_property_or_throw(vm.names.writable, Value(*property_descriptor->writable)));
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
if (property_descriptor->get.has_value())
|
2021-10-03 01:18:46 +01:00
|
|
|
MUST(object->create_data_property_or_throw(vm.names.get, *property_descriptor->get ? Value(*property_descriptor->get) : js_undefined()));
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
if (property_descriptor->set.has_value())
|
2021-10-03 01:18:46 +01:00
|
|
|
MUST(object->create_data_property_or_throw(vm.names.set, *property_descriptor->set ? Value(*property_descriptor->set) : js_undefined()));
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
if (property_descriptor->enumerable.has_value())
|
2021-10-03 01:18:46 +01:00
|
|
|
MUST(object->create_data_property_or_throw(vm.names.enumerable, Value(*property_descriptor->enumerable)));
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
if (property_descriptor->configurable.has_value())
|
2021-10-03 01:18:46 +01:00
|
|
|
MUST(object->create_data_property_or_throw(vm.names.configurable, Value(*property_descriptor->configurable)));
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
return object;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 6.2.5.5 ToPropertyDescriptor ( Obj ), https://tc39.es/ecma262/#sec-topropertydescriptor
|
2022-08-21 20:38:35 +01:00
|
|
|
ThrowCompletionOr<PropertyDescriptor> to_property_descriptor(VM& vm, Value argument)
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
{
|
2021-10-03 20:07:00 +01:00
|
|
|
// 1. If Type(Obj) is not Object, throw a TypeError exception.
|
|
|
|
if (!argument.is_object())
|
2023-08-09 08:49:02 +02:00
|
|
|
return vm.throw_completion<TypeError>(ErrorType::NotAnObject, argument.to_string_without_side_effects());
|
2021-10-03 20:07:00 +01:00
|
|
|
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
auto& object = argument.as_object();
|
2021-10-03 20:07:00 +01:00
|
|
|
|
|
|
|
// 2. Let desc be a new Property Descriptor that initially has no fields.
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
PropertyDescriptor descriptor;
|
2021-10-03 20:07:00 +01:00
|
|
|
|
|
|
|
// 3. Let hasEnumerable be ? HasProperty(Obj, "enumerable").
|
|
|
|
auto has_enumerable = TRY(object.has_property(vm.names.enumerable));
|
|
|
|
|
|
|
|
// 4. If hasEnumerable is true, then
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
if (has_enumerable) {
|
2022-05-02 20:54:39 +02:00
|
|
|
// a. Let enumerable be ToBoolean(? Get(Obj, "enumerable")).
|
2021-10-03 20:07:00 +01:00
|
|
|
auto enumerable = TRY(object.get(vm.names.enumerable)).to_boolean();
|
|
|
|
|
|
|
|
// b. Set desc.[[Enumerable]] to enumerable.
|
|
|
|
descriptor.enumerable = enumerable;
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
}
|
2021-10-03 20:07:00 +01:00
|
|
|
|
|
|
|
// 5. Let hasConfigurable be ? HasProperty(Obj, "configurable").
|
|
|
|
auto has_configurable = TRY(object.has_property(vm.names.configurable));
|
|
|
|
|
|
|
|
// 6. If hasConfigurable is true, then
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
if (has_configurable) {
|
2022-05-02 20:54:39 +02:00
|
|
|
// a. Let configurable be ToBoolean(? Get(Obj, "configurable")).
|
2021-10-03 20:07:00 +01:00
|
|
|
auto configurable = TRY(object.get(vm.names.configurable)).to_boolean();
|
|
|
|
|
|
|
|
// b. Set desc.[[Configurable]] to configurable.
|
|
|
|
descriptor.configurable = configurable;
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
}
|
2021-10-03 20:07:00 +01:00
|
|
|
|
|
|
|
// 7. Let hasValue be ? HasProperty(Obj, "value").
|
|
|
|
auto has_value = TRY(object.has_property(vm.names.value));
|
|
|
|
|
|
|
|
// 8. If hasValue is true, then
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
if (has_value) {
|
2021-10-03 20:07:00 +01:00
|
|
|
// a. Let value be ? Get(Obj, "value").
|
|
|
|
auto value = TRY(object.get(vm.names.value));
|
|
|
|
|
|
|
|
// b. Set desc.[[Value]] to value.
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
descriptor.value = value;
|
|
|
|
}
|
2021-10-03 20:07:00 +01:00
|
|
|
|
|
|
|
// 9. Let hasWritable be ? HasProperty(Obj, "writable").
|
|
|
|
auto has_writable = TRY(object.has_property(vm.names.writable));
|
|
|
|
|
|
|
|
// 10. If hasWritable is true, then
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
if (has_writable) {
|
2022-05-02 20:54:39 +02:00
|
|
|
// a. Let writable be ToBoolean(? Get(Obj, "writable")).
|
2021-10-03 20:07:00 +01:00
|
|
|
auto writable = TRY(object.get(vm.names.writable)).to_boolean();
|
|
|
|
|
|
|
|
// b. Set desc.[[Writable]] to writable.
|
|
|
|
descriptor.writable = writable;
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
}
|
2021-10-03 20:07:00 +01:00
|
|
|
|
|
|
|
// 11. Let hasGet be ? HasProperty(Obj, "get").
|
|
|
|
auto has_get = TRY(object.has_property(vm.names.get));
|
|
|
|
|
|
|
|
// 12. If hasGet is true, then
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
if (has_get) {
|
2021-10-03 20:07:00 +01:00
|
|
|
// a. Let getter be ? Get(Obj, "get").
|
|
|
|
auto getter = TRY(object.get(vm.names.get));
|
|
|
|
|
|
|
|
// b. If IsCallable(getter) is false and getter is not undefined, throw a TypeError exception.
|
|
|
|
if (!getter.is_function() && !getter.is_undefined())
|
2022-08-16 20:33:17 +01:00
|
|
|
return vm.throw_completion<TypeError>(ErrorType::AccessorBadField, "get");
|
2021-10-03 20:07:00 +01:00
|
|
|
|
|
|
|
// c. Set desc.[[Get]] to getter.
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
descriptor.get = getter.is_function() ? &getter.as_function() : nullptr;
|
|
|
|
}
|
2021-10-03 20:07:00 +01:00
|
|
|
|
|
|
|
// 13. Let hasSet be ? HasProperty(Obj, "set").
|
|
|
|
auto has_set = TRY(object.has_property(vm.names.set));
|
|
|
|
|
|
|
|
// 14. If hasSet is true, then
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
if (has_set) {
|
2021-10-03 20:07:00 +01:00
|
|
|
// a. Let setter be ? Get(Obj, "set").
|
|
|
|
auto setter = TRY(object.get(vm.names.set));
|
|
|
|
|
|
|
|
// b. If IsCallable(setter) is false and setter is not undefined, throw a TypeError exception.
|
|
|
|
if (!setter.is_function() && !setter.is_undefined())
|
2022-08-16 20:33:17 +01:00
|
|
|
return vm.throw_completion<TypeError>(ErrorType::AccessorBadField, "set");
|
2021-10-03 20:07:00 +01:00
|
|
|
|
|
|
|
// c. Set desc.[[Set]] to setter.
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
descriptor.set = setter.is_function() ? &setter.as_function() : nullptr;
|
|
|
|
}
|
2021-10-03 20:07:00 +01:00
|
|
|
|
2022-05-01 00:47:55 +02:00
|
|
|
// 15. If desc has a [[Get]] field or desc has a [[Set]] field, then
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
if (descriptor.get.has_value() || descriptor.set.has_value()) {
|
2022-05-01 00:47:55 +02:00
|
|
|
// a. If desc has a [[Value]] field or desc has a [[Writable]] field, throw a TypeError exception.
|
2021-10-03 20:07:00 +01:00
|
|
|
if (descriptor.value.has_value() || descriptor.writable.has_value())
|
2022-08-16 20:33:17 +01:00
|
|
|
return vm.throw_completion<TypeError>(ErrorType::AccessorValueOrWritable);
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
}
|
2021-10-03 20:07:00 +01:00
|
|
|
|
|
|
|
// 16. Return desc.
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
return descriptor;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 6.2.5.6 CompletePropertyDescriptor ( Desc ), https://tc39.es/ecma262/#sec-completepropertydescriptor
|
|
|
|
void PropertyDescriptor::complete()
|
|
|
|
{
|
|
|
|
if (is_generic_descriptor() || is_data_descriptor()) {
|
|
|
|
if (!value.has_value())
|
2025-04-04 23:16:34 +02:00
|
|
|
value = js_undefined();
|
LibJS: Add new PropertyDescriptor class and related abstract operations
This is an implementation of 'The Property Descriptor Specification
Type' and related abstract operations, namely:
- IsAccessorDescriptor
- IsDataDescriptor
- IsGenericDescriptor
- FromPropertyDescriptor
- ToPropertyDescriptor
- CompletePropertyDescriptor
It works with Optional<T> to enable omitting certain fields, which will
eventually replace the Attribute::Has{Getter,Setter,Configurable,
Enumerable,Writable} bit flags, which are awkward to work with - being
able to use an initializer list with any of the possible attributes is
much more convenient.
Parts of the current PropertyAttributes implementation as well as the
much simpler PropertyDescriptor struct in Object.h will eventually be
replaced with this and completely go away.
Property storage will still use the PropertyAttributes bit flags, this
is for the layers above.
Note that this is currently guarded behind an #if 0 as if conflicts with
the existing PropertyDescriptor struct, but it's known to compile and
work just fine - I simply want to have this in a separate commit, the
primary object rewrite commit will be large enough as is.
2021-07-03 22:57:21 +01:00
|
|
|
if (!writable.has_value())
|
|
|
|
writable = false;
|
|
|
|
} else {
|
|
|
|
if (!get.has_value())
|
|
|
|
get = nullptr;
|
|
|
|
if (!set.has_value())
|
|
|
|
set = nullptr;
|
|
|
|
}
|
|
|
|
if (!enumerable.has_value())
|
|
|
|
enumerable = false;
|
|
|
|
if (!configurable.has_value())
|
|
|
|
configurable = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Non-standard, just a convenient way to get from three Optional<bool> to PropertyAttributes.
|
|
|
|
PropertyAttributes PropertyDescriptor::attributes() const
|
|
|
|
{
|
|
|
|
u8 attributes = 0;
|
|
|
|
if (writable.value_or(false))
|
|
|
|
attributes |= Attribute::Writable;
|
|
|
|
if (enumerable.value_or(false))
|
|
|
|
attributes |= Attribute::Enumerable;
|
|
|
|
if (configurable.value_or(false))
|
|
|
|
attributes |= Attribute::Configurable;
|
|
|
|
return { attributes };
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|