Bug 1865597 - Add error checking when initializing parallel marking and disable on...
[gecko.git] / js / src / frontend / WhileEmitter.cpp
blob5b5fd13cd0f6b8b02c43128782ed6266c42bd424
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 #include "frontend/WhileEmitter.h"
9 #include "frontend/BytecodeEmitter.h"
10 #include "vm/Opcodes.h"
11 #include "vm/StencilEnums.h" // TryNoteKind
13 using namespace js;
14 using namespace js::frontend;
16 WhileEmitter::WhileEmitter(BytecodeEmitter* bce) : bce_(bce) {}
18 bool WhileEmitter::emitCond(uint32_t whilePos, uint32_t condPos,
19 uint32_t endPos) {
20 MOZ_ASSERT(state_ == State::Start);
22 // If we have a single-line while, like "while (x) ;", we want to emit the
23 // line note before the loop, so that the debugger sees a single entry point.
24 // This way, if there is a breakpoint on the line, it will only fire once; and
25 // "next"ing will skip the whole loop. However, for the multi-line case we
26 // want to emit the line note for the JSOp::LoopHead, so that "cont" stops on
27 // each iteration -- but without a stop before the first iteration.
28 if (bce_->errorReporter().lineAt(whilePos) ==
29 bce_->errorReporter().lineAt(endPos)) {
30 if (!bce_->updateSourceCoordNotes(whilePos)) {
31 return false;
33 // Emit a Nop to ensure the source position is not part of the loop.
34 if (!bce_->emit1(JSOp::Nop)) {
35 return false;
39 loopInfo_.emplace(bce_, StatementKind::WhileLoop);
41 if (!loopInfo_->emitLoopHead(bce_, mozilla::Some(condPos))) {
42 return false;
45 #ifdef DEBUG
46 state_ = State::Cond;
47 #endif
48 return true;
51 bool WhileEmitter::emitBody() {
52 MOZ_ASSERT(state_ == State::Cond);
54 if (!bce_->emitJump(JSOp::JumpIfFalse, &loopInfo_->breaks)) {
55 return false;
58 tdzCacheForBody_.emplace(bce_);
60 #ifdef DEBUG
61 state_ = State::Body;
62 #endif
63 return true;
66 bool WhileEmitter::emitEnd() {
67 MOZ_ASSERT(state_ == State::Body);
69 tdzCacheForBody_.reset();
71 if (!loopInfo_->emitContinueTarget(bce_)) {
72 return false;
75 if (!loopInfo_->emitLoopEnd(bce_, JSOp::Goto, TryNoteKind::Loop)) {
76 return false;
79 loopInfo_.reset();
81 #ifdef DEBUG
82 state_ = State::End;
83 #endif
84 return true;
87 #ifdef ENABLE_DECORATORS
88 bool InternalWhileEmitter::emitCond() {
89 MOZ_ASSERT(state_ == State::Start);
91 loopInfo_.emplace(bce_, StatementKind::WhileLoop);
93 if (!loopInfo_->emitLoopHead(bce_, mozilla::Nothing())) {
94 return false;
97 # ifdef DEBUG
98 state_ = State::Cond;
99 # endif
100 return true;
102 #endif