123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- /*
- * Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #pragma once
- #include <AK/String.h>
- #include <LibJS/Runtime/Environment.h>
- #include <LibJS/Runtime/PropertyName.h>
- #include <LibJS/Runtime/Value.h>
- namespace JS {
- class Reference {
- public:
- enum class BaseType : u8 {
- Unresolvable,
- Value,
- Environment,
- };
- Reference() { }
- Reference(BaseType type, PropertyName name, bool strict)
- : m_base_type(type)
- , m_name(move(name))
- , m_strict(strict)
- {
- }
- Reference(Value base, PropertyName name, Value this_value, bool strict = false)
- : m_base_type(BaseType::Value)
- , m_base_value(base)
- , m_name(move(name))
- , m_this_value(this_value)
- , m_strict(strict)
- {
- if (base.is_nullish()) {
- m_base_type = BaseType::Unresolvable;
- m_base_value = {};
- m_this_value = {};
- m_name = {};
- }
- }
- Reference(Environment& base, FlyString referenced_name, bool strict = false)
- : m_base_type(BaseType::Environment)
- , m_base_environment(&base)
- , m_name(move(referenced_name))
- , m_strict(strict)
- {
- }
- Value base() const
- {
- VERIFY(m_base_type == BaseType::Value);
- return m_base_value;
- }
- Environment& base_environment() const
- {
- VERIFY(m_base_type == BaseType::Environment);
- return *m_base_environment;
- }
- PropertyName const& name() const { return m_name; }
- bool is_strict() const { return m_strict; }
- // 6.2.4.2 IsUnresolvableReference ( V ), https://tc39.es/ecma262/#sec-isunresolvablereference
- bool is_unresolvable() const { return m_base_type == BaseType::Unresolvable; }
- // 6.2.4.1 IsPropertyReference ( V ), https://tc39.es/ecma262/#sec-ispropertyreference
- bool is_property_reference() const
- {
- if (is_unresolvable())
- return false;
- if (m_base_type == BaseType::Environment)
- return false;
- if (m_base_value.is_boolean() || m_base_value.is_string() || m_base_value.is_symbol() || m_base_value.is_bigint() || m_base_value.is_number() || m_base_value.is_object())
- return true;
- return false;
- }
- // 6.2.4.7 GetThisValue ( V ), https://tc39.es/ecma262/#sec-getthisvalue
- Value get_this_value() const
- {
- VERIFY(is_property_reference());
- if (is_super_reference())
- return m_this_value;
- return m_base_value;
- }
- // 6.2.4.3 IsSuperReference ( V ), https://tc39.es/ecma262/#sec-issuperreference
- bool is_super_reference() const
- {
- return !m_this_value.is_empty();
- }
- // Note: Non-standard helper.
- bool is_environment_reference() const
- {
- return m_base_type == BaseType::Environment;
- }
- void put_value(GlobalObject&, Value);
- Value get_value(GlobalObject&, bool throw_if_undefined = true) const;
- bool delete_(GlobalObject&);
- String to_string() const;
- private:
- void throw_reference_error(GlobalObject&) const;
- BaseType m_base_type { BaseType::Unresolvable };
- union {
- Value m_base_value {};
- Environment* m_base_environment;
- };
- PropertyName m_name;
- Value m_this_value;
- bool m_strict { false };
- };
- }
|