|
|
|
Lines 587-603
ReturnedValueMustNotBePrimitive(JSContex
|
Link Here
|
|---|
|
| 587 |
} |
587 |
} |
| 588 |
return true; |
588 |
return true; |
| 589 |
} |
589 |
} |
| 590 |
|
590 |
|
| 591 |
static JSObject * |
591 |
static JSObject * |
| 592 |
GetProxyHandlerObject(JSContext *cx, JSObject *proxy) |
592 |
GetProxyHandlerObject(JSContext *cx, JSObject *proxy) |
| 593 |
{ |
593 |
{ |
| 594 |
JS_ASSERT(OperationInProgress(cx, proxy)); |
594 |
JS_ASSERT(OperationInProgress(cx, proxy)); |
| 595 |
return GetProxyPrivate(proxy).toObjectOrNull(); |
595 |
return GetProxyHandlerValue(proxy).toObjectOrNull(); |
| 596 |
} |
596 |
} |
| 597 |
|
597 |
|
| 598 |
bool |
598 |
bool |
| 599 |
ScriptedProxyHandler::getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, |
599 |
ScriptedProxyHandler::getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, bool set, |
| 600 |
PropertyDescriptor *desc) |
600 |
PropertyDescriptor *desc) |
| 601 |
{ |
601 |
{ |
| 602 |
JSObject *handler = GetProxyHandlerObject(cx, proxy); |
602 |
JSObject *handler = GetProxyHandlerObject(cx, proxy); |
| 603 |
AutoValueRooter tvr(cx); |
603 |
AutoValueRooter tvr(cx); |
|
Lines 1007-1023
Proxy::iteratorNext(JSContext *cx, JSObj
|
Link Here
|
|---|
|
| 1007 |
JS_CHECK_RECURSION(cx, return NULL); |
1007 |
JS_CHECK_RECURSION(cx, return NULL); |
| 1008 |
AutoPendingProxyOperation pending(cx, proxy); |
1008 |
AutoPendingProxyOperation pending(cx, proxy); |
| 1009 |
return GetProxyHandler(proxy)->iteratorNext(cx, proxy, vp); |
1009 |
return GetProxyHandler(proxy)->iteratorNext(cx, proxy, vp); |
| 1010 |
} |
1010 |
} |
| 1011 |
|
1011 |
|
| 1012 |
static JSObject * |
1012 |
static JSObject * |
| 1013 |
proxy_innerObject(JSContext *cx, JSObject *obj) |
1013 |
proxy_innerObject(JSContext *cx, JSObject *obj) |
| 1014 |
{ |
1014 |
{ |
| 1015 |
return GetProxyPrivate(obj).toObjectOrNull(); |
1015 |
return GetProxyHandlerValue(obj).toObjectOrNull(); |
| 1016 |
} |
1016 |
} |
| 1017 |
|
1017 |
|
| 1018 |
static JSBool |
1018 |
static JSBool |
| 1019 |
proxy_LookupGeneric(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, |
1019 |
proxy_LookupGeneric(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, |
| 1020 |
JSProperty **propp) |
1020 |
JSProperty **propp) |
| 1021 |
{ |
1021 |
{ |
| 1022 |
id = js_CheckForStringIndex(id); |
1022 |
id = js_CheckForStringIndex(id); |
| 1023 |
|
1023 |
|
|
Lines 1263-1281
proxy_DeleteSpecial(JSContext *cx, JSObj
|
Link Here
|
|---|
|
| 1263 |
{ |
1263 |
{ |
| 1264 |
return proxy_DeleteGeneric(cx, obj, SPECIALID_TO_JSID(sid), rval, strict); |
1264 |
return proxy_DeleteGeneric(cx, obj, SPECIALID_TO_JSID(sid), rval, strict); |
| 1265 |
} |
1265 |
} |
| 1266 |
|
1266 |
|
| 1267 |
static void |
1267 |
static void |
| 1268 |
proxy_TraceObject(JSTracer *trc, JSObject *obj) |
1268 |
proxy_TraceObject(JSTracer *trc, JSObject *obj) |
| 1269 |
{ |
1269 |
{ |
| 1270 |
GetProxyHandler(obj)->trace(trc, obj); |
1270 |
GetProxyHandler(obj)->trace(trc, obj); |
| 1271 |
MarkCrossCompartmentSlot(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_PRIVATE), "private"); |
1271 |
MarkCrossCompartmentSlot(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_TARGET_VALUE), "target"); |
| 1272 |
MarkCrossCompartmentSlot(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 0), "extra0"); |
1272 |
MarkCrossCompartmentSlot(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_HANDLER_VALUE), "handler"); |
| 1273 |
MarkCrossCompartmentSlot(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA + 1), "extra1"); |
1273 |
MarkCrossCompartmentSlot(trc, &obj->getReservedSlotRef(JSSLOT_PROXY_EXTRA), "extra"); |
| 1274 |
} |
1274 |
} |
| 1275 |
|
1275 |
|
| 1276 |
static void |
1276 |
static void |
| 1277 |
proxy_TraceFunction(JSTracer *trc, JSObject *obj) |
1277 |
proxy_TraceFunction(JSTracer *trc, JSObject *obj) |
| 1278 |
{ |
1278 |
{ |
| 1279 |
MarkCrossCompartmentSlot(trc, &GetCall(obj), "call"); |
1279 |
MarkCrossCompartmentSlot(trc, &GetCall(obj), "call"); |
| 1280 |
MarkCrossCompartmentSlot(trc, &GetFunctionProxyConstruct(obj), "construct"); |
1280 |
MarkCrossCompartmentSlot(trc, &GetFunctionProxyConstruct(obj), "construct"); |
| 1281 |
proxy_TraceObject(trc, obj); |
1281 |
proxy_TraceObject(trc, obj); |
|
Lines 1507-1524
JS_FRIEND_DATA(Class) js::FunctionProxyC
|
Link Here
|
|---|
|
| 1507 |
proxy_TypeOf, |
1507 |
proxy_TypeOf, |
| 1508 |
proxy_Fix, /* fix */ |
1508 |
proxy_Fix, /* fix */ |
| 1509 |
NULL, /* thisObject */ |
1509 |
NULL, /* thisObject */ |
| 1510 |
NULL, /* clear */ |
1510 |
NULL, /* clear */ |
| 1511 |
} |
1511 |
} |
| 1512 |
}; |
1512 |
}; |
| 1513 |
|
1513 |
|
| 1514 |
JS_FRIEND_API(JSObject *) |
1514 |
JS_FRIEND_API(JSObject *) |
| 1515 |
js::NewProxyObject(JSContext *cx, ProxyHandler *handler, const Value &priv, JSObject *proto, |
1515 |
js::NewProxyObject(JSContext *cx, ProxyHandler *handler, |
| 1516 |
JSObject *parent, JSObject *call, JSObject *construct) |
1516 |
const Value &targetValue, const Value &handlerValue, |
|
|
1517 |
JSObject *proto, JSObject *parent, JSObject *call, |
| 1518 |
JSObject *construct) |
| 1517 |
{ |
1519 |
{ |
| 1518 |
JS_ASSERT_IF(proto, cx->compartment == proto->compartment()); |
1520 |
JS_ASSERT_IF(proto, cx->compartment == proto->compartment()); |
| 1519 |
JS_ASSERT_IF(parent, cx->compartment == parent->compartment()); |
1521 |
JS_ASSERT_IF(parent, cx->compartment == parent->compartment()); |
| 1520 |
bool fun = call || construct; |
1522 |
bool fun = call || construct; |
| 1521 |
Class *clasp; |
1523 |
Class *clasp; |
| 1522 |
if (fun) |
1524 |
if (fun) |
| 1523 |
clasp = &FunctionProxyClass; |
1525 |
clasp = &FunctionProxyClass; |
| 1524 |
else |
1526 |
else |
|
Lines 1531-1547
js::NewProxyObject(JSContext *cx, ProxyH
|
Link Here
|
|---|
|
| 1531 |
*/ |
1533 |
*/ |
| 1532 |
if (proto && !proto->setNewTypeUnknown(cx)) |
1534 |
if (proto && !proto->setNewTypeUnknown(cx)) |
| 1533 |
return NULL; |
1535 |
return NULL; |
| 1534 |
|
1536 |
|
| 1535 |
JSObject *obj = NewObjectWithGivenProto(cx, clasp, proto, parent); |
1537 |
JSObject *obj = NewObjectWithGivenProto(cx, clasp, proto, parent); |
| 1536 |
if (!obj) |
1538 |
if (!obj) |
| 1537 |
return NULL; |
1539 |
return NULL; |
| 1538 |
obj->setSlot(JSSLOT_PROXY_HANDLER, PrivateValue(handler)); |
1540 |
obj->setSlot(JSSLOT_PROXY_HANDLER, PrivateValue(handler)); |
| 1539 |
obj->setSlot(JSSLOT_PROXY_PRIVATE, priv); |
1541 |
obj->setSlot(JSSLOT_PROXY_TARGET_VALUE, targetValue); |
|
|
1542 |
obj->setSlot(JSSLOT_PROXY_HANDLER_VALUE, handlerValue); |
| 1540 |
if (fun) { |
1543 |
if (fun) { |
| 1541 |
obj->setSlot(JSSLOT_PROXY_CALL, call ? ObjectValue(*call) : UndefinedValue()); |
1544 |
obj->setSlot(JSSLOT_PROXY_CALL, call ? ObjectValue(*call) : UndefinedValue()); |
| 1542 |
if (construct) { |
1545 |
if (construct) { |
| 1543 |
obj->setSlot(JSSLOT_PROXY_CONSTRUCT, ObjectValue(*construct)); |
1546 |
obj->setSlot(JSSLOT_PROXY_CONSTRUCT, ObjectValue(*construct)); |
| 1544 |
} |
1547 |
} |
| 1545 |
} |
1548 |
} |
| 1546 |
|
1549 |
|
| 1547 |
/* Don't track types of properties of proxies. */ |
1550 |
/* Don't track types of properties of proxies. */ |
|
Lines 1566-1583
proxy_create(JSContext *cx, unsigned arg
|
Link Here
|
|---|
|
| 1566 |
proto = &vp[3].toObject(); |
1569 |
proto = &vp[3].toObject(); |
| 1567 |
parent = proto->getParent(); |
1570 |
parent = proto->getParent(); |
| 1568 |
} else { |
1571 |
} else { |
| 1569 |
JS_ASSERT(IsFunctionObject(vp[0])); |
1572 |
JS_ASSERT(IsFunctionObject(vp[0])); |
| 1570 |
proto = NULL; |
1573 |
proto = NULL; |
| 1571 |
} |
1574 |
} |
| 1572 |
if (!parent) |
1575 |
if (!parent) |
| 1573 |
parent = vp[0].toObject().getParent(); |
1576 |
parent = vp[0].toObject().getParent(); |
| 1574 |
JSObject *proxy = NewProxyObject(cx, &ScriptedProxyHandler::singleton, ObjectValue(*handler), |
1577 |
JSObject *proxy = NewProxyObject(cx, &ScriptedProxyHandler::singleton, |
| 1575 |
proto, parent); |
1578 |
ObjectValue(*handler), |
|
|
1579 |
ObjectValue(*handler), proto, parent); |
| 1576 |
if (!proxy) |
1580 |
if (!proxy) |
| 1577 |
return false; |
1581 |
return false; |
| 1578 |
|
1582 |
|
| 1579 |
vp->setObject(*proxy); |
1583 |
vp->setObject(*proxy); |
| 1580 |
return true; |
1584 |
return true; |
| 1581 |
} |
1585 |
} |
| 1582 |
|
1586 |
|
| 1583 |
static JSBool |
1587 |
static JSBool |
|
Lines 1605-1621
proxy_createFunction(JSContext *cx, unsi
|
Link Here
|
|---|
|
| 1605 |
if (argc > 2) { |
1609 |
if (argc > 2) { |
| 1606 |
construct = js_ValueToCallableObject(cx, &vp[4], JSV2F_SEARCH_STACK); |
1610 |
construct = js_ValueToCallableObject(cx, &vp[4], JSV2F_SEARCH_STACK); |
| 1607 |
if (!construct) |
1611 |
if (!construct) |
| 1608 |
return false; |
1612 |
return false; |
| 1609 |
} |
1613 |
} |
| 1610 |
|
1614 |
|
| 1611 |
JSObject *proxy = NewProxyObject(cx, &ScriptedProxyHandler::singleton, |
1615 |
JSObject *proxy = NewProxyObject(cx, &ScriptedProxyHandler::singleton, |
| 1612 |
ObjectValue(*handler), |
1616 |
ObjectValue(*handler), |
| 1613 |
proto, parent, call, construct); |
1617 |
ObjectValue(*handler), proto, parent, call, |
|
|
1618 |
construct); |
| 1614 |
if (!proxy) |
1619 |
if (!proxy) |
| 1615 |
return false; |
1620 |
return false; |
| 1616 |
|
1621 |
|
| 1617 |
vp->setObject(*proxy); |
1622 |
vp->setObject(*proxy); |
| 1618 |
return true; |
1623 |
return true; |
| 1619 |
} |
1624 |
} |
| 1620 |
|
1625 |
|
| 1621 |
#ifdef DEBUG |
1626 |
#ifdef DEBUG |
|
Lines 1798-1823
FixProxy(JSContext *cx, JSObject *proxy,
|
Link Here
|
|---|
|
| 1798 |
return false; |
1803 |
return false; |
| 1799 |
|
1804 |
|
| 1800 |
/* The GC will dispose of the proxy object. */ |
1805 |
/* The GC will dispose of the proxy object. */ |
| 1801 |
|
1806 |
|
| 1802 |
*bp = true; |
1807 |
*bp = true; |
| 1803 |
return true; |
1808 |
return true; |
| 1804 |
} |
1809 |
} |
| 1805 |
|
1810 |
|
|
|
1811 |
JSBool |
| 1812 |
js_Proxy(JSContext *cx, unsigned argc, Value *vp) |
| 1813 |
{ |
| 1814 |
if (argc < 1) { |
| 1815 |
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_MORE_ARGS_NEEDED, |
| 1816 |
"Proxy", "0", "s"); |
| 1817 |
return false; |
| 1818 |
} |
| 1819 |
JSObject *target = NonNullObject(cx, vp[2]); |
| 1820 |
if (!target) |
| 1821 |
return false; |
| 1822 |
JSObject *handler = NULL; |
| 1823 |
if (argc > 1 && vp[3].isObject()) |
| 1824 |
handler = &vp[3].toObject(); |
| 1825 |
JSObject *proto = NULL; |
| 1826 |
JSObject *parent = vp[0].toObject().getParent(); |
| 1827 |
if (target->isFunction()) { |
| 1828 |
proto = parent->global().getOrCreateFunctionPrototype(cx); |
| 1829 |
if (!proto) |
| 1830 |
return false; |
| 1831 |
parent = proto->getParent(); |
| 1832 |
} |
| 1833 |
JSObject *proxy = NewProxyObject(cx, &ScriptedProxyHandler::singleton, |
| 1834 |
ObjectValue(*target), ObjectValue(*handler), |
| 1835 |
proto, parent, NULL, NULL); |
| 1836 |
if (!proxy) |
| 1837 |
return false; |
| 1838 |
vp->setObject(*proxy); |
| 1839 |
return true; |
| 1840 |
} |
| 1841 |
|
| 1806 |
Class js::ProxyClass = { |
1842 |
Class js::ProxyClass = { |
| 1807 |
"Proxy", |
1843 |
"Proxy", |
| 1808 |
JSCLASS_HAS_CACHED_PROTO(JSProto_Proxy), |
1844 |
JSCLASS_HAS_CACHED_PROTO(JSProto_Proxy), |
| 1809 |
JS_PropertyStub, /* addProperty */ |
1845 |
JS_PropertyStub, /* addProperty */ |
| 1810 |
JS_PropertyStub, /* delProperty */ |
1846 |
JS_PropertyStub, /* delProperty */ |
| 1811 |
JS_PropertyStub, /* getProperty */ |
1847 |
JS_PropertyStub, /* getProperty */ |
| 1812 |
JS_StrictPropertyStub, /* setProperty */ |
1848 |
JS_StrictPropertyStub, /* setProperty */ |
| 1813 |
JS_EnumerateStub, |
1849 |
JS_EnumerateStub, |
| 1814 |
JS_ResolveStub, |
1850 |
JS_ResolveStub, |
| 1815 |
JS_ConvertStub |
1851 |
JS_ConvertStub, |
|
|
1852 |
NULL, /* finalize */ |
| 1853 |
NULL, /* checkAccess */ |
| 1854 |
js_Proxy, /* call */ |
| 1855 |
js_Proxy /* construct */ |
| 1816 |
}; |
1856 |
}; |
| 1817 |
|
1857 |
|
| 1818 |
JS_FRIEND_API(JSObject *) |
1858 |
JS_FRIEND_API(JSObject *) |
| 1819 |
js_InitProxyClass(JSContext *cx, JSObject *obj) |
1859 |
js_InitProxyClass(JSContext *cx, JSObject *obj) |
| 1820 |
{ |
1860 |
{ |
| 1821 |
JSObject *module = NewObjectWithClassProto(cx, &ProxyClass, NULL, obj); |
1861 |
JSObject *module = NewObjectWithClassProto(cx, &ProxyClass, NULL, obj); |
| 1822 |
if (!module || !module->setSingletonType(cx)) |
1862 |
if (!module || !module->setSingletonType(cx)) |
| 1823 |
return NULL; |
1863 |
return NULL; |