Skip to content

Commit

Permalink
LibJS/Bytecode: Throw on destructuring assignment to non-object-coerc…
Browse files Browse the repository at this point in the history
…ible

24 new passes on test262. :^)
  • Loading branch information
awesomekling committed Jun 25, 2023
1 parent c7a77bb commit 8e5d9b7
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,8 @@ Bytecode::CodeGenerationErrorOr<void> FunctionExpression::generate_bytecode(Byte

static Bytecode::CodeGenerationErrorOr<void> generate_object_binding_pattern_bytecode(Bytecode::Generator& generator, BindingPattern const& pattern, Bytecode::Op::SetVariable::InitializationMode initialization_mode, Bytecode::Register const& value_reg, bool create_variables)
{
generator.emit<Bytecode::Op::ThrowIfNullish>();

Vector<Bytecode::Register> excluded_property_names;
auto has_rest = false;
if (pattern.entries.size() > 0)
Expand Down
1 change: 1 addition & 0 deletions Userland/Libraries/LibJS/Bytecode/Instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
O(SuperCall) \
O(Throw) \
O(ThrowIfNotObject) \
O(ThrowIfNullish) \
O(ToNumeric) \
O(Typeof) \
O(TypeofVariable) \
Expand Down
14 changes: 14 additions & 0 deletions Userland/Libraries/LibJS/Bytecode/Op.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,15 @@ ThrowCompletionOr<void> ThrowIfNotObject::execute_impl(Bytecode::Interpreter& in
return {};
}

ThrowCompletionOr<void> ThrowIfNullish::execute_impl(Bytecode::Interpreter& interpreter) const
{
auto& vm = interpreter.vm();
auto value = interpreter.accumulator();
if (value.is_nullish())
return vm.throw_completion<TypeError>(ErrorType::NotObjectCoercible, TRY_OR_THROW_OOM(vm, value.to_string_without_side_effects()));
return {};
}

ThrowCompletionOr<void> EnterUnwindContext::execute_impl(Bytecode::Interpreter& interpreter) const
{
interpreter.enter_unwind_context(m_handler_target, m_finalizer_target);
Expand Down Expand Up @@ -1432,6 +1441,11 @@ DeprecatedString ThrowIfNotObject::to_deprecated_string_impl(Bytecode::Executabl
return "ThrowIfNotObject";
}

DeprecatedString ThrowIfNullish::to_deprecated_string_impl(Bytecode::Executable const&) const
{
return "ThrowIfNullish";
}

DeprecatedString EnterUnwindContext::to_deprecated_string_impl(Bytecode::Executable const&) const
{
auto handler_string = m_handler_target.has_value() ? DeprecatedString::formatted("{}", *m_handler_target) : "<empty>";
Expand Down
13 changes: 13 additions & 0 deletions Userland/Libraries/LibJS/Bytecode/Op.h
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,19 @@ class ThrowIfNotObject final : public Instruction {
void replace_references_impl(Register, Register) { }
};

class ThrowIfNullish final : public Instruction {
public:
ThrowIfNullish()
: Instruction(Type::ThrowIfNullish)
{
}

ThrowCompletionOr<void> 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) { }
};

class EnterUnwindContext final : public Instruction {
public:
constexpr static bool IsTerminator = true;
Expand Down

0 comments on commit 8e5d9b7

Please sign in to comment.