ladybird/Libraries/LibJS/Runtime/BoundFunction.h
Andreas Kling 7281091fdb LibJS: Make bytecode generation infallible
Remove CodeGenerationError and make all bytecode generation functions
return their results directly instead of wrapping them in
CodeGenerationErrorOr.

For the few remaining sites where codegen encounters an unimplemented
or unexpected AST node, we now use a new emit_todo() helper that emits
a NewTypeError + Throw sequence at compile time (preserving the runtime
behavior) and then switches to a dead basic block so subsequent codegen
for the same function can continue without issue.

This allows us to remove error handling from all callers of the
bytecode compiler, simplifying the code significantly.
2026-02-12 11:37:43 +01:00

51 lines
2 KiB
C++

/*
* Copyright (c) 2020, Jack Karamanian <karamanian.jack@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibJS/Runtime/Completion.h>
#include <LibJS/Runtime/FunctionObject.h>
namespace JS {
class BoundFunction final : public FunctionObject {
JS_OBJECT(BoundFunction, FunctionObject);
GC_DECLARE_ALLOCATOR(BoundFunction);
public:
static ThrowCompletionOr<GC::Ref<BoundFunction>> create(Realm&, FunctionObject& target_function, Value bound_this, Vector<Value> bound_arguments);
virtual ~BoundFunction() override = default;
virtual ThrowCompletionOr<Value> internal_call(ExecutionContext&, Value this_argument) override;
virtual ThrowCompletionOr<GC::Ref<Object>> internal_construct(ExecutionContext& arguments_list, FunctionObject& new_target) override;
virtual bool is_strict_mode() const override { return m_bound_target_function->is_strict_mode(); }
virtual bool has_constructor() const override { return m_bound_target_function->has_constructor(); }
FunctionObject& bound_target_function() const { return *m_bound_target_function; }
Value bound_this() const { return m_bound_this; }
Vector<Value> const& bound_arguments() const { return m_bound_arguments; }
virtual Utf16String name_for_call_stack() const override;
private:
BoundFunction(Realm&, FunctionObject& target_function, Value bound_this, Vector<Value> bound_arguments, Object* prototype);
void get_stack_frame_size(size_t& registers_and_locals_count, size_t& constants_count, size_t& argument_count) override;
virtual void visit_edges(Visitor&) override;
virtual bool is_bound_function() const final { return true; }
GC::Ptr<FunctionObject> m_bound_target_function; // [[BoundTargetFunction]]
Value m_bound_this; // [[BoundThis]]
Vector<Value> m_bound_arguments; // [[BoundArguments]]
};
template<>
inline bool Object::fast_is<BoundFunction>() const { return is_bound_function(); }
}