説明を見る。00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef V8_TOP_H_
00029 #define V8_TOP_H_
00030
00031 #include "frames-inl.h"
00032
00033 namespace v8 { namespace internal {
00034
00035
00036 #define RETURN_IF_SCHEDULED_EXCEPTION() \
00037 if (Top::has_scheduled_exception()) return Top::PromoteScheduledException()
00038
00039
00040
00041 class SaveContext;
00042
00043 class ThreadLocalTop BASE_EMBEDDED {
00044 public:
00045
00046
00047 Context* context_;
00048 Object* pending_exception_;
00049
00050
00051
00052 Object* scheduled_exception_;
00053 bool external_caught_exception_;
00054 v8::TryCatch* try_catch_handler_;
00055 SaveContext* save_context_;
00056 v8::TryCatch* catcher_;
00057
00058
00059 Address c_entry_fp_;
00060 Address handler_;
00061 bool stack_is_cooked_;
00062 inline bool stack_is_cooked() { return stack_is_cooked_; }
00063 inline void set_stack_is_cooked(bool value) { stack_is_cooked_ = value; }
00064
00065
00066 int32_t formal_count_;
00067
00068
00069 v8::FailedAccessCheckCallback failed_access_check_callback_;
00070 };
00071
00072 #define TOP_ADDRESS_LIST(C) \
00073 C(handler_address) \
00074 C(c_entry_fp_address) \
00075 C(context_address) \
00076 C(pending_exception_address) \
00077 C(external_caught_exception_address)
00078
00079 class Top {
00080 public:
00081 enum AddressId {
00082 #define C(name) k_##name,
00083 TOP_ADDRESS_LIST(C)
00084 #undef C
00085 k_top_address_count
00086 };
00087
00088 static Address get_address_from_id(AddressId id);
00089
00090
00091 static Context* context() { return thread_local_.context_; }
00092 static void set_context(Context* context) {
00093 thread_local_.context_ = context;
00094 }
00095 static Context** context_address() { return &thread_local_.context_; }
00096
00097 static SaveContext* save_context() {return thread_local_.save_context_; }
00098 static void set_save_context(SaveContext* save) {
00099 thread_local_.save_context_ = save;
00100 }
00101
00102
00103 static Object* pending_exception() {
00104 ASSERT(has_pending_exception());
00105 return thread_local_.pending_exception_;
00106 }
00107 static bool external_caught_exception() {
00108 return thread_local_.external_caught_exception_;
00109 }
00110 static void set_pending_exception(Object* exception) {
00111 thread_local_.pending_exception_ = exception;
00112 }
00113 static void clear_pending_exception() {
00114 thread_local_.pending_exception_ = Heap::the_hole_value();
00115 }
00116
00117 static Object** pending_exception_address() {
00118 return &thread_local_.pending_exception_;
00119 }
00120 static bool has_pending_exception() {
00121 return !thread_local_.pending_exception_->IsTheHole();
00122 }
00123 static v8::TryCatch* try_catch_handler() {
00124 return thread_local_.try_catch_handler_;
00125 }
00126
00127
00128
00129
00130 static bool optional_reschedule_exception(bool is_bottom_call);
00131
00132 static bool* external_caught_exception_address() {
00133 return &thread_local_.external_caught_exception_;
00134 }
00135
00136 static Object* scheduled_exception() {
00137 ASSERT(has_scheduled_exception());
00138 return thread_local_.scheduled_exception_;
00139 }
00140 static bool has_scheduled_exception() {
00141 return !thread_local_.scheduled_exception_->IsTheHole();
00142 }
00143 static void clear_scheduled_exception() {
00144 thread_local_.scheduled_exception_ = Heap::the_hole_value();
00145 }
00146
00147 static void setup_external_caught() {
00148 thread_local_.external_caught_exception_ =
00149 (thread_local_.catcher_ != NULL) &&
00150 (Top::thread_local_.try_catch_handler_ == Top::thread_local_.catcher_);
00151 }
00152
00153
00154
00155 static bool is_out_of_memory();
00156
00157
00158 static Address c_entry_fp(ThreadLocalTop* thread) {
00159 return thread->c_entry_fp_;
00160 }
00161 static Address handler(ThreadLocalTop* thread) { return thread->handler_; }
00162
00163 static inline Address* c_entry_fp_address() {
00164 return &thread_local_.c_entry_fp_;
00165 }
00166 static inline Address* handler_address() { return &thread_local_.handler_; }
00167
00168
00169 static void* formal_count_address() { return &thread_local_.formal_count_; }
00170
00171 static void new_break(StackFrame::Id break_frame_id);
00172 static void set_break(StackFrame::Id break_frame_id, int break_id);
00173 static bool check_break(int break_id);
00174 static bool is_break();
00175 static StackFrame::Id break_frame_id();
00176 static int break_id();
00177
00178 static void MarkCompactPrologue();
00179 static void MarkCompactEpilogue();
00180 static void MarkCompactPrologue(char* archived_thread_data);
00181 static void MarkCompactEpilogue(char* archived_thread_data);
00182 static void PrintCurrentStackTrace(FILE* out);
00183 static void PrintStackTrace(FILE* out, char* thread_data);
00184 static void PrintStack(StringStream* accumulator);
00185 static void PrintStack();
00186 static Handle<String> StackTrace();
00187
00188
00189
00190
00191 static bool MayNamedAccess(JSObject* receiver,
00192 Object* key,
00193 v8::AccessType type);
00194 static bool MayIndexedAccess(JSObject* receiver,
00195 uint32_t index,
00196 v8::AccessType type);
00197
00198 static void SetFailedAccessCheckCallback(
00199 v8::FailedAccessCheckCallback callback);
00200 static void ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type);
00201
00202
00203
00204 static Failure* Throw(Object* exception, MessageLocation* location = NULL);
00205
00206
00207
00208 static Failure* ReThrow(Object* exception, MessageLocation* location = NULL);
00209 static void ScheduleThrow(Object* exception);
00210
00211
00212 static Object* PromoteScheduledException();
00213 static void DoThrow(Object* exception,
00214 MessageLocation* location,
00215 const char* message);
00216 static bool ShouldReportException(bool* is_caught_externally);
00217 static void ReportUncaughtException(Handle<Object> exception,
00218 MessageLocation* location,
00219 Handle<String> stack_trace);
00220
00221
00222
00223 static void ComputeLocation(MessageLocation* target);
00224
00225
00226 static void TraceException(bool flag);
00227
00228
00229 static Failure* StackOverflow();
00230
00231
00232 static void Initialize();
00233 static void TearDown();
00234 static void Iterate(ObjectVisitor* v);
00235 static void Iterate(ObjectVisitor* v, ThreadLocalTop* t);
00236 static char* Iterate(ObjectVisitor* v, char* t);
00237
00238
00239
00240 static Handle<GlobalObject> global() {
00241 return Handle<GlobalObject>(context()->global());
00242 }
00243
00244
00245 static Object* global_proxy() {
00246 return context()->global_proxy();
00247 }
00248
00249 static Handle<Context> global_context();
00250
00251 static Handle<JSBuiltinsObject> builtins() {
00252 return Handle<JSBuiltinsObject>(thread_local_.context_->builtins());
00253 }
00254
00255 static Object* LookupSpecialFunction(JSObject* receiver,
00256 JSObject* prototype,
00257 JSFunction* value);
00258
00259 static void RegisterTryCatchHandler(v8::TryCatch* that);
00260 static void UnregisterTryCatchHandler(v8::TryCatch* that);
00261
00262 #define TOP_GLOBAL_CONTEXT_FIELD_ACCESSOR(index, type, name) \
00263 static Handle<type> name() { \
00264 return Handle<type>(context()->global_context()->name()); \
00265 }
00266 GLOBAL_CONTEXT_FIELDS(TOP_GLOBAL_CONTEXT_FIELD_ACCESSOR)
00267 #undef TOP_GLOBAL_CONTEXT_FIELD_ACCESSOR
00268
00269 static inline ThreadLocalTop* GetCurrentThread() { return &thread_local_; }
00270 static int ArchiveSpacePerThread() { return sizeof(ThreadLocalTop); }
00271 static char* ArchiveThread(char* to);
00272 static char* RestoreThread(char* from);
00273
00274 private:
00275
00276 static ThreadLocalTop thread_local_;
00277 static void InitializeThreadLocal();
00278 static void PrintStackTrace(FILE* out, ThreadLocalTop* thread);
00279 static void MarkCompactPrologue(ThreadLocalTop* archived_thread_data);
00280 static void MarkCompactEpilogue(ThreadLocalTop* archived_thread_data);
00281
00282
00283
00284 static Mutex* break_access_;
00285
00286
00287 static StackFrame::Id break_frame_id_;
00288
00289
00290 static int break_count_;
00291
00292
00293 static int break_id_;
00294
00295 friend class SaveContext;
00296 friend class AssertNoContextChange;
00297 friend class ExecutionAccess;
00298
00299 static void FillCache();
00300 };
00301
00302
00303
00304
00305
00306 class SaveContext BASE_EMBEDDED {
00307 public:
00308 SaveContext() :
00309 context_(Top::context()),
00310 #if __GNUC_VERSION__ >= 40100 && __GNUC_VERSION__ < 40300
00311 dummy_(Top::context()),
00312 #endif
00313 prev_(Top::save_context()) {
00314 Top::set_save_context(this);
00315 }
00316
00317 ~SaveContext() {
00318 Top::set_context(*context_);
00319 Top::set_save_context(prev_);
00320 }
00321
00322 Handle<Context> context() { return context_; }
00323 SaveContext* prev() { return prev_; }
00324
00325 private:
00326 Handle<Context> context_;
00327 #if __GNUC_VERSION__ >= 40100 && __GNUC_VERSION__ < 40300
00328 Handle<Context> dummy_;
00329 #endif
00330 SaveContext* prev_;
00331 };
00332
00333
00334 class AssertNoContextChange BASE_EMBEDDED {
00335 #ifdef DEBUG
00336 public:
00337 AssertNoContextChange() :
00338 context_(Top::context()) {
00339 }
00340
00341 ~AssertNoContextChange() {
00342 ASSERT(Top::context() == *context_);
00343 }
00344
00345 private:
00346 HandleScope scope_;
00347 Handle<Context> context_;
00348 #else
00349 public:
00350 AssertNoContextChange() { }
00351 #endif
00352 };
00353
00354
00355 class ExecutionAccess BASE_EMBEDDED {
00356 public:
00357 ExecutionAccess();
00358 ~ExecutionAccess();
00359 };
00360
00361 } }
00362
00363 #endif // V8_TOP_H_