/* -*- 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/. */

// Interfaces by which the embedding can interact with the Debugger API.

#ifndef js_Debug_h
#define js_Debug_h

#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/UniquePtr.h"

#include "jsapi.h"
#include "jspubtd.h"

#include "js/GCAPI.h"
#include "js/RootingAPI.h"
#include "js/TypeDecls.h"

namespace js {
class Debugger;
} // namespace js

namespace JS {

using mozilla::UniquePtr;

namespace dbg {

// Helping embedding code build objects for Debugger
// -------------------------------------------------
//
// Some Debugger API features lean on the embedding application to construct
// their result values. For example, Debugger.Frame.prototype.scriptEntryReason
// calls hooks provided by the embedding to construct values explaining why it
// invoked JavaScript; if F is a frame called from a mouse click event handler,
// F.scriptEntryReason would return an object of the form:
//
//   { eventType: "mousedown", event: <object> }
//
// where <object> is a Debugger.Object whose referent is the event being
// dispatched.
//
// However, Debugger implements a trust boundary. Debuggee code may be
// considered untrusted; debugger code needs to be protected from debuggee
// getters, setters, proxies, Object.watch watchpoints, and any other feature
// that might accidentally cause debugger code to set the debuggee running. The
// Debugger API tries to make it easy to write safe debugger code by only
// offering access to debuggee objects via Debugger.Object instances, which
// ensure that only those operations whose explicit purpose is to invoke
// debuggee code do so. But this protective membrane is only helpful if we
// interpose Debugger.Object instances in all the necessary spots.
//
// SpiderMonkey's compartment system also implements a trust boundary. The
// debuggee and debugger are always in different compartments. Inter-compartment
// work requires carefully tracking which compartment each JSObject or JS::Value
// belongs to, and ensuring that is is correctly wrapped for each operation.
//
// It seems precarious to expect the embedding's hooks to implement these trust
// boundaries. Instead, the JS::dbg::Builder API segregates the code which
// constructs trusted objects from that which deals with untrusted objects.
// Trusted objects have an entirely different C++ type, so code that improperly
// mixes trusted and untrusted objects is caught at compile time.
//
// In the structure shown above, there are two trusted objects, and one
// untrusted object:
//
// - The overall object, with the 'eventType' and 'event' properties, is a
//   trusted object. We're going to return it to D.F.p.scriptEntryReason's
//   caller, which will handle it directly.
//
// - The Debugger.Object instance appearing as the value of the 'event' property
//   is a trusted object. It belongs to the same Debugger instance as the
//   Debugger.Frame instance whose scriptEntryReason accessor was called, and
//   presents a safe reflection-oriented API for inspecting its referent, which
//   is:
//
// - The actual event object, an untrusted object, and the referent of the
//   Debugger.Object above. (Content can do things like replacing accessors on
//   Event.prototype.)
//
// Using JS::dbg::Builder, all objects and values the embedding deals with
// directly are considered untrusted, and are assumed to be debuggee values. The
// only way to construct trusted objects is to use Builder's own methods, which
// return a separate Object type. The only way to set a property on a trusted
// object is through that Object type. The actual trusted object is never
// exposed to the embedding.
//
// So, for example, the embedding might use code like the following to construct
// the object shown above, given a Builder passed to it by Debugger:
//
//    bool
//    MyScriptEntryReason::explain(JSContext* cx,
//                                 Builder& builder,
//                                 Builder::Object& result)
//    {
//        JSObject* eventObject = ... obtain debuggee event object somehow ...;
//        if (!eventObject)
//            return false;
//        result = builder.newObject(cx);
//        return result &&
//               result.defineProperty(cx, "eventType", SafelyFetchType(eventObject)) &&
//               result.defineProperty(cx, "event", eventObject);
//    }
//
//
// Object::defineProperty also accepts an Object as the value to store on the
// property. By its type, we know that the value is trusted, so we set it
// directly as the property's value, without interposing a Debugger.Object
// wrapper. This allows the embedding to builted nested structures of trusted
// objects.
//
// The Builder and Builder::Object methods take care of doing whatever
// compartment switching and wrapping are necessary to construct the trusted
// values in the Debugger's compartment.
//
// The Object type is self-rooting. Construction, assignment, and destruction
// all properly root the referent object.

class BuilderOrigin;

class Builder {
    // The Debugger instance whose client we are building a value for. We build
    // objects in this object's compartment.
    PersistentRootedObject debuggerObject;

