/*
 * Copyright (C) 2013-2018 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. 
 */

#pragma once

#if ENABLE(FTL_JIT)

#include "B3ValueRep.h"
#include "CodeOrigin.h"
#include "DFGExitProfile.h"
#include "DFGNodeOrigin.h"
#include "DFGOSRExitBase.h"
#include "FTLAbbreviatedTypes.h"
#include "FTLExitTimeObjectMaterialization.h"
#include "FTLExitValue.h"
#include "FTLFormattedValue.h"
#include "FTLOSRExitHandle.h"
#include "FTLStackmapArgumentList.h"
#include "HandlerInfo.h"
#include "MethodOfGettingAValueProfile.h"
#include "Operands.h"
#include "Reg.h"
#include "ValueProfile.h"
#include "VirtualRegister.h"

namespace JSC {

class TrackedReferences;

namespace B3 {
class StackmapGenerationParams;
namespace Air {
struct GenerationContext;
} // namespace Air
} // namespace B3

namespace DFG {
struct NodeOrigin;
} // namespace DFG;

namespace FTL {

class State;
struct OSRExitDescriptorImpl;
struct OSRExitHandle;

struct OSRExitDescriptor {
    OSRExitDescriptor(
        DataFormat profileDataFormat, MethodOfGettingAValueProfile,
        unsigned numberOfArguments, unsigned numberOfLocals, unsigned numberOfTmps);

    // The first argument to the exit call may be a value we wish to profile.
    // If that's the case, the format will be not Invalid and we'll have a
    // method of getting a value profile. Note that all of the ExitArgument's
    // are already aware of this possible off-by-one, so there is no need to
    // correct them.
    DataFormat m_profileDataFormat;
    MethodOfGettingAValueProfile m_valueProfile;
    
    Operands<ExitValue> m_values;
    Bag<ExitTimeObjectMaterialization> m_materializations;

    void validateReferences(const TrackedReferences&);

    // Call this once we have a place to emit the OSR exit jump and we have data about how the state
    // should be recovered. This effectively emits code that does the exit, though the code is really a
    // patchable jump and we emit the real code lazily. The description of how to emit the real code is
    // up to the OSRExit object, which this creates. Note that it's OK to drop the OSRExitHandle object
    // on the ground. It contains information that is mostly not useful if you use this API, since after
    // this call, the OSRExit is simply ready to go.
    Ref<OSRExitHandle> emitOSRExit(
        State&, ExitKind, const DFG::NodeOrigin&, CCallHelpers&, const B3::StackmapGenerationParams&,
        unsigned offset = 0);

    // In some cases you want an OSRExit to come into existence, but you don't want to emit it right now.
    // This will emit the OSR exit in a late path. You can't be sure exactly when that will happen, but
    // you know that it will be done by the time late path emission is done. So, a linker task will
    // surely happen after that. You can use the OSRExitHandle to retrieve the exit's label.
    //
    // This API is meant to be used for things like exception handling, where some patchpoint wants to
    // have a place to jump to for OSR exit. It doesn't care where that OSR exit is emitted so long as it
    // eventually gets access to its label.
    Ref<OSRExitHandle> emitOSRExitLater(
        State&, ExitKind, const DFG::NodeOrigin&, const B3::StackmapGenerationParams&,
        unsigned offset = 0);

private:
    // This is the low-level interface. It will create a handle representing the desire to emit code for
    // an OSR exit. You can call OSRExitHandle::emitExitThunk() once you have a place to emit it. Note
    // that the above two APIs are written in terms of this and OSRExitHandle::emitExitThunk().
    Ref<OSRExitHandle> prepareOSRExitHandle(
        State&, ExitKind, const DFG::NodeOrigin&, const B3::StackmapGenerationParams&,
        unsigned offset = 0);
};

struct OSRExit : public DFG::OSRExitBase {
    OSRExit(OSRExitDescriptor*, ExitKind, CodeOrigin, CodeOrigin codeOriginForExitProfile, bool wasHoisted);

    OSRExitDescriptor* m_descriptor;
    MacroAssemblerCodeRef<OSRExitPtrTag> m_code;
    // This tells us where to place a jump.
    CodeLocationJump<JSInternalPtrTag> m_patchableJump;
    Vector<B3::ValueRep> m_valueReps;

    CodeLocationJump<JSInternalPtrTag> codeLocationForRepatch(CodeBlock* ftlCodeBlock) const;
    void considerAddingAsFrequentExitSite(CodeBlock* profiledCodeBlock)
    {
        OSRExitBase::considerAddingAsFrequentExitSite(profiledCodeBlock, ExitFromFTL);
    }
};

} } // namespace JSC::FTL

#endif // ENABLE(FTL_JIT)
