1 // Copyright 2018 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_OBJECTS_JS_PROXY_H_ 6 #define V8_OBJECTS_JS_PROXY_H_ 7 8 #include "src/objects.h" 9 10 // Has to be the last include (doesn't have include guards): 11 #include "src/objects/object-macros.h" 12 13 namespace v8 { 14 namespace internal { 15 16 // The JSProxy describes EcmaScript Harmony proxies 17 class JSProxy : public JSReceiver { 18 public: 19 V8_WARN_UNUSED_RESULT static MaybeHandle<JSProxy> New(Isolate* isolate, 20 Handle<Object>, 21 Handle<Object>); 22 23 // [handler]: The handler property. 24 DECL_ACCESSORS(handler, Object) 25 // [target]: The target property. 26 DECL_ACCESSORS(target, Object) 27 28 static MaybeHandle<Context> GetFunctionRealm(Handle<JSProxy> proxy); 29 30 DECL_CAST(JSProxy) 31 32 V8_INLINE bool IsRevoked() const; 33 static void Revoke(Handle<JSProxy> proxy); 34 35 // ES6 9.5.1 36 static MaybeHandle<Object> GetPrototype(Handle<JSProxy> receiver); 37 38 // ES6 9.5.2 39 V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype( 40 Handle<JSProxy> proxy, Handle<Object> value, bool from_javascript, 41 ShouldThrow should_throw); 42 // ES6 9.5.3 43 V8_WARN_UNUSED_RESULT static Maybe<bool> IsExtensible(Handle<JSProxy> proxy); 44 45 // ES6, #sec-isarray. NOT to be confused with %_IsArray. 46 V8_WARN_UNUSED_RESULT static Maybe<bool> IsArray(Handle<JSProxy> proxy); 47 48 // ES6 9.5.4 (when passed kDontThrow) 49 V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensions( 50 Handle<JSProxy> proxy, ShouldThrow should_throw); 51 52 // ES6 9.5.5 53 V8_WARN_UNUSED_RESULT static Maybe<bool> GetOwnPropertyDescriptor( 54 Isolate* isolate, Handle<JSProxy> proxy, Handle<Name> name, 55 PropertyDescriptor* desc); 56 57 // ES6 9.5.6 58 V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty( 59 Isolate* isolate, Handle<JSProxy> object, Handle<Object> key, 60 PropertyDescriptor* desc, ShouldThrow should_throw); 61 62 // ES6 9.5.7 63 V8_WARN_UNUSED_RESULT static Maybe<bool> HasProperty(Isolate* isolate, 64 Handle<JSProxy> proxy, 65 Handle<Name> name); 66 67 // This function never returns false. 68 // It returns either true or throws. 69 V8_WARN_UNUSED_RESULT static Maybe<bool> CheckHasTrap( 70 Isolate* isolate, Handle<Name> name, Handle<JSReceiver> target); 71 72 // ES6 9.5.8 73 V8_WARN_UNUSED_RESULT static MaybeHandle<Object> GetProperty( 74 Isolate* isolate, Handle<JSProxy> proxy, Handle<Name> name, 75 Handle<Object> receiver, bool* was_found); 76 77 enum AccessKind { kGet, kSet }; 78 79 static MaybeHandle<Object> CheckGetSetTrapResult(Isolate* isolate, 80 Handle<Name> name, 81 Handle<JSReceiver> target, 82 Handle<Object> trap_result, 83 AccessKind access_kind); 84 85 // ES6 9.5.9 86 V8_WARN_UNUSED_RESULT static Maybe<bool> SetProperty( 87 Handle<JSProxy> proxy, Handle<Name> name, Handle<Object> value, 88 Handle<Object> receiver, LanguageMode language_mode); 89 90 // ES6 9.5.10 (when passed LanguageMode::kSloppy) 91 V8_WARN_UNUSED_RESULT static Maybe<bool> DeletePropertyOrElement( 92 Handle<JSProxy> proxy, Handle<Name> name, LanguageMode language_mode); 93 94 // ES6 9.5.12 95 V8_WARN_UNUSED_RESULT static Maybe<bool> OwnPropertyKeys( 96 Isolate* isolate, Handle<JSReceiver> receiver, Handle<JSProxy> proxy, 97 PropertyFilter filter, KeyAccumulator* accumulator); 98 99 V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes( 100 LookupIterator* it); 101 102 // Dispatched behavior. 103 DECL_PRINTER(JSProxy) 104 DECL_VERIFIER(JSProxy) 105 106 static const int kMaxIterationLimit = 100 * 1024; 107 108 // Layout description. 109 static const int kTargetOffset = JSReceiver::kHeaderSize; 110 static const int kHandlerOffset = kTargetOffset + kPointerSize; 111 static const int kSize = kHandlerOffset + kPointerSize; 112 113 // kTargetOffset aliases with the elements of JSObject. The fact that 114 // JSProxy::target is a Javascript value which cannot be confused with an 115 // elements backing store is exploited by loading from this offset from an 116 // unknown JSReceiver. 117 STATIC_ASSERT(JSObject::kElementsOffset == JSProxy::kTargetOffset); 118 119 typedef FixedBodyDescriptor<JSReceiver::kPropertiesOrHashOffset, kSize, kSize> 120 BodyDescriptor; 121 // No weak fields. 122 typedef BodyDescriptor BodyDescriptorWeak; 123 124 static Maybe<bool> SetPrivateSymbol(Isolate* isolate, Handle<JSProxy> proxy, 125 Handle<Symbol> private_name, 126 PropertyDescriptor* desc, 127 ShouldThrow should_throw); 128 129 private: 130 DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy); 131 }; 132 133 // JSProxyRevocableResult is just a JSObject with a specific initial map. 134 // This initial map adds in-object properties for "proxy" and "revoke". 135 // See https://tc39.github.io/ecma262/#sec-proxy.revocable 136 class JSProxyRevocableResult : public JSObject { 137 public: 138 // Offsets of object fields. 139 static const int kProxyOffset = JSObject::kHeaderSize; 140 static const int kRevokeOffset = kProxyOffset + kPointerSize; 141 static const int kSize = kRevokeOffset + kPointerSize; 142 // Indices of in-object properties. 143 static const int kProxyIndex = 0; 144 static const int kRevokeIndex = 1; 145 146 private: 147 DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxyRevocableResult); 148 }; 149 150 } // namespace internal 151 } // namespace v8 152 153 #include "src/objects/object-macros-undef.h" 154 155 #endif // V8_OBJECTS_JS_PROXY_H_ 156