    // debuggerObject's Debugger structure, for convenience.
    js::Debugger* debugger;

    // Check that |thing| is in the same compartment as our debuggerObject. Used
    // for assertions when constructing BuiltThings. We can overload this as we
    // add more instantiations of BuiltThing.
#if DEBUG
    void assertBuilt(JSObject* obj);
#else
    void assertBuilt(JSObject* obj) { }
#endif

  protected:
    // A reference to a trusted object or value. At the moment, we only use it
    // with JSObject*.
    template<typename T>
    class BuiltThing {
        friend class BuilderOrigin;

      protected:
        // The Builder to which this trusted thing belongs.
        Builder& owner;

        // A rooted reference to our value.
        PersistentRooted<T> value;

        BuiltThing(JSContext* cx, Builder& owner_, T value_ = js::GCMethods<T>::initial())
          : owner(owner_), value(cx, value_)
        {
            owner.assertBuilt(value_);
        }

        // Forward some things from our owner, for convenience.
        js::Debugger* debugger() const { return owner.debugger; }
        JSObject* debuggerObject() const { return owner.debuggerObject; }

      public:
        BuiltThing(const BuiltThing& rhs) : owner(rhs.owner), value(rhs.value) { }
        BuiltThing& operator=(const BuiltThing& rhs) {
            MOZ_ASSERT(&owner == &rhs.owner);
            owner.assertBuilt(rhs.value);
            value = rhs.value;
            return *this;
        }

        explicit operator bool() const {
            // If we ever instantiate BuiltThing<Value>, this might not suffice.
            return value;
        }

      private:
        BuiltThing() = delete;
    };

  public:
    // A reference to a trusted object, possibly null. Instances of Object are
    // always properly rooted. They can be copied and assigned, as if they were
    // pointers.
    class Object: private BuiltThing<JSObject*> {
        friend class Builder;           // for construction
        friend class BuilderOrigin;     // for unwrapping

        typedef BuiltThing<JSObject*> Base;

        // This is private, because only Builders can create Objects that
        // actually point to something (hence the 'friend' declaration).
        Object(JSContext* cx, Builder& owner_, HandleObject obj) : Base(cx, owner_, obj.get()) { }

        bool definePropertyToTrusted(JSContext* cx, const char* name,
                                     JS::MutableHandleValue value);

      public:
        Object(JSContext* cx, Builder& owner_) : Base(cx, owner_, nullptr) { }
        Object(const Object& rhs) : Base(rhs) { }

        // Our automatically-generated assignment operator can see our base
        // class's assignment operator, so we don't need to write one out here.

        // Set the property named |name| on this object to |value|.
        //
        // If |value| is a string or primitive, re-wrap it for the debugger's
        // compartment.
        //
        // If |value| is an object, assume it is a debuggee object and make a
        // Debugger.Object instance referring to it. Set that as the propery's
        // value.
        //
        // If |value| is another trusted object, store it directly as the
        // property's value.
        //
        // On error, report the problem on cx and return false.
        bool defineProperty(JSContext* cx, const char* name, JS::HandleValue value);
        bool defineProperty(JSContext* cx, const char* name, JS::HandleObject value);
        bool defineProperty(JSContext* cx, const char* name, Object& value);

        using Base::operator bool;
    };

    // Build an empty object for direct use by debugger code, owned by this
    // Builder. If an error occurs, report it on cx and return a false Object.
    Object newObject(JSContext* cx);

  protected:
    Builder(JSContext* cx, js::Debugger* debugger);
};

// Debugger itself instantiates this subclass of Builder, which can unwrap
// BuiltThings that belong to it.
class BuilderOrigin : public Builder {
    template<typename T>
    T unwrapAny(const BuiltThing<T>& thing) {
        MOZ_ASSERT(&thing.owner == this);
        return thing.value.get();
    }

  public:
    BuilderOrigin(JSContext* cx, js::Debugger* debugger_)
      : Builder(cx, debugger_)
    { }

