Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  IfEmitter.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 * 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/IfEmitter.h"

#include "frontend/BytecodeEmitter.h"
#include "vm/Opcodes.h"

using namespace js;
using namespace js::frontend;

using mozilla::Maybe;

BranchEmitterBase::BranchEmitterBase(BytecodeEmitter* bce,
                                     LexicalKind lexicalKind)
    : bce_(bce), lexicalKind_(lexicalKind) {}

IfEmitter::IfEmitter(BytecodeEmitter* bce, LexicalKind lexicalKind)
    : BranchEmitterBase(bce, lexicalKind) {}

IfEmitter::IfEmitter(BytecodeEmitter* bce)
    : IfEmitter(bce, LexicalKind::MayContainLexicalAccessInBranch) {}

bool BranchEmitterBase::emitThenInternal(ConditionKind conditionKind) {
  // The end of TDZCheckCache for cond for else-if.
  if (lexicalKind_ == LexicalKind::MayContainLexicalAccessInBranch) {
    tdzCache_.reset();
  }

  // Emit a jump around the then part.
  JSOp op = conditionKind == ConditionKind::Positive ? JSOp::JumpIfFalse
                                                     : JSOp::JumpIfTrue;
  if (!bce_->emitJump(op, &jumpAroundThen_)) {
    return false;
  }

  // To restore stack depth in else part (if present), save depth of the then
  // part.
  thenDepth_ = bce_->bytecodeSection().stackDepth();

  // Enclose then-branch with TDZCheckCache.
  if (lexicalKind_ == LexicalKind::MayContainLexicalAccessInBranch) {
    tdzCache_.emplace(bce_);
  }

  return true;
}

void BranchEmitterBase::calculateOrCheckPushed() {
#ifdef DEBUG
  if (!calculatedPushed_) {
    pushed_ = bce_->bytecodeSection().stackDepth() - thenDepth_;
    calculatedPushed_ = true;
  } else {
    MOZ_ASSERT(pushed_ == bce_->bytecodeSection().stackDepth() - thenDepth_);
  }
#endif
}

bool BranchEmitterBase::emitElseInternal() {
  calculateOrCheckPushed();

  // The end of TDZCheckCache for then-clause.
  if (lexicalKind_ == LexicalKind::MayContainLexicalAccessInBranch) {
    MOZ_ASSERT(tdzCache_.isSome());
    tdzCache_.reset();
  }

  // Emit a jump from the end of our then part around the else part. The
  // patchJumpsToTarget call at the bottom of this function will fix up
  // the offset with jumpsAroundElse value.
  if (!bce_->emitJump(JSOp::Goto, &jumpsAroundElse_)) {
    return false;
  }

  // Ensure the branch-if-false comes here, then emit the else.
  if (!bce_->emitJumpTargetAndPatch(jumpAroundThen_)) {
    return false;
  }

  // Clear jumpAroundThen_ offset, to tell emitEnd there was an else part.
  jumpAroundThen_ = JumpList();

  // Restore stack depth of the then part.
  bce_->bytecodeSection().setStackDepth(thenDepth_);

  // Enclose else-branch with TDZCheckCache.
  if (lexicalKind_ == LexicalKind::MayContainLexicalAccessInBranch) {
    tdzCache_.emplace(bce_);
  }

  return true;
}

bool BranchEmitterBase::emitEndInternal() {
  // The end of TDZCheckCache for then or else-clause.
  if (lexicalKind_ == LexicalKind::MayContainLexicalAccessInBranch) {
    MOZ_ASSERT(tdzCache_.isSome());
    tdzCache_.reset();
  }

  calculateOrCheckPushed();

  if (jumpAroundThen_.offset.valid()) {
    // No else part for the last branch, fixup the branch-if-false to
    // come here.
    if (!bce_->emitJumpTargetAndPatch(jumpAroundThen_)) {
      return false;
    }
  }

  // Patch all the jumps around else parts.
  if (!bce_->emitJumpTargetAndPatch(jumpsAroundElse_)) {
    return false;
  }

  return true;
}

bool IfEmitter::emitIf(const Maybe<uint32_t>& ifPos) {
  MOZ_ASSERT(state_ == State::Start);

  if (ifPos) {
    // Make sure this code is attributed to the "if" so that it gets a
    // useful column number, instead of the default 0 value.
    if (!bce_->updateSourceCoordNotes(*ifPos)) {
      return false;
    }
  }

#ifdef DEBUG
  state_ = State::If;
#endif
  return true;
}

