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  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "proxy/DeadObjectProxy.h"
8 
9 #include "jsapi.h"
10 #include "jsfun.h" // XXXefaust Bug 1064662
11 
12 #include "vm/ProxyObject.h"
13 
14 using namespace js;
15 using namespace js::gc;
16 
17 static void
ReportDead(JSContext * cx)18 ReportDead(JSContext *cx)
19 {
20     JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
21 }
22 
23 bool
getOwnPropertyDescriptor(JSContext * cx,HandleObject wrapper,HandleId id,MutableHandle<PropertyDescriptor> desc) const24 DeadObjectProxy::getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper, HandleId id,
25                                           MutableHandle<PropertyDescriptor> desc) const
26 {
27     ReportDead(cx);
28     return false;
29 }
30 
31 bool
defineProperty(JSContext * cx,HandleObject wrapper,HandleId id,Handle<PropertyDescriptor> desc,ObjectOpResult & result) const32 DeadObjectProxy::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
33                                 Handle<PropertyDescriptor> desc,
34                                 ObjectOpResult& result) const
35 {
36     ReportDead(cx);
37     return false;
38 }
39 
40 bool
ownPropertyKeys(JSContext * cx,HandleObject wrapper,AutoIdVector & props) const41 DeadObjectProxy::ownPropertyKeys(JSContext* cx, HandleObject wrapper,
42                                  AutoIdVector& props) const
43 {
44     ReportDead(cx);
45     return false;
46 }
47 
48 bool
delete_(JSContext * cx,HandleObject wrapper,HandleId id,ObjectOpResult & result) const49 DeadObjectProxy::delete_(JSContext* cx, HandleObject wrapper, HandleId id,
50                          ObjectOpResult& result) const
51 {
52     ReportDead(cx);
53     return false;
54 }
55 
56 bool
enumerate(JSContext * cx,HandleObject wrapper,MutableHandleObject objp) const57 DeadObjectProxy::enumerate(JSContext* cx, HandleObject wrapper, MutableHandleObject objp) const
58 {
59     ReportDead(cx);
60     return false;
61 }
62 
63 bool
getPrototype(JSContext * cx,HandleObject proxy,MutableHandleObject protop) const64 DeadObjectProxy::getPrototype(JSContext* cx, HandleObject proxy, MutableHandleObject protop) const
65 {
66     protop.set(nullptr);
67     return true;
68 }
69 
70 bool
preventExtensions(JSContext * cx,HandleObject proxy,ObjectOpResult & result) const71 DeadObjectProxy::preventExtensions(JSContext* cx, HandleObject proxy, ObjectOpResult& result) const
72 {
73     ReportDead(cx);
74     return false;
75 }
76 
77 bool
isExtensible(JSContext * cx,HandleObject proxy,bool * extensible) const78 DeadObjectProxy::isExtensible(JSContext* cx, HandleObject proxy, bool* extensible) const
79 {
80     // This is kind of meaningless, but dead-object semantics aside,
81     // [[Extensible]] always being true is consistent with other proxy types.
82     *extensible = true;
83     return true;
84 }
85 
86 bool
call(JSContext * cx,HandleObject wrapper,const CallArgs & args) const87 DeadObjectProxy::call(JSContext* cx, HandleObject wrapper, const CallArgs& args) const
88 {
89     ReportDead(cx);
90     return false;
91 }
92 
93 bool
construct(JSContext * cx,HandleObject wrapper,const CallArgs & args) const94 DeadObjectProxy::construct(JSContext* cx, HandleObject wrapper, const CallArgs& args) const
95 {
96     ReportDead(cx);
97     return false;
98 }
99 
100 bool
nativeCall(JSContext * cx,IsAcceptableThis test,NativeImpl impl,const CallArgs & args) const101 DeadObjectProxy::nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
102                             const CallArgs& args) const
103 {
104     ReportDead(cx);
105     return false;
106 }
107 
108 bool
hasInstance(JSContext * cx,HandleObject proxy,MutableHandleValue v,bool * bp) const109 DeadObjectProxy::hasInstance(JSContext* cx, HandleObject proxy, MutableHandleValue v,
110                              bool* bp) const
111 {
112     ReportDead(cx);
113     return false;
114 }
115 
116 bool
getBuiltinClass(JSContext * cx,HandleObject proxy,ESClassValue * classValue) const117 DeadObjectProxy::getBuiltinClass(JSContext* cx, HandleObject proxy,
118                                  ESClassValue* classValue) const
119 {
120     ReportDead(cx);
121     return false;
122 }
123 
124 bool
isArray(JSContext * cx,HandleObject obj,JS::IsArrayAnswer * answer) const125 DeadObjectProxy::isArray(JSContext* cx, HandleObject obj, JS::IsArrayAnswer* answer) const
126 {
127     ReportDead(cx);
128     return false;
129 }
130 
131 const char*
className(JSContext * cx,HandleObject wrapper) const132 DeadObjectProxy::className(JSContext* cx, HandleObject wrapper) const
133 {
134     return "DeadObject";
135 }
136 
137 JSString*
fun_toString(JSContext * cx,HandleObject proxy,unsigned indent) const138 DeadObjectProxy::fun_toString(JSContext* cx, HandleObject proxy, unsigned indent) const
139 {
140     ReportDead(cx);
141     return nullptr;
142 }
143 
144 bool
regexp_toShared(JSContext * cx,HandleObject proxy,RegExpGuard * g) const145 DeadObjectProxy::regexp_toShared(JSContext* cx, HandleObject proxy, RegExpGuard* g) const
146 {
147     ReportDead(cx);
148     return false;
149 }
150 
151 const char DeadObjectProxy::family = 0;
152 const DeadObjectProxy DeadObjectProxy::singleton;
153 
154 bool
IsDeadProxyObject(JSObject * obj)155 js::IsDeadProxyObject(JSObject* obj)
156 {
157     return IsDerivedProxyObject(obj, &DeadObjectProxy::singleton);
158 }
159