⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 top.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
  // The callers of this method are not expecting a GC.  AssertNoAllocation no_gc;  // Get the data object from access check info.  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());  Object* info = constructor->shared()->function_data();  if (info == Heap::undefined_value()) return;  Object* data_obj = FunctionTemplateInfo::cast(info)->access_check_info();  if (data_obj == Heap::undefined_value()) return;  HandleScope scope;  Handle<JSObject> receiver_handle(receiver);  Handle<Object> data(AccessCheckInfo::cast(data_obj)->data());  thread_local_.failed_access_check_callback_(    v8::Utils::ToLocal(receiver_handle),    type,    v8::Utils::ToLocal(data));}bool Top::MayNamedAccess(JSObject* receiver, Object* key, v8::AccessType type) {  ASSERT(receiver->IsAccessCheckNeeded());  // Check for compatibility between the security tokens in the  // current security context and the accessed object.  ASSERT(Top::security_context());  // The callers of this method are not expecting a GC.  AssertNoAllocation no_gc;  // During bootstrapping, callback functions are not enabled yet.  if (Bootstrapper::IsActive()) return true;  if (receiver->IsJSGlobalObject()) {    JSGlobalObject* global = JSGlobalObject::cast(receiver);    JSGlobalObject* current =        JSGlobalObject::cast(Top::security_context()->global());    if (current->security_token() == global->security_token()) return true;  }  // Get named access check callback  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());  Object* info = constructor->shared()->function_data();  if (info == Heap::undefined_value()) return false;  Object* data_obj = FunctionTemplateInfo::cast(info)->access_check_info();  if (data_obj == Heap::undefined_value()) return false;  Object* fun_obj = AccessCheckInfo::cast(data_obj)->named_callback();  v8::NamedSecurityCallback callback =      v8::ToCData<v8::NamedSecurityCallback>(fun_obj);  if (!callback) return false;  HandleScope scope;  Handle<JSObject> receiver_handle(receiver);  Handle<Object> key_handle(key);  Handle<Object> data(AccessCheckInfo::cast(data_obj)->data());  LOG(ApiNamedSecurityCheck(key));  bool result = false;  {    // Leaving JavaScript.    VMState state(OTHER);    result = callback(v8::Utils::ToLocal(receiver_handle),                      v8::Utils::ToLocal(key_handle),                      type,                      v8::Utils::ToLocal(data));  }  return result;}bool Top::MayIndexedAccess(JSObject* receiver,                           uint32_t index,                           v8::AccessType type) {  ASSERT(receiver->IsAccessCheckNeeded());  // Check for compatibility between the security tokens in the  // current security context and the accessed object.  ASSERT(Top::security_context());  // The callers of this method are not expecting a GC.  AssertNoAllocation no_gc;  // During bootstrapping, callback functions are not enabled yet.  if (Bootstrapper::IsActive()) return true;  if (receiver->IsJSGlobalObject()) {    JSGlobalObject* global = JSGlobalObject::cast(receiver);    JSGlobalObject* current =      JSGlobalObject::cast(Top::security_context()->global());    if (current->security_token() == global->security_token()) return true;  }  // Get indexed access check callback  JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());  Object* info = constructor->shared()->function_data();  if (info == Heap::undefined_value()) return false;  Object* data_obj = FunctionTemplateInfo::cast(info)->access_check_info();  if (data_obj == Heap::undefined_value()) return false;  Object* fun_obj = AccessCheckInfo::cast(data_obj)->indexed_callback();  v8::IndexedSecurityCallback callback =      v8::ToCData<v8::IndexedSecurityCallback>(fun_obj);  if (!callback) return false;  HandleScope scope;  Handle<JSObject> receiver_handle(receiver);  Handle<Object> data(AccessCheckInfo::cast(data_obj)->data());  LOG(ApiIndexedSecurityCheck(index));  bool result = false;  {    // Leaving JavaScript.    VMState state(OTHER);    result = callback(v8::Utils::ToLocal(receiver_handle),                      index,                      type,                      v8::Utils::ToLocal(data));  }  return result;}Failure* Top::StackOverflow() {  HandleScope scope;  Handle<String> key = Factory::stack_overflow_symbol();  Handle<JSObject> boilerplate =      Handle<JSObject>::cast(          GetProperty(Top::security_context_builtins(), key));  Handle<Object> exception = Copy(boilerplate);  // TODO(1240995): To avoid having to call JavaScript code to compute  // the message for stack overflow exceptions which is very likely to  // double fault with another stack overflow exception, we use a  // precomputed message. This is somewhat problematic in that it  // doesn't use ReportUncaughtException to determine the location  // from where the exception occurred. It should probably be  // reworked.  static const char* kMessage =      "Uncaught RangeError: Maximum call stack size exceeded";  DoThrow(*exception, NULL, kMessage, false);  return Failure::Exception();}Failure* Top::Throw(Object* exception, MessageLocation* location) {  DoThrow(exception, location, NULL, false);  return Failure::Exception();}Failure* Top::ReThrow(Object* exception, MessageLocation* location) {  DoThrow(exception, location, NULL, true);  return Failure::Exception();}void Top::ScheduleThrow(Object* exception) {  // When scheduling a throw we first throw the exception to get the  // error reporting if it is uncaught before rescheduling it.  Throw(exception);  thread_local_.scheduled_exception_ = pending_exception();  thread_local_.external_caught_exception_ = false;  clear_pending_exception();}Object* Top::PromoteScheduledException() {  Object* thrown = scheduled_exception();  clear_scheduled_exception();  // Re-throw the exception to avoid getting repeated error reporting.  return ReThrow(thrown);}// NOTE: The stack trace frame iterator is an iterator that only// traverse proper JavaScript frames; that is JavaScript frames that// have proper JavaScript functions. This excludes the problematic// functions in runtime.js.class StackTraceFrameIterator: public JavaScriptFrameIterator { public:  StackTraceFrameIterator() {    if (!done() && !frame()->function()->IsJSFunction()) Advance();  }  void Advance() {    while (true) {      JavaScriptFrameIterator::Advance();      if (done()) return;      if (frame()->function()->IsJSFunction()) return;    }  }};void Top::PrintCurrentStackTrace(FILE* out) {  StackTraceFrameIterator it;  while (!it.done()) {    HandleScope scope;    // Find code position if recorded in relocation info.    JavaScriptFrame* frame = it.frame();    int pos = frame->FindCode()->SourcePosition(frame->pc());    Handle<Object> pos_obj(Smi::FromInt(pos));    // Fetch function and receiver.    Handle<JSFunction> fun(JSFunction::cast(frame->function()));    Handle<Object> recv(frame->receiver());    // Advance to the next JavaScript frame and determine if the    // current frame is the top-level frame.    it.Advance();    Handle<Object> is_top_level = it.done()        ? Factory::true_value()        : Factory::false_value();    // Generate and print strack trace line.    Handle<String> line =        Execution::GetStackTraceLine(recv, fun, pos_obj, is_top_level);    if (line->length() > 0) {      line->PrintOn(out);      fprintf(out, "\n");    }  }}void Top::ComputeLocation(MessageLocation* target) {  *target = MessageLocation(empty_script(), -1, -1);  StackTraceFrameIterator it;  if (!it.done()) {    JavaScriptFrame* frame = it.frame();    JSFunction* fun = JSFunction::cast(frame->function());    Object* script = fun->shared()->script();    if (script->IsScript() &&        !(Script::cast(script)->source()->IsUndefined())) {      int pos = frame->FindCode()->SourcePosition(frame->pc());      // Compute the location from the function and the reloc info.      Handle<Script> casted_script(Script::cast(script));      *target = MessageLocation(casted_script, pos, pos + 1);    }  }}void Top::ReportUncaughtException(Handle<Object> exception,                                  MessageLocation* location,                                  Handle<String> stack_trace) {  Handle<Object> message =    MessageHandler::MakeMessageObject("uncaught_exception",                                      location,                                      HandleVector<Object>(&exception, 1),                                      stack_trace);  // Report the uncaught exception.  MessageHandler::ReportMessage(location, message);}bool Top::ShouldReportException(bool* is_caught_externally) {  StackHandler* handler =      StackHandler::FromAddress(Top::handler(Top::GetCurrentThread()));  // Determine if we have an external exception handler and get the  // address of the external handler so we can compare the address to  // determine which one is closer to the top of the stack.  bool has_external_handler = (thread_local_.try_catch_handler_ != NULL);  Address external_handler_address =      reinterpret_cast<Address>(thread_local_.try_catch_handler_);  // NOTE: The stack is assumed to grown towards lower addresses. If  // the handler is at a higher address than the external address it  // means that it is below it on the stack.  // Find the top-most try-catch or try-finally handler.  while (handler != NULL && handler->is_entry()) {    handler = handler->next();  }  // The exception has been externally caught if and only if there is  // an external handler which is above any JavaScript try-catch or  // try-finally handlers.  *is_caught_externally = has_external_handler &&      (handler == NULL || handler->address() > external_handler_address);  // Find the top-most try-catch handler.  while (handler != NULL && !handler->is_try_catch()) {    handler = handler->next();  }  // If we have a try-catch handler then the exception is caught in  // JavaScript code.  bool is_uncaught_by_js = (handler == NULL);  // If there is no external try-catch handler, we report the  // exception if it isn't caught by JavaScript code.  if (!has_external_handler) return is_uncaught_by_js;  if (is_uncaught_by_js || handler->address() > external_handler_address) {    // Only report the exception if the external handler is verbose.    return thread_local_.try_catch_handler_->is_verbose_;  } else {    // Report the exception if it isn't caught by JavaScript code.    return is_uncaught_by_js;  }}void Top::DoThrow(Object* exception,                  MessageLocation* location,                  const char* message,                  bool is_rethrow) {  ASSERT(!has_pending_exception());  ASSERT(!external_caught_exception());  HandleScope scope;  Handle<Object> exception_handle(exception);  bool is_caught_externally = false;  bool report_exception = (exception != Failure::OutOfMemoryException()) &&    ShouldReportException(&is_caught_externally);  if (is_rethrow) report_exception = false;  Handle<Object> message_obj;  MessageLocation potential_computed_location;  bool try_catch_needs_message =    is_caught_externally && thread_local_.try_catch_handler_->capture_message_;  if (report_exception || try_catch_needs_message) {    if (location == NULL) {      // If no location was specified we use a computed one instead      ComputeLocation(&potential_computed_location);      location = &potential_computed_location;    }    Handle<String> stack_trace;    if (FLAG_trace_exception) stack_trace = StackTrace();    message_obj = MessageHandler::MakeMessageObject("uncaught_exception",        location, HandleVector<Object>(&exception_handle, 1), stack_trace);  }  // If the exception is caught externally, we store it in the  // try/catch handler. The C code can find it later and process it if  // necessary.  if (is_caught_externally) {    thread_local_.try_catch_handler_->exception_ =      reinterpret_cast<void*>(*exception_handle);    if (!message_obj.is_null()) {      thread_local_.try_catch_handler_->message_ =        reinterpret_cast<void*>(*message_obj);    }  }  // Notify debugger of exception.  Debugger::OnException(exception_handle, report_exception);  if (report_exception) {    if (message != NULL) {      MessageHandler::ReportMessage(message);    } else {      MessageHandler::ReportMessage(location, message_obj);    }  }  thread_local_.external_caught_exception_ = is_caught_externally;  // NOTE: Notifying the debugger or reporting the exception may have caused  // new exceptions. For now, we just ignore that and set the pending exception  // to the original one.  set_pending_exception(*exception_handle);}void Top::TraceException(bool flag) {  FLAG_trace_exception = flag;}bool Top::optional_reschedule_exception(bool is_bottom_call) {  if (!is_out_of_memory() &&      (thread_local_.external_caught_exception_ || is_bottom_call)) {    thread_local_.external_caught_exception_ = false;    clear_pending_exception();    return false;  } else {    thread_local_.scheduled_exception_ = pending_exception();    clear_pending_exception();    return true;  }}bool Top::is_out_of_memory() {  if (has_pending_exception()) {    Object* e = pending_exception();    if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) {      return true;    }  }  if (has_scheduled_exception()) {    Object* e = scheduled_exception();    if (e->IsFailure() && Failure::cast(e)->IsOutOfMemoryException()) {      return true;    }  }  return false;}Handle<Context> Top::global_context() {  GlobalObject* global = thread_local_.context_->global();  return Handle<Context>(global->global_context());}Object* Top::LookupSpecialFunction(JSObject* receiver,                                   JSObject* prototype,                                   JSFunction* function) {  if (receiver->IsJSArray()) {    FixedArray* table = context()->global_context()->special_function_table();    for (int index = 0; index < table->length(); index +=3) {      if ((prototype == table->get(index)) &&          (function == table->get(index+1))) {        return table->get(index+2);      }    }  }  return Heap::undefined_value();}char* Top::ArchiveThread(char* to) {  memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(thread_local_));  InitializeThreadLocal();  return to + sizeof(thread_local_);}char* Top::RestoreThread(char* from) {  memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(thread_local_));  return from + sizeof(thread_local_);}ExecutionAccess::ExecutionAccess() {  Top::break_access_->Lock();}ExecutionAccess::~ExecutionAccess() {  Top::break_access_->Unlock();}} }  // namespace v8::internal

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -