Bug 1867190 - Add prefs for PHC probablities r=glandium
[gecko.git] / js / src / frontend / PropOpEmitter.h
blob76402025ea0ecf07c1df1690e0b16526007077dd
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 "vm/SharedStencil.h" // GCThingIndex
14 namespace js {
15 namespace frontend {
17 struct BytecodeEmitter;
18 class TaggedParserAtomIndex;
19 enum class ValueUsage;
21 // Class for emitting bytecode for property operation.
23 // Usage: (check for the return value is omitted for simplicity)
25 // `obj.prop;`
26 // PropOpEmitter poe(this,
27 // PropOpEmitter::Kind::Get,
28 // PropOpEmitter::ObjKind::Other);
29 // poe.prepareForObj();
30 // emit(obj);
31 // poe.emitGet(atom_of_prop);
33 // `super.prop;`
34 // PropOpEmitter poe(this,
35 // PropOpEmitter::Kind::Get,
36 // PropOpEmitter::ObjKind::Super);
37 // poe.prepareForObj();
38 // emit(obj);
39 // poe.emitGet(atom_of_prop);
41 // `obj.prop();`
42 // PropOpEmitter poe(this,
43 // PropOpEmitter::Kind::Call,
44 // PropOpEmitter::ObjKind::Other);
45 // poe.prepareForObj();
46 // emit(obj);
47 // poe.emitGet(atom_of_prop);
48 // emit_call_here();
50 // `new obj.prop();`
51 // PropOpEmitter poe(this,
52 // PropOpEmitter::Kind::Call,
53 // PropOpEmitter::ObjKind::Other);
54 // poe.prepareForObj();
55 // emit(obj);
56 // poe.emitGet(atom_of_prop);
57 // emit_call_here();
59 // `delete obj.prop;`
60 // PropOpEmitter poe(this,
61 // PropOpEmitter::Kind::Delete,
62 // PropOpEmitter::ObjKind::Other);
63 // poe.prepareForObj();
64 // emit(obj);
65 // poe.emitDelete(atom_of_prop);
67 // `delete super.prop;`
68 // PropOpEmitter poe(this,
69 // PropOpEmitter::Kind::Delete,
70 // PropOpEmitter::ObjKind::Other);
71 // poe.emitDelete(atom_of_prop);
73 // `obj.prop++;`
74 // PropOpEmitter poe(this,
75 // PropOpEmitter::Kind::PostIncrement,
76 // PropOpEmitter::ObjKind::Other);
77 // poe.prepareForObj();
78 // emit(obj);
79 // poe.emitIncDec(atom_of_prop);
81 // `obj.prop = value;`
82 // PropOpEmitter poe(this,
83 // PropOpEmitter::Kind::SimpleAssignment,
84 // PropOpEmitter::ObjKind::Other);
85 // poe.prepareForObj();
86 // emit(obj);
87 // poe.prepareForRhs();
88 // emit(value);
89 // poe.emitAssignment(atom_of_prop);
91 // `obj.prop += value;`
92 // PropOpEmitter poe(this,
93 // PropOpEmitter::Kind::CompoundAssignment,
94 // PropOpEmitter::ObjKind::Other);
95 // poe.prepareForObj();
96 // emit(obj);
97 // poe.emitGet(atom_of_prop);
98 // poe.prepareForRhs();
99 // emit(value);
100 // emit_add_op_here();
101 // poe.emitAssignment(nullptr); // nullptr for CompoundAssignment
103 class MOZ_STACK_CLASS PropOpEmitter {
104 public:
105 enum class Kind {
106 Get,
107 Call,
108 Delete,
109 PostIncrement,
110 PreIncrement,
111 PostDecrement,
112 PreDecrement,
113 SimpleAssignment,
114 PropInit,
115 CompoundAssignment
117 enum class ObjKind { Super, Other };
119 private:
120 BytecodeEmitter* bce_;
122 Kind kind_;
123 ObjKind objKind_;
125 // The index for the property name's atom.
126 GCThingIndex propAtomIndex_;
128 #ifdef DEBUG
129 // The state of this emitter.
131 // skipObjAndRhs
132 // +----------------------------+
133 // | |
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 or skipObjAndRhs.
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();
240 [[nodiscard]] bool skipObjAndRhs();
242 [[nodiscard]] bool emitDelete(TaggedParserAtomIndex prop);
244 // `prop` can be nullptr for CompoundAssignment.
245 [[nodiscard]] bool emitAssignment(TaggedParserAtomIndex prop);
247 [[nodiscard]] bool emitIncDec(TaggedParserAtomIndex prop,
248 ValueUsage valueUsage);
251 } /* namespace frontend */
252 } /* namespace js */
254 #endif /* frontend_PropOpEmitter_h */