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

#include "js/Proxy.h"

#include <string.h>

#include "jsapi.h"
#include "jscntxt.h"
#include "jsfun.h"
#include "jsgc.h"
#include "jswrapper.h"

#include "gc/Marking.h"
#include "proxy/DeadObjectProxy.h"
#include "proxy/ScriptedDirectProxyHandler.h"
#include "proxy/ScriptedIndirectProxyHandler.h"
#include "vm/WrapperObject.h"

#include "jsatominlines.h"
#include "jsobjinlines.h"

#include "vm/NativeObject-inl.h"

using namespace js;
using namespace js::gc;

void
js::AutoEnterPolicy::reportErrorIfExceptionIsNotPending(JSContext* cx, jsid id)
{
    if (JS_IsExceptionPending(cx))
        return;

    if (JSID_IS_VOID(id)) {
        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
                             JSMSG_OBJECT_ACCESS_DENIED);
    } else {
        RootedValue idVal(cx, IdToValue(id));
        JSString* str = ValueToSource(cx, idVal);
        if (!str) {
            return;
        }
        AutoStableStringChars chars(cx);
        const char16_t* prop = nullptr;
        if (str->ensureFlat(cx) && chars.initTwoByte(cx, str))
            prop = chars.twoByteChars();

        JS_ReportErrorNumberUC(cx, GetErrorMessage, nullptr, JSMSG_PROPERTY_ACCESS_DENIED,
                               prop);
    }
}

#ifdef DEBUG
void
js::AutoEnterPolicy::recordEnter(JSContext* cx, HandleObject proxy, HandleId id, Action act)
{
    if (allowed()) {
        context = cx;
        enteredProxy.emplace(proxy);
        enteredId.emplace(id);
        enteredAction = act;
        prev = cx->runtime()->enteredPolicy;
        cx->runtime()->enteredPolicy = this;
    }
}

void
js::AutoEnterPolicy::recordLeave()
{
    if (enteredProxy) {
        MOZ_ASSERT(context->runtime()->enteredPolicy == this);
        context->runtime()->enteredPolicy = prev;
    }
}

JS_FRIEND_API(void)
js::assertEnteredPolicy(JSContext* cx, JSObject* proxy, jsid id,
                        BaseProxyHandler::Action act)
{
    MOZ_ASSERT(proxy->is<ProxyObject>());
    MOZ_ASSERT(cx->runtime()->enteredPolicy);
    MOZ_ASSERT(cx->runtime()->enteredPolicy->enteredProxy->get() == proxy);
    MOZ_ASSERT(cx->runtime()->enteredPolicy->enteredId->get() == id);
    MOZ_ASSERT(cx->runtime()->enteredPolicy->enteredAction & act);
}
#endif

bool
Proxy::getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
                             MutableHandle<PropertyDescriptor> desc)
{
    JS_CHECK_RECURSION(cx, return false);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    desc.object().set(nullptr); // default result if we refuse to perform this action
    AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET_PROPERTY_DESCRIPTOR, true);
    if (!policy.allowed())
        return policy.returnValue();

    // Special case. See the comment on BaseProxyHandler::mHasPrototype.
    if (handler->hasPrototype())
        return handler->BaseProxyHandler::getPropertyDescriptor(cx, proxy, id, desc);

    return handler->getPropertyDescriptor(cx, proxy, id, desc);
}

bool
Proxy::getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
                                MutableHandle<PropertyDescriptor> desc)
{
    JS_CHECK_RECURSION(cx, return false);

    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    desc.object().set(nullptr); // default result if we refuse to perform this action
    AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET_PROPERTY_DESCRIPTOR, true);
    if (!policy.allowed())
        return policy.returnValue();
    return handler->getOwnPropertyDescriptor(cx, proxy, id, desc);
}

bool
Proxy::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
                      Handle<PropertyDescriptor> desc, ObjectOpResult& result)
{
    JS_CHECK_RECURSION(cx, return false);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
    if (!policy.allowed()) {
        if (!policy.returnValue())
            return false;
        return result.succeed();
    }
    return proxy->as<ProxyObject>().handler()->defineProperty(cx, proxy, id, desc, result);
}

