--- af48b695bea3268b0db1123d7c67a729cbffac3a/js/src/frontend/DoWhileEmitter.cpp
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/DoWhileEmitter.cpp
@@ -9,40 +9,34 @@
#include "frontend/BytecodeEmitter.h"
#include "frontend/SourceNotes.h"
#include "vm/Opcodes.h"
#include "vm/StencilEnums.h" // TryNoteKind
using namespace js;
using namespace js::frontend;
-using mozilla::Maybe;
-using mozilla::Nothing;
-
DoWhileEmitter::DoWhileEmitter(BytecodeEmitter* bce) : bce_(bce) {}
-bool DoWhileEmitter::emitBody(const Maybe<uint32_t>& doPos,
- const Maybe<uint32_t>& bodyPos) {
+bool DoWhileEmitter::emitBody(uint32_t doPos, uint32_t bodyPos) {
MOZ_ASSERT(state_ == State::Start);
// Ensure that the column of the 'do' is set properly.
- if (doPos) {
- if (!bce_->updateSourceCoordNotes(*doPos)) {
- return false;
- }
+ if (!bce_->updateSourceCoordNotes(doPos)) {
+ return false;
}
// We need a nop here to make it possible to set a breakpoint on `do`.
if (!bce_->emit1(JSOp::Nop)) {
return false;
}
loopInfo_.emplace(bce_, StatementKind::DoLoop);
- if (!loopInfo_->emitLoopHead(bce_, bodyPos)) {
+ if (!loopInfo_->emitLoopHead(bce_, mozilla::Some(bodyPos))) {
return false;
}
#ifdef DEBUG
state_ = State::Body;
#endif
return true;
}
--- b4978b94e6054328409c38ba4c365c1132fef20c/js/src/frontend/EmitterScope.cpp
+++ 4036a68b398ad551903599206007598802bcf95f/js/src/frontend/EmitterScope.cpp
@@ -1002,17 +1002,17 @@ uint32_t EmitterScope::CountEnclosingCom
while ((emitterScope = emitterScope->enclosing(&bce))) {
if (emitterScope->hasEnvironment()) {
environments++;
}
}
return environments;
}
-bool EmitterScope::lookupPrivate(BytecodeEmitter* bce,
+void EmitterScope::lookupPrivate(BytecodeEmitter* bce,
TaggedParserAtomIndex name, NameLocation& loc,
mozilla::Maybe<NameLocation>& brandLoc) {
loc = lookup(bce, name);
// Private Brand checking relies on the ability to construct a new
// environment coordinate for a name at a fixed offset, which will
// correspond to the private brand for that class.
//
@@ -1060,17 +1060,17 @@ bool EmitterScope::lookupPrivate(Bytecod
uint32_t external_hops = cacheEntry->environmentCoordinate().hops();
brandLoc = Some(NameLocation::DebugEnvironmentCoordinate(
BindingKind::Synthetic, compilation_hops + external_hops,
ClassBodyLexicalEnvironmentObject::privateBrandSlot()));
} else {
brandLoc = Nothing();
}
- return true;
+ return;
}
if (loc.bindingKind() == BindingKind::PrivateMethod) {
uint32_t hops = 0;
if (loc.kind() == NameLocation::Kind::EnvironmentCoordinate) {
hops = loc.environmentCoordinate().hops();
} else {
// If we have a FrameSlot, then our innermost emitter scope must be a
@@ -1080,17 +1080,16 @@ bool EmitterScope::lookupPrivate(Bytecod
}
brandLoc = Some(NameLocation::EnvironmentCoordinate(
BindingKind::Synthetic, hops,
ClassBodyLexicalEnvironmentObject::privateBrandSlot()));
} else {
brandLoc = Nothing();
}
- return true;
}
Maybe<NameLocation> EmitterScope::locationBoundInScope(
TaggedParserAtomIndex name, EmitterScope* target) {
// The target scope must be an intra-frame enclosing scope of this
// one. Count the number of extra hops to reach it.
uint8_t extraHops = 0;
for (EmitterScope* es = this; es != target; es = es->enclosingInFrame()) {
--- ea02687ba7fefa71bfaad3294ca8328b7fe706b0/js/src/frontend/EmitterScope.h
+++ 4036a68b398ad551903599206007598802bcf95f/js/src/frontend/EmitterScope.h
@@ -187,20 +187,17 @@ class EmitterScope : public Nestable<Emi
// have `.privateBrand` bindings. In a normal `lookup`, the inner binding
// would shadow the outer one.
//
// This method instead sets `brandLoc` to the location of the `.privateBrand`
// binding in the same class body as the private name `name`, ignoring
// shadowing. If `name` refers to a name that is actually stamped onto the
// target object (anything other than a non-static private method), then
// `brandLoc` is set to Nothing.
- //
- // To handle cases where it's not possible to find the private brand, this
- // method has to be fallible.
- bool lookupPrivate(BytecodeEmitter* bce, TaggedParserAtomIndex name,
+ void lookupPrivate(BytecodeEmitter* bce, TaggedParserAtomIndex name,
NameLocation& loc, mozilla::Maybe<NameLocation>& brandLoc);
mozilla::Maybe<NameLocation> locationBoundInScope(TaggedParserAtomIndex name,
EmitterScope* target);
// For a given emitter scope, return the number of enclosing environments in
// the current compilation (this excludes environments that could enclose the
// compilation, like would happen for an eval copmilation).
--- bfaa95b5e04a36143ef2d3cff446cdda75cb5fab/js/src/frontend/ExpressionStatementEmitter.h
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/ExpressionStatementEmitter.h
@@ -3,17 +3,16 @@
* 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 frontend_ExpressionStatementEmitter_h
#define frontend_ExpressionStatementEmitter_h
#include "mozilla/Attributes.h"
-#include "mozilla/Maybe.h"
#include <stdint.h>
#include "frontend/ValueUsage.h"
namespace js {
namespace frontend {
@@ -24,17 +23,17 @@ struct BytecodeEmitter;
// Usage: (check for the return value is omitted for simplicity)
//
// `expr;`
// // IgnoreValue if this is in normal script.
// // WantValue if this is in eval script.
// ValueUsage valueUsage = ...;
//
// ExpressionStatementEmitter ese(this, valueUsage);
-// ese.prepareForExpr(Some(offset_of_expr));
+// ese.prepareForExpr(offset_of_expr);
// emit(expr);
// ese.emitEnd();
//
class MOZ_STACK_CLASS ExpressionStatementEmitter {
BytecodeEmitter* bce_;
#ifdef DEBUG
// The stack depth before emitting expression.
@@ -67,18 +66,16 @@ class MOZ_STACK_CLASS ExpressionStatemen
ExpressionStatementEmitter(BytecodeEmitter* bce, ValueUsage valueUsage);
// Parameters are the offset in the source code for each character below:
//
// expr;
// ^
// |
// beginPos
- //
- // Can be Nothing() if not available.
- [[nodiscard]] bool prepareForExpr(const mozilla::Maybe<uint32_t>& beginPos);
+ [[nodiscard]] bool prepareForExpr(uint32_t beginPos);
[[nodiscard]] bool emitEnd();
};
} // namespace frontend
} // namespace js
#endif /* frontend_ExpressionStatementEmitter_h */
--- af48b695bea3268b0db1123d7c67a729cbffac3a/js/src/frontend/ForOfEmitter.cpp
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/ForOfEmitter.cpp
@@ -13,17 +13,16 @@
#include "frontend/SourceNotes.h"
#include "vm/Opcodes.h"
#include "vm/Scope.h"
#include "vm/StencilEnums.h" // TryNoteKind
using namespace js;
using namespace js::frontend;
-using mozilla::Maybe;
using mozilla::Nothing;
ForOfEmitter::ForOfEmitter(BytecodeEmitter* bce,
const EmitterScope* headLexicalEmitterScope,
bool allowSelfHostedIter, IteratorKind iterKind)
: bce_(bce),
allowSelfHostedIter_(allowSelfHostedIter),
iterKind_(iterKind),
@@ -38,17 +37,17 @@ bool ForOfEmitter::emitIterated() {
tdzCacheForIteratedValue_.emplace(bce_);
#ifdef DEBUG
state_ = State::Iterated;
#endif
return true;
}
-bool ForOfEmitter::emitInitialize(const Maybe<uint32_t>& forPos) {
+bool ForOfEmitter::emitInitialize(uint32_t forPos) {
MOZ_ASSERT(state_ == State::Iterated);
tdzCacheForIteratedValue_.reset();
if (iterKind_ == IteratorKind::Async) {
if (!bce_->emitAsyncIterator()) {
// [stack] NEXT ITER
return false;
@@ -96,28 +95,27 @@ bool ForOfEmitter::emitInitialize(const
}
}
#ifdef DEBUG
loopDepth_ = bce_->bytecodeSection().stackDepth();
#endif
// Make sure this code is attributed to the "for".
- if (forPos) {
- if (!bce_->updateSourceCoordNotes(*forPos)) {
- return false;
- }
+ if (!bce_->updateSourceCoordNotes(forPos)) {
+ return false;
}
if (!bce_->emit1(JSOp::Dup2)) {
// [stack] NEXT ITER NEXT ITER
return false;
}
- if (!bce_->emitIteratorNext(forPos, iterKind_, allowSelfHostedIter_)) {
+ if (!bce_->emitIteratorNext(mozilla::Some(forPos), iterKind_,
+ allowSelfHostedIter_)) {
// [stack] NEXT ITER RESULT
return false;
}
if (!bce_->emit1(JSOp::Dup)) {
// [stack] NEXT ITER RESULT RESULT
return false;
}
@@ -163,17 +161,17 @@ bool ForOfEmitter::emitBody() {
"operation");
#ifdef DEBUG
state_ = State::Body;
#endif
return true;
}
-bool ForOfEmitter::emitEnd(const Maybe<uint32_t>& iteratedPos) {
+bool ForOfEmitter::emitEnd(uint32_t iteratedPos) {
MOZ_ASSERT(state_ == State::Body);
MOZ_ASSERT(bce_->bytecodeSection().stackDepth() == loopDepth_ + 1,
"the stack must be balanced around the for-of body");
if (!loopInfo_->emitEndCodeNeedingIteratorClose(bce_)) {
// [stack] NEXT ITER VALUE
return false;
@@ -183,20 +181,18 @@ bool ForOfEmitter::emitEnd(const Maybe<u
// [stack] NEXT ITER VALUE
return false;
}
// We use the iterated value's position to attribute the backedge,
// which corresponds to the iteration protocol.
// This is a bit misleading for 2nd and later iterations and might need
// some fix (bug 1482003).
- if (iteratedPos) {
- if (!bce_->updateSourceCoordNotes(*iteratedPos)) {
- return false;
- }
+ if (!bce_->updateSourceCoordNotes(iteratedPos)) {
+ return false;
}
if (!bce_->emit1(JSOp::Pop)) {
// [stack] NEXT ITER
return false;
}
if (!loopInfo_->emitLoopEnd(bce_, JSOp::Goto, TryNoteKind::ForOf)) {
--- a670453eafa37490a13b0e2c86640ba2b7854886/js/src/frontend/WhileEmitter.cpp
+++ 32bb1dfaf41b36d433295f58a7bb4077432d5da4/js/src/frontend/WhileEmitter.cpp
@@ -9,46 +9,42 @@
#include "frontend/BytecodeEmitter.h"
#include "frontend/SourceNotes.h"
#include "vm/Opcodes.h"
#include "vm/StencilEnums.h" // TryNoteKind
using namespace js;
using namespace js::frontend;
-using mozilla::Maybe;
-
WhileEmitter::WhileEmitter(BytecodeEmitter* bce) : bce_(bce) {}
-bool WhileEmitter::emitCond(const Maybe<uint32_t>& whilePos,
- const Maybe<uint32_t>& condPos,
- const Maybe<uint32_t>& endPos) {
+bool WhileEmitter::emitCond(uint32_t whilePos, uint32_t condPos,
+ uint32_t endPos) {
MOZ_ASSERT(state_ == State::Start);
// If we have a single-line while, like "while (x) ;", we want to emit the
// line note before the loop, so that the debugger sees a single entry point.
// This way, if there is a breakpoint on the line, it will only fire once; and
// "next"ing will skip the whole loop. However, for the multi-line case we
// want to emit the line note for the JSOp::LoopHead, so that "cont" stops on
// each iteration -- but without a stop before the first iteration.
- if (whilePos && endPos &&
- bce_->parser->errorReporter().lineAt(*whilePos) ==
- bce_->parser->errorReporter().lineAt(*endPos)) {
- if (!bce_->updateSourceCoordNotes(*whilePos)) {
+ if (bce_->parser->errorReporter().lineAt(whilePos) ==
+ bce_->parser->errorReporter().lineAt(endPos)) {
+ if (!bce_->updateSourceCoordNotes(whilePos)) {
return false;
}
// Emit a Nop to ensure the source position is not part of the loop.
if (!bce_->emit1(JSOp::Nop)) {
return false;
}
}
loopInfo_.emplace(bce_, StatementKind::WhileLoop);
- if (!loopInfo_->emitLoopHead(bce_, condPos)) {
+ if (!loopInfo_->emitLoopHead(bce_, mozilla::Some(condPos))) {
return false;
}
#ifdef DEBUG
state_ = State::Cond;
#endif
return true;
}
--- 84ccc63222c2237308430c9491ffb2d274b7977e/js/src/vm/Opcodes.h
+++ 5e6d1848ce620a905a1d5de23ca5b9e4e0eaa2af/js/src/vm/Opcodes.h
@@ -1157,24 +1157,32 @@
*
* Two arguments:
* - throwCondition: One of the ThrowConditions defined in
* ThrowMsgKind.h. Determines why (or if) this op will throw.
* - msgKind: One of the ThrowMsgKinds defined in ThrowMsgKind.h, which
* maps to one of the messages in js.msg. Note: It's not possible to
* pass arguments to the message at the moment.
*
- * Category: Control flow
* Category: Objects
* Type: Accessing properties
* Operands: ThrowCondition throwCondition, ThrowMsgKind msgKind
* Stack: obj, key => obj, key, (obj.hasOwnProperty(id))
*/ \
MACRO(CheckPrivateField, check_private_field, NULL, 3, 2, 3, JOF_TWO_UINT8|JOF_CHECKSTRICT|JOF_IC) \
/*
+ * Push a new private name.
+ *
+ * Category: Objects
+ * Type: Accessing properties
+ * Operands: uint32_t nameIndex
+ * Stack: => private_name
+ */ \
+ MACRO(NewPrivateName, new_private_name, NULL, 5, 0, 1, JOF_ATOM) \
+ /*
* Push the SuperBase of the method `callee`. The SuperBase is
* `callee.[[HomeObject]].[[GetPrototypeOf]]()`, the object where `super`
* property lookups should begin.
*
* `callee` must be a function that has a HomeObject that's an object,
* typically produced by `JSOp::Callee` or `JSOp::EnvCallee`.
*
* Implements: [GetSuperBase][1], except that instead of the environment,
@@ -3509,17 +3517,16 @@
// clang-format on
/*
* In certain circumstances it may be useful to "pad out" the opcode space to
* a power of two. Use this macro to do so.
*/
#define FOR_EACH_TRAILING_UNUSED_OPCODE(MACRO) \
- MACRO(227) \
MACRO(228) \
MACRO(229) \
MACRO(230) \
MACRO(231) \
MACRO(232) \
MACRO(233) \
MACRO(234) \
MACRO(235) \
Files
/js/src/frontend/BytecodeEmitter.cpp
/js/src/frontend/BytecodeEmitter.h
/js/src/frontend/CForEmitter.cpp
/js/src/frontend/CForEmitter.h
/js/src/frontend/CallOrNewEmitter.cpp
/js/src/frontend/CallOrNewEmitter.h
/js/src/frontend/DefaultEmitter.cpp
/js/src/frontend/DoWhileEmitter.cpp
/js/src/frontend/DoWhileEmitter.h
/js/src/frontend/EmitterScope.cpp
/js/src/frontend/EmitterScope.h
/js/src/frontend/ExpressionStatementEmitter.cpp
/js/src/frontend/ExpressionStatementEmitter.h
/js/src/frontend/ForInEmitter.cpp
/js/src/frontend/ForInEmitter.h
/js/src/frontend/ForOfEmitter.cpp
/js/src/frontend/ForOfEmitter.h
/js/src/frontend/ObjectEmitter.cpp
/js/src/frontend/ObjectEmitter.h
/js/src/frontend/OptionalEmitter.h
/js/src/frontend/SwitchEmitter.cpp
/js/src/frontend/SwitchEmitter.h
/js/src/frontend/WhileEmitter.cpp
/js/src/frontend/WhileEmitter.h
/js/src/vm/BytecodeUtil.cpp
/js/src/vm/BytecodeUtil.h
/js/src/vm/Opcodes.h
/js/src/vm/SharedStencil.h
Changesets
Diffs
/js/src/frontend/BytecodeEmitter.cpp
/js/src/frontend/BytecodeEmitter.h
/js/src/frontend/CForEmitter.cpp
/js/src/frontend/CForEmitter.h
/js/src/frontend/CallOrNewEmitter.cpp
/js/src/frontend/CallOrNewEmitter.h
/js/src/frontend/DefaultEmitter.cpp
/js/src/frontend/DoWhileEmitter.cpp
/js/src/frontend/DoWhileEmitter.h
/js/src/frontend/EmitterScope.cpp
/js/src/frontend/EmitterScope.h
/js/src/frontend/ExpressionStatementEmitter.cpp
/js/src/frontend/ExpressionStatementEmitter.h
/js/src/frontend/ForInEmitter.cpp
/js/src/frontend/ForInEmitter.h
/js/src/frontend/ForOfEmitter.cpp
/js/src/frontend/ForOfEmitter.h
/js/src/frontend/ObjectEmitter.cpp
/js/src/frontend/ObjectEmitter.h
/js/src/frontend/OptionalEmitter.h
/js/src/frontend/SwitchEmitter.cpp
/js/src/frontend/SwitchEmitter.h
/js/src/frontend/WhileEmitter.cpp
/js/src/frontend/WhileEmitter.h
/js/src/vm/BytecodeUtil.cpp
/js/src/vm/BytecodeUtil.h
/js/src/vm/Opcodes.h
/js/src/vm/SharedStencil.h