mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 12:05:15 +00:00
LibJS: Add the [[Unimplemented]] attribute
Properties marked with the [[Unimplemented]] attribute behave as normal but invoke the `VM::on_unimplemented_property_access callback` when they are accessed.
This commit is contained in:
parent
ebfb847d34
commit
88d425f32b
Notes:
sideshowbarker
2024-07-17 02:38:39 +09:00
Author: https://github.com/tcl3 Commit: https://github.com/LadybirdBrowser/ladybird/commit/88d425f32b Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/136 Reviewed-by: https://github.com/awesomekling
4 changed files with 15 additions and 1 deletions
|
@ -808,6 +808,13 @@ ThrowCompletionOr<Optional<PropertyDescriptor>> Object::internal_get_own_propert
|
|||
// 3. Let X be O's own property whose key is P.
|
||||
auto [value, attributes, property_offset] = *maybe_storage_entry;
|
||||
|
||||
// AD-HOC: Properties with the [[Unimplemented]] attribute are used for reporting unimplemented IDL interfaces.
|
||||
if (attributes.is_unimplemented()) {
|
||||
if (vm().on_unimplemented_property_access)
|
||||
vm().on_unimplemented_property_access(*this, property_key);
|
||||
descriptor.unimplemented = true;
|
||||
}
|
||||
|
||||
// 4. If X is a data property, then
|
||||
if (!value.is_accessor()) {
|
||||
// a. Set D.[[Value]] to the value of X's [[Value]] attribute.
|
||||
|
|
|
@ -19,6 +19,8 @@ struct Attribute {
|
|||
Writable = 1 << 0,
|
||||
Enumerable = 1 << 1,
|
||||
Configurable = 1 << 2,
|
||||
// AD-HOC: This is used for reporting unimplemented IDL interfaces.
|
||||
Unimplemented = 1 << 3,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -33,6 +35,7 @@ public:
|
|||
[[nodiscard]] bool is_writable() const { return m_bits & Attribute::Writable; }
|
||||
[[nodiscard]] bool is_enumerable() const { return m_bits & Attribute::Enumerable; }
|
||||
[[nodiscard]] bool is_configurable() const { return m_bits & Attribute::Configurable; }
|
||||
[[nodiscard]] bool is_unimplemented() const { return m_bits & Attribute::Unimplemented; }
|
||||
|
||||
void set_writable(bool writable = true)
|
||||
{
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
// Not a standard abstract operation, but "If every field in Desc is absent".
|
||||
[[nodiscard]] bool is_empty() const
|
||||
{
|
||||
return !value.has_value() && !get.has_value() && !set.has_value() && !writable.has_value() && !enumerable.has_value() && !configurable.has_value();
|
||||
return !value.has_value() && !get.has_value() && !set.has_value() && !writable.has_value() && !enumerable.has_value() && !configurable.has_value() && !unimplemented.has_value();
|
||||
}
|
||||
|
||||
Optional<Value> value {};
|
||||
|
@ -40,6 +40,7 @@ public:
|
|||
Optional<bool> writable {};
|
||||
Optional<bool> enumerable {};
|
||||
Optional<bool> configurable {};
|
||||
Optional<bool> unimplemented {};
|
||||
|
||||
Optional<u32> property_offset {};
|
||||
};
|
||||
|
@ -65,6 +66,8 @@ struct Formatter<JS::PropertyDescriptor> : Formatter<StringView> {
|
|||
TRY(parts.try_append(TRY(String::formatted("[[Enumerable]]: {}", *property_descriptor.enumerable))));
|
||||
if (property_descriptor.configurable.has_value())
|
||||
TRY(parts.try_append(TRY(String::formatted("[[Configurable]]: {}", *property_descriptor.configurable))));
|
||||
if (property_descriptor.unimplemented.has_value())
|
||||
TRY(parts.try_append(TRY(String::formatted("[[Unimplemented]]: {}", *property_descriptor.unimplemented))));
|
||||
return Formatter<StringView>::format(builder, TRY(String::formatted("PropertyDescriptor {{ {} }}", TRY(String::join(", "sv, parts)))));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -223,6 +223,7 @@ public:
|
|||
Function<void()> on_call_stack_emptied;
|
||||
Function<void(Promise&)> on_promise_unhandled_rejection;
|
||||
Function<void(Promise&)> on_promise_rejection_handled;
|
||||
Function<void(Object const&, PropertyKey const&)> on_unimplemented_property_access;
|
||||
|
||||
CustomData* custom_data() { return m_custom_data; }
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue