/*
 * Copyright (C) 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. AND ITS CONTRIBUTORS ``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 ITS 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.
 */

#ifndef LazyProperty_h
#define LazyProperty_h

#include "VM.h"

namespace JSC {

class JSCell;
class SlotVisitor;
class VM;

// Note that if all you're doing is calling LazyProperty::get(), it's completely safe to bitcast
// this LazyProperty<JSCell, JSCell>.
template<typename OwnerType, typename ElementType>
class LazyProperty {
public:
    struct Initializer {
        Initializer(OwnerType* owner, LazyProperty& property)
            : vm(*Heap::heap(owner)->vm())
            , owner(owner)
            , property(property)
        {
        }
        
        void set(ElementType* value) const;

        VM& vm;
        OwnerType* owner;
        LazyProperty& property;
    };

private:
    typedef ElementType* (*FuncType)(const Initializer&);

public:
    LazyProperty()
    {
    }

    // Tell the property to run the given callback next time someone tries to get the value
    // using get(). The passed callback must be stateless. For example:
    //
    //     property.initLater(
    //         [] (const LazyProperty<Foo, Bar>::Initializer& init) {
    //             init.set(...things...);
    //         });
    //
    // This method is always inlineable and should always compile to a store of a constant
    // pointer no matter how complicated the callback is.
    template<typename Func>
    void initLater(const Func&);

    // This lazily initializes the property. Note that this gracefully supports recursive calls.
    // If this gets called while the property is being initialized, it will simply return null.
    ElementType* get(const OwnerType* owner) const
    {
        ASSERT(!isCompilationThread());
        if (UNLIKELY(m_pointer & lazyTag)) {
            FuncType func = *bitwise_cast<FuncType*>(m_pointer & ~(lazyTag | initializingTag));
            return func(Initializer(const_cast<OwnerType*>(owner), *const_cast<LazyProperty*>(this)));
        }
        return bitwise_cast<ElementType*>(m_pointer);
    }
    
    ElementType* getConcurrently() const
    {
        uintptr_t pointer = m_pointer;
        if (pointer & lazyTag)
            return nullptr;
        return bitwise_cast<ElementType*>(pointer);
    }
    
    void setMayBeNull(VM&, const OwnerType* owner, ElementType*);
    void set(VM&, const OwnerType* owner, ElementType*);
    
    void visit(SlotVisitor&);
    
    void dump(PrintStream&) const;
    
private:
    template<typename Func>
    static ElementType* callFunc(const Initializer&);
    
    static const uintptr_t lazyTag = 1;
    static const uintptr_t initializingTag = 2;
    
    uintptr_t m_pointer { 0 };
};

// It's valid to bitcast any LazyProperty to LazyCellProperty if you're just going to call get()
// or getConcurrently().
typedef LazyProperty<JSCell, JSCell> LazyCellProperty;

} // namespace JSC

#endif // LazyProperty_h