bool
Proxy::ownPropertyKeys(JSContext* cx, HandleObject proxy, AutoIdVector& props)
{
    JS_CHECK_RECURSION(cx, return false);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE, BaseProxyHandler::ENUMERATE, true);
    if (!policy.allowed())
        return policy.returnValue();
    return proxy->as<ProxyObject>().handler()->ownPropertyKeys(cx, proxy, props);
}

bool
Proxy::delete_(JSContext* cx, HandleObject proxy, HandleId id, ObjectOpResult& result)
{
    JS_CHECK_RECURSION(cx, return false);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
    if (!policy.allowed()) {
        bool ok = policy.returnValue();
        if (ok)
            result.succeed();
        return ok;
    }
    return proxy->as<ProxyObject>().handler()->delete_(cx, proxy, id, result);
}

JS_FRIEND_API(bool)
js::AppendUnique(JSContext* cx, AutoIdVector& base, AutoIdVector& others)
{
    AutoIdVector uniqueOthers(cx);
    if (!uniqueOthers.reserve(others.length()))
        return false;
    for (size_t i = 0; i < others.length(); ++i) {
        bool unique = true;
        for (size_t j = 0; j < base.length(); ++j) {
            if (others[i].get() == base[j]) {
                unique = false;
                break;
            }
        }
        if (unique)
            uniqueOthers.append(others[i]);
    }
    return base.appendAll(uniqueOthers);
}

/* static */ bool
Proxy::getPrototype(JSContext* cx, HandleObject proxy, MutableHandleObject proto)
{
    MOZ_ASSERT(proxy->hasLazyPrototype());
    JS_CHECK_RECURSION(cx, return false);
    return proxy->as<ProxyObject>().handler()->getPrototype(cx, proxy, proto);
}

/* static */ bool
Proxy::setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto, ObjectOpResult& result)
{
    MOZ_ASSERT(proxy->hasLazyPrototype());
    JS_CHECK_RECURSION(cx, return false);
    return proxy->as<ProxyObject>().handler()->setPrototype(cx, proxy, proto, result);
}

/* static */ bool
Proxy::setImmutablePrototype(JSContext* cx, HandleObject proxy, bool* succeeded)
{
    JS_CHECK_RECURSION(cx, return false);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    return handler->setImmutablePrototype(cx, proxy, succeeded);
}

/* static */ bool
Proxy::preventExtensions(JSContext* cx, HandleObject proxy, ObjectOpResult& result)
{
    JS_CHECK_RECURSION(cx, return false);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    return handler->preventExtensions(cx, proxy, result);
}

/* static */ bool
Proxy::isExtensible(JSContext* cx, HandleObject proxy, bool* extensible)
{
    JS_CHECK_RECURSION(cx, return false);
    return proxy->as<ProxyObject>().handler()->isExtensible(cx, proxy, extensible);
}

bool
Proxy::has(JSContext* cx, HandleObject proxy, HandleId id, bool* bp)
{
    JS_CHECK_RECURSION(cx, return false);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    *bp = false; // default result if we refuse to perform this action
    AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
    if (!policy.allowed())
        return policy.returnValue();

    if (handler->hasPrototype()) {
        if (!handler->hasOwn(cx, proxy, id, bp))
            return false;
        if (*bp)
            return true;

        RootedObject proto(cx);
        if (!GetPrototype(cx, proxy, &proto))
            return false;
        if (!proto)
            return true;

        return HasProperty(cx, proto, id, bp);
    }

    return handler->has(cx, proxy, id, bp);
}

bool
Proxy::hasOwn(JSContext* cx, HandleObject proxy, HandleId id, bool* bp)
{
    JS_CHECK_RECURSION(cx, return false);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    *bp = false; // default result if we refuse to perform this action
    AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
    if (!policy.allowed())
        return policy.returnValue();
    return handler->hasOwn(cx, proxy, id, bp);
}

static Value
ValueToWindowProxyIfWindow(Value v)
{
    if (v.isObject())
        return ObjectValue(*ToWindowProxyIfWindow(&v.toObject()));
    return v;
}

