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

📄 api.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
// Copyright 2007-2008 the V8 project authors. All rights reserved.// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:////     * Redistributions of source code must retain the above copyright//       notice, this list of conditions and the following disclaimer.//     * Redistributions in binary form must reproduce the above//       copyright notice, this list of conditions and the following//       disclaimer in the documentation and/or other materials provided//       with the distribution.//     * Neither the name of Google Inc. nor the names of its//       contributors may be used to endorse or promote products derived//       from this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#include "v8.h"#include "api.h"#include "bootstrapper.h"#include "compiler.h"#include "debug.h"#include "execution.h"#include "global-handles.h"#include "platform.h"#include "serialize.h"#include "snapshot.h"namespace i = v8::internal;#define LOG_API(expr) LOG(ApiEntryCall(expr))namespace v8 {#define ON_BAILOUT(location, code)              \  if (IsDeadCheck(location)) {                  \    code;                                       \    UNREACHABLE();                              \  }#define EXCEPTION_PREAMBLE()                                      \  thread_local.IncrementCallDepth();                              \  ASSERT(!i::Top::external_caught_exception());                   \  bool has_pending_exception = false#define EXCEPTION_BAILOUT_CHECK(value)                                         \  do {                                                                         \    thread_local.DecrementCallDepth();                                         \    if (has_pending_exception) {                                               \      if (thread_local.CallDepthIsZero() && i::Top::is_out_of_memory()) {      \        if (!thread_local.IgnoreOutOfMemory())                                 \          i::V8::FatalProcessOutOfMemory(NULL);                                \      }                                                                        \      bool call_depth_is_zero = thread_local.CallDepthIsZero();                \      i::Top::optional_reschedule_exception(call_depth_is_zero);               \      return value;                                                            \    }                                                                          \  } while (false)// --- D a t a   t h a t   i s   s p e c i f i c   t o   a   t h r e a d ---static i::HandleScopeImplementer thread_local;// --- E x c e p t i o n   B e h a v i o r ---static bool has_shut_down = false;static FatalErrorCallback exception_behavior = NULL;static void DefaultFatalErrorHandler(const char* location,                                     const char* message) {  API_Fatal(location, message);}static FatalErrorCallback& GetFatalErrorHandler() {  if (exception_behavior == NULL) {    exception_behavior = DefaultFatalErrorHandler;  }  return exception_behavior;}// When V8 cannot allocated memory FatalProcessOutOfMemory is called.// The default fatal error handler is called and execution is stopped.void i::V8::FatalProcessOutOfMemory(const char* location) {  has_shut_down = true;  FatalErrorCallback callback = GetFatalErrorHandler();  callback(location, "Allocation failed - process out of memory");  // If the callback returns, we stop execution.  UNREACHABLE();}void V8::SetFatalErrorHandler(FatalErrorCallback that) {  exception_behavior = that;}bool Utils::ReportApiFailure(const char* location, const char* message) {  FatalErrorCallback callback = GetFatalErrorHandler();  callback(location, message);  has_shut_down = true;  return false;}bool V8::IsDead() {  return has_shut_down;}static inline bool ApiCheck(bool condition,                            const char* location,                            const char* message) {  return condition ? true : Utils::ReportApiFailure(location, message);}static bool ReportV8Dead(const char* location) {  FatalErrorCallback callback = GetFatalErrorHandler();  callback(location, "V8 is no longer useable");  return true;}static bool ReportEmptyHandle(const char* location) {  FatalErrorCallback callback = GetFatalErrorHandler();  callback(location, "Reading from empty handle");  return true;}/** * IsDeadCheck checks that the vm is useable.  If, for instance, the vm has been * out of memory at some point this check will fail.  It should be called on * entry to all methods that touch anything in the heap, except destructors * which you sometimes can't avoid calling after the vm has crashed.  Functions * that call EnsureInitialized or ON_BAILOUT don't have to also call * IsDeadCheck.  ON_BAILOUT has the advantage over EnsureInitialized that you * can arrange to return if the VM is dead.  This is needed to ensure that no VM * heap allocations are attempted on a dead VM.  EnsureInitialized has the * advantage over ON_BAILOUT that it actually initializes the VM if this has not * yet been done. */static inline bool IsDeadCheck(const char* location) {  return has_shut_down ? ReportV8Dead(location) : false;}static inline bool EmptyCheck(const char* location, v8::Handle<v8::Data> obj) {  return obj.IsEmpty() ? ReportEmptyHandle(location) : false;}static inline bool EmptyCheck(const char* location, v8::Data* obj) {  return (obj == 0) ? ReportEmptyHandle(location) : false;}// --- S t a t i c s ---static i::StringInputBuffer write_input_buffer;static void EnsureInitialized(const char* location) {  if (IsDeadCheck(location)) return;  ApiCheck(v8::V8::Initialize(), location, "Error initializing V8");}v8::Handle<v8::Primitive> ImplementationUtilities::Undefined() {  if (IsDeadCheck("v8::Undefined()")) return v8::Handle<v8::Primitive>();  EnsureInitialized("v8::Undefined()");  return v8::Handle<Primitive>(ToApi<Primitive>(i::Factory::undefined_value()));}v8::Handle<v8::Primitive> ImplementationUtilities::Null() {  if (IsDeadCheck("v8::Null()")) return v8::Handle<v8::Primitive>();  EnsureInitialized("v8::Null()");  return v8::Handle<Primitive>(ToApi<Primitive>(i::Factory::null_value()));}v8::Handle<v8::Boolean> ImplementationUtilities::True() {  if (IsDeadCheck("v8::True()")) return v8::Handle<v8::Boolean>();  EnsureInitialized("v8::True()");  return v8::Handle<v8::Boolean>(ToApi<Boolean>(i::Factory::true_value()));}v8::Handle<v8::Boolean> ImplementationUtilities::False() {  if (IsDeadCheck("v8::False()")) return v8::Handle<v8::Boolean>();  EnsureInitialized("v8::False()");  return v8::Handle<v8::Boolean>(ToApi<Boolean>(i::Factory::false_value()));}void V8::SetFlagsFromString(const char* str, int length) {  i::FlagList::SetFlagsFromString(str, length);}void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {  i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);}v8::Handle<Value> ThrowException(v8::Handle<v8::Value> value) {  if (IsDeadCheck("v8::ThrowException()")) return v8::Handle<Value>();  i::Top::ScheduleThrow(*Utils::OpenHandle(*value));  return v8::Undefined();}RegisteredExtension* RegisteredExtension::first_extension_ = NULL;RegisteredExtension::RegisteredExtension(Extension* extension)    : extension_(extension), state_(UNVISITED) { }void RegisteredExtension::Register(RegisteredExtension* that) {  that->next_ = RegisteredExtension::first_extension_;  RegisteredExtension::first_extension_ = that;}void RegisterExtension(Extension* that) {  RegisteredExtension* extension = new RegisteredExtension(that);  RegisteredExtension::Register(extension);}Extension::Extension(const char* name,                     const char* source,                     int dep_count,                     const char** deps)    : name_(name),      source_(source),      dep_count_(dep_count),      deps_(deps),      auto_enable_(false) { }v8::Handle<Primitive> Undefined() {  LOG_API("Undefined");  return ImplementationUtilities::Undefined();}v8::Handle<Primitive> Null() {  LOG_API("Null");  return ImplementationUtilities::Null();}v8::Handle<Boolean> True() {  LOG_API("True");  return ImplementationUtilities::True();}v8::Handle<Boolean> False() {  LOG_API("False");  return ImplementationUtilities::False();}ResourceConstraints::ResourceConstraints()  : max_young_space_size_(0),    max_old_space_size_(0),    stack_limit_(NULL) { }bool SetResourceConstraints(ResourceConstraints* constraints) {  bool result = i::Heap::ConfigureHeap(constraints->max_young_space_size(),                                       constraints->max_old_space_size());  if (!result) return false;  if (constraints->stack_limit() != NULL) {    uintptr_t limit = reinterpret_cast<uintptr_t>(constraints->stack_limit());    i::StackGuard::SetStackLimit(limit);  }  return true;}void** V8::GlobalizeReference(void** obj) {  LOG_API("Persistent::New");  if (IsDeadCheck("V8::Persistent::New")) return NULL;  i::Handle<i::Object> result =      i::GlobalHandles::Create(*reinterpret_cast<i::Object**>(obj));  return reinterpret_cast<void**>(result.location());}void V8::MakeWeak(void** object, void* parameters,                  WeakReferenceCallback callback) {  LOG_API("MakeWeak");  i::GlobalHandles::MakeWeak(reinterpret_cast<i::Object**>(object), parameters,      callback);}void V8::ClearWeak(void** obj) {  LOG_API("ClearWeak");  i::GlobalHandles::ClearWeakness(reinterpret_cast<i::Object**>(obj));}bool V8::IsGlobalNearDeath(void** obj) {  LOG_API("IsGlobalNearDeath");  if (has_shut_down) return false;  return i::GlobalHandles::IsNearDeath(reinterpret_cast<i::Object**>(obj));}bool V8::IsGlobalWeak(void** obj) {  LOG_API("IsGlobalWeak");  if (has_shut_down) return false;  return i::GlobalHandles::IsWeak(reinterpret_cast<i::Object**>(obj));}void V8::DisposeGlobal(void** obj) {  LOG_API("DisposeGlobal");  if (has_shut_down) return;  i::GlobalHandles::Destroy(reinterpret_cast<i::Object**>(obj));}// --- H a n d l e s ---HandleScope::Data HandleScope::current_ = { -1, NULL, NULL };int HandleScope::NumberOfHandles() {  int n = thread_local.Blocks()->length();  if (n == 0) return 0;  return ((n - 1) * i::kHandleBlockSize) +       (current_.next - thread_local.Blocks()->last());}void** v8::HandleScope::CreateHandle(void* value) {  void** result = current_.next;  if (result == current_.limit) {    // Make sure there's at least one scope on the stack and that the    // top of the scope stack isn't a barrier.    if (!ApiCheck(current_.extensions >= 0,                  "v8::HandleScope::CreateHandle()",                  "Cannot create a handle without a HandleScope")) {      return NULL;    }    // If there's more room in the last block, we use that. This is used    // for fast creation of scopes after scope barriers.    if (!thread_local.Blocks()->is_empty()) {      void** limit = &thread_local.Blocks()->last()[i::kHandleBlockSize];      if (current_.limit != limit) {        current_.limit = limit;      }    }    // If we still haven't found a slot for the handle, we extend the    // current handle scope by allocating a new handle block.    if (result == current_.limit) {      // If there's a spare block, use it for growing the current scope.      result = thread_local.GetSpareOrNewBlock();      // Add the extension to the global list of blocks, but count the      // extension as part of the current scope.      thread_local.Blocks()->Add(result);      current_.extensions++;      current_.limit = &result[i::kHandleBlockSize];    }  }  // Update the current next field, set the value in the created  // handle, and return the result.  ASSERT(result < current_.limit);  current_.next = result + 1;  *result = value;  return result;

⌨️ 快捷键说明

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