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

📄 execution.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
// Copyright 2006-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 <stdlib.h>#include "v8.h"#include "api.h"#include "codegen-inl.h"#if defined(ARM) || defined (__arm__) || defined(__thumb__)#include "simulator-arm.h"#else  // ia32#include "simulator-ia32.h"#endifnamespace v8 { namespace internal {static Handle<Object> Invoke(bool construct,                             Handle<JSFunction> func,                             Handle<Object> receiver,                             int argc,                             Object*** args,                             bool* has_pending_exception) {  // Make sure we have a real function, not a boilerplate function.  ASSERT(!func->IsBoilerplate());  // Entering JavaScript.  VMState state(JS);  // Guard the stack against too much recursion.  StackGuard guard;  // Placeholder for return value.  Object* value = reinterpret_cast<Object*>(kZapValue);  typedef Object* (*JSEntryFunction)(    byte* entry,    Object* function,    Object* receiver,    int argc,    Object*** args);  Handle<Code> code;  if (construct) {    JSConstructEntryStub stub;    code = stub.GetCode();  } else {    JSEntryStub stub;    code = stub.GetCode();  }  {    // Save and restore context around invocation and block the    // allocation of handles without explicit handle scopes.    SaveContext save;    NoHandleAllocation na;    JSEntryFunction entry = FUNCTION_CAST<JSEntryFunction>(code->entry());    // Call the function through the right JS entry stub.    value = CALL_GENERATED_CODE(entry, func->code()->entry(), *func,                                *receiver, argc, args);  }#ifdef DEBUG  value->Verify();#endif  // Update the pending exception flag and return the value.  *has_pending_exception = value->IsException();  ASSERT(*has_pending_exception == Top::has_pending_exception());  // If the pending exception is OutOfMemoryException set out_of_memory in  // the global context.  Note: We have to mark the global context here  // since the GenerateThrowOutOfMemory stub cannot make a RuntimeCall to  // set it.  if (*has_pending_exception) {    if (Top::pending_exception() == Failure::OutOfMemoryException()) {      Top::context()->mark_out_of_memory();    }  }  return Handle<Object>(value);}Handle<Object> Execution::Call(Handle<JSFunction> func,                               Handle<Object> receiver,                               int argc,                               Object*** args,                               bool* pending_exception) {  return Invoke(false, func, receiver, argc, args, pending_exception);}Handle<Object> Execution::New(Handle<JSFunction> func, int argc,                              Object*** args, bool* pending_exception) {  return Invoke(true, func, Top::global(), argc, args, pending_exception);}Handle<Object> Execution::TryCall(Handle<JSFunction> func,                                  Handle<Object> receiver,                                  int argc,                                  Object*** args,                                  bool* caught_exception) {  // Enter a try-block while executing the JavaScript code. To avoid  // duplicate error printing it must be non-verbose.  Also, to avoid  // creating message objects during stack overflow we shouldn't  // capture messages.  v8::TryCatch catcher;  catcher.SetVerbose(false);  catcher.SetCaptureMessage(false);  Handle<Object> result = Invoke(false, func, receiver, argc, args,                                 caught_exception);  if (*caught_exception) {    ASSERT(catcher.HasCaught());    ASSERT(Top::has_pending_exception());    ASSERT(Top::external_caught_exception());    Top::optional_reschedule_exception(true);    result = v8::Utils::OpenHandle(*catcher.Exception());  }  ASSERT(!Top::has_pending_exception());  ASSERT(!Top::external_caught_exception());  return result;}Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) {  ASSERT(!object->IsJSFunction());  // If you return a function from here, it will be called when an  // attempt is made to call the given object as a function.  // The regular expression code here is really meant more as an  // example than anything else. KJS does not support calling regular  // expressions as functions, but SpiderMonkey does.  if (FLAG_call_regexp) {    bool is_regexp =        object->IsHeapObject() &&        (HeapObject::cast(*object)->map()->constructor() ==         *Top::regexp_function());    if (is_regexp) {      Handle<String> exec = Factory::exec_symbol();      return Handle<Object>(object->GetProperty(*exec));    }  }  // Objects created through the API can have an instance-call handler  // that should be used when calling the object as a function.  if (object->IsHeapObject() &&      HeapObject::cast(*object)->map()->has_instance_call_handler()) {    return Handle<JSFunction>(        Top::global_context()->call_as_function_delegate());  }  return Factory::undefined_value();}// Static state for stack guards.StackGuard::ThreadLocal StackGuard::thread_local_;StackGuard::StackGuard() {  ExecutionAccess access;  if (thread_local_.nesting_++ == 0 &&      thread_local_.jslimit_ != kInterruptLimit) {    // NOTE: We assume that the stack grows towards lower addresses.    ASSERT(thread_local_.jslimit_ == kIllegalLimit);    ASSERT(thread_local_.climit_ == kIllegalLimit);    thread_local_.initial_jslimit_ = thread_local_.jslimit_ =        GENERATED_CODE_STACK_LIMIT(kLimitSize);    // NOTE: The check for overflow is not safe as there is no guarantee that    // the running thread has its stack in all memory up to address 0x00000000.    thread_local_.initial_climit_ = thread_local_.climit_ =        reinterpret_cast<uintptr_t>(this) >= kLimitSize ?            reinterpret_cast<uintptr_t>(this) - kLimitSize : 0;    if (thread_local_.interrupt_flags_ != 0) {      set_limits(kInterruptLimit, access);    }  }  // make sure we have proper limits setup  ASSERT(thread_local_.jslimit_ != kIllegalLimit &&         thread_local_.climit_ != kIllegalLimit);}StackGuard::~StackGuard() {  ExecutionAccess access;  if (--thread_local_.nesting_ == 0) {    set_limits(kIllegalLimit, access);  }}bool StackGuard::IsStackOverflow() {  ExecutionAccess access;  return (thread_local_.jslimit_ != kInterruptLimit &&          thread_local_.climit_ != kInterruptLimit);}void StackGuard::EnableInterrupts() {  ExecutionAccess access;  if (IsSet(access)) {    set_limits(kInterruptLimit, access);  }}void StackGuard::SetStackLimit(uintptr_t limit) {  ExecutionAccess access;  // If the current limits are special (eg due to a pending interrupt) then  // leave them alone.  if (thread_local_.jslimit_ == thread_local_.initial_jslimit_) {    thread_local_.jslimit_ = limit;  }  if (thread_local_.climit_ == thread_local_.initial_climit_) {    thread_local_.climit_ = limit;  }  thread_local_.initial_climit_ = limit;  thread_local_.initial_jslimit_ = limit;}void StackGuard::DisableInterrupts() {  ExecutionAccess access;  reset_limits(access);}bool StackGuard::IsSet(const ExecutionAccess& lock) {  return thread_local_.interrupt_flags_ != 0;}bool StackGuard::IsInterrupted() {  ExecutionAccess access;  return thread_local_.interrupt_flags_ & INTERRUPT;}void StackGuard::Interrupt() {  ExecutionAccess access;  thread_local_.interrupt_flags_ |= INTERRUPT;  set_limits(kInterruptLimit, access);}bool StackGuard::IsPreempted() {  ExecutionAccess access;  return thread_local_.interrupt_flags_ & PREEMPT;}void StackGuard::Preempt() {  ExecutionAccess access;  thread_local_.interrupt_flags_ |= PREEMPT;  set_limits(kInterruptLimit, access);}bool StackGuard::IsDebugBreak() {  ExecutionAccess access;  return thread_local_.interrupt_flags_ & DEBUGBREAK;}void StackGuard::DebugBreak() {  ExecutionAccess access;  thread_local_.interrupt_flags_ |= DEBUGBREAK;  set_limits(kInterruptLimit, access);}void StackGuard::Continue(InterruptFlag after_what) {  ExecutionAccess access;  thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what);  if (thread_local_.interrupt_flags_ == 0) {    reset_limits(access);  }}int StackGuard::ArchiveSpacePerThread() {  return sizeof(ThreadLocal);}char* StackGuard::ArchiveStackGuard(char* to) {  ExecutionAccess access;  memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));  ThreadLocal blank;  thread_local_ = blank;  return to + sizeof(ThreadLocal);}char* StackGuard::RestoreStackGuard(char* from) {  ExecutionAccess access;  memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));  return from + sizeof(ThreadLocal);}

⌨️ 快捷键说明

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