diff options
author | davidot <david.tuin@gmail.com> | 2021-09-18 01:11:32 +0200 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-09-30 08:16:32 +0100 |
commit | bfc1b4ba6185726f8b567f188a407e821892d5b1 (patch) | |
tree | 09c786930c9e41dc4b3a4e369c685886c0c48028 /Userland/Libraries/LibJS/Runtime/VM.cpp | |
parent | 9cb570039891b88a8d75c3fae761f617c340e2b7 (diff) | |
download | serenity-bfc1b4ba6185726f8b567f188a407e821892d5b1.zip |
LibJS: Allow member expressions in binding patterns
Also allows literal string and numbers as property names in object
binding patterns.
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime/VM.cpp')
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/VM.cpp | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index b98969b86c..ec114f2a47 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -197,6 +197,20 @@ void VM::assign(const NonnullRefPtr<BindingPattern>& target, Value value, Global auto& entry = binding.entries[i]; + Optional<Reference> assignment_target; + entry.alias.visit( + [&](Empty) {}, + [&](NonnullRefPtr<Identifier> const&) { + // FIXME: We need to get the reference but bindings are broken so this doesn't work yet. + }, + [&](NonnullRefPtr<BindingPattern> const&) {}, + [&](NonnullRefPtr<MemberExpression> const& member_expression) { + assignment_target = member_expression->to_reference(interpreter(), global_object); + }); + + if (exception()) + return; + if (entry.is_rest) { VERIFY(i == binding.entries.size() - 1); @@ -254,8 +268,15 @@ void VM::assign(const NonnullRefPtr<BindingPattern>& target, Value value, Global }, [&](NonnullRefPtr<BindingPattern> const& pattern) { assign(pattern, value, global_object, first_assignment, specific_scope); + }, + [&](NonnullRefPtr<MemberExpression> const&) { + VERIFY(assignment_target.has_value()); + assignment_target->put_value(global_object, value); }); + if (exception()) + return; + if (entry.is_rest) break; } @@ -269,10 +290,21 @@ void VM::assign(const NonnullRefPtr<BindingPattern>& target, Value value, Global VERIFY(!property.is_elision()); PropertyName assignment_name; + Optional<Reference> assignment_target; + JS::Value value_to_assign; if (property.is_rest) { - VERIFY(property.name.has<NonnullRefPtr<Identifier>>()); - assignment_name = property.name.get<NonnullRefPtr<Identifier>>()->string(); + if (auto identifier_ptr = property.name.get_pointer<NonnullRefPtr<Identifier>>()) + assignment_name = (*identifier_ptr)->string(); + property.alias.visit( + [&](Empty) {}, + [&](NonnullRefPtr<Identifier> const&) { + // FIXME: We need to get the reference but bindings are broken so this doesn't work yet. + }, + [&](NonnullRefPtr<BindingPattern> const&) {}, + [&](NonnullRefPtr<MemberExpression> const& member_expression) { + assignment_target = member_expression->to_reference(interpreter(), global_object); + }); auto* rest_object = Object::create(global_object, global_object.object_prototype()); for (auto& object_property : object->shape().property_table()) { @@ -298,6 +330,15 @@ void VM::assign(const NonnullRefPtr<BindingPattern>& target, Value value, Global return; assignment_name = result.to_property_key(global_object); }); + property.alias.visit( + [&](Empty) {}, + [&](NonnullRefPtr<Identifier> const&) { + // FIXME: We need to get the reference but bindings are broken so this doesn't work yet. + }, + [&](NonnullRefPtr<BindingPattern> const&) {}, + [&](NonnullRefPtr<MemberExpression> const& member_expression) { + assignment_target = member_expression->to_reference(interpreter(), global_object); + }); if (exception()) break; @@ -327,8 +368,15 @@ void VM::assign(const NonnullRefPtr<BindingPattern>& target, Value value, Global [&](NonnullRefPtr<BindingPattern> const& pattern) { VERIFY(!property.is_rest); assign(pattern, value_to_assign, global_object, first_assignment, specific_scope); + }, + [&](NonnullRefPtr<MemberExpression> const&) { + VERIFY(assignment_target.has_value()); + assignment_target->put_value(global_object, value_to_assign); }); + if (exception()) + return; + if (property.is_rest) break; } |