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_EXECUTION_ISOLATE_INL_H_
6 #define V8_EXECUTION_ISOLATE_INL_H_
7 
8 #include "src/execution/isolate.h"
9 #include "src/objects/contexts-inl.h"
10 #include "src/objects/js-function.h"
11 #include "src/objects/objects-inl.h"
12 #include "src/objects/oddball.h"
13 #include "src/objects/property-cell.h"
14 #include "src/objects/regexp-match-info.h"
15 #include "src/objects/shared-function-info.h"
16 #include "src/objects/source-text-module-inl.h"
17 
18 namespace v8 {
19 namespace internal {
20 
set_context(Context context)21 void Isolate::set_context(Context context) {
22   DCHECK(context.is_null() || context.IsContext());
23   thread_local_top()->context_ = context;
24 }
25 
native_context()26 Handle<NativeContext> Isolate::native_context() {
27   DCHECK(!context().is_null());
28   return handle(context().native_context(), this);
29 }
30 
raw_native_context()31 NativeContext Isolate::raw_native_context() {
32   DCHECK(!context().is_null());
33   return context().native_context();
34 }
35 
set_pending_message(Object message_obj)36 void Isolate::set_pending_message(Object message_obj) {
37   thread_local_top()->pending_message_ = message_obj;
38 }
39 
pending_message()40 Object Isolate::pending_message() {
41   return thread_local_top()->pending_message_;
42 }
43 
clear_pending_message()44 void Isolate::clear_pending_message() {
45   set_pending_message(ReadOnlyRoots(this).the_hole_value());
46 }
47 
has_pending_message()48 bool Isolate::has_pending_message() {
49   return !pending_message().IsTheHole(this);
50 }
51 
pending_exception()52 Object Isolate::pending_exception() {
53   CHECK(has_pending_exception());
54   DCHECK(!thread_local_top()->pending_exception_.IsException(this));
55   return thread_local_top()->pending_exception_;
56 }
57 
set_pending_exception(Object exception_obj)58 void Isolate::set_pending_exception(Object exception_obj) {
59   DCHECK(!exception_obj.IsException(this));
60   thread_local_top()->pending_exception_ = exception_obj;
61 }
62 
clear_pending_exception()63 void Isolate::clear_pending_exception() {
64   DCHECK(!thread_local_top()->pending_exception_.IsException(this));
65   thread_local_top()->pending_exception_ = ReadOnlyRoots(this).the_hole_value();
66 }
67 
has_pending_exception()68 bool Isolate::has_pending_exception() {
69   DCHECK(!thread_local_top()->pending_exception_.IsException(this));
70   return !thread_local_top()->pending_exception_.IsTheHole(this);
71 }
72 
scheduled_exception()73 Object Isolate::scheduled_exception() {
74   DCHECK(has_scheduled_exception());
75   DCHECK(!thread_local_top()->scheduled_exception_.IsException(this));
76   return thread_local_top()->scheduled_exception_;
77 }
78 
has_scheduled_exception()79 bool Isolate::has_scheduled_exception() {
80   DCHECK(!thread_local_top()->scheduled_exception_.IsException(this));
81   return thread_local_top()->scheduled_exception_ !=
82          ReadOnlyRoots(this).the_hole_value();
83 }
84 
clear_scheduled_exception()85 void Isolate::clear_scheduled_exception() {
86   DCHECK(!thread_local_top()->scheduled_exception_.IsException(this));
87   set_scheduled_exception(ReadOnlyRoots(this).the_hole_value());
88 }
89 
set_scheduled_exception(Object exception)90 void Isolate::set_scheduled_exception(Object exception) {
91   thread_local_top()->scheduled_exception_ = exception;
92 }
93 
is_catchable_by_javascript(Object exception)94 bool Isolate::is_catchable_by_javascript(Object exception) {
95   return exception != ReadOnlyRoots(heap()).termination_exception();
96 }
97 
is_catchable_by_wasm(Object exception)98 bool Isolate::is_catchable_by_wasm(Object exception) {
99   if (!is_catchable_by_javascript(exception)) return false;
100   if (!exception.IsJSObject()) return true;
101   // We don't allocate, but the LookupIterator interface expects a handle.
102   DisallowGarbageCollection no_gc;
103   HandleScope handle_scope(this);
104   LookupIterator it(this, handle(JSReceiver::cast(exception), this),
105                     factory()->wasm_uncatchable_symbol(),
106                     LookupIterator::OWN_SKIP_INTERCEPTOR);
107   return !JSReceiver::HasProperty(&it).FromJust();
108 }
109 
FireBeforeCallEnteredCallback()110 void Isolate::FireBeforeCallEnteredCallback() {
111   for (auto& callback : before_call_entered_callbacks_) {
112     callback(reinterpret_cast<v8::Isolate*>(this));
113   }
114 }
115 
global_object()116 Handle<JSGlobalObject> Isolate::global_object() {
117   return handle(context().global_object(), this);
118 }
119 
global_proxy()120 Handle<JSGlobalProxy> Isolate::global_proxy() {
121   return handle(context().global_proxy(), this);
122 }
123 
ExceptionScope(Isolate * isolate)124 Isolate::ExceptionScope::ExceptionScope(Isolate* isolate)
125     : isolate_(isolate),
126       pending_exception_(isolate_->pending_exception(), isolate_) {}
127 
~ExceptionScope()128 Isolate::ExceptionScope::~ExceptionScope() {
129   isolate_->set_pending_exception(*pending_exception_);
130 }
131 
IsAnyInitialArrayPrototype(JSArray array)132 bool Isolate::IsAnyInitialArrayPrototype(JSArray array) {
133   DisallowGarbageCollection no_gc;
134   return IsInAnyContext(array, Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
135 }
136 
DidFinishModuleAsyncEvaluation(unsigned ordinal)137 void Isolate::DidFinishModuleAsyncEvaluation(unsigned ordinal) {
138   // To address overflow, the ordinal is reset when the async module with the
139   // largest vended ordinal finishes evaluating. Modules are evaluated in
140   // ascending order of their async_evaluating_ordinal.
141   //
142   // While the specification imposes a global total ordering, the intention is
143   // that for each async module, all its parents are totally ordered by when
144   // they first had their [[AsyncEvaluating]] bit set.
145   //
146   // The module with largest vended ordinal finishes evaluating implies that the
147   // async dependency as well as all other modules in that module's graph
148   // depending on async dependencies are finished evaluating.
149   //
150   // If the async dependency participates in other module graphs (e.g. via
151   // dynamic import, or other <script type=module> tags), those module graphs
152   // must have been evaluated either before or after the async dependency is
153   // settled, as the concrete Evaluate() method on cyclic module records is
154   // neither reentrant nor performs microtask checkpoints during its
155   // evaluation. If before, then all modules that depend on the async
156   // dependencies were given an ordinal that ensure they are relatively ordered,
157   // before the global ordinal was reset. If after, then the async evaluating
158   // ordering does not apply, as the dependency is no longer asynchronous.
159   //
160   // https://tc39.es/ecma262/#sec-moduleevaluation
161   if (ordinal + 1 == next_module_async_evaluating_ordinal_) {
162     next_module_async_evaluating_ordinal_ =
163         SourceTextModule::kFirstAsyncEvaluatingOrdinal;
164   }
165 }
166 
167 #define NATIVE_CONTEXT_FIELD_ACCESSOR(index, type, name)    \
168   Handle<type> Isolate::name() {                            \
169     return Handle<type>(raw_native_context().name(), this); \
170   }                                                         \
171   bool Isolate::is_##name(type value) {                     \
172     return raw_native_context().is_##name(value);           \
173   }
174 NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSOR)
175 #undef NATIVE_CONTEXT_FIELD_ACCESSOR
176 
177 }  // namespace internal
178 }  // namespace v8
179 
180 #endif  // V8_EXECUTION_ISOLATE_INL_H_
181