|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * vim: set ts=8 sts=4 et sw=4 tw=99: |
|
3 */ |
|
4 |
|
5 #include "jsfriendapi.h" |
|
6 #include "jsproxy.h" |
|
7 |
|
8 #include "jsapi-tests/tests.h" |
|
9 |
|
10 using namespace js; |
|
11 using namespace JS; |
|
12 |
|
13 class CustomProxyHandler : public DirectProxyHandler { |
|
14 public: |
|
15 CustomProxyHandler() : DirectProxyHandler(nullptr) {} |
|
16 |
|
17 bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, |
|
18 MutableHandle<JSPropertyDescriptor> desc) MOZ_OVERRIDE |
|
19 { |
|
20 return impl(cx, proxy, id, desc, false); |
|
21 } |
|
22 |
|
23 bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, |
|
24 MutableHandle<JSPropertyDescriptor> desc) MOZ_OVERRIDE |
|
25 { |
|
26 return impl(cx, proxy, id, desc, true); |
|
27 } |
|
28 |
|
29 bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, |
|
30 HandleId id, bool strict, MutableHandleValue vp) MOZ_OVERRIDE |
|
31 { |
|
32 Rooted<JSPropertyDescriptor> desc(cx); |
|
33 if (!DirectProxyHandler::getPropertyDescriptor(cx, proxy, id, &desc)) |
|
34 return false; |
|
35 return SetPropertyIgnoringNamedGetter(cx, this, proxy, receiver, id, &desc, |
|
36 desc.object() == proxy, strict, vp); |
|
37 } |
|
38 |
|
39 private: |
|
40 bool impl(JSContext *cx, HandleObject proxy, HandleId id, |
|
41 MutableHandle<JSPropertyDescriptor> desc, bool ownOnly) |
|
42 { |
|
43 if (JSID_IS_STRING(id)) { |
|
44 bool match; |
|
45 if (!JS_StringEqualsAscii(cx, JSID_TO_STRING(id), "phantom", &match)) |
|
46 return false; |
|
47 if (match) { |
|
48 desc.object().set(proxy); |
|
49 desc.attributesRef() = JSPROP_READONLY | JSPROP_ENUMERATE; |
|
50 desc.value().setInt32(42); |
|
51 return true; |
|
52 } |
|
53 } |
|
54 |
|
55 if (ownOnly) |
|
56 return DirectProxyHandler::getOwnPropertyDescriptor(cx, proxy, id, desc); |
|
57 return DirectProxyHandler::getPropertyDescriptor(cx, proxy, id, desc); |
|
58 } |
|
59 |
|
60 }; |
|
61 |
|
62 CustomProxyHandler customProxyHandler; |
|
63 |
|
64 |
|
65 BEGIN_TEST(testSetPropertyIgnoringNamedGetter_direct) |
|
66 { |
|
67 RootedValue protov(cx); |
|
68 EVAL("Object.prototype", &protov); |
|
69 |
|
70 RootedValue targetv(cx); |
|
71 EVAL("({})", &targetv); |
|
72 |
|
73 RootedObject proxyObj(cx, NewProxyObject(cx, &customProxyHandler, targetv, |
|
74 &protov.toObject(), global, ProxyOptions())); |
|
75 CHECK(proxyObj); |
|
76 |
|
77 CHECK(JS_DefineProperty(cx, global, "target", targetv, 0)); |
|
78 CHECK(JS_DefineProperty(cx, global, "proxy", proxyObj, 0)); |
|
79 |
|
80 RootedValue v(cx); |
|
81 EVAL("Object.getOwnPropertyDescriptor(proxy, 'phantom').value", &v); |
|
82 CHECK_SAME(v, Int32Value(42)); |
|
83 |
|
84 EXEC("proxy.phantom = 123"); |
|
85 EVAL("Object.getOwnPropertyDescriptor(proxy, 'phantom').value", &v); |
|
86 CHECK_SAME(v, Int32Value(42)); |
|
87 EVAL("target.phantom", &v); |
|
88 CHECK_SAME(v, Int32Value(123)); |
|
89 |
|
90 return true; |
|
91 } |
|
92 END_TEST(testSetPropertyIgnoringNamedGetter_direct) |