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