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
26 // So you think named lambda callee names are consts? Nope! They don't
27 // throw when being assigned to in sloppy mode.
28 NamedLambdaCallee,
29
30 // ClassBodyScope bindings that aren't bindings in the spec, but are put into
31 // a scope as an implementation detail: `.privateBrand`,
32 // `.staticInitializers`, private names, and private accessor functions.
33 Synthetic,
34
35 // ClassBodyScope binding that stores the function object for a non-static
36 // private method.
37 PrivateMethod,
38 };
39
BindingKindIsLexical(BindingKind kind)40 static inline bool BindingKindIsLexical(BindingKind kind) {
41 return kind == BindingKind::Let || kind == BindingKind::Const;
42 }
43
44 class BindingLocation {
45 public:
46 enum class Kind {
47 Global,
48 Argument,
49 Frame,
50 Environment,
51 Import,
52 NamedLambdaCallee
53 };
54
55 private:
56 Kind kind_;
57 uint32_t slot_;
58
BindingLocation(Kind kind,uint32_t slot)59 BindingLocation(Kind kind, uint32_t slot) : kind_(kind), slot_(slot) {}
60
61 public:
Global()62 static BindingLocation Global() {
63 return BindingLocation(Kind::Global, UINT32_MAX);
64 }
65
Argument(uint16_t slot)66 static BindingLocation Argument(uint16_t slot) {
67 return BindingLocation(Kind::Argument, slot);
68 }
69
Frame(uint32_t slot)70 static BindingLocation Frame(uint32_t slot) {
71 MOZ_ASSERT(slot < LOCALNO_LIMIT);
72 return BindingLocation(Kind::Frame, slot);
73 }
74
Environment(uint32_t slot)75 static BindingLocation Environment(uint32_t slot) {
76 MOZ_ASSERT(slot < ENVCOORD_SLOT_LIMIT);
77 return BindingLocation(Kind::Environment, slot);
78 }
79
Import()80 static BindingLocation Import() {
81 return BindingLocation(Kind::Import, UINT32_MAX);
82 }
83
NamedLambdaCallee()84 static BindingLocation NamedLambdaCallee() {
85 return BindingLocation(Kind::NamedLambdaCallee, UINT32_MAX);
86 }
87
88 bool operator==(const BindingLocation& other) const {
89 return kind_ == other.kind_ && slot_ == other.slot_;
90 }
91
92 bool operator!=(const BindingLocation& other) const {
93 return !operator==(other);
94 }
95
kind()96 Kind kind() const { return kind_; }
97
slot()98 uint32_t slot() const {
99 MOZ_ASSERT(kind_ == Kind::Frame || kind_ == Kind::Environment);
100 return slot_;
101 }
102
argumentSlot()103 uint16_t argumentSlot() const {
104 MOZ_ASSERT(kind_ == Kind::Argument);
105 return mozilla::AssertedCast<uint16_t>(slot_);
106 }
107 };
108
109 } // namespace js
110
111 #endif // vm_BindingKind_h
112