Backed out 4 changesets (bug 1454816) for causing build bustages. CLOSED TREE
[gecko.git] / js / src / frontend / PropOpEmitter.h
blob91a182685fa545b6cd21c7b87001e448df01f66e
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/. */
7 #ifndef frontend_PropOpEmitter_h
8 #define frontend_PropOpEmitter_h
10 #include "mozilla/Attributes.h"
12 #include <stddef.h>
14 #include "vm/SharedStencil.h" // GCThingIndex
16 namespace js {
17 namespace frontend {
19 struct BytecodeEmitter;
20 class TaggedParserAtomIndex;
21 enum class ValueUsage;
23 // Class for emitting bytecode for property operation.
25 // Usage: (check for the return value is omitted for simplicity)
27 // `obj.prop;`
28 // PropOpEmitter poe(this,
29 // PropOpEmitter::Kind::Get,
30 // PropOpEmitter::ObjKind::Other);
31 // poe.prepareForObj();
32 // emit(obj);
33 // poe.emitGet(atom_of_prop);
35 // `super.prop;`
36 // PropOpEmitter poe(this,
37 // PropOpEmitter::Kind::Get,
38 // PropOpEmitter::ObjKind::Super);
39 // poe.prepareForObj();
40 // emit(obj);
41 // poe.emitGet(atom_of_prop);
43 // `obj.prop();`
44 // PropOpEmitter poe(this,
45 // PropOpEmitter::Kind::Call,
46 // PropOpEmitter::ObjKind::Other);
47 // poe.prepareForObj();
48 // emit(obj);
49 // poe.emitGet(atom_of_prop);
50 // emit_call_here();
52 // `new obj.prop();`
53 // PropOpEmitter poe(this,
54 // PropOpEmitter::Kind::Call,
55 // PropOpEmitter::ObjKind::Other);
56 // poe.prepareForObj();
57 // emit(obj);
58 // poe.emitGet(atom_of_prop);
59 // emit_call_here();
61 // `delete obj.prop;`
62 // PropOpEmitter poe(this,
63 // PropOpEmitter::Kind::Delete,
64 // PropOpEmitter::ObjKind::Other);
65 // poe.prepareForObj();
66 // emit(obj);
67 // poe.emitDelete(atom_of_prop);
69 // `delete super.prop;`
70 // PropOpEmitter poe(this,
71 // PropOpEmitter::Kind::Delete,
72 // PropOpEmitter::ObjKind::Other);
73 // poe.emitDelete(atom_of_prop);
75 // `obj.prop++;`
76 // PropOpEmitter poe(this,
77 // PropOpEmitter::Kind::PostIncrement,
78 // PropOpEmitter::ObjKind::Other);
79 // poe.prepareForObj();
80 // emit(obj);
81 // poe.emitIncDec(atom_of_prop);
83 // `obj.prop = value;`
84 // PropOpEmitter poe(this,
85 // PropOpEmitter::Kind::SimpleAssignment,
86 // PropOpEmitter::ObjKind::Other);
87 // poe.prepareForObj();
88 // emit(obj);
89 // poe.prepareForRhs();
90 // emit(value);
91 // poe.emitAssignment(atom_of_prop);
93 // `obj.prop += value;`
94 // PropOpEmitter poe(this,
95 // PropOpEmitter::Kind::CompoundAssignment,
96 // PropOpEmitter::ObjKind::Other);
97 // poe.prepareForObj();
98 // emit(obj);
99 // poe.emitGet(atom_of_prop);
100 // poe.prepareForRhs();
101 // emit(value);
102 // emit_add_op_here();
103 // poe.emitAssignment(nullptr); // nullptr for CompoundAssignment
105 class MOZ_STACK_CLASS PropOpEmitter {
106 public:
107 enum class Kind {
108 Get,
109 Call,
110 Delete,
111 PostIncrement,
112 PreIncrement,
113 PostDecrement,
114 PreDecrement,
115 SimpleAssignment,
116 PropInit,
117 CompoundAssignment
119 enum class ObjKind { Super, Other };
121 private:
122 BytecodeEmitter* bce_;
124 Kind kind_;
125 ObjKind objKind_;
127 // The index for the property name's atom.
128 GCThingIndex propAtomIndex_;
130 #ifdef DEBUG
131 // The state of this emitter.
134 // +-------+ prepareForObj +-----+
135 // | Start |---------------->| Obj |-+
136 // +-------+ +-----+ |
137 // |
138 // +---------------------------------+
139 // |
140 // |
141 // | [Get]
142 // | [Call]
143 // | emitGet +-----+
144 // +---------->| Get |
145 // | +-----+
146 // |
147 // | [Delete]
148 // | emitDelete +--------+
149 // +------------->| Delete |
150 // | +--------+
151 // |
152 // | [PostIncrement]
153 // | [PreIncrement]
154 // | [PostDecrement]
155 // | [PreDecrement]
156 // | emitIncDec +--------+
157 // +------------->| IncDec |
158 // | +--------+
159 // |
160 // | [SimpleAssignment]
161 // | [PropInit]
162 // | prepareForRhs +-----+
163 // +--------------------->+----------------->| Rhs |-+
164 // | ^ +-----+ |
165 // | | |
166 // | | +---------+
167 // | [CompoundAssignment] | |
168 // | emitGet +-----+ | | emitAssignment +------------+
169 // +---------->| Get |----+ + -------------->| Assignment |
170 // +-----+ +------------+
171 enum class State {
172 // The initial state.
173 Start,
175 // After calling prepareForObj.
176 Obj,
178 // After calling emitGet.
179 Get,
181 // After calling emitDelete.
182 Delete,
184 // After calling emitIncDec.
185 IncDec,
187 // After calling prepareForRhs.
188 Rhs,
190 // After calling emitAssignment.
191 Assignment,
193 State state_ = State::Start;
194 #endif
196 public:
197 PropOpEmitter(BytecodeEmitter* bce, Kind kind, ObjKind objKind);
199 private:
200 [[nodiscard]] bool isCall() const { return kind_ == Kind::Call; }
202 [[nodiscard]] bool isSuper() const { return objKind_ == ObjKind::Super; }
204 [[nodiscard]] bool isSimpleAssignment() const {
205 return kind_ == Kind::SimpleAssignment;
208 [[nodiscard]] bool isPropInit() const { return kind_ == Kind::PropInit; }
210 [[nodiscard]] bool isDelete() const { return kind_ == Kind::Delete; }
212 [[nodiscard]] bool isCompoundAssignment() const {
213 return kind_ == Kind::CompoundAssignment;
216 [[nodiscard]] bool isIncDec() const {
217 return isPostIncDec() || isPreIncDec();
220 [[nodiscard]] bool isPostIncDec() const {
221 return kind_ == Kind::PostIncrement || kind_ == Kind::PostDecrement;
224 [[nodiscard]] bool isPreIncDec() const {
225 return kind_ == Kind::PreIncrement || kind_ == Kind::PreDecrement;
228 [[nodiscard]] bool isInc() const {
229 return kind_ == Kind::PostIncrement || kind_ == Kind::PreIncrement;
232 [[nodiscard]] bool prepareAtomIndex(TaggedParserAtomIndex prop);
234 public:
235 [[nodiscard]] bool prepareForObj();
237 [[nodiscard]] bool emitGet(TaggedParserAtomIndex prop);
239 [[nodiscard]] bool prepareForRhs();
241 [[nodiscard]] bool emitDelete(TaggedParserAtomIndex prop);
243 // `prop` can be nullptr for CompoundAssignment.
244 [[nodiscard]] bool emitAssignment(TaggedParserAtomIndex prop);
246 [[nodiscard]] bool emitIncDec(TaggedParserAtomIndex prop,
247 ValueUsage valueUsage);
249 size_t numReferenceSlots() const { return 1 + isSuper(); }
252 } /* namespace frontend */
253 } /* namespace js */
255 #endif /* frontend_PropOpEmitter_h */