/*
 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include "B3SwitchValue.h"

#if ENABLE(B3_JIT)

#include "B3BasicBlockInlines.h"
#include <wtf/ListDump.h>

namespace JSC { namespace B3 {

SwitchValue::~SwitchValue()
{
}

BasicBlock* SwitchValue::fallThrough(const BasicBlock* owner)
{
    ASSERT(hasFallThrough());
    BasicBlock* fallThrough = owner->successor(owner->numSuccessors() - 1).block();
    ASSERT(fallThrough == owner->fallThrough().block());
    return fallThrough;
}

bool SwitchValue::hasFallThrough(const BasicBlock* block) const
{
    unsigned numSuccessors = block->numSuccessors();
    unsigned numValues = m_values.size();
    RELEASE_ASSERT(numValues == numSuccessors || numValues + 1 == numSuccessors);
    
    return numValues + 1 == numSuccessors;
}

bool SwitchValue::hasFallThrough() const
{
    return hasFallThrough(owner);
}

void SwitchValue::setFallThrough(BasicBlock* block, const FrequentedBlock& target)
{
    if (!hasFallThrough())
        block->successors().append(target);
    else
        block->successors().last() = target;
    ASSERT(hasFallThrough(block));
}

void SwitchValue::appendCase(BasicBlock* block, const SwitchCase& switchCase)
{
    if (!hasFallThrough())
        block->successors().append(switchCase.target());
    else {
        block->successors().append(block->successors().last());
        block->successor(block->numSuccessors() - 2) = switchCase.target();
    }
    m_values.append(switchCase.caseValue());
}

void SwitchValue::setFallThrough(const FrequentedBlock& target)
{
    setFallThrough(owner, target);
}

void SwitchValue::appendCase(const SwitchCase& switchCase)
{
    appendCase(owner, switchCase);
}

void SwitchValue::dumpSuccessors(const BasicBlock* block, PrintStream& out) const
{
    // We must not crash due to a number-of-successors mismatch! Someone debugging a
    // number-of-successors bug will want to dump IR!
    if (numCaseValues() + 1 != block->numSuccessors()) {
        Value::dumpSuccessors(block, out);
        return;
    }
    
    out.print(cases(block));
}

void SwitchValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
{
    out.print(comma, "cases = [", listDump(m_values), "]");
}

SwitchValue::SwitchValue(Origin origin, Value* child)
    : Value(CheckedOpcode, Switch, Void, One, origin, child)
{
}

} } // namespace JSC::B3

#endif // ENABLE(B3_JIT)
