diff options
Diffstat (limited to '')
-rw-r--r-- | js/src/vm/BindingKind.h | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/js/src/vm/BindingKind.h b/js/src/vm/BindingKind.h new file mode 100644 index 0000000000..793aa7e82f --- /dev/null +++ b/js/src/vm/BindingKind.h @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set ts=8 sts=2 et sw=2 tw=80: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef vm_BindingKind_h +#define vm_BindingKind_h + +#include "mozilla/Assertions.h" // MOZ_ASSERT, MOZ_ASSERT_IF +#include "mozilla/Casting.h" // mozilla::AssertedCast + +#include <stdint.h> // uint16_t, uint32_t + +#include "vm/BytecodeUtil.h" // LOCALNO_LIMIT, ENVCOORD_SLOT_LIMIT + +namespace js { + +enum class BindingKind : uint8_t { + Import, + FormalParameter, + Var, + Let, + Const, + + // So you think named lambda callee names are consts? Nope! They don't + // throw when being assigned to in sloppy mode. + NamedLambdaCallee, + + // ClassBodyScope bindings that aren't bindings in the spec, but are put into + // a scope as an implementation detail: `.privateBrand`, + // `.staticInitializers`, private names, and private accessor functions. + Synthetic, + + // ClassBodyScope binding that stores the function object for a non-static + // private method. + PrivateMethod, +}; + +static inline bool BindingKindIsLexical(BindingKind kind) { + return kind == BindingKind::Let || kind == BindingKind::Const; +} + +class BindingLocation { + public: + enum class Kind { + Global, + Argument, + Frame, + Environment, + Import, + NamedLambdaCallee + }; + + private: + Kind kind_; + uint32_t slot_; + + BindingLocation(Kind kind, uint32_t slot) : kind_(kind), slot_(slot) {} + + public: + static BindingLocation Global() { + return BindingLocation(Kind::Global, UINT32_MAX); + } + + static BindingLocation Argument(uint16_t slot) { + return BindingLocation(Kind::Argument, slot); + } + + static BindingLocation Frame(uint32_t slot) { + MOZ_ASSERT(slot < LOCALNO_LIMIT); + return BindingLocation(Kind::Frame, slot); + } + + static BindingLocation Environment(uint32_t slot) { + MOZ_ASSERT(slot < ENVCOORD_SLOT_LIMIT); + return BindingLocation(Kind::Environment, slot); + } + + static BindingLocation Import() { + return BindingLocation(Kind::Import, UINT32_MAX); + } + + static BindingLocation NamedLambdaCallee() { + return BindingLocation(Kind::NamedLambdaCallee, UINT32_MAX); + } + + bool operator==(const BindingLocation& other) const { + return kind_ == other.kind_ && slot_ == other.slot_; + } + + bool operator!=(const BindingLocation& other) const { + return !operator==(other); + } + + Kind kind() const { return kind_; } + + uint32_t slot() const { + MOZ_ASSERT(kind_ == Kind::Frame || kind_ == Kind::Environment); + return slot_; + } + + uint16_t argumentSlot() const { + MOZ_ASSERT(kind_ == Kind::Argument); + return mozilla::AssertedCast<uint16_t>(slot_); + } +}; + +} // namespace js + +#endif // vm_BindingKind_h |