summaryrefslogtreecommitdiff
path: root/js/src/frontend/BytecodeControlStructures.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/frontend/BytecodeControlStructures.cpp')
-rw-r--r--js/src/frontend/BytecodeControlStructures.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/js/src/frontend/BytecodeControlStructures.cpp b/js/src/frontend/BytecodeControlStructures.cpp
new file mode 100644
index 0000000000..281f1e9cfd
--- /dev/null
+++ b/js/src/frontend/BytecodeControlStructures.cpp
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * 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/. */
+
+#include "frontend/BytecodeControlStructures.h"
+
+#include "frontend/BytecodeEmitter.h"
+#include "frontend/EmitterScope.h"
+
+using namespace js;
+using namespace js::frontend;
+
+NestableControl::NestableControl(BytecodeEmitter* bce, StatementKind kind)
+ : Nestable<NestableControl>(&bce->innermostNestableControl),
+ kind_(kind),
+ emitterScope_(bce->innermostEmitterScopeNoCheck())
+{}
+
+BreakableControl::BreakableControl(BytecodeEmitter* bce, StatementKind kind)
+ : NestableControl(bce, kind)
+{
+ MOZ_ASSERT(is<BreakableControl>());
+}
+
+bool
+BreakableControl::patchBreaks(BytecodeEmitter* bce)
+{
+ return bce->emitJumpTargetAndPatch(breaks);
+}
+
+LabelControl::LabelControl(BytecodeEmitter* bce, JSAtom* label, ptrdiff_t startOffset)
+ : BreakableControl(bce, StatementKind::Label),
+ label_(bce->cx, label),
+ startOffset_(startOffset)
+{}
+
+LoopControl::LoopControl(BytecodeEmitter* bce, StatementKind loopKind)
+ : BreakableControl(bce, loopKind),
+ tdzCache_(bce),
+ continueTarget({ -1 })
+{
+ MOZ_ASSERT(is<LoopControl>());
+
+ LoopControl* enclosingLoop = findNearest<LoopControl>(enclosing());
+
+ stackDepth_ = bce->stackDepth;
+ loopDepth_ = enclosingLoop ? enclosingLoop->loopDepth_ + 1 : 1;
+
+ int loopSlots;
+ if (loopKind == StatementKind::Spread || loopKind == StatementKind::ForOfLoop)
+ loopSlots = 3;
+ else if (loopKind == StatementKind::ForInLoop)
+ loopSlots = 2;
+ else
+ loopSlots = 0;
+
+ MOZ_ASSERT(loopSlots <= stackDepth_);
+
+ if (enclosingLoop) {
+ canIonOsr_ = (enclosingLoop->canIonOsr_ &&
+ stackDepth_ == enclosingLoop->stackDepth_ + loopSlots);
+ } else {
+ canIonOsr_ = stackDepth_ == loopSlots;
+ }
+}
+
+bool
+LoopControl::patchBreaksAndContinues(BytecodeEmitter* bce)
+{
+ MOZ_ASSERT(continueTarget.offset != -1);
+ if (!patchBreaks(bce))
+ return false;
+ bce->patchJumpsToTarget(continues, continueTarget);
+ return true;
+}
+
+TryFinallyControl::TryFinallyControl(BytecodeEmitter* bce, StatementKind kind)
+ : NestableControl(bce, kind),
+ emittingSubroutine_(false)
+{
+ MOZ_ASSERT(is<TryFinallyControl>());
+}