Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/prototype-inl.h')
-rw-r--r--deps/v8/src/prototype-inl.h145
1 files changed, 145 insertions, 0 deletions
diff --git a/deps/v8/src/prototype-inl.h b/deps/v8/src/prototype-inl.h
new file mode 100644
index 00000000000..820d5756f1e
--- /dev/null
+++ b/deps/v8/src/prototype-inl.h
@@ -0,0 +1,145 @@
+// 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_PROTOTYPE_INL_H_
+#define V8_PROTOTYPE_INL_H_
+
+#include "src/prototype.h"
+
+#include "src/handles-inl.h"
+#include "src/objects/map-inl.h"
+
+namespace v8 {
+namespace internal {
+
+PrototypeIterator::PrototypeIterator(Isolate* isolate,
+ Handle<JSReceiver> receiver,
+ WhereToStart where_to_start,
+ WhereToEnd where_to_end)
+ : isolate_(isolate),
+ object_(nullptr),
+ handle_(receiver),
+ where_to_end_(where_to_end),
+ is_at_end_(false),
+ seen_proxies_(0) {
+ CHECK(!handle_.is_null());
+ if (where_to_start == kStartAtPrototype) Advance();
+}
+
+PrototypeIterator::PrototypeIterator(Isolate* isolate, JSReceiver* receiver,
+ WhereToStart where_to_start,
+ WhereToEnd where_to_end)
+ : isolate_(isolate),
+ object_(receiver),
+ where_to_end_(where_to_end),
+ is_at_end_(false),
+ seen_proxies_(0) {
+ if (where_to_start == kStartAtPrototype) Advance();
+}
+
+PrototypeIterator::PrototypeIterator(Isolate* isolate, Map* receiver_map,
+ WhereToEnd where_to_end)
+ : isolate_(isolate),
+ object_(receiver_map->GetPrototypeChainRootMap(isolate_)->prototype()),
+ where_to_end_(where_to_end),
+ is_at_end_(object_->IsNull(isolate_)),
+ seen_proxies_(0) {
+ if (!is_at_end_ && where_to_end_ == END_AT_NON_HIDDEN) {
+ DCHECK(object_->IsJSReceiver());
+ Map* map = JSReceiver::cast(object_)->map();
+ is_at_end_ = !map->has_hidden_prototype();
+ }
+}
+
+PrototypeIterator::PrototypeIterator(Isolate* isolate, Handle<Map> receiver_map,
+ WhereToEnd where_to_end)
+ : isolate_(isolate),
+ object_(nullptr),
+ handle_(receiver_map->GetPrototypeChainRootMap(isolate_)->prototype(),
+ isolate_),
+ where_to_end_(where_to_end),
+ is_at_end_(handle_->IsNull(isolate_)),
+ seen_proxies_(0) {
+ if (!is_at_end_ && where_to_end_ == END_AT_NON_HIDDEN) {
+ DCHECK(handle_->IsJSReceiver());
+ Map* map = JSReceiver::cast(*handle_)->map();
+ is_at_end_ = !map->has_hidden_prototype();
+ }
+}
+
+bool PrototypeIterator::HasAccess() const {
+ // We can only perform access check in the handlified version of the
+ // PrototypeIterator.
+ DCHECK(!handle_.is_null());
+ if (handle_->IsAccessCheckNeeded()) {
+ return isolate_->MayAccess(handle(isolate_->context(), isolate_),
+ Handle<JSObject>::cast(handle_));
+ }
+ return true;
+}
+
+void PrototypeIterator::Advance() {
+ if (handle_.is_null() && object_->IsJSProxy()) {
+ is_at_end_ = true;
+ object_ = ReadOnlyRoots(isolate_).null_value();
+ return;
+ } else if (!handle_.is_null() && handle_->IsJSProxy()) {
+ is_at_end_ = true;
+ handle_ = isolate_->factory()->null_value();
+ return;
+ }
+ AdvanceIgnoringProxies();
+}
+
+void PrototypeIterator::AdvanceIgnoringProxies() {
+ Object* object = handle_.is_null() ? object_ : *handle_;
+ Map* map = HeapObject::cast(object)->map();
+
+ Object* prototype = map->prototype();
+ is_at_end_ = where_to_end_ == END_AT_NON_HIDDEN ? !map->has_hidden_prototype()
+ : prototype->IsNull(isolate_);
+
+ if (handle_.is_null()) {
+ object_ = prototype;
+ } else {
+ handle_ = handle(prototype, isolate_);
+ }
+}
+
+V8_WARN_UNUSED_RESULT bool PrototypeIterator::AdvanceFollowingProxies() {
+ DCHECK(!(handle_.is_null() && object_->IsJSProxy()));
+ if (!HasAccess()) {
+ // Abort the lookup if we do not have access to the current object.
+ handle_ = isolate_->factory()->null_value();
+ is_at_end_ = true;
+ return true;
+ }
+ return AdvanceFollowingProxiesIgnoringAccessChecks();
+}
+
+V8_WARN_UNUSED_RESULT bool
+PrototypeIterator::AdvanceFollowingProxiesIgnoringAccessChecks() {
+ if (handle_.is_null() || !handle_->IsJSProxy()) {
+ AdvanceIgnoringProxies();
+ return true;
+ }
+
+ // Due to possible __proto__ recursion limit the number of Proxies
+ // we visit to an arbitrarily chosen large number.
+ seen_proxies_++;
+ if (seen_proxies_ > JSProxy::kMaxIterationLimit) {
+ isolate_->StackOverflow();
+ return false;
+ }
+ MaybeHandle<Object> proto =
+ JSProxy::GetPrototype(Handle<JSProxy>::cast(handle_));
+ if (!proto.ToHandle(&handle_)) return false;
+ is_at_end_ = where_to_end_ == END_AT_NON_HIDDEN || handle_->IsNull(isolate_);
+ return true;
+}
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_PROTOTYPE_INL_H_