BindingKind.h (3014B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef vm_BindingKind_h 8 #define vm_BindingKind_h 9 10 #include "mozilla/Assertions.h" // MOZ_ASSERT, MOZ_ASSERT_IF 11 #include "mozilla/Casting.h" // mozilla::AssertedCast 12 13 #include <stdint.h> // uint16_t, uint32_t 14 15 #include "vm/BytecodeUtil.h" // LOCALNO_LIMIT, ENVCOORD_SLOT_LIMIT 16 17 namespace js { 18 19 enum class BindingKind : uint8_t { 20 Import, 21 FormalParameter, 22 Var, 23 Let, 24 Const, 25 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT 26 Using, 27 #endif 28 29 // So you think named lambda callee names are consts? Nope! They don't 30 // throw when being assigned to in sloppy mode. 31 NamedLambdaCallee, 32 33 // ClassBodyScope bindings that aren't bindings in the spec, but are put into 34 // a scope as an implementation detail: `.privateBrand`, 35 // `.staticInitializers`, private names, and private accessor functions. 36 Synthetic, 37 38 // ClassBodyScope binding that stores the function object for a non-static 39 // private method. 40 PrivateMethod, 41 }; 42 43 static inline bool BindingKindIsLexical(BindingKind kind) { 44 return kind == BindingKind::Let || kind == BindingKind::Const 45 #ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT 46 || kind == BindingKind::Using 47 #endif 48 ; 49 } 50 51 class BindingLocation { 52 public: 53 enum class Kind { 54 Global, 55 Argument, 56 Frame, 57 Environment, 58 Import, 59 NamedLambdaCallee 60 }; 61 62 private: 63 Kind kind_; 64 uint32_t slot_; 65 66 BindingLocation(Kind kind, uint32_t slot) : kind_(kind), slot_(slot) {} 67 68 public: 69 static BindingLocation Global() { 70 return BindingLocation(Kind::Global, UINT32_MAX); 71 } 72 73 static BindingLocation Argument(uint16_t slot) { 74 return BindingLocation(Kind::Argument, slot); 75 } 76 77 static BindingLocation Frame(uint32_t slot) { 78 MOZ_ASSERT(slot < LOCALNO_LIMIT); 79 return BindingLocation(Kind::Frame, slot); 80 } 81 82 static BindingLocation Environment(uint32_t slot) { 83 MOZ_ASSERT(slot < ENVCOORD_SLOT_LIMIT); 84 return BindingLocation(Kind::Environment, slot); 85 } 86 87 static BindingLocation Import() { 88 return BindingLocation(Kind::Import, UINT32_MAX); 89 } 90 91 static BindingLocation NamedLambdaCallee() { 92 return BindingLocation(Kind::NamedLambdaCallee, UINT32_MAX); 93 } 94 95 bool operator==(const BindingLocation& other) const { 96 return kind_ == other.kind_ && slot_ == other.slot_; 97 } 98 99 bool operator!=(const BindingLocation& other) const { 100 return !operator==(other); 101 } 102 103 Kind kind() const { return kind_; } 104 105 uint32_t slot() const { 106 MOZ_ASSERT(kind_ == Kind::Frame || kind_ == Kind::Environment); 107 return slot_; 108 } 109 110 uint16_t argumentSlot() const { 111 MOZ_ASSERT(kind_ == Kind::Argument); 112 return mozilla::AssertedCast<uint16_t>(slot_); 113 } 114 }; 115 116 } // namespace js 117 118 #endif // vm_BindingKind_h