1// Copyright 2015 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_ISOLATE_INL_H_
6#define V8_ISOLATE_INL_H_
7
8#include "src/isolate.h"
9#include "src/objects-inl.h"
10#include "src/objects/cell-inl.h"
11#include "src/objects/oddball.h"
12#include "src/objects/property-cell.h"
13#include "src/objects/regexp-match-info.h"
14#include "src/objects/shared-function-info.h"
15
16namespace v8 {
17namespace internal {
18
19IsolateAllocationMode Isolate::isolate_allocation_mode() {
20 return isolate_allocator_->mode();
21}
22
23void Isolate::set_context(Context context) {
24 DCHECK(context.is_null() || context->IsContext());
25 thread_local_top()->context_ = context;
26}
27
28Handle<NativeContext> Isolate::native_context() {
29 return handle(context()->native_context(), this);
30}
31
32NativeContext Isolate::raw_native_context() {
33 return context()->native_context();
34}
35
36Object Isolate::pending_exception() {
37 DCHECK(has_pending_exception());
38 DCHECK(!thread_local_top()->pending_exception_->IsException(this));
39 return thread_local_top()->pending_exception_;
40}
41
42void Isolate::set_pending_exception(Object exception_obj) {
43 DCHECK(!exception_obj->IsException(this));
44 thread_local_top()->pending_exception_ = exception_obj;
45}
46
47void Isolate::clear_pending_exception() {
48 DCHECK(!thread_local_top()->pending_exception_->IsException(this));
49 thread_local_top()->pending_exception_ = ReadOnlyRoots(this).the_hole_value();
50}
51
52
53bool Isolate::has_pending_exception() {
54 DCHECK(!thread_local_top()->pending_exception_->IsException(this));
55 return !thread_local_top()->pending_exception_->IsTheHole(this);
56}
57
58
59void Isolate::clear_pending_message() {
60 thread_local_top()->pending_message_obj_ =
61 ReadOnlyRoots(this).the_hole_value();
62}
63
64Object Isolate::scheduled_exception() {
65 DCHECK(has_scheduled_exception());
66 DCHECK(!thread_local_top()->scheduled_exception_->IsException(this));
67 return thread_local_top()->scheduled_exception_;
68}
69
70bool Isolate::has_scheduled_exception() {
71 DCHECK(!thread_local_top()->scheduled_exception_->IsException(this));
72 return thread_local_top()->scheduled_exception_ !=
73 ReadOnlyRoots(this).the_hole_value();
74}
75
76
77void Isolate::clear_scheduled_exception() {
78 DCHECK(!thread_local_top()->scheduled_exception_->IsException(this));
79 thread_local_top()->scheduled_exception_ =
80 ReadOnlyRoots(this).the_hole_value();
81}
82
83bool Isolate::is_catchable_by_javascript(Object exception) {
84 return exception != ReadOnlyRoots(heap()).termination_exception();
85}
86
87void Isolate::FireBeforeCallEnteredCallback() {
88 for (auto& callback : before_call_entered_callbacks_) {
89 callback(reinterpret_cast<v8::Isolate*>(this));
90 }
91}
92
93Handle<JSGlobalObject> Isolate::global_object() {
94 return handle(context()->global_object(), this);
95}
96
97Handle<JSGlobalProxy> Isolate::global_proxy() {
98 return handle(context()->global_proxy(), this);
99}
100
101Isolate::ExceptionScope::ExceptionScope(Isolate* isolate)
102 : isolate_(isolate),
103 pending_exception_(isolate_->pending_exception(), isolate_) {}
104
105
106Isolate::ExceptionScope::~ExceptionScope() {
107 isolate_->set_pending_exception(*pending_exception_);
108}
109
110#define NATIVE_CONTEXT_FIELD_ACCESSOR(index, type, name) \
111 Handle<type> Isolate::name() { \
112 return Handle<type>(raw_native_context()->name(), this); \
113 } \
114 bool Isolate::is_##name(type value) { \
115 return raw_native_context()->is_##name(value); \
116 }
117NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSOR)
118#undef NATIVE_CONTEXT_FIELD_ACCESSOR
119
120bool Isolate::IsArrayConstructorIntact() {
121 Cell array_constructor_cell =
122 Cell::cast(root(RootIndex::kArrayConstructorProtector));
123 return array_constructor_cell->value() == Smi::FromInt(kProtectorValid);
124}
125
126bool Isolate::IsArraySpeciesLookupChainIntact() {
127 // Note: It would be nice to have debug checks to make sure that the
128 // species protector is accurate, but this would be hard to do for most of
129 // what the protector stands for:
130 // - You'd need to traverse the heap to check that no Array instance has
131 // a constructor property
132 // - To check that Array[Symbol.species] == Array, JS code has to execute,
133 // but JS cannot be invoked in callstack overflow situations
134 // All that could be checked reliably is that
135 // Array.prototype.constructor == Array. Given that limitation, no check is
136 // done here. In place, there are mjsunit tests harmony/array-species* which
137 // ensure that behavior is correct in various invalid protector cases.
138
139 PropertyCell species_cell =
140 PropertyCell::cast(root(RootIndex::kArraySpeciesProtector));
141 return species_cell->value()->IsSmi() &&
142 Smi::ToInt(species_cell->value()) == kProtectorValid;
143}
144
145bool Isolate::IsTypedArraySpeciesLookupChainIntact() {
146 PropertyCell species_cell =
147 PropertyCell::cast(root(RootIndex::kTypedArraySpeciesProtector));
148 return species_cell->value()->IsSmi() &&
149 Smi::ToInt(species_cell->value()) == kProtectorValid;
150}
151
152bool Isolate::IsRegExpSpeciesLookupChainIntact() {
153 PropertyCell species_cell =
154 PropertyCell::cast(root(RootIndex::kRegExpSpeciesProtector));
155 return species_cell->value()->IsSmi() &&
156 Smi::ToInt(species_cell->value()) == kProtectorValid;
157}
158
159bool Isolate::IsPromiseSpeciesLookupChainIntact() {
160 PropertyCell species_cell =
161 PropertyCell::cast(root(RootIndex::kPromiseSpeciesProtector));
162 return species_cell->value()->IsSmi() &&
163 Smi::ToInt(species_cell->value()) == kProtectorValid;
164}
165
166bool Isolate::IsStringLengthOverflowIntact() {
167 Cell string_length_cell = Cell::cast(root(RootIndex::kStringLengthProtector));
168 return string_length_cell->value() == Smi::FromInt(kProtectorValid);
169}
170
171bool Isolate::IsArrayBufferDetachingIntact() {
172 PropertyCell buffer_detaching =
173 PropertyCell::cast(root(RootIndex::kArrayBufferDetachingProtector));
174 return buffer_detaching->value() == Smi::FromInt(kProtectorValid);
175}
176
177bool Isolate::IsArrayIteratorLookupChainIntact() {
178 PropertyCell array_iterator_cell =
179 PropertyCell::cast(root(RootIndex::kArrayIteratorProtector));
180 return array_iterator_cell->value() == Smi::FromInt(kProtectorValid);
181}
182
183bool Isolate::IsMapIteratorLookupChainIntact() {
184 PropertyCell map_iterator_cell =
185 PropertyCell::cast(root(RootIndex::kMapIteratorProtector));
186 return map_iterator_cell->value() == Smi::FromInt(kProtectorValid);
187}
188
189bool Isolate::IsSetIteratorLookupChainIntact() {
190 PropertyCell set_iterator_cell =
191 PropertyCell::cast(root(RootIndex::kSetIteratorProtector));
192 return set_iterator_cell->value() == Smi::FromInt(kProtectorValid);
193}
194
195bool Isolate::IsStringIteratorLookupChainIntact() {
196 PropertyCell string_iterator_cell =
197 PropertyCell::cast(root(RootIndex::kStringIteratorProtector));
198 return string_iterator_cell->value() == Smi::FromInt(kProtectorValid);
199}
200
201} // namespace internal
202} // namespace v8
203
204#endif // V8_ISOLATE_INL_H_
205