• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
StackGuard()16 StackGuard::StackGuard()
17     : isolate_(NULL) {
18 }
19 
20 
set_interrupt_limits(const ExecutionAccess & lock)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 
reset_limits(const ExecutionAccess & lock)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 
Invoke(bool is_construct,Handle<JSFunction> function,Handle<Object> receiver,int argc,Handle<Object> args[])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 
Call(Isolate * isolate,Handle<Object> callable,Handle<Object> receiver,int argc,Handle<Object> argv[],bool convert_receiver)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 
New(Handle<JSFunction> func,int argc,Handle<Object> argv[])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 
TryCall(Handle<JSFunction> func,Handle<Object> receiver,int argc,Handle<Object> args[],Handle<Object> * exception_out)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 
GetFunctionDelegate(Isolate * isolate,Handle<Object> object)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 
TryGetFunctionDelegate(Isolate * isolate,Handle<Object> object)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 
GetConstructorDelegate(Isolate * isolate,Handle<Object> object)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 
TryGetConstructorDelegate(Isolate * isolate,Handle<Object> object)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 
EnableInterrupts()310 void StackGuard::EnableInterrupts() {
311   ExecutionAccess access(isolate_);
312   if (has_pending_interrupts(access)) {
313     set_interrupt_limits(access);
314   }
315 }
316 
317 
SetStackLimit(uintptr_t limit)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 
DisableInterrupts()334 void StackGuard::DisableInterrupts() {
335   ExecutionAccess access(isolate_);
336   reset_limits(access);
337 }
338 
339 
CheckInterrupt(int flagbit)340 bool StackGuard::CheckInterrupt(int flagbit) {
341   ExecutionAccess access(isolate_);
342   return thread_local_.interrupt_flags_ & flagbit;
343 }
344 
345 
RequestInterrupt(int flagbit)346 void StackGuard::RequestInterrupt(int flagbit) {
347   ExecutionAccess access(isolate_);
348   thread_local_.interrupt_flags_ |= flagbit;
349   set_interrupt_limits(access);
350 }
351 
352 
ClearInterrupt(int flagbit)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 
CheckAndClearInterrupt(InterruptFlag flag)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 
ArchiveStackGuard(char * to)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 
RestoreStackGuard(char * from)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 
FreeThreadResources()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 
Clear()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 
Initialize(Isolate * isolate)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 
ClearThread(const ExecutionAccess & lock)438 void StackGuard::ClearThread(const ExecutionAccess& lock) {
439   thread_local_.Clear();
440   isolate_->heap()->SetStackLimits();
441 }
442 
443 
InitThread(const ExecutionAccess & lock)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 
ToNumber(Isolate * isolate,Handle<Object> obj)468 MaybeHandle<Object> Execution::ToNumber(
469     Isolate* isolate, Handle<Object> obj) {
470   RETURN_NATIVE_CALL(to_number, { obj });
471 }
472 
473 
ToString(Isolate * isolate,Handle<Object> obj)474 MaybeHandle<Object> Execution::ToString(
475     Isolate* isolate, Handle<Object> obj) {
476   RETURN_NATIVE_CALL(to_string, { obj });
477 }
478 
479 
ToDetailString(Isolate * isolate,Handle<Object> obj)480 MaybeHandle<Object> Execution::ToDetailString(
481     Isolate* isolate, Handle<Object> obj) {
482   RETURN_NATIVE_CALL(to_detail_string, { obj });
483 }
484 
485 
ToObject(Isolate * isolate,Handle<Object> obj)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 
ToInteger(Isolate * isolate,Handle<Object> obj)493 MaybeHandle<Object> Execution::ToInteger(
494     Isolate* isolate, Handle<Object> obj) {
495   RETURN_NATIVE_CALL(to_integer, { obj });
496 }
497 
498 
ToUint32(Isolate * isolate,Handle<Object> obj)499 MaybeHandle<Object> Execution::ToUint32(
500     Isolate* isolate, Handle<Object> obj) {
501   RETURN_NATIVE_CALL(to_uint32, { obj });
502 }
503 
504 
ToInt32(Isolate * isolate,Handle<Object> obj)505 MaybeHandle<Object> Execution::ToInt32(
506     Isolate* isolate, Handle<Object> obj) {
507   RETURN_NATIVE_CALL(to_int32, { obj });
508 }
509 
510 
NewDate(Isolate * isolate,double time)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 
NewJSRegExp(Handle<String> pattern,Handle<String> flags)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 
CharAt(Handle<String> string,uint32_t index)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 
InstantiateFunction(Handle<FunctionTemplateInfo> data)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 
InstantiateObject(Handle<ObjectTemplateInfo> data)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 
ConfigureInstance(Isolate * isolate,Handle<Object> instance,Handle<Object> instance_template)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 
GetStackTraceLine(Handle<Object> recv,Handle<JSFunction> fun,Handle<Object> pos,Handle<Object> is_global)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 
HandleInterrupts()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