bool
Proxy::get(JSContext* cx, HandleObject proxy, HandleValue receiver_, HandleId id,
           MutableHandleValue vp)
{
    JS_CHECK_RECURSION(cx, return false);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    vp.setUndefined(); // default result if we refuse to perform this action
    AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::GET, true);
    if (!policy.allowed())
        return policy.returnValue();

    // Use the WindowProxy as receiver if receiver_ is a Window. Proxy handlers
    // shouldn't have to know about the Window/WindowProxy distinction.
    RootedValue receiver(cx, ValueToWindowProxyIfWindow(receiver_));

    if (handler->hasPrototype()) {
        bool own;
        if (!handler->hasOwn(cx, proxy, id, &own))
            return false;
        if (!own) {
            RootedObject proto(cx);
            if (!GetPrototype(cx, proxy, &proto))
                return false;
            if (!proto)
                return true;
            return GetProperty(cx, proto, receiver, id, vp);
        }
    }

    return handler->get(cx, proxy, receiver, id, vp);
}

bool
Proxy::set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v, HandleValue receiver_,
           ObjectOpResult& result)
{
    JS_CHECK_RECURSION(cx, return false);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
    if (!policy.allowed()) {
        if (!policy.returnValue())
            return false;
        return result.succeed();
    }

    // Use the WindowProxy as receiver if receiver_ is a Window. Proxy handlers
    // shouldn't have to know about the Window/WindowProxy distinction.
    RootedValue receiver(cx, ValueToWindowProxyIfWindow(receiver_));

    // Special case. See the comment on BaseProxyHandler::mHasPrototype.
    if (handler->hasPrototype())
        return handler->BaseProxyHandler::set(cx, proxy, id, v, receiver, result);

    return handler->set(cx, proxy, id, v, receiver, result);
}

bool
Proxy::getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy, AutoIdVector& props)
{
    JS_CHECK_RECURSION(cx, return false);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE, BaseProxyHandler::ENUMERATE, true);
    if (!policy.allowed())
        return policy.returnValue();
    return handler->getOwnEnumerablePropertyKeys(cx, proxy, props);
}

bool
Proxy::enumerate(JSContext* cx, HandleObject proxy, MutableHandleObject objp)
{
    JS_CHECK_RECURSION(cx, return false);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    objp.set(nullptr); // default result if we refuse to perform this action

    if (handler->hasPrototype()) {
        AutoIdVector props(cx);
        if (!Proxy::getOwnEnumerablePropertyKeys(cx, proxy, props))
            return false;

        RootedObject proto(cx);
        if (!GetPrototype(cx, proxy, &proto))
            return false;
        if (!proto)
            return EnumeratedIdVectorToIterator(cx, proxy, 0, props, objp);
        assertSameCompartment(cx, proxy, proto);

        AutoIdVector protoProps(cx);
        return GetPropertyKeys(cx, proto, 0, &protoProps) &&
               AppendUnique(cx, props, protoProps) &&
               EnumeratedIdVectorToIterator(cx, proxy, 0, props, objp);
    }

    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE,
                           BaseProxyHandler::ENUMERATE, true);

    // If the policy denies access but wants us to return true, we need
    // to hand a valid (empty) iterator object to the caller.
    if (!policy.allowed()) {
        return policy.returnValue() &&
            NewEmptyPropertyIterator(cx, 0, objp);
    }
    return handler->enumerate(cx, proxy, objp);
}

bool
Proxy::call(JSContext* cx, HandleObject proxy, const CallArgs& args)
{
    JS_CHECK_RECURSION(cx, return false);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();

    // Because vp[0] is JS_CALLEE on the way in and JS_RVAL on the way out, we
    // can only set our default value once we're sure that we're not calling the
    // trap.
    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE,
                           BaseProxyHandler::CALL, true);
    if (!policy.allowed()) {
        args.rval().setUndefined();
        return policy.returnValue();
    }

    return handler->call(cx, proxy, args);
}

bool
Proxy::construct(JSContext* cx, HandleObject proxy, const CallArgs& args)
{
    JS_CHECK_RECURSION(cx, return false);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();

    // Because vp[0] is JS_CALLEE on the way in and JS_RVAL on the way out, we
    // can only set our default value once we're sure that we're not calling the
    // trap.
    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE,
                           BaseProxyHandler::CALL, true);
    if (!policy.allowed()) {
        args.rval().setUndefined();
        return policy.returnValue();
    }

    return handler->construct(cx, proxy, args);
}

