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 11 namespace v8 { 12 namespace internal { 13 14 bool Isolate::FromWritableHeapObject(HeapObject* obj, Isolate** isolate) { 15 i::MemoryChunk* chunk = i::MemoryChunk::FromHeapObject(obj); 16 if (chunk->owner()->identity() == i::RO_SPACE) { 17 *isolate = nullptr; 18 return false; 19 } 20 *isolate = chunk->heap()->isolate(); 21 return true; 22 } 23 24 void Isolate::set_context(Context* context) { 25 DCHECK(context == nullptr || context->IsContext()); 26 thread_local_top_.context_ = context; 27 } 28 29 Handle<NativeContext> Isolate::native_context() { 30 return handle(context()->native_context(), this); 31 } 32 33 NativeContext* Isolate::raw_native_context() { 34 return context()->native_context(); 35 } 36 37 Object* Isolate::pending_exception() { 38 DCHECK(has_pending_exception()); 39 DCHECK(!thread_local_top_.pending_exception_->IsException(this)); 40 return thread_local_top_.pending_exception_; 41 } 42 43 44 void Isolate::set_pending_exception(Object* exception_obj) { 45 DCHECK(!exception_obj->IsException(this)); 46 thread_local_top_.pending_exception_ = exception_obj; 47 } 48 49 50 void Isolate::clear_pending_exception() { 51 DCHECK(!thread_local_top_.pending_exception_->IsException(this)); 52 thread_local_top_.pending_exception_ = ReadOnlyRoots(this).the_hole_value(); 53 } 54 55 56 bool Isolate::has_pending_exception() { 57 DCHECK(!thread_local_top_.pending_exception_->IsException(this)); 58 return !thread_local_top_.pending_exception_->IsTheHole(this); 59 } 60 61 Object* Isolate::get_wasm_caught_exception() { 62 return thread_local_top_.wasm_caught_exception_; 63 } 64 65 void Isolate::set_wasm_caught_exception(Object* exception) { 66 thread_local_top_.wasm_caught_exception_ = exception; 67 } 68 69 void Isolate::clear_wasm_caught_exception() { 70 thread_local_top_.wasm_caught_exception_ = nullptr; 71 } 72 73 void Isolate::clear_pending_message() { 74 thread_local_top_.pending_message_obj_ = ReadOnlyRoots(this).the_hole_value(); 75 } 76 77 78 Object* Isolate::scheduled_exception() { 79 DCHECK(has_scheduled_exception()); 80 DCHECK(!thread_local_top_.scheduled_exception_->IsException(this)); 81 return thread_local_top_.scheduled_exception_; 82 } 83 84 85 bool Isolate::has_scheduled_exception() { 86 DCHECK(!thread_local_top_.scheduled_exception_->IsException(this)); 87 return thread_local_top_.scheduled_exception_ != 88 ReadOnlyRoots(this).the_hole_value(); 89 } 90 91 92 void Isolate::clear_scheduled_exception() { 93 DCHECK(!thread_local_top_.scheduled_exception_->IsException(this)); 94 thread_local_top_.scheduled_exception_ = ReadOnlyRoots(this).the_hole_value(); 95 } 96 97 bool Isolate::is_catchable_by_javascript(Object* exception) { 98 return exception != ReadOnlyRoots(heap()).termination_exception(); 99 } 100 101 void Isolate::FireBeforeCallEnteredCallback() { 102 for (auto& callback : before_call_entered_callbacks_) { 103 callback(reinterpret_cast<v8::Isolate*>(this)); 104 } 105 } 106 107 void Isolate::FireMicrotasksCompletedCallback() { 108 std::vector<MicrotasksCompletedCallback> callbacks( 109 microtasks_completed_callbacks_); 110 for (auto& callback : callbacks) { 111 callback(reinterpret_cast<v8::Isolate*>(this)); 112 } 113 } 114 115 Handle<JSGlobalObject> Isolate::global_object() { 116 return handle(context()->global_object(), this); 117 } 118 119 Handle<JSObject> Isolate::global_proxy() { 120 return handle(context()->global_proxy(), this); 121 } 122 123 124 Isolate::ExceptionScope::ExceptionScope(Isolate* isolate) 125 : isolate_(isolate), 126 pending_exception_(isolate_->pending_exception(), isolate_) {} 127 128 129 Isolate::ExceptionScope::~ExceptionScope() { 130 isolate_->set_pending_exception(*pending_exception_); 131 } 132 133 #define NATIVE_CONTEXT_FIELD_ACCESSOR(index, type, name) \ 134 Handle<type> Isolate::name() { \ 135 return Handle<type>(raw_native_context()->name(), this); \ 136 } \ 137 bool Isolate::is_##name(type* value) { \ 138 return raw_native_context()->is_##name(value); \ 139 } 140 NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSOR) 141 #undef NATIVE_CONTEXT_FIELD_ACCESSOR 142 143 bool Isolate::IsArrayConstructorIntact() { 144 Cell* array_constructor_cell = heap()->array_constructor_protector(); 145 return array_constructor_cell->value() == Smi::FromInt(kProtectorValid); 146 } 147 148 bool Isolate::IsArraySpeciesLookupChainIntact() { 149 // Note: It would be nice to have debug checks to make sure that the 150 // species protector is accurate, but this would be hard to do for most of 151 // what the protector stands for: 152 // - You'd need to traverse the heap to check that no Array instance has 153 // a constructor property 154 // - To check that Array[Symbol.species] == Array, JS code has to execute, 155 // but JS cannot be invoked in callstack overflow situations 156 // All that could be checked reliably is that 157 // Array.prototype.constructor == Array. Given that limitation, no check is 158 // done here. In place, there are mjsunit tests harmony/array-species* which 159 // ensure that behavior is correct in various invalid protector cases. 160 161 PropertyCell* species_cell = heap()->array_species_protector(); 162 return species_cell->value()->IsSmi() && 163 Smi::ToInt(species_cell->value()) == kProtectorValid; 164 } 165 166 bool Isolate::IsTypedArraySpeciesLookupChainIntact() { 167 PropertyCell* species_cell = heap()->typed_array_species_protector(); 168 return species_cell->value()->IsSmi() && 169 Smi::ToInt(species_cell->value()) == kProtectorValid; 170 } 171 172 bool Isolate::IsPromiseSpeciesLookupChainIntact() { 173 PropertyCell* species_cell = heap()->promise_species_protector(); 174 return species_cell->value()->IsSmi() && 175 Smi::ToInt(species_cell->value()) == kProtectorValid; 176 } 177 178 bool Isolate::IsStringLengthOverflowIntact() { 179 Cell* string_length_cell = heap()->string_length_protector(); 180 return string_length_cell->value() == Smi::FromInt(kProtectorValid); 181 } 182 183 bool Isolate::IsArrayBufferNeuteringIntact() { 184 PropertyCell* buffer_neutering = heap()->array_buffer_neutering_protector(); 185 return buffer_neutering->value() == Smi::FromInt(kProtectorValid); 186 } 187 188 bool Isolate::IsArrayIteratorLookupChainIntact() { 189 PropertyCell* array_iterator_cell = heap()->array_iterator_protector(); 190 return array_iterator_cell->value() == Smi::FromInt(kProtectorValid); 191 } 192 193 } // namespace internal 194 } // namespace v8 195 196 #endif // V8_ISOLATE_INL_H_ 197