current commit
261007.21 · deps: update V8 to 15.5.35.20
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OBJECTS_JS_PROXY_H_
#define V8_OBJECTS_JS_PROXY_H_

#include "src/objects/js-objects.h"
#include "src/objects/oddball.h"

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {

class KeyAccumulator;

// The JSProxy describes ECMAScript Harmony proxies
V8_OBJECT class JSProxy : public JSReceiver {
 public:
  inline Tagged<UnionOf<JSReceiver, Null>> target() const;
  inline void set_target(Tagged<UnionOf<JSReceiver, Null>> value,
                         WriteBarrierMode mode = UPDATE_WRITE_BARRIER);

  inline Tagged<UnionOf<JSReceiver, Null>> handler() const;
  inline void set_handler(Tagged<UnionOf<JSReceiver, Null>> value,
                          WriteBarrierMode mode = UPDATE_WRITE_BARRIER);

  inline int flags() const;
  inline void set_flags(int value);
  V8_WARN_UNUSED_RESULT static MaybeDirectHandle<JSProxy> New(
      Isolate* isolate, DirectHandle<Object>, DirectHandle<Object>,
      bool revocable);

  V8_INLINE bool is_revocable() const;
  V8_INLINE bool IsRevoked() const;
  static void Revoke(DirectHandle<JSProxy> proxy);

  // ES6 9.5.1
  static MaybeDirectHandle<JSPrototype> GetPrototype(
      DirectHandle<JSProxy> receiver);

  // ES6 9.5.2
  V8_WARN_UNUSED_RESULT static Maybe<bool> SetPrototype(
      Isolate* isolate, DirectHandle<JSProxy> proxy,
      DirectHandle<JSPrototype> value, bool from_javascript,
      ShouldThrow should_throw);
  // ES6 9.5.3
  V8_WARN_UNUSED_RESULT static Maybe<bool> IsExtensible(
      DirectHandle<JSProxy> proxy);

  // https://tc39.es/ecma262/#sec-isarray.  NOT to be confused with %_IsArray.
  V8_WARN_UNUSED_RESULT static Maybe<bool> IsArray(DirectHandle<JSProxy> proxy);

  // ES6 9.5.4 (when passed kDontThrow)
  V8_WARN_UNUSED_RESULT static Maybe<bool> PreventExtensions(
      DirectHandle<JSProxy> proxy, ShouldThrow should_throw);

  // ES6 9.5.5
  V8_WARN_UNUSED_RESULT static Maybe<bool> GetOwnPropertyDescriptor(
      Isolate* isolate, DirectHandle<JSProxy> proxy, DirectHandle<Name> name,
      PropertyDescriptor* desc);

  // ES6 9.5.6
  V8_WARN_UNUSED_RESULT static Maybe<bool> DefineOwnProperty(
      Isolate* isolate, DirectHandle<JSProxy> object, DirectHandle<Object> key,
      PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw);

  // ES6 9.5.7
  V8_WARN_UNUSED_RESULT static Maybe<bool> HasProperty(
      Isolate* isolate, DirectHandle<JSProxy> proxy, DirectHandle<Name> name);

  // This function never returns false.
  // It returns either true or throws.
  V8_WARN_UNUSED_RESULT static Maybe<bool> CheckHasTrap(
      Isolate* isolate, DirectHandle<Name> name,
      DirectHandle<JSReceiver> target);

  // ES6 9.5.10
  V8_WARN_UNUSED_RESULT static Maybe<bool> CheckDeleteTrap(
      Isolate* isolate, DirectHandle<Name> name,
      DirectHandle<JSReceiver> target);

  // ES6 9.5.8
  V8_WARN_UNUSED_RESULT static MaybeHandle<JSAny> GetProperty(
      Isolate* isolate, DirectHandle<JSProxy> proxy, DirectHandle<Name> name,
      DirectHandle<JSAny> receiver, bool* was_found);

  enum AccessKind { kGet, kSet };

  static MaybeHandle<JSAny> CheckGetSetTrapResult(
      Isolate* isolate, DirectHandle<Name> name,
      DirectHandle<JSReceiver> target, DirectHandle<Object> trap_result,
      AccessKind access_kind);

  // ES6 9.5.9
  V8_WARN_UNUSED_RESULT static Maybe<bool> SetProperty(
      DirectHandle<JSProxy> proxy, DirectHandle<Name> name,
      DirectHandle<Object> value, DirectHandle<JSAny> receiver,
      Maybe<ShouldThrow> should_throw);

  // ES6 9.5.10 (when passed LanguageMode::kSloppy)
  V8_WARN_UNUSED_RESULT static Maybe<bool> DeletePropertyOrElement(
      DirectHandle<JSProxy> proxy, DirectHandle<Name> name,
      LanguageMode language_mode);

  V8_WARN_UNUSED_RESULT static Maybe<PropertyAttributes> GetPropertyAttributes(
      LookupIterator* it);

  // Dispatched behavior.
  DECL_PRINTER(JSProxy)
  DECL_VERIFIER(JSProxy)

  static const int kMaxIterationLimit = 100 * 1024;

  class BodyDescriptor;

  static Maybe<bool> SetPrivateSymbol(Isolate* isolate,
                                      DirectHandle<JSProxy> proxy,
                                      DirectHandle<Symbol> private_name,
                                      PropertyDescriptor* desc,
                                      Maybe<ShouldThrow> should_throw);

  using IsRevocableBit = base::BitField<bool, 0, 1>;

  static constexpr int kIsRevocableBit = IsRevocableBit::encode(true);

#if TAGGED_SIZE_8_BYTES
  static const int kPaddingOffset;
#endif
  static const int kHeaderSize;
  static const int kSize;

 public:
  TaggedMember<UnionOf<JSReceiver, Null>> target_;
  TaggedMember<UnionOf<JSReceiver, Null>> handler_;
  int32_t flags_;
#if TAGGED_SIZE_8_BYTES
  uint32_t padding_;
#endif
} V8_OBJECT_END;

#if TAGGED_SIZE_8_BYTES
inline constexpr int JSProxy::kPaddingOffset = offsetof(JSProxy, padding_);
#endif
inline constexpr int JSProxy::kHeaderSize = sizeof(JSProxy);
inline constexpr int JSProxy::kSize = JSProxy::kHeaderSize;

// kTargetOffset aliases with the elements of JSObject. The fact that
// JSProxy::target is a Javascript value which cannot be confused with an
// elements backing store is exploited by loading from this offset from an
// unknown JSReceiver.
static_assert(static_cast<int>(offsetof(JSObject, elements_)) ==
              static_cast<int>(offsetof(JSProxy, target_)));

// JSProxyRevocableResult is just a JSObject with a specific initial map.
// This initial map adds in-object properties for "proxy" and "revoke".
// See https://tc39.es/ecma262/#sec-proxy.revocable
// Shape-style: no own C++ storage; fields live in the parent JSObject's
// in-object property slots at fixed offsets past JSObject::kHeaderSize.
class JSProxyRevocableResult : public JSObject {
  V8_IT_REUSE_PARENT;

 public:
  static constexpr int kProxySlotIndex = 0;
  static constexpr int kRevokeSlotIndex = 1;
  static constexpr int kInObjectPropertyCount = 2;

  static constexpr int kProxyOffset =
      JSObject::kHeaderSize + kProxySlotIndex * kTaggedSize;
  static constexpr int kRevokeOffset =
      JSObject::kHeaderSize + kRevokeSlotIndex * kTaggedSize;
  static constexpr int kSize =
      JSObject::kHeaderSize + kInObjectPropertyCount * kTaggedSize;

 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxyRevocableResult);
};

}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_JS_PROXY_H_