bool
Proxy::nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl, const CallArgs& args)
{
    JS_CHECK_RECURSION(cx, return false);
    RootedObject proxy(cx, &args.thisv().toObject());
    // Note - we don't enter a policy here because our security architecture
    // guards against nativeCall by overriding the trap itself in the right
    // circumstances.
    return proxy->as<ProxyObject>().handler()->nativeCall(cx, test, impl, args);
}

bool
Proxy::hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v, bool* bp)
{
    JS_CHECK_RECURSION(cx, return false);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    *bp = false; // default result if we refuse to perform this action
    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE, BaseProxyHandler::GET, true);
    if (!policy.allowed())
        return policy.returnValue();
    return proxy->as<ProxyObject>().handler()->hasInstance(cx, proxy, v, bp);
}

bool
Proxy::getBuiltinClass(JSContext* cx, HandleObject proxy, ESClassValue* classValue)
{
    JS_CHECK_RECURSION(cx, return false);
    return proxy->as<ProxyObject>().handler()->getBuiltinClass(cx, proxy, classValue);
}

bool
Proxy::isArray(JSContext* cx, HandleObject proxy, JS::IsArrayAnswer* answer)
{
    JS_CHECK_RECURSION(cx, return false);
    return proxy->as<ProxyObject>().handler()->isArray(cx, proxy, answer);
}

const char*
Proxy::className(JSContext* cx, HandleObject proxy)
{
    // Check for unbounded recursion, but don't signal an error; className
    // needs to be infallible.
    int stackDummy;
    if (!JS_CHECK_STACK_SIZE(GetNativeStackLimit(cx), &stackDummy))
        return "too much recursion";

    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE,
                           BaseProxyHandler::GET, /* mayThrow = */ false);
    // Do the safe thing if the policy rejects.
    if (!policy.allowed()) {
        return handler->BaseProxyHandler::className(cx, proxy);
    }
    return handler->className(cx, proxy);
}

JSString*
Proxy::fun_toString(JSContext* cx, HandleObject proxy, unsigned indent)
{
    JS_CHECK_RECURSION(cx, return nullptr);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE,
                           BaseProxyHandler::GET, /* mayThrow = */ false);
    // Do the safe thing if the policy rejects.
    if (!policy.allowed())
        return handler->BaseProxyHandler::fun_toString(cx, proxy, indent);
    return handler->fun_toString(cx, proxy, indent);
}

bool
Proxy::regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g)
{
    JS_CHECK_RECURSION(cx, return false);
    return proxy->as<ProxyObject>().handler()->regexp_toShared(cx, proxy, g);
}

bool
Proxy::boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp)
{
    JS_CHECK_RECURSION(cx, return false);
    return proxy->as<ProxyObject>().handler()->boxedValue_unbox(cx, proxy, vp);
}

JSObject * const TaggedProto::LazyProto = reinterpret_cast<JSObject*>(0x1);

/* static */ bool
Proxy::watch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleObject callable)
{
    JS_CHECK_RECURSION(cx, return false);
    return proxy->as<ProxyObject>().handler()->watch(cx, proxy, id, callable);
}

/* static */ bool
Proxy::unwatch(JSContext* cx, JS::HandleObject proxy, JS::HandleId id)
{
    JS_CHECK_RECURSION(cx, return false);
    return proxy->as<ProxyObject>().handler()->unwatch(cx, proxy, id);
}

/* static */ bool
Proxy::getElements(JSContext* cx, HandleObject proxy, uint32_t begin, uint32_t end,
                   ElementAdder* adder)
{
    JS_CHECK_RECURSION(cx, return false);
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    AutoEnterPolicy policy(cx, handler, proxy, JSID_VOIDHANDLE, BaseProxyHandler::GET,
                           /* mayThrow = */ true);
    if (!policy.allowed()) {
        if (policy.returnValue()) {
            MOZ_ASSERT(!cx->isExceptionPending());
            return js::GetElementsWithAdder(cx, proxy, proxy, begin, end, adder);
        }
        return false;
    }
    return handler->getElements(cx, proxy, begin, end, adder);
}

/* static */ void
Proxy::trace(JSTracer* trc, JSObject* proxy)
{
    const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
    handler->trace(trc, proxy);
}

bool
js::proxy_LookupProperty(JSContext* cx, HandleObject obj, HandleId id,
                         MutableHandleObject objp, MutableHandleShape propp)
{
    bool found;
    if (!Proxy::has(cx, obj, id, &found))
        return false;

    if (found) {
        MarkNonNativePropertyFound<CanGC>(propp);
        objp.set(obj);
    } else {
        objp.set(nullptr);
        propp.set(nullptr);
    }
    return true;
}

bool
js::proxy_DefineProperty(JSContext* cx, HandleObject obj, HandleId id,
                         Handle<JSPropertyDescriptor> desc,
                         ObjectOpResult& result)
{
    return Proxy::defineProperty(cx, obj, id, desc, result);
}

bool
js::proxy_HasProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp)
{
    return Proxy::has(cx, obj, id, foundp);
}

bool
js::proxy_GetProperty(JSContext* cx, HandleObject obj, HandleValue receiver, HandleId id,
                      MutableHandleValue vp)
{
    return Proxy::get(cx, obj, receiver, id, vp);
}

bool
js::proxy_SetProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue v,
                      HandleValue receiver, ObjectOpResult& result)
{
    return Proxy::set(cx, obj, id, v, receiver, result);
}

bool
js::proxy_GetOwnPropertyDescriptor(JSContext* cx, HandleObject obj, HandleId id,
                                   MutableHandle<JSPropertyDescriptor> desc)
{
    return Proxy::getOwnPropertyDescriptor(cx, obj, id, desc);
}

bool
js::proxy_DeleteProperty(JSContext* cx, HandleObject obj, HandleId id, ObjectOpResult& result)
{
    if (!Proxy::delete_(cx, obj, id, result))
        return false;
    return SuppressDeletedProperty(cx, obj, id); // XXX is this necessary?
}

void
js::proxy_Trace(JSTracer* trc, JSObject* obj)
{
    MOZ_ASSERT(obj->is<ProxyObject>());
    ProxyObject::trace(trc, obj);
}

/* static */ void
ProxyObject::trace(JSTracer* trc, JSObject* obj)
{
    ProxyObject* proxy = &obj->as<ProxyObject>();

    TraceEdge(trc, &proxy->shape, "ProxyObject_shape");

#ifdef DEBUG
    if (trc->runtime()->gc.isStrictProxyCheckingEnabled() && proxy->is<WrapperObject>()) {
        JSObject* referent = MaybeForwarded(proxy->target());
        if (referent->compartment() != proxy->compartment()) {
            /*
             * Assert that this proxy is tracked in the wrapper map. We maintain
             * the invariant that the wrapped object is the key in the wrapper map.
             */
            Value key = ObjectValue(*referent);
            WrapperMap::Ptr p = proxy->compartment()->lookupWrapper(key);
            MOZ_ASSERT(p);
            MOZ_ASSERT(*p->value().unsafeGet() == ObjectValue(*proxy));
        }
    }
#endif

    // Note: If you add new slots here, make sure to change
    // nuke() to cope.
    TraceCrossCompartmentEdge(trc, obj, proxy->slotOfPrivate(), "private");
    TraceEdge(trc, proxy->slotOfExtra(0), "extra0");

    /*
     * The GC can use the second reserved slot to link the cross compartment
     * wrappers into a linked list, in which case we don't want to trace it.
     */
    if (!proxy->is<CrossCompartmentWrapperObject>())
        TraceEdge(trc, proxy->slotOfExtra(1), "extra1");

    Proxy::trace(trc, obj);
}

JSObject*
js::proxy_WeakmapKeyDelegate(JSObject* obj)
{
    MOZ_ASSERT(obj->is<ProxyObject>());
    return obj->as<ProxyObject>().handler()->weakmapKeyDelegate(obj);
}

