Home | History | Annotate | Download | only in src
      1 // Copyright 2014 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/execution.h"
      6 
      7 #include "src/bootstrapper.h"
      8 #include "src/codegen.h"
      9 #include "src/deoptimizer.h"
     10 #include "src/isolate-inl.h"
     11 #include "src/vm-state-inl.h"
     12 
     13 namespace v8 {
     14 namespace internal {
     15 
     16 StackGuard::StackGuard()
     17     : isolate_(NULL) {
     18 }
     19 
     20 
     21 void StackGuard::set_interrupt_limits(const ExecutionAccess& lock) {
     22   ASSERT(isolate_ != NULL);
     23   // Ignore attempts to interrupt when interrupts are postponed.
     24   if (should_postpone_interrupts(lock)) return;
     25   thread_local_.jslimit_ = kInterruptLimit;
     26   thread_local_.climit_ = kInterruptLimit;
     27   isolate_->heap()->SetStackLimits();
     28 }
     29 
     30 
     31 void StackGuard::reset_limits(const ExecutionAccess& lock) {
     32   ASSERT(isolate_ != NULL);
     33   thread_local_.jslimit_ = thread_local_.real_jslimit_;
     34   thread_local_.climit_ = thread_local_.real_climit_;
     35   isolate_->heap()->SetStackLimits();
     36 }
     37 
     38 
     39 MUST_USE_RESULT static MaybeHandle<Object> Invoke(
     40     bool is_construct,
     41     Handle<JSFunction> function,
     42     Handle<Object> receiver,
     43     int argc,
     44     Handle<Object> args[]) {
     45   Isolate* isolate = function->GetIsolate();
     46 
     47   // Entering JavaScript.
     48   VMState<JS> state(isolate);
     49   CHECK(AllowJavascriptExecution::IsAllowed(isolate));
     50   if (!ThrowOnJavascriptExecution::IsAllowed(isolate)) {
     51     isolate->ThrowIllegalOperation();
     52     isolate->ReportPendingMessages();
     53     return MaybeHandle<Object>();
     54   }
     55 
     56   // Placeholder for return value.
     57   Object* value = NULL;
     58 
     59   typedef Object* (*JSEntryFunction)(byte* entry,
     60                                      Object* function,
     61                                      Object* receiver,
     62                                      int argc,
     63                                      Object*** args);
     64 
     65   Handle<Code> code = is_construct
     66       ? isolate->factory()->js_construct_entry_code()
     67       : isolate->factory()->js_entry_code();
     68 
     69   // Convert calls on global objects to be calls on the global
     70   // receiver instead to avoid having a 'this' pointer which refers
     71   // directly to a global object.
     72   if (receiver->IsGlobalObject()) {
     73     Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
     74     receiver = Handle<JSObject>(global->global_receiver());
     75   }
     76 
     77   // Make sure that the global object of the context we're about to
     78   // make the current one is indeed a global object.
     79   ASSERT(function->context()->global_object()->IsGlobalObject());
     80 
     81   {
     82     // Save and restore context around invocation and block the
     83     // allocation of handles without explicit handle scopes.
     84     SaveContext save(isolate);
     85     SealHandleScope shs(isolate);
     86     JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
     87 
     88     // Call the function through the right JS entry stub.
     89     byte* function_entry = function->code()->entry();
     90     JSFunction* func = *function;
     91     Object* recv = *receiver;
     92     Object*** argv = reinterpret_cast<Object***>(args);
     93     value =
     94         CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
     95   }
     96 
     97 #ifdef VERIFY_HEAP
     98   value->ObjectVerify();
     99 #endif
    100 
    101   // Update the pending exception flag and return the value.
    102   bool has_exception = value->IsException();
    103   ASSERT(has_exception == isolate->has_pending_exception());
    104   if (has_exception) {
    105     isolate->ReportPendingMessages();
    106     // Reset stepping state when script exits with uncaught exception.
    107     if (isolate->debug()->is_active()) {
    108       isolate->debug()->ClearStepping();
    109     }
    110     return MaybeHandle<Object>();
    111   } else {
    112     isolate->clear_pending_message();
    113   }
    114 
    115   return Handle<Object>(value, isolate);
    116 }
    117 
    118 
    119 MaybeHandle<Object> Execution::Call(Isolate* isolate,
    120                                     Handle<Object> callable,
    121                                     Handle<Object> receiver,
    122                                     int argc,
    123                                     Handle<Object> argv[],
    124                                     bool convert_receiver) {
    125   if (!callable->IsJSFunction()) {
    126     ASSIGN_RETURN_ON_EXCEPTION(
    127         isolate, callable, TryGetFunctionDelegate(isolate, callable), Object);
    128   }
    129   Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
    130 
    131   // In sloppy mode, convert receiver.
    132   if (convert_receiver && !receiver->IsJSReceiver() &&
    133       !func->shared()->native() &&
    134       func->shared()->strict_mode() == SLOPPY) {
    135     if (receiver->IsUndefined() || receiver->IsNull()) {
    136       Object* global = func->context()->global_object()->global_receiver();
    137       // Under some circumstances, 'global' can be the JSBuiltinsObject
    138       // In that case, don't rewrite.  (FWIW, the same holds for
    139       // GetIsolate()->global_object()->global_receiver().)
    140       if (!global->IsJSBuiltinsObject()) {
    141         receiver = Handle<Object>(global, func->GetIsolate());
    142       }
    143     } else {
    144       ASSIGN_RETURN_ON_EXCEPTION(
    145           isolate, receiver, ToObject(isolate, receiver), Object);
    146     }
    147   }
    148 
    149   return Invoke(false, func, receiver, argc, argv);
    150 }
    151 
    152 
    153 MaybeHandle<Object> Execution::New(Handle<JSFunction> func,
    154                                    int argc,
    155                                    Handle<Object> argv[]) {
    156   return Invoke(true, func, func->GetIsolate()->global_object(), argc, argv);
    157 }
    158 
    159 
    160 MaybeHandle<Object> Execution::TryCall(Handle<JSFunction> func,
    161                                        Handle<Object> receiver,
    162                                        int argc,
    163                                        Handle<Object> args[],
    164                                        Handle<Object>* exception_out) {
    165   // Enter a try-block while executing the JavaScript code. To avoid
    166   // duplicate error printing it must be non-verbose.  Also, to avoid
    167   // creating message objects during stack overflow we shouldn't
    168   // capture messages.
    169   v8::TryCatch catcher;
    170   catcher.SetVerbose(false);
    171   catcher.SetCaptureMessage(false);
    172 
    173   // Get isolate now, because handle might be persistent
    174   // and get destroyed in the next call.
    175   Isolate* isolate = func->GetIsolate();
    176   MaybeHandle<Object> maybe_result = Invoke(false, func, receiver, argc, args);
    177 
    178   if (maybe_result.is_null()) {
    179     ASSERT(catcher.HasCaught());
    180     ASSERT(isolate->has_pending_exception());
    181     ASSERT(isolate->external_caught_exception());
    182     if (exception_out != NULL) {
    183       if (isolate->pending_exception() ==
    184           isolate->heap()->termination_exception()) {
    185         *exception_out = isolate->factory()->termination_exception();
    186       } else {
    187         *exception_out = v8::Utils::OpenHandle(*catcher.Exception());
    188       }
    189     }
    190     isolate->OptionalRescheduleException(true);
    191   }
    192 
    193   ASSERT(!isolate->has_pending_exception());
    194   ASSERT(!isolate->external_caught_exception());
    195   return maybe_result;
    196 }
    197 
    198 
    199 Handle<Object> Execution::GetFunctionDelegate(Isolate* isolate,
    200                                               Handle<Object> object) {
    201   ASSERT(!object->IsJSFunction());
    202   Factory* factory = isolate->factory();
    203 
    204   // If you return a function from here, it will be called when an
    205   // attempt is made to call the given object as a function.
    206 
    207   // If object is a function proxy, get its handler. Iterate if necessary.
    208   Object* fun = *object;
    209   while (fun->IsJSFunctionProxy()) {
    210     fun = JSFunctionProxy::cast(fun)->call_trap();
    211   }
    212   if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
    213 
    214   // Objects created through the API can have an instance-call handler
    215   // that should be used when calling the object as a function.
    216   if (fun->IsHeapObject() &&
    217       HeapObject::cast(fun)->map()->has_instance_call_handler()) {
    218     return Handle<JSFunction>(
    219         isolate->native_context()->call_as_function_delegate());
    220   }
    221 
    222   return factory->undefined_value();
    223 }
    224 
    225 
    226 MaybeHandle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate,
    227                                                       Handle<Object> object) {
    228   ASSERT(!object->IsJSFunction());
    229 
    230   // If object is a function proxy, get its handler. Iterate if necessary.
    231   Object* fun = *object;
    232   while (fun->IsJSFunctionProxy()) {
    233     fun = JSFunctionProxy::cast(fun)->call_trap();
    234   }
    235   if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
    236 
    237   // Objects created through the API can have an instance-call handler
    238   // that should be used when calling the object as a function.
    239   if (fun->IsHeapObject() &&
    240       HeapObject::cast(fun)->map()->has_instance_call_handler()) {
    241     return Handle<JSFunction>(
    242         isolate->native_context()->call_as_function_delegate());
    243   }
    244 
    245   // If the Object doesn't have an instance-call handler we should
    246   // throw a non-callable exception.
    247   i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
    248       "called_non_callable", i::HandleVector<i::Object>(&object, 1));
    249 
    250   return isolate->Throw<Object>(error_obj);
    251 }
    252 
    253 
    254 Handle<Object> Execution::GetConstructorDelegate(Isolate* isolate,
    255                                                  Handle<Object> object) {
    256   ASSERT(!object->IsJSFunction());
    257 
    258   // If you return a function from here, it will be called when an
    259   // attempt is made to call the given object as a constructor.
    260 
    261   // If object is a function proxies, get its handler. Iterate if necessary.
    262   Object* fun = *object;
    263   while (fun->IsJSFunctionProxy()) {
    264     fun = JSFunctionProxy::cast(fun)->call_trap();
    265   }
    266   if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
    267 
    268   // Objects created through the API can have an instance-call handler
    269   // that should be used when calling the object as a function.
    270   if (fun->IsHeapObject() &&
    271       HeapObject::cast(fun)->map()->has_instance_call_handler()) {
    272     return Handle<JSFunction>(
    273         isolate->native_context()->call_as_constructor_delegate());
    274   }
    275 
    276   return isolate->factory()->undefined_value();
    277 }
    278 
    279 
    280 MaybeHandle<Object> Execution::TryGetConstructorDelegate(
    281     Isolate* isolate, Handle<Object> object) {
    282   ASSERT(!object->IsJSFunction());
    283 
    284   // If you return a function from here, it will be called when an
    285   // attempt is made to call the given object as a constructor.
    286 
    287   // If object is a function proxies, get its handler. Iterate if necessary.
    288   Object* fun = *object;
    289   while (fun->IsJSFunctionProxy()) {
    290     fun = JSFunctionProxy::cast(fun)->call_trap();
    291   }
    292   if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
    293 
    294   // Objects created through the API can have an instance-call handler
    295   // that should be used when calling the object as a function.
    296   if (fun->IsHeapObject() &&
    297       HeapObject::cast(fun)->map()->has_instance_call_handler()) {
    298     return Handle<JSFunction>(
    299         isolate->native_context()->call_as_constructor_delegate());
    300   }
    301 
    302   // If the Object doesn't have an instance-call handler we should
    303   // throw a non-callable exception.
    304   i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
    305       "called_non_callable", i::HandleVector<i::Object>(&object, 1));
    306   return isolate->Throw<Object>(error_obj);
    307 }
    308 
    309 
    310 void StackGuard::EnableInterrupts() {
    311   ExecutionAccess access(isolate_);
    312   if (has_pending_interrupts(access)) {
    313     set_interrupt_limits(access);
    314   }
    315 }
    316 
    317 
    318 void StackGuard::SetStackLimit(uintptr_t limit) {
    319   ExecutionAccess access(isolate_);
    320   // If the current limits are special (e.g. due to a pending interrupt) then
    321   // leave them alone.
    322   uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit);
    323   if (thread_local_.jslimit_ == thread_local_.real_jslimit_) {
    324     thread_local_.jslimit_ = jslimit;
    325   }
    326   if (thread_local_.climit_ == thread_local_.real_climit_) {
    327     thread_local_.climit_ = limit;
    328   }
    329   thread_local_.real_climit_ = limit;
    330   thread_local_.real_jslimit_ = jslimit;
    331 }
    332 
    333 
    334 void StackGuard::DisableInterrupts() {
    335   ExecutionAccess access(isolate_);
    336   reset_limits(access);
    337 }
    338 
    339 
    340 bool StackGuard::CheckInterrupt(int flagbit) {
    341   ExecutionAccess access(isolate_);
    342   return thread_local_.interrupt_flags_ & flagbit;
    343 }
    344 
    345 
    346 void StackGuard::RequestInterrupt(int flagbit) {
    347   ExecutionAccess access(isolate_);
    348   thread_local_.interrupt_flags_ |= flagbit;
    349   set_interrupt_limits(access);
    350 }
    351 
    352 
    353 void StackGuard::ClearInterrupt(int flagbit) {
    354   ExecutionAccess access(isolate_);
    355   thread_local_.interrupt_flags_ &= ~flagbit;
    356   if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
    357     reset_limits(access);
    358   }
    359 }
    360 
    361 
    362 bool StackGuard::CheckAndClearInterrupt(InterruptFlag flag) {
    363   ExecutionAccess access(isolate_);
    364   int flagbit = 1 << flag;
    365   bool result = (thread_local_.interrupt_flags_ & flagbit);
    366   thread_local_.interrupt_flags_ &= ~flagbit;
    367   if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
    368     reset_limits(access);
    369   }
    370   return result;
    371 }
    372 
    373 
    374 char* StackGuard::ArchiveStackGuard(char* to) {
    375   ExecutionAccess access(isolate_);
    376   MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
    377   ThreadLocal blank;
    378 
    379   // Set the stack limits using the old thread_local_.
    380   // TODO(isolates): This was the old semantics of constructing a ThreadLocal
    381   //                 (as the ctor called SetStackLimits, which looked at the
    382   //                 current thread_local_ from StackGuard)-- but is this
    383   //                 really what was intended?
    384   isolate_->heap()->SetStackLimits();
    385   thread_local_ = blank;
    386 
    387   return to + sizeof(ThreadLocal);
    388 }
    389 
    390 
    391 char* StackGuard::RestoreStackGuard(char* from) {
    392   ExecutionAccess access(isolate_);
    393   MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
    394   isolate_->heap()->SetStackLimits();
    395   return from + sizeof(ThreadLocal);
    396 }
    397 
    398 
    399 void StackGuard::FreeThreadResources() {
    400   Isolate::PerIsolateThreadData* per_thread =
    401       isolate_->FindOrAllocatePerThreadDataForThisThread();
    402   per_thread->set_stack_limit(thread_local_.real_climit_);
    403 }
    404 
    405 
    406 void StackGuard::ThreadLocal::Clear() {
    407   real_jslimit_ = kIllegalLimit;
    408   jslimit_ = kIllegalLimit;
    409   real_climit_ = kIllegalLimit;
    410   climit_ = kIllegalLimit;
    411   nesting_ = 0;
    412   postpone_interrupts_nesting_ = 0;
    413   interrupt_flags_ = 0;
    414 }
    415 
    416 
    417 bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
    418   bool should_set_stack_limits = false;
    419   if (real_climit_ == kIllegalLimit) {
    420     // Takes the address of the limit variable in order to find out where
    421     // the top of stack is right now.
    422     const uintptr_t kLimitSize = FLAG_stack_size * KB;
    423     uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize;
    424     ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize);
    425     real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
    426     jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
    427     real_climit_ = limit;
    428     climit_ = limit;
    429     should_set_stack_limits = true;
    430   }
    431   nesting_ = 0;
    432   postpone_interrupts_nesting_ = 0;
    433   interrupt_flags_ = 0;
    434   return should_set_stack_limits;
    435 }
    436 
    437 
    438 void StackGuard::ClearThread(const ExecutionAccess& lock) {
    439   thread_local_.Clear();
    440   isolate_->heap()->SetStackLimits();
    441 }
    442 
    443 
    444 void StackGuard::InitThread(const ExecutionAccess& lock) {
    445   if (thread_local_.Initialize(isolate_)) isolate_->heap()->SetStackLimits();
    446   Isolate::PerIsolateThreadData* per_thread =
    447       isolate_->FindOrAllocatePerThreadDataForThisThread();
    448   uintptr_t stored_limit = per_thread->stack_limit();
    449   // You should hold the ExecutionAccess lock when you call this.
    450   if (stored_limit != 0) {
    451     SetStackLimit(stored_limit);
    452   }
    453 }
    454 
    455 
    456 // --- C a l l s   t o   n a t i v e s ---
    457 
    458 #define RETURN_NATIVE_CALL(name, args)                                  \
    459   do {                                                                  \
    460     Handle<Object> argv[] = args;                                       \
    461     return Call(isolate,                                                \
    462                 isolate->name##_fun(),                                  \
    463                 isolate->js_builtins_object(),                          \
    464                 ARRAY_SIZE(argv), argv);                                \
    465   } while (false)
    466 
    467 
    468 MaybeHandle<Object> Execution::ToNumber(
    469     Isolate* isolate, Handle<Object> obj) {
    470   RETURN_NATIVE_CALL(to_number, { obj });
    471 }
    472 
    473 
    474 MaybeHandle<Object> Execution::ToString(
    475     Isolate* isolate, Handle<Object> obj) {
    476   RETURN_NATIVE_CALL(to_string, { obj });
    477 }
    478 
    479 
    480 MaybeHandle<Object> Execution::ToDetailString(
    481     Isolate* isolate, Handle<Object> obj) {
    482   RETURN_NATIVE_CALL(to_detail_string, { obj });
    483 }
    484 
    485 
    486 MaybeHandle<Object> Execution::ToObject(
    487     Isolate* isolate, Handle<Object> obj) {
    488   if (obj->IsSpecObject()) return obj;
    489   RETURN_NATIVE_CALL(to_object, { obj });
    490 }
    491 
    492 
    493 MaybeHandle<Object> Execution::ToInteger(
    494     Isolate* isolate, Handle<Object> obj) {
    495   RETURN_NATIVE_CALL(to_integer, { obj });
    496 }
    497 
    498 
    499 MaybeHandle<Object> Execution::ToUint32(
    500     Isolate* isolate, Handle<Object> obj) {
    501   RETURN_NATIVE_CALL(to_uint32, { obj });
    502 }
    503 
    504 
    505 MaybeHandle<Object> Execution::ToInt32(
    506     Isolate* isolate, Handle<Object> obj) {
    507   RETURN_NATIVE_CALL(to_int32, { obj });
    508 }
    509 
    510 
    511 MaybeHandle<Object> Execution::NewDate(Isolate* isolate, double time) {
    512   Handle<Object> time_obj = isolate->factory()->NewNumber(time);
    513   RETURN_NATIVE_CALL(create_date, { time_obj });
    514 }
    515 
    516 
    517 #undef RETURN_NATIVE_CALL
    518 
    519 
    520 MaybeHandle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern,
    521                                              Handle<String> flags) {
    522   Isolate* isolate = pattern->GetIsolate();
    523   Handle<JSFunction> function = Handle<JSFunction>(
    524       isolate->native_context()->regexp_function());
    525   Handle<Object> re_obj;
    526   ASSIGN_RETURN_ON_EXCEPTION(
    527       isolate, re_obj,
    528       RegExpImpl::CreateRegExpLiteral(function, pattern, flags),
    529       JSRegExp);
    530   return Handle<JSRegExp>::cast(re_obj);
    531 }
    532 
    533 
    534 Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) {
    535   Isolate* isolate = string->GetIsolate();
    536   Factory* factory = isolate->factory();
    537 
    538   int int_index = static_cast<int>(index);
    539   if (int_index < 0 || int_index >= string->length()) {
    540     return factory->undefined_value();
    541   }
    542 
    543   Handle<Object> char_at = Object::GetProperty(
    544       isolate->js_builtins_object(),
    545       factory->char_at_string()).ToHandleChecked();
    546   if (!char_at->IsJSFunction()) {
    547     return factory->undefined_value();
    548   }
    549 
    550   Handle<Object> index_object = factory->NewNumberFromInt(int_index);
    551   Handle<Object> index_arg[] = { index_object };
    552   Handle<Object> result;
    553   if (!TryCall(Handle<JSFunction>::cast(char_at),
    554                string,
    555                ARRAY_SIZE(index_arg),
    556                index_arg).ToHandle(&result)) {
    557     return factory->undefined_value();
    558   }
    559   return result;
    560 }
    561 
    562 
    563 MaybeHandle<JSFunction> Execution::InstantiateFunction(
    564     Handle<FunctionTemplateInfo> data) {
    565   Isolate* isolate = data->GetIsolate();
    566   if (!data->do_not_cache()) {
    567     // Fast case: see if the function has already been instantiated
    568     int serial_number = Smi::cast(data->serial_number())->value();
    569     Handle<JSObject> cache(isolate->native_context()->function_cache());
    570     Handle<Object> elm =
    571         Object::GetElement(isolate, cache, serial_number).ToHandleChecked();
    572     if (elm->IsJSFunction()) return Handle<JSFunction>::cast(elm);
    573   }
    574   // The function has not yet been instantiated in this context; do it.
    575   Handle<Object> args[] = { data };
    576   Handle<Object> result;
    577   ASSIGN_RETURN_ON_EXCEPTION(
    578       isolate, result,
    579       Call(isolate,
    580            isolate->instantiate_fun(),
    581            isolate->js_builtins_object(),
    582            ARRAY_SIZE(args),
    583            args),
    584       JSFunction);
    585   return Handle<JSFunction>::cast(result);
    586 }
    587 
    588 
    589 MaybeHandle<JSObject> Execution::InstantiateObject(
    590     Handle<ObjectTemplateInfo> data) {
    591   Isolate* isolate = data->GetIsolate();
    592   Handle<Object> result;
    593   if (data->property_list()->IsUndefined() &&
    594       !data->constructor()->IsUndefined()) {
    595     Handle<FunctionTemplateInfo> cons_template =
    596         Handle<FunctionTemplateInfo>(
    597             FunctionTemplateInfo::cast(data->constructor()));
    598     Handle<JSFunction> cons;
    599     ASSIGN_RETURN_ON_EXCEPTION(
    600         isolate, cons, InstantiateFunction(cons_template), JSObject);
    601     ASSIGN_RETURN_ON_EXCEPTION(isolate, result, New(cons, 0, NULL), JSObject);
    602   } else {
    603     Handle<Object> args[] = { data };
    604     ASSIGN_RETURN_ON_EXCEPTION(
    605         isolate, result,
    606         Call(isolate,
    607              isolate->instantiate_fun(),
    608              isolate->js_builtins_object(),
    609              ARRAY_SIZE(args),
    610              args),
    611         JSObject);
    612   }
    613   return Handle<JSObject>::cast(result);
    614 }
    615 
    616 
    617 MaybeHandle<Object> Execution::ConfigureInstance(
    618     Isolate* isolate,
    619     Handle<Object> instance,
    620     Handle<Object> instance_template) {
    621   Handle<Object> args[] = { instance, instance_template };
    622   return Execution::Call(isolate,
    623                          isolate->configure_instance_fun(),
    624                          isolate->js_builtins_object(),
    625                          ARRAY_SIZE(args),
    626                          args);
    627 }
    628 
    629 
    630 Handle<String> Execution::GetStackTraceLine(Handle<Object> recv,
    631                                             Handle<JSFunction> fun,
    632                                             Handle<Object> pos,
    633                                             Handle<Object> is_global) {
    634   Isolate* isolate = fun->GetIsolate();
    635   Handle<Object> args[] = { recv, fun, pos, is_global };
    636   MaybeHandle<Object> maybe_result =
    637       TryCall(isolate->get_stack_trace_line_fun(),
    638               isolate->js_builtins_object(),
    639               ARRAY_SIZE(args),
    640               args);
    641   Handle<Object> result;
    642   if (!maybe_result.ToHandle(&result) || !result->IsString()) {
    643     return isolate->factory()->empty_string();
    644   }
    645 
    646   return Handle<String>::cast(result);
    647 }
    648 
    649 
    650 Object* StackGuard::HandleInterrupts() {
    651   {
    652     ExecutionAccess access(isolate_);
    653     if (should_postpone_interrupts(access)) {
    654       return isolate_->heap()->undefined_value();
    655     }
    656   }
    657 
    658   if (CheckAndClearInterrupt(GC_REQUEST)) {
    659     isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt");
    660   }
    661 
    662   if (CheckDebugBreak() || CheckDebugCommand()) {
    663     isolate_->debug()->HandleDebugBreak();
    664   }
    665 
    666   if (CheckAndClearInterrupt(TERMINATE_EXECUTION)) {
    667     return isolate_->TerminateExecution();
    668   }
    669 
    670   if (CheckAndClearInterrupt(DEOPT_MARKED_ALLOCATION_SITES)) {
    671     isolate_->heap()->DeoptMarkedAllocationSites();
    672   }
    673 
    674   if (CheckAndClearInterrupt(INSTALL_CODE)) {
    675     ASSERT(isolate_->concurrent_recompilation_enabled());
    676     isolate_->optimizing_compiler_thread()->InstallOptimizedFunctions();
    677   }
    678 
    679   if (CheckAndClearInterrupt(API_INTERRUPT)) {
    680     // Callback must be invoked outside of ExecusionAccess lock.
    681     isolate_->InvokeApiInterruptCallback();
    682   }
    683 
    684   isolate_->counters()->stack_interrupts()->Increment();
    685   isolate_->counters()->runtime_profiler_ticks()->Increment();
    686   isolate_->runtime_profiler()->OptimizeNow();
    687 
    688   return isolate_->heap()->undefined_value();
    689 }
    690 
    691 } }  // namespace v8::internal
    692