bool IfEmitter::emitThen(
    ConditionKind conditionKind /* = ConditionKind::Positive */) {
  MOZ_ASSERT(state_ == State::If || state_ == State::ElseIf);

  if (lexicalKind_ == LexicalKind::MayContainLexicalAccessInBranch) {
    MOZ_ASSERT_IF(state_ == State::ElseIf, tdzCache_.isSome());
    MOZ_ASSERT_IF(state_ != State::ElseIf, tdzCache_.isNothing());
  }

  if (!emitThenInternal(conditionKind)) {
    return false;
  }

#ifdef DEBUG
  state_ = State::Then;
#endif
  return true;
}

bool IfEmitter::emitThenElse(
    ConditionKind conditionKind /* = ConditionKind::Positive */) {
  MOZ_ASSERT(state_ == State::If || state_ == State::ElseIf);

  if (lexicalKind_ == LexicalKind::MayContainLexicalAccessInBranch) {
    MOZ_ASSERT_IF(state_ == State::ElseIf, tdzCache_.isSome());
    MOZ_ASSERT_IF(state_ != State::ElseIf, tdzCache_.isNothing());
  }

  if (!emitThenInternal(conditionKind)) {
    return false;
  }

#ifdef DEBUG
  state_ = State::ThenElse;
#endif
  return true;
}

bool IfEmitter::emitElseIf(const Maybe<uint32_t>& ifPos) {
  MOZ_ASSERT(state_ == State::ThenElse);

  if (!emitElseInternal()) {
    return false;
  }

  if (ifPos) {
    // Make sure this code is attributed to the "if" so that it gets a
    // useful column number, instead of the default 0 value.
    if (!bce_->updateSourceCoordNotes(*ifPos)) {
      return false;
    }
  }

#ifdef DEBUG
  state_ = State::ElseIf;
#endif
  return true;
}

bool IfEmitter::emitElse() {
  MOZ_ASSERT(state_ == State::ThenElse);

  if (!emitElseInternal()) {
    return false;
  }

#ifdef DEBUG
  state_ = State::Else;
#endif
  return true;
}

bool IfEmitter::emitEnd() {
  MOZ_ASSERT(state_ == State::Then || state_ == State::Else);
  // If there was an else part for the last branch, jumpAroundThen_ is
  // already fixed up when emitting the else part.
  MOZ_ASSERT_IF(state_ == State::Then, jumpAroundThen_.offset.valid());
  MOZ_ASSERT_IF(state_ == State::Else, !jumpAroundThen_.offset.valid());

  if (!emitEndInternal()) {
    return false;
  }

#ifdef DEBUG
  state_ = State::End;
#endif
  return true;
}

InternalIfEmitter::InternalIfEmitter(BytecodeEmitter* bce,
                                     LexicalKind lexicalKind)
    : IfEmitter(bce, lexicalKind) {
#ifdef DEBUG
  // Skip emitIf (see the comment above InternalIfEmitter declaration).
  state_ = State::If;
#endif
}

CondEmitter::CondEmitter(BytecodeEmitter* bce)
    : BranchEmitterBase(bce, LexicalKind::MayContainLexicalAccessInBranch) {}

bool CondEmitter::emitCond() {
  MOZ_ASSERT(state_ == State::Start);
#ifdef DEBUG
  state_ = State::Cond;
#endif
  return true;
}

bool CondEmitter::emitThenElse(
    ConditionKind conditionKind /* = ConditionKind::Positive */) {
  MOZ_ASSERT(state_ == State::Cond);
  if (!emitThenInternal(conditionKind)) {
    return false;
  }

#ifdef DEBUG
  state_ = State::ThenElse;
#endif
  return true;
}

bool CondEmitter::emitElse() {
  MOZ_ASSERT(state_ == State::ThenElse);

  if (!emitElseInternal()) {
    return false;
  }

#ifdef DEBUG
  state_ = State::Else;
#endif
  return true;
}

bool CondEmitter::emitEnd() {
  MOZ_ASSERT(state_ == State::Else);
  MOZ_ASSERT(!jumpAroundThen_.offset.valid());

  if (!emitEndInternal()) {
    return false;
  }

#ifdef DEBUG
  state_ = State::End;
#endif
  return true;
}

Messung V0.5
C=86 H=95 G=90

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge