blob: 5d4ac870d0596a6f5dad051d3917223cda77cfc5 [file] [log] [blame]
/* -*- 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 "jswrapper.h" // UncheckedUnwrap
#include "js/Proxy.h"
#include "vm/ProxyObject.h"
#include "jsobjinlines.h"
using namespace js;
bool
DirectProxyHandler::getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
MutableHandle<PropertyDescriptor> desc) const
{
assertEnteredPolicy(cx, proxy, id, GET | SET | GET_PROPERTY_DESCRIPTOR);
MOZ_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
RootedObject target(cx, proxy->as<ProxyObject>().target());
return GetPropertyDescriptor(cx, target, id, desc);
}
bool
DirectProxyHandler::getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
MutableHandle<PropertyDescriptor> desc) const
{
assertEnteredPolicy(cx, proxy, id, GET | SET | GET_PROPERTY_DESCRIPTOR);
RootedObject target(cx, proxy->as<ProxyObject>().target());
return GetOwnPropertyDescriptor(cx, target, id, desc);
}
bool
DirectProxyHandler::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
Handle<PropertyDescriptor> desc,
ObjectOpResult& result) const
{
assertEnteredPolicy(cx, proxy, id, SET);
RootedObject target(cx, proxy->as<ProxyObject>().target());
return DefineProperty(cx, target, id, desc, result);
}
bool
DirectProxyHandler::ownPropertyKeys(JSContext* cx, HandleObject proxy,
AutoIdVector& props) const
{
assertEnteredPolicy(cx, proxy, JSID_VOID, ENUMERATE);
RootedObject target(cx, proxy->as<ProxyObject>().target());
return GetPropertyKeys(cx, target, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &props);
}
bool
DirectProxyHandler::delete_(JSContext* cx, HandleObject proxy, HandleId id,
ObjectOpResult& result) const
{
assertEnteredPolicy(cx, proxy, id, SET);
RootedObject target(cx, proxy->as<ProxyObject>().target());
return DeleteProperty(cx, target, id, result);
}
bool
DirectProxyHandler::enumerate(JSContext* cx, HandleObject proxy, MutableHandleObject objp) const
{
assertEnteredPolicy(cx, proxy, JSID_VOID, ENUMERATE);
MOZ_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
RootedObject target(cx, proxy->as<ProxyObject>().target());
return GetIterator(cx, target, 0, objp);
}
bool
DirectProxyHandler::call(JSContext* cx, HandleObject proxy, const CallArgs& args) const
{
assertEnteredPolicy(cx, proxy, JSID_VOID, CALL);
RootedValue target(cx, proxy->as<ProxyObject>().private_());
return Invoke(cx, args.thisv(), target, args.length(), args.array(), args.rval());
}
bool
DirectProxyHandler::construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const
{
assertEnteredPolicy(cx, proxy, JSID_VOID, CALL);
RootedValue target(cx, proxy->as<ProxyObject>().private_());
if (!IsConstructor(target)) {
ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, JSDVG_IGNORE_STACK, target, nullptr);
return false;
}
ConstructArgs cargs(cx);
if (!FillArgumentsFromArraylike(cx, cargs, args))
return false;
return Construct(cx, target, cargs, args.newTarget(), args.rval());
}
bool
DirectProxyHandler::nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
const CallArgs& args) const
{
args.setThis(ObjectValue(*args.thisv().toObject().as<ProxyObject>().target()));
if (!test(args.thisv())) {
ReportIncompatible(cx, args);
return false;
}
return CallNativeImpl(cx, impl, args);
}
bool
DirectProxyHandler::hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
bool* bp) const
{
assertEnteredPolicy(cx, proxy, JSID_VOID, GET);
RootedObject target(cx, proxy->as<ProxyObject>().target());
return HasInstance(cx, target, v, bp);
}
bool
DirectProxyHandler::getPrototype(JSContext* cx, HandleObject proxy, MutableHandleObject protop) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return GetPrototype(cx, target, protop);
}
bool
DirectProxyHandler::setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto,
ObjectOpResult& result) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return SetPrototype(cx, target, proto, result);
}
bool
DirectProxyHandler::setImmutablePrototype(JSContext* cx, HandleObject proxy, bool* succeeded) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return SetImmutablePrototype(cx, target, succeeded);
}
bool
DirectProxyHandler::preventExtensions(JSContext* cx, HandleObject proxy, ObjectOpResult& result) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return PreventExtensions(cx, target, result);
}
bool
DirectProxyHandler::isExtensible(JSContext* cx, HandleObject proxy, bool* extensible) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return IsExtensible(cx, target, extensible);
}
bool
DirectProxyHandler::getBuiltinClass(JSContext* cx, HandleObject proxy,
ESClassValue* classValue) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return GetBuiltinClass(cx, target, classValue);
}
bool
DirectProxyHandler::isArray(JSContext* cx, HandleObject proxy, JS::IsArrayAnswer* answer) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return IsArray(cx, target, answer);
}
const char*
DirectProxyHandler::className(JSContext* cx, HandleObject proxy) const
{
assertEnteredPolicy(cx, proxy, JSID_VOID, GET);
RootedObject target(cx, proxy->as<ProxyObject>().target());
return GetObjectClassName(cx, target);
}
JSString*
DirectProxyHandler::fun_toString(JSContext* cx, HandleObject proxy,
unsigned indent) const
{
assertEnteredPolicy(cx, proxy, JSID_VOID, GET);
RootedObject target(cx, proxy->as<ProxyObject>().target());
return fun_toStringHelper(cx, target, indent);
}
bool
DirectProxyHandler::regexp_toShared(JSContext* cx, HandleObject proxy,
RegExpGuard* g) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return RegExpToShared(cx, target, g);
}
bool
DirectProxyHandler::boxedValue_unbox(JSContext* cx, HandleObject proxy, MutableHandleValue vp) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return Unbox(cx, target, vp);
}
JSObject*
DirectProxyHandler::weakmapKeyDelegate(JSObject* proxy) const
{
return UncheckedUnwrap(proxy);
}
bool
DirectProxyHandler::has(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const
{
assertEnteredPolicy(cx, proxy, id, GET);
MOZ_ASSERT(!hasPrototype()); // Should never be called if there's a prototype.
RootedObject target(cx, proxy->as<ProxyObject>().target());
return HasProperty(cx, target, id, bp);
}
bool
DirectProxyHandler::hasOwn(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const
{
assertEnteredPolicy(cx, proxy, id, GET);
RootedObject target(cx, proxy->as<ProxyObject>().target());
return HasOwnProperty(cx, target, id, bp);
}
bool
DirectProxyHandler::get(JSContext* cx, HandleObject proxy, HandleValue receiver,
HandleId id, MutableHandleValue vp) const
{
assertEnteredPolicy(cx, proxy, id, GET);
RootedObject target(cx, proxy->as<ProxyObject>().target());
return GetProperty(cx, target, receiver, id, vp);
}
bool
DirectProxyHandler::set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult& result) const
{
assertEnteredPolicy(cx, proxy, id, SET);
RootedObject target(cx, proxy->as<ProxyObject>().target());
return SetProperty(cx, target, id, v, receiver, result);
}
bool
DirectProxyHandler::getOwnEnumerablePropertyKeys(JSContext* cx, HandleObject proxy,
AutoIdVector& props) const
{
assertEnteredPolicy(cx, proxy, JSID_VOID, ENUMERATE);
RootedObject target(cx, proxy->as<ProxyObject>().target());
return GetPropertyKeys(cx, target, JSITER_OWNONLY, &props);
}
bool
DirectProxyHandler::isCallable(JSObject* obj) const
{
JSObject * target = obj->as<ProxyObject>().target();
return target->isCallable();
}