1// Copyright 2019 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_THREAD_LOCAL_TOP_H_
6#define V8_THREAD_LOCAL_TOP_H_
7
8#include "src/contexts.h"
9#include "src/globals.h"
10#include "src/thread-id.h"
11
12namespace v8 {
13
14class TryCatch;
15
16namespace internal {
17
18class ExternalCallbackScope;
19class Isolate;
20class PromiseOnStack;
21class Simulator;
22
23class ThreadLocalTop {
24 public:
25 // TODO(all): This is not particularly beautiful. We should probably
26 // refactor this to really consist of just Addresses and 32-bit
27 // integer fields.
28 static constexpr uint32_t kSizeInBytes = 23 * kSystemPointerSize;
29
30 // Does early low-level initialization that does not depend on the
31 // isolate being present.
32 ThreadLocalTop() = default;
33
34 // Initialize the thread data.
35 void Initialize(Isolate*);
36
37 // The top C++ try catch handler or nullptr if none are registered.
38 //
39 // This field is not guaranteed to hold an address that can be
40 // used for comparison with addresses into the JS stack. If such
41 // an address is needed, use try_catch_handler_address.
42 v8::TryCatch* try_catch_handler_ = nullptr;
43
44 // Get the address of the top C++ try catch handler or nullptr if
45 // none are registered.
46 //
47 // This method always returns an address that can be compared to
48 // pointers into the JavaScript stack. When running on actual
49 // hardware, try_catch_handler_address and TryCatchHandler return
50 // the same pointer. When running on a simulator with a separate JS
51 // stack, try_catch_handler_address returns a JS stack address that
52 // corresponds to the place on the JS stack where the C++ handler
53 // would have been if the stack were not separate.
54 Address try_catch_handler_address() {
55 return reinterpret_cast<Address>(
56 v8::TryCatch::JSStackComparableAddress(try_catch_handler_));
57 }
58
59 void Free();
60
61 Isolate* isolate_ = nullptr;
62 // The context where the current execution method is created and for variable
63 // lookups.
64 // TODO(3770): This field is read/written from generated code, so it would
65 // be cleaner to make it an "Address raw_context_", and construct a Context
66 // object in the getter. Same for {pending_handler_context_} below. In the
67 // meantime, assert that the memory layout is the same.
68 STATIC_ASSERT(sizeof(Context) == kSystemPointerSize);
69 Context context_;
70 ThreadId thread_id_ = ThreadId::Invalid();
71 Object pending_exception_;
72
73 // Communication channel between Isolate::FindHandler and the CEntry.
74 Context pending_handler_context_;
75 Address pending_handler_entrypoint_ = kNullAddress;
76 Address pending_handler_constant_pool_ = kNullAddress;
77 Address pending_handler_fp_ = kNullAddress;
78 Address pending_handler_sp_ = kNullAddress;
79
80 // Communication channel between Isolate::Throw and message consumers.
81 Object pending_message_obj_;
82 bool rethrowing_message_ = false;
83
84 // Use a separate value for scheduled exceptions to preserve the
85 // invariants that hold about pending_exception. We may want to
86 // unify them later.
87 bool external_caught_exception_ = false;
88 Object scheduled_exception_;
89
90 // Stack.
91 // The frame pointer of the top c entry frame.
92 Address c_entry_fp_ = kNullAddress;
93 // Try-blocks are chained through the stack.
94 Address handler_ = kNullAddress;
95 // C function that was called at c entry.
96 Address c_function_ = kNullAddress;
97
98 // Throwing an exception may cause a Promise rejection. For this purpose
99 // we keep track of a stack of nested promises and the corresponding
100 // try-catch handlers.
101 PromiseOnStack* promise_on_stack_ = nullptr;
102
103 // Simulator field is always present to get predictable layout.
104 Simulator* simulator_ = nullptr;
105
106 // The stack pointer of the bottom JS entry frame.
107 Address js_entry_sp_ = kNullAddress;
108 // The external callback we're currently in.
109 ExternalCallbackScope* external_callback_scope_ = nullptr;
110 StateTag current_vm_state_ = EXTERNAL;
111
112 // Call back function to report unsafe JS accesses.
113 v8::FailedAccessCheckCallback failed_access_check_callback_ = nullptr;
114
115 // Address of the thread-local "thread in wasm" flag.
116 Address thread_in_wasm_flag_address_ = kNullAddress;
117};
118
119} // namespace internal
120} // namespace v8
121
122#endif // V8_THREAD_LOCAL_TOP_H_
123