1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- /*
- * Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #pragma once
- #include <AK/StringView.h>
- #include <AK/TypeCasts.h>
- #include <LibJS/Runtime/Completion.h>
- #include <LibJS/Runtime/GlobalObject.h>
- #include <LibJS/Runtime/Object.h>
- namespace JS {
- #define JS_PROTOTYPE_OBJECT(prototype_class, object_class, display_name_) \
- using Prototype = PrototypeObject<prototype_class, object_class>; \
- JS_OBJECT(prototype_class, Prototype) \
- static constexpr StringView display_name() \
- { \
- return #display_name_##sv; \
- }
- template<typename PrototypeType, typename ObjectType>
- class PrototypeObject : public Object {
- JS_OBJECT(PrototypeObject, Object);
- public:
- virtual ~PrototypeObject() override = default;
- static ThrowCompletionOr<GC::Ref<Object>> this_object(VM& vm)
- {
- auto this_value = vm.this_value();
- if (!this_value.is_object())
- return vm.throw_completion<TypeError>(ErrorType::NotAnObject, this_value);
- return this_value.as_object();
- }
- // Use typed_this_object() when the spec coerces |this| value to an object.
- static ThrowCompletionOr<GC::Ref<ObjectType>> typed_this_object(VM& vm)
- {
- auto this_object = TRY(vm.this_value().to_object(vm));
- if (!is<ObjectType>(*this_object))
- return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, PrototypeType::display_name());
- return static_cast<ObjectType&>(*this_object);
- }
- // Use typed_this_value() when the spec does not coerce |this| value to an object.
- static ThrowCompletionOr<GC::Ref<ObjectType>> typed_this_value(VM& vm)
- {
- auto this_value = vm.this_value();
- if (!this_value.is_object() || !is<ObjectType>(this_value.as_object()))
- return vm.throw_completion<TypeError>(ErrorType::NotAnObjectOfType, PrototypeType::display_name());
- return static_cast<ObjectType&>(this_value.as_object());
- }
- protected:
- explicit PrototypeObject(Object& prototype)
- : Object(ConstructWithPrototypeTag::Tag, prototype)
- {
- }
- };
- }
|