ScriptedProxyHandler.h (6119B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 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 NurseryAllocableProxyHandler { 16 public: 17 enum class GetTrapValidationResult { 18 OK, 19 MustReportSameValue, 20 MustReportUndefined, 21 Exception, 22 }; 23 24 constexpr ScriptedProxyHandler() : NurseryAllocableProxyHandler(&family) {} 25 26 /* Standard internal methods. */ 27 virtual bool getOwnPropertyDescriptor( 28 JSContext* cx, JS::HandleObject proxy, JS::HandleId id, 29 JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc) 30 const override; 31 virtual bool defineProperty(JSContext* cx, JS::HandleObject proxy, 32 JS::HandleId id, 33 JS::Handle<JS::PropertyDescriptor> desc, 34 JS::ObjectOpResult& result) const override; 35 virtual bool ownPropertyKeys(JSContext* cx, JS::HandleObject proxy, 36 JS::MutableHandleIdVector props) const override; 37 virtual bool delete_(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, 38 JS::ObjectOpResult& result) const override; 39 40 virtual bool getPrototype(JSContext* cx, JS::HandleObject proxy, 41 JS::MutableHandleObject protop) const override; 42 virtual bool setPrototype(JSContext* cx, JS::HandleObject proxy, 43 JS::HandleObject proto, 44 JS::ObjectOpResult& result) const override; 45 /* Non-standard, but needed to correctly implement OrdinaryGetPrototypeOf. */ 46 virtual bool getPrototypeIfOrdinary( 47 JSContext* cx, JS::HandleObject proxy, bool* isOrdinary, 48 JS::MutableHandleObject protop) const override; 49 /* Non-standard, but needed to handle revoked proxies. */ 50 virtual bool setImmutablePrototype(JSContext* cx, JS::HandleObject proxy, 51 bool* succeeded) const override; 52 53 virtual bool preventExtensions(JSContext* cx, JS::HandleObject proxy, 54 JS::ObjectOpResult& result) const override; 55 virtual bool isExtensible(JSContext* cx, JS::HandleObject proxy, 56 bool* extensible) const override; 57 58 virtual bool has(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, 59 bool* bp) const override; 60 virtual bool get(JSContext* cx, JS::HandleObject proxy, 61 JS::HandleValue receiver, JS::HandleId id, 62 JS::MutableHandleValue vp) const override; 63 virtual bool set(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, 64 JS::HandleValue v, JS::HandleValue receiver, 65 JS::ObjectOpResult& result) const override; 66 virtual bool call(JSContext* cx, JS::HandleObject proxy, 67 const JS::CallArgs& args) const override; 68 virtual bool construct(JSContext* cx, JS::HandleObject proxy, 69 const JS::CallArgs& args) const override; 70 71 /* SpiderMonkey extensions. */ 72 virtual bool hasOwn(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, 73 bool* bp) const override { 74 return BaseProxyHandler::hasOwn(cx, proxy, id, bp); 75 } 76 77 // A scripted proxy should not be treated as generic in most contexts. 78 virtual bool nativeCall(JSContext* cx, JS::IsAcceptableThis test, 79 JS::NativeImpl impl, 80 const JS::CallArgs& args) const override; 81 virtual bool getBuiltinClass(JSContext* cx, JS::HandleObject proxy, 82 ESClass* cls) const override; 83 virtual bool isArray(JSContext* cx, JS::HandleObject proxy, 84 JS::IsArrayAnswer* answer) const override; 85 virtual const char* className(JSContext* cx, 86 JS::HandleObject proxy) const override; 87 virtual JSString* fun_toString(JSContext* cx, JS::HandleObject proxy, 88 bool isToSource) const override; 89 virtual RegExpShared* regexp_toShared(JSContext* cx, 90 JS::HandleObject proxy) const override; 91 virtual bool boxedValue_unbox(JSContext* cx, JS::HandleObject proxy, 92 JS::MutableHandleValue vp) const override; 93 94 virtual bool isCallable(JSObject* obj) const override; 95 virtual bool isConstructor(JSObject* obj) const override; 96 97 virtual bool isScripted() const override { return true; } 98 99 static GetTrapValidationResult checkGetTrapResult(JSContext* cx, 100 JS::HandleObject target, 101 JS::HandleId id, 102 JS::HandleValue trapResult); 103 104 static void reportGetTrapValidationError(JSContext* cx, JS::HandleId id, 105 GetTrapValidationResult validation); 106 107 static const char family; 108 static const ScriptedProxyHandler singleton; 109 110 // The "proxy extra" slot index in which the handler is stored. Revocable 111 // proxies need to set this at revocation time. 112 static const int HANDLER_EXTRA = 0; 113 static const int IS_CALLCONSTRUCT_EXTRA = 1; 114 // Bitmasks for the "call/construct" slot 115 static const int IS_CALLABLE = 1 << 0; 116 static const int IS_CONSTRUCTOR = 1 << 1; 117 // The "function extended" slot index in which the revocation object is 118 // stored. Per spec, this is to be cleared during the first revocation. 119 static const int REVOKE_SLOT = 0; 120 121 static JSObject* handlerObject(const JSObject* proxy); 122 }; 123 124 bool proxy(JSContext* cx, unsigned argc, JS::Value* vp); 125 126 bool proxy_revocable(JSContext* cx, unsigned argc, JS::Value* vp); 127 128 } /* namespace js */ 129 130 #endif /* proxy_ScriptedProxyHandler_h */