Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #include <stdlib.h>
     29 
     30 #include "v8.h"
     31 
     32 #include "api.h"
     33 #include "bootstrapper.h"
     34 #include "codegen.h"
     35 #include "debug.h"
     36 #include "deoptimizer.h"
     37 #include "isolate-inl.h"
     38 #include "runtime-profiler.h"
     39 #include "simulator.h"
     40 #include "v8threads.h"
     41 #include "vm-state-inl.h"
     42 
     43 namespace v8 {
     44 namespace internal {
     45 
     46 
     47 StackGuard::StackGuard()
     48     : isolate_(NULL) {
     49 }
     50 
     51 
     52 void StackGuard::set_interrupt_limits(const ExecutionAccess& lock) {
     53   ASSERT(isolate_ != NULL);
     54   // Ignore attempts to interrupt when interrupts are postponed.
     55   if (should_postpone_interrupts(lock)) return;
     56   thread_local_.jslimit_ = kInterruptLimit;
     57   thread_local_.climit_ = kInterruptLimit;
     58   isolate_->heap()->SetStackLimits();
     59 }
     60 
     61 
     62 void StackGuard::reset_limits(const ExecutionAccess& lock) {
     63   ASSERT(isolate_ != NULL);
     64   thread_local_.jslimit_ = thread_local_.real_jslimit_;
     65   thread_local_.climit_ = thread_local_.real_climit_;
     66   isolate_->heap()->SetStackLimits();
     67 }
     68 
     69 
     70 static Handle<Object> Invoke(bool is_construct,
     71                              Handle<JSFunction> function,
     72                              Handle<Object> receiver,
     73                              int argc,
     74                              Handle<Object> args[],
     75                              bool* has_pending_exception) {
     76   Isolate* isolate = function->GetIsolate();
     77 
     78   // Entering JavaScript.
     79   VMState<JS> state(isolate);
     80 
     81   // Placeholder for return value.
     82   MaybeObject* value = reinterpret_cast<Object*>(kZapValue);
     83 
     84   typedef Object* (*JSEntryFunction)(byte* entry,
     85                                      Object* function,
     86                                      Object* receiver,
     87                                      int argc,
     88                                      Object*** args);
     89 
     90   Handle<Code> code = is_construct
     91       ? isolate->factory()->js_construct_entry_code()
     92       : isolate->factory()->js_entry_code();
     93 
     94   // Convert calls on global objects to be calls on the global
     95   // receiver instead to avoid having a 'this' pointer which refers
     96   // directly to a global object.
     97   if (receiver->IsGlobalObject()) {
     98     Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
     99     receiver = Handle<JSObject>(global->global_receiver());
    100   }
    101 
    102   // Make sure that the global object of the context we're about to
    103   // make the current one is indeed a global object.
    104   ASSERT(function->context()->global_object()->IsGlobalObject());
    105 
    106   {
    107     // Save and restore context around invocation and block the
    108     // allocation of handles without explicit handle scopes.
    109     SaveContext save(isolate);
    110     SealHandleScope shs(isolate);
    111     JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
    112 
    113     // Call the function through the right JS entry stub.
    114     byte* function_entry = function->code()->entry();
    115     JSFunction* func = *function;
    116     Object* recv = *receiver;
    117     Object*** argv = reinterpret_cast<Object***>(args);
    118     value =
    119         CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
    120   }
    121 
    122 #ifdef VERIFY_HEAP
    123   value->Verify();
    124 #endif
    125 
    126   // Update the pending exception flag and return the value.
    127   *has_pending_exception = value->IsException();
    128   ASSERT(*has_pending_exception == isolate->has_pending_exception());
    129   if (*has_pending_exception) {
    130     isolate->ReportPendingMessages();
    131     if (isolate->pending_exception()->IsOutOfMemory()) {
    132       if (!isolate->ignore_out_of_memory()) {
    133         V8::FatalProcessOutOfMemory("JS", true);
    134       }
    135     }
    136 #ifdef ENABLE_DEBUGGER_SUPPORT
    137     // Reset stepping state when script exits with uncaught exception.
    138     if (isolate->debugger()->IsDebuggerActive()) {
    139       isolate->debug()->ClearStepping();
    140     }
    141 #endif  // ENABLE_DEBUGGER_SUPPORT
    142     return Handle<Object>();
    143   } else {
    144     isolate->clear_pending_message();
    145   }
    146 
    147   return Handle<Object>(value->ToObjectUnchecked(), isolate);
    148 }
    149 
    150 
    151 Handle<Object> Execution::Call(Isolate* isolate,
    152                                Handle<Object> callable,
    153                                Handle<Object> receiver,
    154                                int argc,
    155                                Handle<Object> argv[],
    156                                bool* pending_exception,
    157                                bool convert_receiver) {
    158   *pending_exception = false;
    159 
    160   if (!callable->IsJSFunction()) {
    161     callable = TryGetFunctionDelegate(isolate, callable, pending_exception);
    162     if (*pending_exception) return callable;
    163   }
    164   Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
    165 
    166   // In non-strict mode, convert receiver.
    167   if (convert_receiver && !receiver->IsJSReceiver() &&
    168       !func->shared()->native() && func->shared()->is_classic_mode()) {
    169     if (receiver->IsUndefined() || receiver->IsNull()) {
    170       Object* global = func->context()->global_object()->global_receiver();
    171       // Under some circumstances, 'global' can be the JSBuiltinsObject
    172       // In that case, don't rewrite.  (FWIW, the same holds for
    173       // GetIsolate()->global_object()->global_receiver().)
    174       if (!global->IsJSBuiltinsObject()) {
    175         receiver = Handle<Object>(global, func->GetIsolate());
    176       }
    177     } else {
    178       receiver = ToObject(isolate, receiver, pending_exception);
    179     }
    180     if (*pending_exception) return callable;
    181   }
    182 
    183   return Invoke(false, func, receiver, argc, argv, pending_exception);
    184 }
    185 
    186 
    187 Handle<Object> Execution::New(Handle<JSFunction> func,
    188                               int argc,
    189                               Handle<Object> argv[],
    190                               bool* pending_exception) {
    191   return Invoke(true, func, func->GetIsolate()->global_object(), argc, argv,
    192                 pending_exception);
    193 }
    194 
    195 
    196 Handle<Object> Execution::TryCall(Handle<JSFunction> func,
    197                                   Handle<Object> receiver,
    198                                   int argc,
    199                                   Handle<Object> args[],
    200                                   bool* caught_exception) {
    201   // Enter a try-block while executing the JavaScript code. To avoid
    202   // duplicate error printing it must be non-verbose.  Also, to avoid
    203   // creating message objects during stack overflow we shouldn't
    204   // capture messages.
    205   v8::TryCatch catcher;
    206   catcher.SetVerbose(false);
    207   catcher.SetCaptureMessage(false);
    208   *caught_exception = false;
    209 
    210   // Get isolate now, because handle might be persistent
    211   // and get destroyed in the next call.
    212   Isolate* isolate = func->GetIsolate();
    213   Handle<Object> result = Invoke(false, func, receiver, argc, args,
    214                                  caught_exception);
    215 
    216   if (*caught_exception) {
    217     ASSERT(catcher.HasCaught());
    218     ASSERT(isolate->has_pending_exception());
    219     ASSERT(isolate->external_caught_exception());
    220     if (isolate->is_out_of_memory() && !isolate->ignore_out_of_memory()) {
    221       V8::FatalProcessOutOfMemory("OOM during Execution::TryCall");
    222     }
    223     if (isolate->pending_exception() ==
    224         isolate->heap()->termination_exception()) {
    225       result = isolate->factory()->termination_exception();
    226     } else {
    227       result = v8::Utils::OpenHandle(*catcher.Exception());
    228     }
    229     isolate->OptionalRescheduleException(true);
    230   }
    231 
    232   ASSERT(!isolate->has_pending_exception());
    233   ASSERT(!isolate->external_caught_exception());
    234   return result;
    235 }
    236 
    237 
    238 Handle<Object> Execution::GetFunctionDelegate(Isolate* isolate,
    239                                               Handle<Object> object) {
    240   ASSERT(!object->IsJSFunction());
    241   Factory* factory = isolate->factory();
    242 
    243   // If you return a function from here, it will be called when an
    244   // attempt is made to call the given object as a function.
    245 
    246   // If object is a function proxy, get its handler. Iterate if necessary.
    247   Object* fun = *object;
    248   while (fun->IsJSFunctionProxy()) {
    249     fun = JSFunctionProxy::cast(fun)->call_trap();
    250   }
    251   if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
    252 
    253   // Objects created through the API can have an instance-call handler
    254   // that should be used when calling the object as a function.
    255   if (fun->IsHeapObject() &&
    256       HeapObject::cast(fun)->map()->has_instance_call_handler()) {
    257     return Handle<JSFunction>(
    258         isolate->native_context()->call_as_function_delegate());
    259   }
    260 
    261   return factory->undefined_value();
    262 }
    263 
    264 
    265 Handle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate,
    266                                                  Handle<Object> object,
    267                                                  bool* has_pending_exception) {
    268   ASSERT(!object->IsJSFunction());
    269 
    270   // If object is a function proxy, get its handler. Iterate if necessary.
    271   Object* fun = *object;
    272   while (fun->IsJSFunctionProxy()) {
    273     fun = JSFunctionProxy::cast(fun)->call_trap();
    274   }
    275   if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
    276 
    277   // Objects created through the API can have an instance-call handler
    278   // that should be used when calling the object as a function.
    279   if (fun->IsHeapObject() &&
    280       HeapObject::cast(fun)->map()->has_instance_call_handler()) {
    281     return Handle<JSFunction>(
    282         isolate->native_context()->call_as_function_delegate());
    283   }
    284 
    285   // If the Object doesn't have an instance-call handler we should
    286   // throw a non-callable exception.
    287   i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
    288       "called_non_callable", i::HandleVector<i::Object>(&object, 1));
    289   isolate->Throw(*error_obj);
    290   *has_pending_exception = true;
    291 
    292   return isolate->factory()->undefined_value();
    293 }
    294 
    295 
    296 Handle<Object> Execution::GetConstructorDelegate(Isolate* isolate,
    297                                                  Handle<Object> object) {
    298   ASSERT(!object->IsJSFunction());
    299 
    300   // If you return a function from here, it will be called when an
    301   // attempt is made to call the given object as a constructor.
    302 
    303   // If object is a function proxies, get its handler. Iterate if necessary.
    304   Object* fun = *object;
    305   while (fun->IsJSFunctionProxy()) {
    306     fun = JSFunctionProxy::cast(fun)->call_trap();
    307   }
    308   if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
    309 
    310   // Objects created through the API can have an instance-call handler
    311   // that should be used when calling the object as a function.
    312   if (fun->IsHeapObject() &&
    313       HeapObject::cast(fun)->map()->has_instance_call_handler()) {
    314     return Handle<JSFunction>(
    315         isolate->native_context()->call_as_constructor_delegate());
    316   }
    317 
    318   return isolate->factory()->undefined_value();
    319 }
    320 
    321 
    322 Handle<Object> Execution::TryGetConstructorDelegate(
    323     Isolate* isolate,
    324     Handle<Object> object,
    325     bool* has_pending_exception) {
    326   ASSERT(!object->IsJSFunction());
    327 
    328   // If you return a function from here, it will be called when an
    329   // attempt is made to call the given object as a constructor.
    330 
    331   // If object is a function proxies, get its handler. Iterate if necessary.
    332   Object* fun = *object;
    333   while (fun->IsJSFunctionProxy()) {
    334     fun = JSFunctionProxy::cast(fun)->call_trap();
    335   }
    336   if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
    337 
    338   // Objects created through the API can have an instance-call handler
    339   // that should be used when calling the object as a function.
    340   if (fun->IsHeapObject() &&
    341       HeapObject::cast(fun)->map()->has_instance_call_handler()) {
    342     return Handle<JSFunction>(
    343         isolate->native_context()->call_as_constructor_delegate());
    344   }
    345 
    346   // If the Object doesn't have an instance-call handler we should
    347   // throw a non-callable exception.
    348   i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
    349       "called_non_callable", i::HandleVector<i::Object>(&object, 1));
    350   isolate->Throw(*error_obj);
    351   *has_pending_exception = true;
    352 
    353   return isolate->factory()->undefined_value();
    354 }
    355 
    356 
    357 void Execution::RunMicrotasks(Isolate* isolate) {
    358   ASSERT(isolate->microtask_pending());
    359   bool threw = false;
    360   Execution::Call(
    361       isolate,
    362       isolate->run_microtasks(),
    363       isolate->factory()->undefined_value(),
    364       0,
    365       NULL,
    366       &threw);
    367   ASSERT(!threw);
    368 }
    369 
    370 
    371 bool StackGuard::IsStackOverflow() {
    372   ExecutionAccess access(isolate_);
    373   return (thread_local_.jslimit_ != kInterruptLimit &&
    374           thread_local_.climit_ != kInterruptLimit);
    375 }
    376 
    377 
    378 void StackGuard::EnableInterrupts() {
    379   ExecutionAccess access(isolate_);
    380   if (has_pending_interrupts(access)) {
    381     set_interrupt_limits(access);
    382   }
    383 }
    384 
    385 
    386 void StackGuard::SetStackLimit(uintptr_t limit) {
    387   ExecutionAccess access(isolate_);
    388   // If the current limits are special (e.g. due to a pending interrupt) then
    389   // leave them alone.
    390   uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit);
    391   if (thread_local_.jslimit_ == thread_local_.real_jslimit_) {
    392     thread_local_.jslimit_ = jslimit;
    393   }
    394   if (thread_local_.climit_ == thread_local_.real_climit_) {
    395     thread_local_.climit_ = limit;
    396   }
    397   thread_local_.real_climit_ = limit;
    398   thread_local_.real_jslimit_ = jslimit;
    399 }
    400 
    401 
    402 void StackGuard::DisableInterrupts() {
    403   ExecutionAccess access(isolate_);
    404   reset_limits(access);
    405 }
    406 
    407 
    408 bool StackGuard::ShouldPostponeInterrupts() {
    409   ExecutionAccess access(isolate_);
    410   return should_postpone_interrupts(access);
    411 }
    412 
    413 
    414 bool StackGuard::IsInterrupted() {
    415   ExecutionAccess access(isolate_);
    416   return (thread_local_.interrupt_flags_ & INTERRUPT) != 0;
    417 }
    418 
    419 
    420 void StackGuard::Interrupt() {
    421   ExecutionAccess access(isolate_);
    422   thread_local_.interrupt_flags_ |= INTERRUPT;
    423   set_interrupt_limits(access);
    424 }
    425 
    426 
    427 bool StackGuard::IsPreempted() {
    428   ExecutionAccess access(isolate_);
    429   return thread_local_.interrupt_flags_ & PREEMPT;
    430 }
    431 
    432 
    433 void StackGuard::Preempt() {
    434   ExecutionAccess access(isolate_);
    435   thread_local_.interrupt_flags_ |= PREEMPT;
    436   set_interrupt_limits(access);
    437 }
    438 
    439 
    440 bool StackGuard::IsTerminateExecution() {
    441   ExecutionAccess access(isolate_);
    442   return (thread_local_.interrupt_flags_ & TERMINATE) != 0;
    443 }
    444 
    445 
    446 void StackGuard::CancelTerminateExecution() {
    447   ExecutionAccess access(isolate_);
    448   Continue(TERMINATE);
    449   isolate_->CancelTerminateExecution();
    450 }
    451 
    452 
    453 void StackGuard::TerminateExecution() {
    454   ExecutionAccess access(isolate_);
    455   thread_local_.interrupt_flags_ |= TERMINATE;
    456   set_interrupt_limits(access);
    457 }
    458 
    459 
    460 bool StackGuard::IsGCRequest() {
    461   ExecutionAccess access(isolate_);
    462   return (thread_local_.interrupt_flags_ & GC_REQUEST) != 0;
    463 }
    464 
    465 
    466 void StackGuard::RequestGC() {
    467   ExecutionAccess access(isolate_);
    468   thread_local_.interrupt_flags_ |= GC_REQUEST;
    469   if (thread_local_.postpone_interrupts_nesting_ == 0) {
    470     thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
    471     isolate_->heap()->SetStackLimits();
    472   }
    473 }
    474 
    475 
    476 bool StackGuard::IsInstallCodeRequest() {
    477   ExecutionAccess access(isolate_);
    478   return (thread_local_.interrupt_flags_ & INSTALL_CODE) != 0;
    479 }
    480 
    481 
    482 void StackGuard::RequestInstallCode() {
    483   ExecutionAccess access(isolate_);
    484   thread_local_.interrupt_flags_ |= INSTALL_CODE;
    485   if (thread_local_.postpone_interrupts_nesting_ == 0) {
    486     thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
    487     isolate_->heap()->SetStackLimits();
    488   }
    489 }
    490 
    491 
    492 bool StackGuard::IsFullDeopt() {
    493   ExecutionAccess access(isolate_);
    494   return (thread_local_.interrupt_flags_ & FULL_DEOPT) != 0;
    495 }
    496 
    497 
    498 void StackGuard::FullDeopt() {
    499   ExecutionAccess access(isolate_);
    500   thread_local_.interrupt_flags_ |= FULL_DEOPT;
    501   set_interrupt_limits(access);
    502 }
    503 
    504 
    505 #ifdef ENABLE_DEBUGGER_SUPPORT
    506 bool StackGuard::IsDebugBreak() {
    507   ExecutionAccess access(isolate_);
    508   return thread_local_.interrupt_flags_ & DEBUGBREAK;
    509 }
    510 
    511 
    512 void StackGuard::DebugBreak() {
    513   ExecutionAccess access(isolate_);
    514   thread_local_.interrupt_flags_ |= DEBUGBREAK;
    515   set_interrupt_limits(access);
    516 }
    517 
    518 
    519 bool StackGuard::IsDebugCommand() {
    520   ExecutionAccess access(isolate_);
    521   return thread_local_.interrupt_flags_ & DEBUGCOMMAND;
    522 }
    523 
    524 
    525 void StackGuard::DebugCommand() {
    526   if (FLAG_debugger_auto_break) {
    527     ExecutionAccess access(isolate_);
    528     thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
    529     set_interrupt_limits(access);
    530   }
    531 }
    532 #endif
    533 
    534 void StackGuard::Continue(InterruptFlag after_what) {
    535   ExecutionAccess access(isolate_);
    536   thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what);
    537   if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
    538     reset_limits(access);
    539   }
    540 }
    541 
    542 
    543 char* StackGuard::ArchiveStackGuard(char* to) {
    544   ExecutionAccess access(isolate_);
    545   OS::MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
    546   ThreadLocal blank;
    547 
    548   // Set the stack limits using the old thread_local_.
    549   // TODO(isolates): This was the old semantics of constructing a ThreadLocal
    550   //                 (as the ctor called SetStackLimits, which looked at the
    551   //                 current thread_local_ from StackGuard)-- but is this
    552   //                 really what was intended?
    553   isolate_->heap()->SetStackLimits();
    554   thread_local_ = blank;
    555 
    556   return to + sizeof(ThreadLocal);
    557 }
    558 
    559 
    560 char* StackGuard::RestoreStackGuard(char* from) {
    561   ExecutionAccess access(isolate_);
    562   OS::MemCopy(
    563       reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
    564   isolate_->heap()->SetStackLimits();
    565   return from + sizeof(ThreadLocal);
    566 }
    567 
    568 
    569 void StackGuard::FreeThreadResources() {
    570   Isolate::PerIsolateThreadData* per_thread =
    571       isolate_->FindOrAllocatePerThreadDataForThisThread();
    572   per_thread->set_stack_limit(thread_local_.real_climit_);
    573 }
    574 
    575 
    576 void StackGuard::ThreadLocal::Clear() {
    577   real_jslimit_ = kIllegalLimit;
    578   jslimit_ = kIllegalLimit;
    579   real_climit_ = kIllegalLimit;
    580   climit_ = kIllegalLimit;
    581   nesting_ = 0;
    582   postpone_interrupts_nesting_ = 0;
    583   interrupt_flags_ = 0;
    584 }
    585 
    586 
    587 bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
    588   bool should_set_stack_limits = false;
    589   if (real_climit_ == kIllegalLimit) {
    590     // Takes the address of the limit variable in order to find out where
    591     // the top of stack is right now.
    592     const uintptr_t kLimitSize = FLAG_stack_size * KB;
    593     uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize;
    594     ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize);
    595     real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
    596     jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
    597     real_climit_ = limit;
    598     climit_ = limit;
    599     should_set_stack_limits = true;
    600   }
    601   nesting_ = 0;
    602   postpone_interrupts_nesting_ = 0;
    603   interrupt_flags_ = 0;
    604   return should_set_stack_limits;
    605 }
    606 
    607 
    608 void StackGuard::ClearThread(const ExecutionAccess& lock) {
    609   thread_local_.Clear();
    610   isolate_->heap()->SetStackLimits();
    611 }
    612 
    613 
    614 void StackGuard::InitThread(const ExecutionAccess& lock) {
    615   if (thread_local_.Initialize(isolate_)) isolate_->heap()->SetStackLimits();
    616   Isolate::PerIsolateThreadData* per_thread =
    617       isolate_->FindOrAllocatePerThreadDataForThisThread();
    618   uintptr_t stored_limit = per_thread->stack_limit();
    619   // You should hold the ExecutionAccess lock when you call this.
    620   if (stored_limit != 0) {
    621     SetStackLimit(stored_limit);
    622   }
    623 }
    624 
    625 
    626 // --- C a l l s   t o   n a t i v e s ---
    627 
    628 #define RETURN_NATIVE_CALL(name, args, has_pending_exception)           \
    629   do {                                                                  \
    630     Handle<Object> argv[] = args;                                       \
    631     ASSERT(has_pending_exception != NULL);                              \
    632     return Call(isolate,                                                \
    633                 isolate->name##_fun(),                                  \
    634                 isolate->js_builtins_object(),                          \
    635                 ARRAY_SIZE(argv), argv,                                 \
    636                 has_pending_exception);                                 \
    637   } while (false)
    638 
    639 
    640 Handle<Object> Execution::ToNumber(
    641     Isolate* isolate, Handle<Object> obj, bool* exc) {
    642   RETURN_NATIVE_CALL(to_number, { obj }, exc);
    643 }
    644 
    645 
    646 Handle<Object> Execution::ToString(
    647     Isolate* isolate, Handle<Object> obj, bool* exc) {
    648   RETURN_NATIVE_CALL(to_string, { obj }, exc);
    649 }
    650 
    651 
    652 Handle<Object> Execution::ToDetailString(
    653     Isolate* isolate, Handle<Object> obj, bool* exc) {
    654   RETURN_NATIVE_CALL(to_detail_string, { obj }, exc);
    655 }
    656 
    657 
    658 Handle<Object> Execution::ToObject(
    659     Isolate* isolate, Handle<Object> obj, bool* exc) {
    660   if (obj->IsSpecObject()) return obj;
    661   RETURN_NATIVE_CALL(to_object, { obj }, exc);
    662 }
    663 
    664 
    665 Handle<Object> Execution::ToInteger(
    666     Isolate* isolate, Handle<Object> obj, bool* exc) {
    667   RETURN_NATIVE_CALL(to_integer, { obj }, exc);
    668 }
    669 
    670 
    671 Handle<Object> Execution::ToUint32(
    672     Isolate* isolate, Handle<Object> obj, bool* exc) {
    673   RETURN_NATIVE_CALL(to_uint32, { obj }, exc);
    674 }
    675 
    676 
    677 Handle<Object> Execution::ToInt32(
    678     Isolate* isolate, Handle<Object> obj, bool* exc) {
    679   RETURN_NATIVE_CALL(to_int32, { obj }, exc);
    680 }
    681 
    682 
    683 Handle<Object> Execution::NewDate(Isolate* isolate, double time, bool* exc) {
    684   Handle<Object> time_obj = isolate->factory()->NewNumber(time);
    685   RETURN_NATIVE_CALL(create_date, { time_obj }, exc);
    686 }
    687 
    688 
    689 #undef RETURN_NATIVE_CALL
    690 
    691 
    692 Handle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern,
    693                                         Handle<String> flags,
    694                                         bool* exc) {
    695   Handle<JSFunction> function = Handle<JSFunction>(
    696       pattern->GetIsolate()->native_context()->regexp_function());
    697   Handle<Object> re_obj = RegExpImpl::CreateRegExpLiteral(
    698       function, pattern, flags, exc);
    699   if (*exc) return Handle<JSRegExp>();
    700   return Handle<JSRegExp>::cast(re_obj);
    701 }
    702 
    703 
    704 Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) {
    705   Isolate* isolate = string->GetIsolate();
    706   Factory* factory = isolate->factory();
    707 
    708   int int_index = static_cast<int>(index);
    709   if (int_index < 0 || int_index >= string->length()) {
    710     return factory->undefined_value();
    711   }
    712 
    713   Handle<Object> char_at = GetProperty(
    714       isolate, isolate->js_builtins_object(), factory->char_at_string());
    715   if (!char_at->IsJSFunction()) {
    716     return factory->undefined_value();
    717   }
    718 
    719   bool caught_exception;
    720   Handle<Object> index_object = factory->NewNumberFromInt(int_index);
    721   Handle<Object> index_arg[] = { index_object };
    722   Handle<Object> result = TryCall(Handle<JSFunction>::cast(char_at),
    723                                   string,
    724                                   ARRAY_SIZE(index_arg),
    725                                   index_arg,
    726                                   &caught_exception);
    727   if (caught_exception) {
    728     return factory->undefined_value();
    729   }
    730   return result;
    731 }
    732 
    733 
    734 Handle<JSFunction> Execution::InstantiateFunction(
    735     Handle<FunctionTemplateInfo> data,
    736     bool* exc) {
    737   Isolate* isolate = data->GetIsolate();
    738   if (!data->do_not_cache()) {
    739     // Fast case: see if the function has already been instantiated
    740     int serial_number = Smi::cast(data->serial_number())->value();
    741     Object* elm =
    742         isolate->native_context()->function_cache()->
    743             GetElementNoExceptionThrown(isolate, serial_number);
    744     if (elm->IsJSFunction()) return Handle<JSFunction>(JSFunction::cast(elm));
    745   }
    746   // The function has not yet been instantiated in this context; do it.
    747   Handle<Object> args[] = { data };
    748   Handle<Object> result = Call(isolate,
    749                                isolate->instantiate_fun(),
    750                                isolate->js_builtins_object(),
    751                                ARRAY_SIZE(args),
    752                                args,
    753                                exc);
    754   if (*exc) return Handle<JSFunction>::null();
    755   return Handle<JSFunction>::cast(result);
    756 }
    757 
    758 
    759 Handle<JSObject> Execution::InstantiateObject(Handle<ObjectTemplateInfo> data,
    760                                               bool* exc) {
    761   Isolate* isolate = data->GetIsolate();
    762   if (data->property_list()->IsUndefined() &&
    763       !data->constructor()->IsUndefined()) {
    764     // Initialization to make gcc happy.
    765     Object* result = NULL;
    766     {
    767       HandleScope scope(isolate);
    768       Handle<FunctionTemplateInfo> cons_template =
    769           Handle<FunctionTemplateInfo>(
    770               FunctionTemplateInfo::cast(data->constructor()));
    771       Handle<JSFunction> cons = InstantiateFunction(cons_template, exc);
    772       if (*exc) return Handle<JSObject>::null();
    773       Handle<Object> value = New(cons, 0, NULL, exc);
    774       if (*exc) return Handle<JSObject>::null();
    775       result = *value;
    776     }
    777     ASSERT(!*exc);
    778     return Handle<JSObject>(JSObject::cast(result));
    779   } else {
    780     Handle<Object> args[] = { data };
    781     Handle<Object> result = Call(isolate,
    782                                  isolate->instantiate_fun(),
    783                                  isolate->js_builtins_object(),
    784                                  ARRAY_SIZE(args),
    785                                  args,
    786                                  exc);
    787     if (*exc) return Handle<JSObject>::null();
    788     return Handle<JSObject>::cast(result);
    789   }
    790 }
    791 
    792 
    793 void Execution::ConfigureInstance(Isolate* isolate,
    794                                   Handle<Object> instance,
    795                                   Handle<Object> instance_template,
    796                                   bool* exc) {
    797   Handle<Object> args[] = { instance, instance_template };
    798   Execution::Call(isolate,
    799                   isolate->configure_instance_fun(),
    800                   isolate->js_builtins_object(),
    801                   ARRAY_SIZE(args),
    802                   args,
    803                   exc);
    804 }
    805 
    806 
    807 Handle<String> Execution::GetStackTraceLine(Handle<Object> recv,
    808                                             Handle<JSFunction> fun,
    809                                             Handle<Object> pos,
    810                                             Handle<Object> is_global) {
    811   Isolate* isolate = fun->GetIsolate();
    812   Handle<Object> args[] = { recv, fun, pos, is_global };
    813   bool caught_exception;
    814   Handle<Object> result = TryCall(isolate->get_stack_trace_line_fun(),
    815                                   isolate->js_builtins_object(),
    816                                   ARRAY_SIZE(args),
    817                                   args,
    818                                   &caught_exception);
    819   if (caught_exception || !result->IsString()) {
    820       return isolate->factory()->empty_string();
    821   }
    822 
    823   return Handle<String>::cast(result);
    824 }
    825 
    826 
    827 static Object* RuntimePreempt(Isolate* isolate) {
    828   // Clear the preempt request flag.
    829   isolate->stack_guard()->Continue(PREEMPT);
    830 
    831 #ifdef ENABLE_DEBUGGER_SUPPORT
    832   if (isolate->debug()->InDebugger()) {
    833     // If currently in the debugger don't do any actual preemption but record
    834     // that preemption occoured while in the debugger.
    835     isolate->debug()->PreemptionWhileInDebugger();
    836   } else {
    837     // Perform preemption.
    838     v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
    839     Thread::YieldCPU();
    840   }
    841 #else
    842   { // NOLINT
    843     // Perform preemption.
    844     v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
    845     Thread::YieldCPU();
    846   }
    847 #endif
    848 
    849   return isolate->heap()->undefined_value();
    850 }
    851 
    852 
    853 #ifdef ENABLE_DEBUGGER_SUPPORT
    854 Object* Execution::DebugBreakHelper(Isolate* isolate) {
    855   // Just continue if breaks are disabled.
    856   if (isolate->debug()->disable_break()) {
    857     return isolate->heap()->undefined_value();
    858   }
    859 
    860   // Ignore debug break during bootstrapping.
    861   if (isolate->bootstrapper()->IsActive()) {
    862     return isolate->heap()->undefined_value();
    863   }
    864 
    865   // Ignore debug break if debugger is not active.
    866   if (!isolate->debugger()->IsDebuggerActive()) {
    867     return isolate->heap()->undefined_value();
    868   }
    869 
    870   StackLimitCheck check(isolate);
    871   if (check.HasOverflowed()) {
    872     return isolate->heap()->undefined_value();
    873   }
    874 
    875   {
    876     JavaScriptFrameIterator it(isolate);
    877     ASSERT(!it.done());
    878     Object* fun = it.frame()->function();
    879     if (fun && fun->IsJSFunction()) {
    880       // Don't stop in builtin functions.
    881       if (JSFunction::cast(fun)->IsBuiltin()) {
    882         return isolate->heap()->undefined_value();
    883       }
    884       GlobalObject* global = JSFunction::cast(fun)->context()->global_object();
    885       // Don't stop in debugger functions.
    886       if (isolate->debug()->IsDebugGlobal(global)) {
    887         return isolate->heap()->undefined_value();
    888       }
    889     }
    890   }
    891 
    892   // Collect the break state before clearing the flags.
    893   bool debug_command_only =
    894       isolate->stack_guard()->IsDebugCommand() &&
    895       !isolate->stack_guard()->IsDebugBreak();
    896 
    897   // Clear the debug break request flag.
    898   isolate->stack_guard()->Continue(DEBUGBREAK);
    899 
    900   ProcessDebugMessages(isolate, debug_command_only);
    901 
    902   // Return to continue execution.
    903   return isolate->heap()->undefined_value();
    904 }
    905 
    906 
    907 void Execution::ProcessDebugMessages(Isolate* isolate,
    908                                      bool debug_command_only) {
    909   // Clear the debug command request flag.
    910   isolate->stack_guard()->Continue(DEBUGCOMMAND);
    911 
    912   StackLimitCheck check(isolate);
    913   if (check.HasOverflowed()) {
    914     return;
    915   }
    916 
    917   HandleScope scope(isolate);
    918   // Enter the debugger. Just continue if we fail to enter the debugger.
    919   EnterDebugger debugger(isolate);
    920   if (debugger.FailedToEnter()) {
    921     return;
    922   }
    923 
    924   // Notify the debug event listeners. Indicate auto continue if the break was
    925   // a debug command break.
    926   isolate->debugger()->OnDebugBreak(isolate->factory()->undefined_value(),
    927                                     debug_command_only);
    928 }
    929 
    930 
    931 #endif
    932 
    933 MaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) {
    934   StackGuard* stack_guard = isolate->stack_guard();
    935   if (stack_guard->ShouldPostponeInterrupts()) {
    936     return isolate->heap()->undefined_value();
    937   }
    938 
    939   if (stack_guard->IsGCRequest()) {
    940     isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
    941                                        "StackGuard GC request");
    942     stack_guard->Continue(GC_REQUEST);
    943   }
    944 
    945   isolate->counters()->stack_interrupts()->Increment();
    946   isolate->counters()->runtime_profiler_ticks()->Increment();
    947 #ifdef ENABLE_DEBUGGER_SUPPORT
    948   if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) {
    949     DebugBreakHelper(isolate);
    950   }
    951 #endif
    952   if (stack_guard->IsPreempted()) RuntimePreempt(isolate);
    953   if (stack_guard->IsTerminateExecution()) {
    954     stack_guard->Continue(TERMINATE);
    955     return isolate->TerminateExecution();
    956   }
    957   if (stack_guard->IsInterrupted()) {
    958     stack_guard->Continue(INTERRUPT);
    959     return isolate->StackOverflow();
    960   }
    961   if (stack_guard->IsFullDeopt()) {
    962     stack_guard->Continue(FULL_DEOPT);
    963     Deoptimizer::DeoptimizeAll(isolate);
    964   }
    965   if (stack_guard->IsInstallCodeRequest()) {
    966     ASSERT(isolate->concurrent_recompilation_enabled());
    967     stack_guard->Continue(INSTALL_CODE);
    968     isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
    969   }
    970   isolate->runtime_profiler()->OptimizeNow();
    971   return isolate->heap()->undefined_value();
    972 }
    973 
    974 
    975 } }  // namespace v8::internal
    976