void
js::proxy_Finalize(FreeOp* fop, JSObject* obj)
{
    // Suppress a bogus warning about finalize().
    JS::AutoSuppressGCAnalysis nogc;

    MOZ_ASSERT(obj->is<ProxyObject>());
    obj->as<ProxyObject>().handler()->finalize(fop, obj);
    js_free(GetProxyDataLayout(obj)->values);
}

void
js::proxy_ObjectMoved(JSObject* obj, const JSObject* old)
{
    MOZ_ASSERT(obj->is<ProxyObject>());
    obj->as<ProxyObject>().handler()->objectMoved(obj, old);
}

bool
js::proxy_HasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v, bool* bp)
{
    bool b;
    if (!Proxy::hasInstance(cx, proxy, v, &b))
        return false;
    *bp = !!b;
    return true;
}

bool
js::proxy_Call(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    RootedObject proxy(cx, &args.callee());
    MOZ_ASSERT(proxy->is<ProxyObject>());
    return Proxy::call(cx, proxy, args);
}

bool
js::proxy_Construct(JSContext* cx, unsigned argc, Value* vp)
{
    CallArgs args = CallArgsFromVp(argc, vp);
    RootedObject proxy(cx, &args.callee());
    MOZ_ASSERT(proxy->is<ProxyObject>());
    return Proxy::construct(cx, proxy, args);
}

bool
js::proxy_Watch(JSContext* cx, HandleObject obj, HandleId id, HandleObject callable)
{
    return Proxy::watch(cx, obj, id, callable);
}

bool
js::proxy_Unwatch(JSContext* cx, HandleObject obj, HandleId id)
{
    return Proxy::unwatch(cx, obj, id);
}

bool
js::proxy_GetElements(JSContext* cx, HandleObject proxy, uint32_t begin, uint32_t end,
                      ElementAdder* adder)
{
    return Proxy::getElements(cx, proxy, begin, end, adder);
}

JSString*
js::proxy_FunToString(JSContext* cx, HandleObject proxy, unsigned indent)
{
    return Proxy::fun_toString(cx, proxy, indent);
}

const Class js::ProxyObject::proxyClass =
    PROXY_CLASS_DEF("Proxy", JSCLASS_HAS_CACHED_PROTO(JSProto_Proxy));

const Class* const js::ProxyClassPtr = &js::ProxyObject::proxyClass;

JS_FRIEND_API(JSObject*)
js::NewProxyObject(JSContext* cx, const BaseProxyHandler* handler, HandleValue priv, JSObject* proto_,
                   const ProxyOptions& options)
{
    if (options.lazyProto()) {
        MOZ_ASSERT(!proto_);
        proto_ = TaggedProto::LazyProto;
    }

    return ProxyObject::New(cx, handler, priv, TaggedProto(proto_), options);
}

void
ProxyObject::renew(JSContext* cx, const BaseProxyHandler* handler, Value priv)
{
    MOZ_ASSERT_IF(IsCrossCompartmentWrapper(this), IsDeadProxyObject(this));
    MOZ_ASSERT(getClass() == &ProxyObject::proxyClass);
    MOZ_ASSERT(!IsWindowProxy(this));
    MOZ_ASSERT(hasLazyPrototype());

    setHandler(handler);
    setCrossCompartmentPrivate(priv);
    setExtra(0, UndefinedValue());
    setExtra(1, UndefinedValue());
}

JS_FRIEND_API(JSObject*)
js::InitProxyClass(JSContext* cx, HandleObject obj)
{
    static const JSFunctionSpec static_methods[] = {
        JS_FN("create",         proxy_create,          2, 0),
        JS_FN("createFunction", proxy_createFunction,  3, 0),
        JS_FN("revocable",      proxy_revocable,       2, 0),
        JS_FS_END
    };

    Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
    RootedFunction ctor(cx);
    ctor = global->createConstructor(cx, proxy, cx->names().Proxy, 2);
    if (!ctor)
        return nullptr;

    if (!JS_DefineFunctions(cx, ctor, static_methods))
        return nullptr;
    if (!JS_DefineProperty(cx, obj, "Proxy", ctor, JSPROP_RESOLVING, JS_STUBGETTER, JS_STUBSETTER))
        return nullptr;

    global->setConstructor(JSProto_Proxy, ObjectValue(*ctor));
    return ctor;
}
