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