    JSObject* unwrap(Object& object) { return unwrapAny(object); }
};



// Finding the size of blocks allocated with malloc
// ------------------------------------------------
//
// Debugger.Memory wants to be able to report how many bytes items in memory are
// consuming. To do this, it needs a function that accepts a pointer to a block,
// and returns the number of bytes allocated to that block. SpiderMonkey itself
// doesn't know which function is appropriate to use, but the embedding does.

// Tell Debuggers in |runtime| to use |mallocSizeOf| to find the size of
// malloc'd blocks.
JS_PUBLIC_API(void)
SetDebuggerMallocSizeOf(JSRuntime* runtime, mozilla::MallocSizeOf mallocSizeOf);

// Get the MallocSizeOf function that the given runtime is using to find the
// size of malloc'd blocks.
JS_PUBLIC_API(mozilla::MallocSizeOf)
GetDebuggerMallocSizeOf(JSRuntime* runtime);



// Debugger and Garbage Collection Events
// --------------------------------------
//
// The Debugger wants to report about its debuggees' GC cycles, however entering
// JS after a GC is troublesome since SpiderMonkey will often do something like
// force a GC and then rely on the nursery being empty. If we call into some
// Debugger's hook after the GC, then JS runs and the nursery won't be
// empty. Instead, we rely on embedders to call back into SpiderMonkey after a
// GC and notify Debuggers to call their onGarbageCollection hook.


// For each Debugger that observed a debuggee involved in the given GC event,
// call its `onGarbageCollection` hook.
JS_PUBLIC_API(bool)
FireOnGarbageCollectionHook(JSContext* cx, GarbageCollectionEvent::Ptr&& data);



// Handlers for observing Promises
// -------------------------------
//
// The Debugger wants to observe behavior of promises, which are implemented by
// Gecko with webidl and which SpiderMonkey knows nothing about. On the other
// hand, Gecko knows nothing about which (if any) debuggers are observing a
// promise's global. The compromise is that Gecko is responsible for calling
// these handlers at the appropriate times, and SpiderMonkey will handle
// notifying any Debugger instances that are observing the given promise's
// global.

// Notify any Debugger instances observing this promise's global that a new
// promise was allocated.
JS_PUBLIC_API(void)
onNewPromise(JSContext* cx, HandleObject promise);

// Notify any Debugger instances observing this promise's global that the
// promise has settled (ie, it has either been fulfilled or rejected). Note that
// this is *not* equivalent to the promise resolution (ie, the promise's fate
// getting locked in) because you can resolve a promise with another pending
// promise, in which case neither promise has settled yet.
//
// It is Gecko's responsibility to ensure that this is never called on the same
// promise more than once (because a promise can only make the transition from
// unsettled to settled once).
JS_PUBLIC_API(void)
onPromiseSettled(JSContext* cx, HandleObject promise);



// Return true if the given value is a Debugger object, false otherwise.
JS_PUBLIC_API(bool)
IsDebugger(JSObject& obj);

// Append each of the debuggee global objects observed by the Debugger object
// |dbgObj| to |vector|. Returns true on success, false on failure.
JS_PUBLIC_API(bool)
GetDebuggeeGlobals(JSContext* cx, JSObject& dbgObj, AutoObjectVector& vector);


// Hooks for reporting where JavaScript execution began.
//
// Our performance tools would like to be able to label blocks of JavaScript
// execution with the function name and source location where execution began:
// the event handler, the callback, etc.
//
// Construct an instance of this class on the stack, providing a JSContext
// belonging to the runtime in which execution will occur. Each time we enter
// JavaScript --- specifically, each time we push a JavaScript stack frame that
// has no older JS frames younger than this AutoEntryMonitor --- we will
// call the appropriate |Entry| member function to indicate where we've begun
// execution.

class MOZ_STACK_CLASS AutoEntryMonitor {
    JSRuntime* runtime_;
    AutoEntryMonitor* savedMonitor_;

  public:
    explicit AutoEntryMonitor(JSContext* cx);
    ~AutoEntryMonitor();

    // SpiderMonkey reports the JavaScript entry points occuring within this
    // AutoEntryMonitor's scope to the following member functions, which the
    // embedding is expected to override.

    // We have begun executing |function|. Note that |function| may not be the
    // actual closure we are running, but only the canonical function object to
    // which the script refers.
    virtual void Entry(JSContext* cx, JSFunction* function,
                       HandleValue asyncStack,
                       HandleString asyncCause) = 0;

    // Execution has begun at the entry point of |script|, which is not a
    // function body. (This is probably being executed by 'eval' or some
    // JSAPI equivalent.)
    virtual void Entry(JSContext* cx, JSScript* script,
                       HandleValue asyncStack,
                       HandleString asyncCause) = 0;

    // Execution of the function or script has ended.
    virtual void Exit(JSContext* cx) { }
};



} // namespace dbg
} // namespace JS


#endif /* js_Debug_h */
