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 #ifndef proxy_ScriptedProxyHandler_h
8 #define proxy_ScriptedProxyHandler_h
9 
10 #include "js/Proxy.h"
11 
12 namespace js {
13 
14 /* Derived class for all scripted proxy handlers. */
15 class ScriptedProxyHandler : public BaseProxyHandler {
16  public:
ScriptedProxyHandler()17   constexpr ScriptedProxyHandler() : BaseProxyHandler(&family) {}
18 
19   /* Standard internal methods. */
20   virtual bool getOwnPropertyDescriptor(
21       JSContext* cx, HandleObject proxy, HandleId id,
22       MutableHandle<PropertyDescriptor> desc) const override;
23   virtual bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
24                               Handle<PropertyDescriptor> desc,
25                               ObjectOpResult& result) const override;
26   virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy,
27                                AutoIdVector& props) const override;
28   virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id,
29                        ObjectOpResult& result) const override;
30 
31   virtual bool getPrototype(JSContext* cx, HandleObject proxy,
32                             MutableHandleObject protop) const override;
33   virtual bool setPrototype(JSContext* cx, HandleObject proxy,
34                             HandleObject proto,
35                             ObjectOpResult& result) const override;
36   /* Non-standard, but needed to correctly implement OrdinaryGetPrototypeOf. */
37   virtual bool getPrototypeIfOrdinary(
38       JSContext* cx, HandleObject proxy, bool* isOrdinary,
39       MutableHandleObject protop) const override;
40   /* Non-standard, but needed to handle revoked proxies. */
41   virtual bool setImmutablePrototype(JSContext* cx, HandleObject proxy,
42                                      bool* succeeded) const override;
43 
44   virtual bool preventExtensions(JSContext* cx, HandleObject proxy,
45                                  ObjectOpResult& result) const override;
46   virtual bool isExtensible(JSContext* cx, HandleObject proxy,
47                             bool* extensible) const override;
48 
49   virtual bool has(JSContext* cx, HandleObject proxy, HandleId id,
50                    bool* bp) const override;
51   virtual bool get(JSContext* cx, HandleObject proxy, HandleValue receiver,
52                    HandleId id, MutableHandleValue vp) const override;
53   virtual bool set(JSContext* cx, HandleObject proxy, HandleId id,
54                    HandleValue v, HandleValue receiver,
55                    ObjectOpResult& result) const override;
56   virtual bool call(JSContext* cx, HandleObject proxy,
57                     const CallArgs& args) const override;
58   virtual bool construct(JSContext* cx, HandleObject proxy,
59                          const CallArgs& args) const override;
60 
61   /* SpiderMonkey extensions. */
hasOwn(JSContext * cx,HandleObject proxy,HandleId id,bool * bp)62   virtual bool hasOwn(JSContext* cx, HandleObject proxy, HandleId id,
63                       bool* bp) const override {
64     return BaseProxyHandler::hasOwn(cx, proxy, id, bp);
65   }
66 
67   // A scripted proxy should not be treated as generic in most contexts.
68   virtual bool nativeCall(JSContext* cx, IsAcceptableThis test, NativeImpl impl,
69                           const CallArgs& args) const override;
70   virtual bool hasInstance(JSContext* cx, HandleObject proxy,
71                            MutableHandleValue v, bool* bp) const override;
72   virtual bool getBuiltinClass(JSContext* cx, HandleObject proxy,
73                                ESClass* cls) const override;
74   virtual bool isArray(JSContext* cx, HandleObject proxy,
75                        JS::IsArrayAnswer* answer) const override;
76   virtual const char* className(JSContext* cx,
77                                 HandleObject proxy) const override;
78   virtual JSString* fun_toString(JSContext* cx, HandleObject proxy,
79                                  bool isToSource) const override;
80   virtual RegExpShared* regexp_toShared(JSContext* cx,
81                                         HandleObject proxy) const override;
82   virtual bool boxedValue_unbox(JSContext* cx, HandleObject proxy,
83                                 MutableHandleValue vp) const override;
84 
85   virtual bool isCallable(JSObject* obj) const override;
86   virtual bool isConstructor(JSObject* obj) const override;
87 
isScripted()88   virtual bool isScripted() const override { return true; }
89 
90   static const char family;
91   static const ScriptedProxyHandler singleton;
92 
93   // The "proxy extra" slot index in which the handler is stored. Revocable
94   // proxies need to set this at revocation time.
95   static const int HANDLER_EXTRA = 0;
96   static const int IS_CALLCONSTRUCT_EXTRA = 1;
97   // Bitmasks for the "call/construct" slot
98   static const int IS_CALLABLE = 1 << 0;
99   static const int IS_CONSTRUCTOR = 1 << 1;
100   // The "function extended" slot index in which the revocation object is
101   // stored. Per spec, this is to be cleared during the first revocation.
102   static const int REVOKE_SLOT = 0;
103 
104   static JSObject* handlerObject(const JSObject* proxy);
105 };
106 
107 bool proxy(JSContext* cx, unsigned argc, Value* vp);
108 
109 bool proxy_revocable(JSContext* cx, unsigned argc, Value* vp);
110 
111 } /* namespace js */
112 
113 #endif /* proxy_ScriptedProxyHandler_h */
114