diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index 81bfbba25d..fffe584c9b 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -66,6 +66,13 @@ Bytecode::CodeGenerationErrorOr ExpressionStatement::generate_bytecode(Byt Bytecode::CodeGenerationErrorOr BinaryExpression::generate_bytecode(Bytecode::Generator& generator) const { + if (m_op == BinaryOp::In && is(*m_lhs)) { + auto const& private_identifier = static_cast(*m_lhs).string(); + TRY(m_rhs->generate_bytecode(generator)); + generator.emit(generator.intern_identifier(private_identifier)); + return {}; + } + TRY(m_lhs->generate_bytecode(generator)); auto lhs_reg = generator.allocate_register(); generator.emit(lhs_reg); diff --git a/Userland/Libraries/LibJS/Bytecode/Instruction.h b/Userland/Libraries/LibJS/Bytecode/Instruction.h index 6e033e2ba5..629a2f95a7 100644 --- a/Userland/Libraries/LibJS/Bytecode/Instruction.h +++ b/Userland/Libraries/LibJS/Bytecode/Instruction.h @@ -43,6 +43,7 @@ O(GetVariable) \ O(GreaterThan) \ O(GreaterThanEquals) \ + O(HasPrivateId) \ O(ImportCall) \ O(In) \ O(Increment) \ diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index 1112eedc4f..5ba2dd4cd3 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -544,6 +544,20 @@ ThrowCompletionOr GetPrivateById::execute_impl(Bytecode::Interpreter& inte return {}; } +ThrowCompletionOr HasPrivateId::execute_impl(Bytecode::Interpreter& interpreter) const +{ + auto& vm = interpreter.vm(); + + if (!interpreter.accumulator().is_object()) + return vm.throw_completion(ErrorType::InOperatorWithObject); + + auto private_environment = vm.running_execution_context().private_environment; + VERIFY(private_environment); + auto private_name = private_environment->resolve_private_identifier(interpreter.current_executable().get_identifier(m_property)); + interpreter.accumulator() = Value(interpreter.accumulator().as_object().private_element_find(private_name) != nullptr); + return {}; +} + ThrowCompletionOr PutById::execute_impl(Bytecode::Interpreter& interpreter) const { auto& vm = interpreter.vm(); @@ -1383,6 +1397,11 @@ DeprecatedString GetPrivateById::to_deprecated_string_impl(Bytecode::Executable return DeprecatedString::formatted("GetPrivateById {} ({})", m_property, executable.identifier_table->get(m_property)); } +DeprecatedString HasPrivateId::to_deprecated_string_impl(Bytecode::Executable const& executable) const +{ + return DeprecatedString::formatted("HasPrivateId {} ({})", m_property, executable.identifier_table->get(m_property)); +} + DeprecatedString DeleteById::to_deprecated_string_impl(Bytecode::Executable const& executable) const { return DeprecatedString::formatted("DeleteById {} ({})", m_property, executable.identifier_table->get(m_property)); diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h index 824849c899..235c262527 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -558,6 +558,23 @@ private: IdentifierTableIndex m_property; }; +class HasPrivateId final : public Instruction { +public: + explicit HasPrivateId(IdentifierTableIndex property) + : Instruction(Type::HasPrivateId) + , m_property(property) + { + } + + ThrowCompletionOr execute_impl(Bytecode::Interpreter&) const; + DeprecatedString to_deprecated_string_impl(Bytecode::Executable const&) const; + void replace_references_impl(BasicBlock const&, BasicBlock const&) { } + void replace_references_impl(Register, Register) { } + +private: + IdentifierTableIndex m_property; +}; + enum class PropertyKind { Getter, Setter,