bug 580128 - Allow proxies to answer the "hasInstance" question. r=mrbkap

This commit is contained in:
Andreas Gal 2010-10-10 15:39:26 -07:00
Родитель dc1082fc97
Коммит 15df9eaaec
5 изменённых файлов: 47 добавлений и 5 удалений

Просмотреть файл

@ -49,7 +49,7 @@
#include "jsclist.h"
#include "jsxml.h"
struct JSCompartment {
struct JS_FRIEND_API(JSCompartment) {
JSRuntime *rt;
JSPrincipals *principals;
js::gc::Chunk *chunk;

Просмотреть файл

@ -284,6 +284,15 @@ JSProxyHandler::construct(JSContext *cx, JSObject *proxy,
return ExternalInvoke(cx, thisobj, fval, argc, argv, rval);
}
bool
JSProxyHandler::hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp)
{
JS_ASSERT(OperationInProgress(cx, proxy));
js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,
JSDVG_SEARCH_STACK, ObjectValue(*proxy), NULL);
return false;
}
void
JSProxyHandler::finalize(JSContext *cx, JSObject *proxy)
{
@ -920,6 +929,17 @@ proxy_Finalize(JSContext *cx, JSObject *obj)
obj->getProxyHandler()->finalize(cx, obj);
}
static JSBool
proxy_HasInstance(JSContext *cx, JSObject *proxy, const Value *v, JSBool *bp)
{
AutoPendingProxyOperation pending(cx, proxy);
bool b;
if (!proxy->getProxyHandler()->hasInstance(cx, proxy, v, &b))
return false;
*bp = !!b;
return true;
}
JS_FRIEND_API(Class) ObjectProxyClass = {
"Proxy",
Class::NON_NATIVE | JSCLASS_HAS_RESERVED_SLOTS(3),
@ -936,7 +956,7 @@ JS_FRIEND_API(Class) ObjectProxyClass = {
NULL, /* call */
NULL, /* construct */
NULL, /* xdrObject */
NULL, /* hasInstance */
proxy_HasInstance, /* hasInstance */
NULL, /* mark */
JS_NULL_CLASS_EXT,
{
@ -1022,8 +1042,6 @@ proxy_TypeOf_fun(JSContext *cx, JSObject *obj)
return JSTYPE_FUNCTION;
}
#define proxy_HasInstance js_FunctionClass.hasInstance
JS_FRIEND_API(Class) FunctionProxyClass = {
"Proxy",
Class::NON_NATIVE | JSCLASS_HAS_RESERVED_SLOTS(5),
@ -1040,7 +1058,7 @@ JS_FRIEND_API(Class) FunctionProxyClass = {
proxy_Call,
proxy_Construct,
NULL, /* xdrObject */
proxy_HasInstance,
js_FunctionClass.hasInstance,
NULL, /* mark */
JS_NULL_CLASS_EXT,
{

Просмотреть файл

@ -79,6 +79,7 @@ class JS_FRIEND_API(JSProxyHandler) {
virtual bool call(JSContext *cx, JSObject *proxy, uintN argc, js::Value *vp);
virtual bool construct(JSContext *cx, JSObject *proxy,
uintN argc, js::Value *argv, js::Value *rval);
virtual bool hasInstance(JSContext *cx, JSObject *proxy, const js::Value *vp, bool *bp);
virtual JSString *obj_toString(JSContext *cx, JSObject *proxy);
virtual JSString *fun_toString(JSContext *cx, JSObject *proxy, uintN indent);
virtual void finalize(JSContext *cx, JSObject *proxy);

Просмотреть файл

@ -239,6 +239,14 @@ JSWrapper::construct(JSContext *cx, JSObject *wrapper, uintN argc, Value *argv,
GET(JSProxyHandler::construct(cx, wrapper, argc, argv, rval));
}
bool
JSWrapper::hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp)
{
const jsid id = JSID_VOID;
JSBool b;
GET(JS_HasInstance(cx, wrappedObject(wrapper), Jsvalify(*vp), &b) && Cond(b, bp));
}
JSString *
JSWrapper::obj_toString(JSContext *cx, JSObject *wrapper)
{
@ -604,6 +612,19 @@ JSCrossCompartmentWrapper::construct(JSContext *cx, JSObject *wrapper, uintN arg
call.origin->wrapException(cx);
}
bool
JSCrossCompartmentWrapper::hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp)
{
AutoCompartment call(cx, wrappedObject(wrapper));
if (!call.enter())
return false;
Value v = *vp;
if (!call.destination->wrap(cx, &v))
return false;
return JSWrapper::hasInstance(cx, wrapper, &v, bp);
}
JSString *
JSCrossCompartmentWrapper::obj_toString(JSContext *cx, JSObject *wrapper)
{

Просмотреть файл

@ -83,6 +83,7 @@ class JS_FRIEND_API(JSWrapper) : public js::JSProxyHandler {
virtual bool call(JSContext *cx, JSObject *wrapper, uintN argc, js::Value *vp);
virtual bool construct(JSContext *cx, JSObject *wrapper, uintN argc, js::Value *argv,
js::Value *rval);
virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const js::Value *vp, bool *bp);
virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper);
virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, uintN indent);
@ -135,6 +136,7 @@ class JS_FRIEND_API(JSCrossCompartmentWrapper) : public JSWrapper {
virtual bool call(JSContext *cx, JSObject *wrapper, uintN argc, js::Value *vp);
virtual bool construct(JSContext *cx, JSObject *wrapper,
uintN argc, js::Value *argv, js::Value *rval);
virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const js::Value *vp, bool *bp);
virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper);
virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, uintN indent);