mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 12:20:00 +01:00
This commits puts the strict mode flag in the header of every bytecode instruction. This allows us to check for strict mode without looking at the currently running execution context.
142 lines
4.0 KiB
C++
142 lines
4.0 KiB
C++
/*
|
|
* Copyright (c) 2020-2021, Andreas Kling <andreas@ladybird.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <LibJS/Export.h>
|
|
#include <LibJS/Runtime/Environment.h>
|
|
#include <LibJS/Runtime/EnvironmentCoordinate.h>
|
|
#include <LibJS/Runtime/PropertyKey.h>
|
|
#include <LibJS/Runtime/Value.h>
|
|
|
|
namespace JS {
|
|
|
|
Reference make_private_reference(VM&, Value base_value, Utf16FlyString const& private_identifier);
|
|
|
|
class JS_API Reference {
|
|
public:
|
|
enum class BaseType : u8 {
|
|
Unresolvable,
|
|
Value,
|
|
Environment,
|
|
};
|
|
|
|
Reference(BaseType type, PropertyKey name, Strict strict)
|
|
: m_base_type(type)
|
|
, m_name(move(name))
|
|
, m_strict(strict)
|
|
{
|
|
}
|
|
|
|
Reference(Value base, PropertyKey name, Optional<Value> this_value, Strict strict)
|
|
: m_base_type(BaseType::Value)
|
|
, m_base_value(base)
|
|
, m_name(move(name))
|
|
, m_this_value(this_value)
|
|
, m_strict(strict)
|
|
{
|
|
}
|
|
|
|
Reference(Environment& base, Utf16FlyString referenced_name, Strict strict, Optional<EnvironmentCoordinate> environment_coordinate = {})
|
|
: m_base_type(BaseType::Environment)
|
|
, m_base_environment(&base)
|
|
, m_name(move(referenced_name))
|
|
, m_strict(strict)
|
|
, m_environment_coordinate(move(environment_coordinate))
|
|
{
|
|
}
|
|
|
|
Reference(Value base, PrivateName name)
|
|
: m_base_type(BaseType::Value)
|
|
, m_base_value(base)
|
|
, m_name(move(name))
|
|
, m_strict(Strict::Yes)
|
|
{
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
PropertyKey const& name() const { return m_name.get<PropertyKey>(); }
|
|
PrivateName const& private_name() const { return m_name.get<PrivateName>(); }
|
|
bool is_strict() const { return m_strict == Strict::Yes; }
|
|
|
|
// 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;
|
|
return true;
|
|
}
|
|
|
|
// 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.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.has_value();
|
|
}
|
|
|
|
// 6.2.4.4 IsPrivateReference ( V ), https://tc39.es/ecma262/#sec-isprivatereference
|
|
bool is_private_reference() const
|
|
{
|
|
return m_name.has<PrivateName>();
|
|
}
|
|
|
|
// Note: Non-standard helper.
|
|
bool is_environment_reference() const
|
|
{
|
|
return m_base_type == BaseType::Environment;
|
|
}
|
|
|
|
ThrowCompletionOr<void> initialize_referenced_binding(VM&, Value value, Environment::InitializeBindingHint hint = Environment::InitializeBindingHint::Normal) const;
|
|
|
|
ThrowCompletionOr<void> put_value(VM&, Value);
|
|
ThrowCompletionOr<Value> get_value(VM&) const;
|
|
ThrowCompletionOr<bool> delete_(VM&);
|
|
|
|
bool is_valid_reference() const { return true; }
|
|
|
|
Optional<EnvironmentCoordinate> environment_coordinate() const { return m_environment_coordinate; }
|
|
|
|
private:
|
|
Completion throw_reference_error(VM&) const;
|
|
|
|
BaseType m_base_type { BaseType::Unresolvable };
|
|
union {
|
|
Value m_base_value {};
|
|
mutable Environment* m_base_environment;
|
|
};
|
|
Variant<PropertyKey, PrivateName> m_name;
|
|
Optional<Value> m_this_value;
|
|
Strict m_strict { Strict::No };
|
|
|
|
Optional<EnvironmentCoordinate> m_environment_coordinate;
|
|
};
|
|
|
|
}
|