v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
execution.cc
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include <stdlib.h>
29 
30 #include "v8.h"
31 
32 #include "api.h"
33 #include "bootstrapper.h"
34 #include "codegen.h"
35 #include "debug.h"
36 #include "deoptimizer.h"
37 #include "isolate-inl.h"
38 #include "runtime-profiler.h"
39 #include "simulator.h"
40 #include "v8threads.h"
41 #include "vm-state-inl.h"
42 
43 namespace v8 {
44 namespace internal {
45 
46 
47 StackGuard::StackGuard()
48  : isolate_(NULL) {
49 }
50 
51 
52 void StackGuard::set_interrupt_limits(const ExecutionAccess& lock) {
53  ASSERT(isolate_ != NULL);
54  // Ignore attempts to interrupt when interrupts are postponed.
55  if (should_postpone_interrupts(lock)) return;
56  thread_local_.jslimit_ = kInterruptLimit;
57  thread_local_.climit_ = kInterruptLimit;
58  isolate_->heap()->SetStackLimits();
59 }
60 
61 
62 void StackGuard::reset_limits(const ExecutionAccess& lock) {
63  ASSERT(isolate_ != NULL);
64  thread_local_.jslimit_ = thread_local_.real_jslimit_;
65  thread_local_.climit_ = thread_local_.real_climit_;
66  isolate_->heap()->SetStackLimits();
67 }
68 
69 
70 static Handle<Object> Invoke(bool is_construct,
71  Handle<JSFunction> function,
72  Handle<Object> receiver,
73  int argc,
74  Handle<Object> args[],
75  bool* has_pending_exception) {
76  Isolate* isolate = function->GetIsolate();
77 
78  // Entering JavaScript.
79  VMState<JS> state(isolate);
82  isolate->ThrowIllegalOperation();
83  *has_pending_exception = true;
84  isolate->ReportPendingMessages();
85  return Handle<Object>();
86  }
87 
88  // Placeholder for return value.
89  MaybeObject* value = reinterpret_cast<Object*>(kZapValue);
90 
91  typedef Object* (*JSEntryFunction)(byte* entry,
92  Object* function,
93  Object* receiver,
94  int argc,
95  Object*** args);
96 
97  Handle<Code> code = is_construct
98  ? isolate->factory()->js_construct_entry_code()
99  : isolate->factory()->js_entry_code();
100 
101  // Convert calls on global objects to be calls on the global
102  // receiver instead to avoid having a 'this' pointer which refers
103  // directly to a global object.
104  if (receiver->IsGlobalObject()) {
105  Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
106  receiver = Handle<JSObject>(global->global_receiver());
107  }
108 
109  // Make sure that the global object of the context we're about to
110  // make the current one is indeed a global object.
111  ASSERT(function->context()->global_object()->IsGlobalObject());
112 
113  {
114  // Save and restore context around invocation and block the
115  // allocation of handles without explicit handle scopes.
116  SaveContext save(isolate);
117  SealHandleScope shs(isolate);
118  JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
119 
120  // Call the function through the right JS entry stub.
121  byte* function_entry = function->code()->entry();
122  JSFunction* func = *function;
123  Object* recv = *receiver;
124  Object*** argv = reinterpret_cast<Object***>(args);
125  value =
126  CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
127  }
128 
129 #ifdef VERIFY_HEAP
130  value->Verify();
131 #endif
132 
133  // Update the pending exception flag and return the value.
134  *has_pending_exception = value->IsException();
135  ASSERT(*has_pending_exception == isolate->has_pending_exception());
136  if (*has_pending_exception) {
137  isolate->ReportPendingMessages();
138 #ifdef ENABLE_DEBUGGER_SUPPORT
139  // Reset stepping state when script exits with uncaught exception.
140  if (isolate->debugger()->IsDebuggerActive()) {
141  isolate->debug()->ClearStepping();
142  }
143 #endif // ENABLE_DEBUGGER_SUPPORT
144  return Handle<Object>();
145  } else {
146  isolate->clear_pending_message();
147  }
148 
149  return Handle<Object>(value->ToObjectUnchecked(), isolate);
150 }
151 
152 
154  Handle<Object> callable,
155  Handle<Object> receiver,
156  int argc,
157  Handle<Object> argv[],
158  bool* pending_exception,
159  bool convert_receiver) {
160  *pending_exception = false;
161 
162  if (!callable->IsJSFunction()) {
163  callable = TryGetFunctionDelegate(isolate, callable, pending_exception);
164  if (*pending_exception) return callable;
165  }
167 
168  // In sloppy mode, convert receiver.
169  if (convert_receiver && !receiver->IsJSReceiver() &&
170  !func->shared()->native() &&
171  func->shared()->strict_mode() == SLOPPY) {
172  if (receiver->IsUndefined() || receiver->IsNull()) {
173  Object* global = func->context()->global_object()->global_receiver();
174  // Under some circumstances, 'global' can be the JSBuiltinsObject
175  // In that case, don't rewrite. (FWIW, the same holds for
176  // GetIsolate()->global_object()->global_receiver().)
177  if (!global->IsJSBuiltinsObject()) {
178  receiver = Handle<Object>(global, func->GetIsolate());
179  }
180  } else {
181  receiver = ToObject(isolate, receiver, pending_exception);
182  }
183  if (*pending_exception) return callable;
184  }
185 
186  return Invoke(false, func, receiver, argc, argv, pending_exception);
187 }
188 
189 
191  int argc,
192  Handle<Object> argv[],
193  bool* pending_exception) {
194  return Invoke(true, func, func->GetIsolate()->global_object(), argc, argv,
195  pending_exception);
196 }
197 
198 
200  Handle<Object> receiver,
201  int argc,
202  Handle<Object> args[],
203  bool* caught_exception) {
204  // Enter a try-block while executing the JavaScript code. To avoid
205  // duplicate error printing it must be non-verbose. Also, to avoid
206  // creating message objects during stack overflow we shouldn't
207  // capture messages.
208  v8::TryCatch catcher;
209  catcher.SetVerbose(false);
210  catcher.SetCaptureMessage(false);
211  *caught_exception = false;
212 
213  // Get isolate now, because handle might be persistent
214  // and get destroyed in the next call.
215  Isolate* isolate = func->GetIsolate();
216  Handle<Object> result = Invoke(false, func, receiver, argc, args,
217  caught_exception);
218 
219  if (*caught_exception) {
220  ASSERT(catcher.HasCaught());
221  ASSERT(isolate->has_pending_exception());
222  ASSERT(isolate->external_caught_exception());
223  if (isolate->pending_exception() ==
224  isolate->heap()->termination_exception()) {
225  result = isolate->factory()->termination_exception();
226  } else {
227  result = v8::Utils::OpenHandle(*catcher.Exception());
228  }
229  isolate->OptionalRescheduleException(true);
230  }
231 
232  ASSERT(!isolate->has_pending_exception());
233  ASSERT(!isolate->external_caught_exception());
234  return result;
235 }
236 
237 
239  Handle<Object> object) {
240  ASSERT(!object->IsJSFunction());
241  Factory* factory = isolate->factory();
242 
243  // If you return a function from here, it will be called when an
244  // attempt is made to call the given object as a function.
245 
246  // If object is a function proxy, get its handler. Iterate if necessary.
247  Object* fun = *object;
248  while (fun->IsJSFunctionProxy()) {
249  fun = JSFunctionProxy::cast(fun)->call_trap();
250  }
251  if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
252 
253  // Objects created through the API can have an instance-call handler
254  // that should be used when calling the object as a function.
255  if (fun->IsHeapObject() &&
257  return Handle<JSFunction>(
258  isolate->native_context()->call_as_function_delegate());
259  }
260 
261  return factory->undefined_value();
262 }
263 
264 
266  Handle<Object> object,
267  bool* has_pending_exception) {
268  ASSERT(!object->IsJSFunction());
269 
270  // If object is a function proxy, get its handler. Iterate if necessary.
271  Object* fun = *object;
272  while (fun->IsJSFunctionProxy()) {
273  fun = JSFunctionProxy::cast(fun)->call_trap();
274  }
275  if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
276 
277  // Objects created through the API can have an instance-call handler
278  // that should be used when calling the object as a function.
279  if (fun->IsHeapObject() &&
281  return Handle<JSFunction>(
282  isolate->native_context()->call_as_function_delegate());
283  }
284 
285  // If the Object doesn't have an instance-call handler we should
286  // throw a non-callable exception.
287  i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
288  "called_non_callable", i::HandleVector<i::Object>(&object, 1));
289  isolate->Throw(*error_obj);
290  *has_pending_exception = true;
291 
292  return isolate->factory()->undefined_value();
293 }
294 
295 
297  Handle<Object> object) {
298  ASSERT(!object->IsJSFunction());
299 
300  // If you return a function from here, it will be called when an
301  // attempt is made to call the given object as a constructor.
302 
303  // If object is a function proxies, get its handler. Iterate if necessary.
304  Object* fun = *object;
305  while (fun->IsJSFunctionProxy()) {
306  fun = JSFunctionProxy::cast(fun)->call_trap();
307  }
308  if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
309 
310  // Objects created through the API can have an instance-call handler
311  // that should be used when calling the object as a function.
312  if (fun->IsHeapObject() &&
314  return Handle<JSFunction>(
315  isolate->native_context()->call_as_constructor_delegate());
316  }
317 
318  return isolate->factory()->undefined_value();
319 }
320 
321 
323  Isolate* isolate,
324  Handle<Object> object,
325  bool* has_pending_exception) {
326  ASSERT(!object->IsJSFunction());
327 
328  // If you return a function from here, it will be called when an
329  // attempt is made to call the given object as a constructor.
330 
331  // If object is a function proxies, get its handler. Iterate if necessary.
332  Object* fun = *object;
333  while (fun->IsJSFunctionProxy()) {
334  fun = JSFunctionProxy::cast(fun)->call_trap();
335  }
336  if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
337 
338  // Objects created through the API can have an instance-call handler
339  // that should be used when calling the object as a function.
340  if (fun->IsHeapObject() &&
342  return Handle<JSFunction>(
343  isolate->native_context()->call_as_constructor_delegate());
344  }
345 
346  // If the Object doesn't have an instance-call handler we should
347  // throw a non-callable exception.
348  i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
349  "called_non_callable", i::HandleVector<i::Object>(&object, 1));
350  isolate->Throw(*error_obj);
351  *has_pending_exception = true;
352 
353  return isolate->factory()->undefined_value();
354 }
355 
356 
358  ASSERT(isolate->microtask_pending());
359  bool threw = false;
361  isolate,
362  isolate->run_microtasks(),
363  isolate->factory()->undefined_value(),
364  0,
365  NULL,
366  &threw);
367  ASSERT(!threw);
368 }
369 
370 
372  bool threw = false;
373  Handle<Object> args[] = { microtask };
375  isolate,
376  isolate->enqueue_external_microtask(),
377  isolate->factory()->undefined_value(),
378  1,
379  args,
380  &threw);
381  ASSERT(!threw);
382 }
383 
384 
386  ExecutionAccess access(isolate_);
387  return (thread_local_.jslimit_ != kInterruptLimit &&
388  thread_local_.climit_ != kInterruptLimit);
389 }
390 
391 
392 void StackGuard::EnableInterrupts() {
393  ExecutionAccess access(isolate_);
394  if (has_pending_interrupts(access)) {
395  set_interrupt_limits(access);
396  }
397 }
398 
399 
400 void StackGuard::SetStackLimit(uintptr_t limit) {
401  ExecutionAccess access(isolate_);
402  // If the current limits are special (e.g. due to a pending interrupt) then
403  // leave them alone.
404  uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit);
405  if (thread_local_.jslimit_ == thread_local_.real_jslimit_) {
406  thread_local_.jslimit_ = jslimit;
407  }
408  if (thread_local_.climit_ == thread_local_.real_climit_) {
409  thread_local_.climit_ = limit;
410  }
411  thread_local_.real_climit_ = limit;
412  thread_local_.real_jslimit_ = jslimit;
413 }
414 
415 
416 void StackGuard::DisableInterrupts() {
417  ExecutionAccess access(isolate_);
418  reset_limits(access);
419 }
420 
421 
423  ExecutionAccess access(isolate_);
424  return should_postpone_interrupts(access);
425 }
426 
427 
429  ExecutionAccess access(isolate_);
430  return (thread_local_.interrupt_flags_ & INTERRUPT) != 0;
431 }
432 
433 
435  ExecutionAccess access(isolate_);
436  thread_local_.interrupt_flags_ |= INTERRUPT;
437  set_interrupt_limits(access);
438 }
439 
440 
442  ExecutionAccess access(isolate_);
443  return thread_local_.interrupt_flags_ & PREEMPT;
444 }
445 
446 
448  ExecutionAccess access(isolate_);
449  thread_local_.interrupt_flags_ |= PREEMPT;
450  set_interrupt_limits(access);
451 }
452 
453 
455  ExecutionAccess access(isolate_);
456  return (thread_local_.interrupt_flags_ & TERMINATE) != 0;
457 }
458 
459 
461  ExecutionAccess access(isolate_);
463  isolate_->CancelTerminateExecution();
464 }
465 
466 
468  ExecutionAccess access(isolate_);
469  thread_local_.interrupt_flags_ |= TERMINATE;
470  set_interrupt_limits(access);
471 }
472 
473 
475  ExecutionAccess access(isolate_);
476  return (thread_local_.interrupt_flags_ & GC_REQUEST) != 0;
477 }
478 
479 
481  ExecutionAccess access(isolate_);
482  thread_local_.interrupt_flags_ |= GC_REQUEST;
483  if (thread_local_.postpone_interrupts_nesting_ == 0) {
484  thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
485  isolate_->heap()->SetStackLimits();
486  }
487 }
488 
489 
491  ExecutionAccess access(isolate_);
492  return (thread_local_.interrupt_flags_ & INSTALL_CODE) != 0;
493 }
494 
495 
497  ExecutionAccess access(isolate_);
498  thread_local_.interrupt_flags_ |= INSTALL_CODE;
499  if (thread_local_.postpone_interrupts_nesting_ == 0) {
500  thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
501  isolate_->heap()->SetStackLimits();
502  }
503 }
504 
505 
507  ExecutionAccess access(isolate_);
508  return (thread_local_.interrupt_flags_ & FULL_DEOPT) != 0;
509 }
510 
511 
513  ExecutionAccess access(isolate_);
514  thread_local_.interrupt_flags_ |= FULL_DEOPT;
515  set_interrupt_limits(access);
516 }
517 
518 
520  ExecutionAccess access(isolate_);
521  return (thread_local_.interrupt_flags_ & DEOPT_MARKED_ALLOCATION_SITES) != 0;
522 }
523 
524 
526  ExecutionAccess access(isolate_);
527  thread_local_.interrupt_flags_ |= DEOPT_MARKED_ALLOCATION_SITES;
528  set_interrupt_limits(access);
529 }
530 
531 
532 #ifdef ENABLE_DEBUGGER_SUPPORT
533 bool StackGuard::IsDebugBreak() {
534  ExecutionAccess access(isolate_);
535  return thread_local_.interrupt_flags_ & DEBUGBREAK;
536 }
537 
538 
539 void StackGuard::DebugBreak() {
540  ExecutionAccess access(isolate_);
541  thread_local_.interrupt_flags_ |= DEBUGBREAK;
542  set_interrupt_limits(access);
543 }
544 
545 
546 bool StackGuard::IsDebugCommand() {
547  ExecutionAccess access(isolate_);
548  return thread_local_.interrupt_flags_ & DEBUGCOMMAND;
549 }
550 
551 
552 void StackGuard::DebugCommand() {
553  if (FLAG_debugger_auto_break) {
554  ExecutionAccess access(isolate_);
555  thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
556  set_interrupt_limits(access);
557  }
558 }
559 #endif
560 
562  ExecutionAccess access(isolate_);
563  thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what);
564  if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
565  reset_limits(access);
566  }
567 }
568 
569 
571  ExecutionAccess access(isolate_);
572  thread_local_.interrupt_flags_ |= API_INTERRUPT;
573  thread_local_.interrupt_callback_ = callback;
574  thread_local_.interrupt_callback_data_ = data;
575  set_interrupt_limits(access);
576 }
577 
578 
580  thread_local_.interrupt_callback_ = 0;
581  thread_local_.interrupt_callback_data_ = 0;
583 }
584 
585 
587  ExecutionAccess access(isolate_);
588  return thread_local_.interrupt_flags_ & API_INTERRUPT;
589 }
590 
591 
593  InterruptCallback callback = 0;
594  void* data = 0;
595 
596  {
597  ExecutionAccess access(isolate_);
598  callback = thread_local_.interrupt_callback_;
599  data = thread_local_.interrupt_callback_data_;
600  thread_local_.interrupt_callback_ = NULL;
601  thread_local_.interrupt_callback_data_ = NULL;
602  }
603 
604  if (callback != NULL) {
605  VMState<EXTERNAL> state(isolate_);
606  HandleScope handle_scope(isolate_);
607  callback(reinterpret_cast<v8::Isolate*>(isolate_), data);
608  }
609 }
610 
611 
613  ExecutionAccess access(isolate_);
614  OS::MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
615  ThreadLocal blank;
616 
617  // Set the stack limits using the old thread_local_.
618  // TODO(isolates): This was the old semantics of constructing a ThreadLocal
619  // (as the ctor called SetStackLimits, which looked at the
620  // current thread_local_ from StackGuard)-- but is this
621  // really what was intended?
622  isolate_->heap()->SetStackLimits();
623  thread_local_ = blank;
624 
625  return to + sizeof(ThreadLocal);
626 }
627 
628 
629 char* StackGuard::RestoreStackGuard(char* from) {
630  ExecutionAccess access(isolate_);
631  OS::MemCopy(
632  reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
633  isolate_->heap()->SetStackLimits();
634  return from + sizeof(ThreadLocal);
635 }
636 
637 
639  Isolate::PerIsolateThreadData* per_thread =
640  isolate_->FindOrAllocatePerThreadDataForThisThread();
641  per_thread->set_stack_limit(thread_local_.real_climit_);
642 }
643 
644 
645 void StackGuard::ThreadLocal::Clear() {
646  real_jslimit_ = kIllegalLimit;
647  jslimit_ = kIllegalLimit;
648  real_climit_ = kIllegalLimit;
649  climit_ = kIllegalLimit;
650  nesting_ = 0;
651  postpone_interrupts_nesting_ = 0;
652  interrupt_flags_ = 0;
653  interrupt_callback_ = NULL;
654  interrupt_callback_data_ = NULL;
655 }
656 
657 
658 bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
659  bool should_set_stack_limits = false;
660  if (real_climit_ == kIllegalLimit) {
661  // Takes the address of the limit variable in order to find out where
662  // the top of stack is right now.
663  const uintptr_t kLimitSize = FLAG_stack_size * KB;
664  uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize;
665  ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize);
666  real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
667  jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
668  real_climit_ = limit;
669  climit_ = limit;
670  should_set_stack_limits = true;
671  }
672  nesting_ = 0;
673  postpone_interrupts_nesting_ = 0;
674  interrupt_flags_ = 0;
675  interrupt_callback_ = NULL;
676  interrupt_callback_data_ = NULL;
677  return should_set_stack_limits;
678 }
679 
680 
681 void StackGuard::ClearThread(const ExecutionAccess& lock) {
682  thread_local_.Clear();
683  isolate_->heap()->SetStackLimits();
684 }
685 
686 
687 void StackGuard::InitThread(const ExecutionAccess& lock) {
688  if (thread_local_.Initialize(isolate_)) isolate_->heap()->SetStackLimits();
689  Isolate::PerIsolateThreadData* per_thread =
690  isolate_->FindOrAllocatePerThreadDataForThisThread();
691  uintptr_t stored_limit = per_thread->stack_limit();
692  // You should hold the ExecutionAccess lock when you call this.
693  if (stored_limit != 0) {
694  SetStackLimit(stored_limit);
695  }
696 }
697 
698 
699 // --- C a l l s t o n a t i v e s ---
700 
701 #define RETURN_NATIVE_CALL(name, args, has_pending_exception) \
702  do { \
703  Handle<Object> argv[] = args; \
704  ASSERT(has_pending_exception != NULL); \
705  return Call(isolate, \
706  isolate->name##_fun(), \
707  isolate->js_builtins_object(), \
708  ARRAY_SIZE(argv), argv, \
709  has_pending_exception); \
710  } while (false)
711 
712 
714  Isolate* isolate, Handle<Object> obj, bool* exc) {
715  RETURN_NATIVE_CALL(to_number, { obj }, exc);
716 }
717 
718 
720  Isolate* isolate, Handle<Object> obj, bool* exc) {
721  RETURN_NATIVE_CALL(to_string, { obj }, exc);
722 }
723 
724 
726  Isolate* isolate, Handle<Object> obj, bool* exc) {
727  RETURN_NATIVE_CALL(to_detail_string, { obj }, exc);
728 }
729 
730 
732  Isolate* isolate, Handle<Object> obj, bool* exc) {
733  if (obj->IsSpecObject()) return obj;
734  RETURN_NATIVE_CALL(to_object, { obj }, exc);
735 }
736 
737 
739  Isolate* isolate, Handle<Object> obj, bool* exc) {
740  RETURN_NATIVE_CALL(to_integer, { obj }, exc);
741 }
742 
743 
745  Isolate* isolate, Handle<Object> obj, bool* exc) {
746  RETURN_NATIVE_CALL(to_uint32, { obj }, exc);
747 }
748 
749 
751  Isolate* isolate, Handle<Object> obj, bool* exc) {
752  RETURN_NATIVE_CALL(to_int32, { obj }, exc);
753 }
754 
755 
756 Handle<Object> Execution::NewDate(Isolate* isolate, double time, bool* exc) {
757  Handle<Object> time_obj = isolate->factory()->NewNumber(time);
758  RETURN_NATIVE_CALL(create_date, { time_obj }, exc);
759 }
760 
761 
762 #undef RETURN_NATIVE_CALL
763 
764 
767  bool* exc) {
769  pattern->GetIsolate()->native_context()->regexp_function());
771  function, pattern, flags, exc);
772  if (*exc) return Handle<JSRegExp>();
773  return Handle<JSRegExp>::cast(re_obj);
774 }
775 
776 
778  Isolate* isolate = string->GetIsolate();
779  Factory* factory = isolate->factory();
780 
781  int int_index = static_cast<int>(index);
782  if (int_index < 0 || int_index >= string->length()) {
783  return factory->undefined_value();
784  }
785 
786  Handle<Object> char_at = GetProperty(
787  isolate, isolate->js_builtins_object(), factory->char_at_string());
788  if (!char_at->IsJSFunction()) {
789  return factory->undefined_value();
790  }
791 
792  bool caught_exception;
793  Handle<Object> index_object = factory->NewNumberFromInt(int_index);
794  Handle<Object> index_arg[] = { index_object };
796  string,
797  ARRAY_SIZE(index_arg),
798  index_arg,
799  &caught_exception);
800  if (caught_exception) {
801  return factory->undefined_value();
802  }
803  return result;
804 }
805 
806 
809  bool* exc) {
810  Isolate* isolate = data->GetIsolate();
811  if (!data->do_not_cache()) {
812  // Fast case: see if the function has already been instantiated
813  int serial_number = Smi::cast(data->serial_number())->value();
814  Handle<JSObject> cache(isolate->native_context()->function_cache());
815  Handle<Object> elm =
816  Object::GetElementNoExceptionThrown(isolate, cache, serial_number);
817  if (elm->IsJSFunction()) return Handle<JSFunction>::cast(elm);
818  }
819  // The function has not yet been instantiated in this context; do it.
820  Handle<Object> args[] = { data };
821  Handle<Object> result = Call(isolate,
822  isolate->instantiate_fun(),
823  isolate->js_builtins_object(),
824  ARRAY_SIZE(args),
825  args,
826  exc);
827  if (*exc) return Handle<JSFunction>::null();
828  return Handle<JSFunction>::cast(result);
829 }
830 
831 
833  bool* exc) {
834  Isolate* isolate = data->GetIsolate();
835  if (data->property_list()->IsUndefined() &&
836  !data->constructor()->IsUndefined()) {
837  // Initialization to make gcc happy.
838  Object* result = NULL;
839  {
840  HandleScope scope(isolate);
841  Handle<FunctionTemplateInfo> cons_template =
843  FunctionTemplateInfo::cast(data->constructor()));
844  Handle<JSFunction> cons = InstantiateFunction(cons_template, exc);
845  if (*exc) return Handle<JSObject>::null();
846  Handle<Object> value = New(cons, 0, NULL, exc);
847  if (*exc) return Handle<JSObject>::null();
848  result = *value;
849  }
850  ASSERT(!*exc);
851  return Handle<JSObject>(JSObject::cast(result));
852  } else {
853  Handle<Object> args[] = { data };
854  Handle<Object> result = Call(isolate,
855  isolate->instantiate_fun(),
856  isolate->js_builtins_object(),
857  ARRAY_SIZE(args),
858  args,
859  exc);
860  if (*exc) return Handle<JSObject>::null();
861  return Handle<JSObject>::cast(result);
862  }
863 }
864 
865 
867  Handle<Object> instance,
868  Handle<Object> instance_template,
869  bool* exc) {
870  Handle<Object> args[] = { instance, instance_template };
871  Execution::Call(isolate,
872  isolate->configure_instance_fun(),
873  isolate->js_builtins_object(),
874  ARRAY_SIZE(args),
875  args,
876  exc);
877 }
878 
879 
881  Handle<JSFunction> fun,
882  Handle<Object> pos,
883  Handle<Object> is_global) {
884  Isolate* isolate = fun->GetIsolate();
885  Handle<Object> args[] = { recv, fun, pos, is_global };
886  bool caught_exception;
887  Handle<Object> result = TryCall(isolate->get_stack_trace_line_fun(),
888  isolate->js_builtins_object(),
889  ARRAY_SIZE(args),
890  args,
891  &caught_exception);
892  if (caught_exception || !result->IsString()) {
893  return isolate->factory()->empty_string();
894  }
895 
896  return Handle<String>::cast(result);
897 }
898 
899 
900 static Object* RuntimePreempt(Isolate* isolate) {
901  // Clear the preempt request flag.
902  isolate->stack_guard()->Continue(PREEMPT);
903 
904 #ifdef ENABLE_DEBUGGER_SUPPORT
905  if (isolate->debug()->InDebugger()) {
906  // If currently in the debugger don't do any actual preemption but record
907  // that preemption occoured while in the debugger.
908  isolate->debug()->PreemptionWhileInDebugger();
909  } else {
910  // Perform preemption.
911  v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
913  }
914 #else
915  { // NOLINT
916  // Perform preemption.
917  v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
919  }
920 #endif
921 
922  return isolate->heap()->undefined_value();
923 }
924 
925 
926 #ifdef ENABLE_DEBUGGER_SUPPORT
927 Object* Execution::DebugBreakHelper(Isolate* isolate) {
928  // Just continue if breaks are disabled.
929  if (isolate->debug()->disable_break()) {
930  return isolate->heap()->undefined_value();
931  }
932 
933  // Ignore debug break during bootstrapping.
934  if (isolate->bootstrapper()->IsActive()) {
935  return isolate->heap()->undefined_value();
936  }
937 
938  // Ignore debug break if debugger is not active.
939  if (!isolate->debugger()->IsDebuggerActive()) {
940  return isolate->heap()->undefined_value();
941  }
942 
943  StackLimitCheck check(isolate);
944  if (check.HasOverflowed()) {
945  return isolate->heap()->undefined_value();
946  }
947 
948  {
949  JavaScriptFrameIterator it(isolate);
950  ASSERT(!it.done());
951  Object* fun = it.frame()->function();
952  if (fun && fun->IsJSFunction()) {
953  // Don't stop in builtin functions.
954  if (JSFunction::cast(fun)->IsBuiltin()) {
955  return isolate->heap()->undefined_value();
956  }
957  GlobalObject* global = JSFunction::cast(fun)->context()->global_object();
958  // Don't stop in debugger functions.
959  if (isolate->debug()->IsDebugGlobal(global)) {
960  return isolate->heap()->undefined_value();
961  }
962  }
963  }
964 
965  // Collect the break state before clearing the flags.
966  bool debug_command_only =
967  isolate->stack_guard()->IsDebugCommand() &&
968  !isolate->stack_guard()->IsDebugBreak();
969 
970  // Clear the debug break request flag.
971  isolate->stack_guard()->Continue(DEBUGBREAK);
972 
973  ProcessDebugMessages(isolate, debug_command_only);
974 
975  // Return to continue execution.
976  return isolate->heap()->undefined_value();
977 }
978 
979 
980 void Execution::ProcessDebugMessages(Isolate* isolate,
981  bool debug_command_only) {
982  // Clear the debug command request flag.
983  isolate->stack_guard()->Continue(DEBUGCOMMAND);
984 
985  StackLimitCheck check(isolate);
986  if (check.HasOverflowed()) {
987  return;
988  }
989 
990  HandleScope scope(isolate);
991  // Enter the debugger. Just continue if we fail to enter the debugger.
992  EnterDebugger debugger(isolate);
993  if (debugger.FailedToEnter()) {
994  return;
995  }
996 
997  // Notify the debug event listeners. Indicate auto continue if the break was
998  // a debug command break.
999  isolate->debugger()->OnDebugBreak(isolate->factory()->undefined_value(),
1000  debug_command_only);
1001 }
1002 
1003 
1004 #endif
1005 
1007  StackGuard* stack_guard = isolate->stack_guard();
1008  if (stack_guard->ShouldPostponeInterrupts()) {
1009  return isolate->heap()->undefined_value();
1010  }
1011 
1012  if (stack_guard->IsAPIInterrupt()) {
1013  stack_guard->InvokeInterruptCallback();
1014  stack_guard->Continue(API_INTERRUPT);
1015  }
1016 
1017  if (stack_guard->IsGCRequest()) {
1019  "StackGuard GC request");
1020  stack_guard->Continue(GC_REQUEST);
1021  }
1022 
1023  isolate->counters()->stack_interrupts()->Increment();
1024  isolate->counters()->runtime_profiler_ticks()->Increment();
1025 #ifdef ENABLE_DEBUGGER_SUPPORT
1026  if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) {
1027  DebugBreakHelper(isolate);
1028  }
1029 #endif
1030  if (stack_guard->IsPreempted()) RuntimePreempt(isolate);
1031  if (stack_guard->IsTerminateExecution()) {
1032  stack_guard->Continue(TERMINATE);
1033  return isolate->TerminateExecution();
1034  }
1035  if (stack_guard->IsInterrupted()) {
1036  stack_guard->Continue(INTERRUPT);
1037  return isolate->StackOverflow();
1038  }
1039  if (stack_guard->IsFullDeopt()) {
1040  stack_guard->Continue(FULL_DEOPT);
1041  Deoptimizer::DeoptimizeAll(isolate);
1042  }
1043  if (stack_guard->IsDeoptMarkedAllocationSites()) {
1045  isolate->heap()->DeoptMarkedAllocationSites();
1046  }
1047  if (stack_guard->IsInstallCodeRequest()) {
1049  stack_guard->Continue(INSTALL_CODE);
1051  }
1052  isolate->runtime_profiler()->OptimizeNow();
1053  return isolate->heap()->undefined_value();
1054 }
1055 
1056 
1057 } } // namespace v8::internal
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
Definition: flags.cc:269
static Handle< Object > New(Handle< JSFunction > func, int argc, Handle< Object > argv[], bool *pending_exception)
Definition: execution.cc:190
Failure * StackOverflow()
Definition: isolate.cc:871
void SetStackLimits()
Definition: heap.cc:6688
static Handle< Object > TryCall(Handle< JSFunction > func, Handle< Object > receiver, int argc, Handle< Object > argv[], bool *caught_exception)
Definition: execution.cc:199
MaybeObject * pending_exception()
Definition: isolate.h:570
void DeoptMarkedAllocationSites()
Definition: heap.cc:571
void CollectAllGarbage(int flags, const char *gc_reason=NULL, const GCCallbackFlags gc_callback_flags=kNoGCCallbackFlags)
Definition: heap.cc:731
Local< Value > Exception() const
Definition: api.cc:1923
static Handle< Object > ToNumber(Isolate *isolate, Handle< Object > obj, bool *exc)
Definition: execution.cc:713
static Handle< Object > ToObject(Isolate *isolate, Handle< Object > obj, bool *exc)
Definition: execution.cc:731
const int KB
Definition: globals.h:245
bool HasCaught() const
Definition: api.cc:1901
void SetCaptureMessage(bool value)
Definition: api.cc:1981
static HeapObject * cast(Object *obj)
static Handle< T > cast(Handle< S > that)
Definition: handles.h:75
static Handle< Object > CreateRegExpLiteral(Handle< JSFunction > constructor, Handle< String > pattern, Handle< String > flags, bool *has_pending_exception)
Definition: jsregexp.cc:69
kSerializedDataOffset Object
Definition: objects-inl.h:5016
static Handle< Object > GetFunctionDelegate(Isolate *isolate, Handle< Object > object)
Definition: execution.cc:238
static Handle< Object > GetElementNoExceptionThrown(Isolate *isolate, Handle< Object > object, uint32_t index)
Definition: objects-inl.h:1071
static Handle< Object > NewDate(Isolate *isolate, double time, bool *exc)
Definition: execution.cc:756
#define ASSERT(condition)
Definition: checks.h:329
static Handle< Object > TryGetFunctionDelegate(Isolate *isolate, Handle< Object > object, bool *has_pending_exception)
Definition: execution.cc:265
bool concurrent_recompilation_enabled()
Definition: isolate.h:1062
static Handle< Object > ToDetailString(Isolate *isolate, Handle< Object > obj, bool *exc)
Definition: execution.cc:725
static bool IsAllowed(Isolate *isolate)
Definition: assert-scope.h:162
Handle< Object > NewNumber(double value, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:998
#define CHECK(condition)
Definition: checks.h:75
bool IsDeoptMarkedAllocationSites()
Definition: execution.cc:519
void SetVerbose(bool value)
Definition: api.cc:1976
Handle< Object > GetProperty(Handle< JSReceiver > obj, const char *name)
Definition: handles.cc:196
Factory * factory()
Definition: isolate.h:995
static Smi * cast(Object *object)
StackGuard * stack_guard()
Definition: isolate.h:874
bool has_instance_call_handler()
Definition: objects-inl.h:4157
uint8_t byte
Definition: globals.h:185
bool OptionalRescheduleException(bool is_bottom_call)
Definition: isolate.cc:1319
GlobalObject * global_object()
Definition: contexts.h:388
static JSFunctionProxy * cast(Object *obj)
V8_INLINE bool IsNull() const
Definition: v8.h:6247
static Handle< Object > CharAt(Handle< String > str, uint32_t index)
Definition: execution.cc:777
static void YieldCPU()
char * RestoreStackGuard(char *from)
Definition: execution.cc:629
void ClearThread(const ExecutionAccess &lock)
Definition: execution.cc:681
void RequestInterrupt(InterruptCallback callback, void *data)
Definition: execution.cc:570
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print statistics of the maximum memory committed for the heap in only print modified registers Don t break for ASM_UNIMPLEMENTED_BREAK macros print stack trace when an illegal exception is thrown randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot testing_bool_flag testing_int_flag string flag tmp file in which to serialize heap Print the time it takes to lazily compile hydrogen code stubs concurrent_recompilation concurrent_sweeping Print usage including flags
Definition: flags.cc:665
static void MemCopy(void *dest, const void *src, size_t size)
Definition: platform.h:399
RuntimeProfiler * runtime_profiler()
Definition: isolate.h:866
char * ArchiveStackGuard(char *to)
Definition: execution.cc:612
static MUST_USE_RESULT MaybeObject * HandleStackGuardInterrupt(Isolate *isolate)
Definition: execution.cc:1006
static const int kNoGCFlags
Definition: heap.h:1257
void check(i::Vector< const uint8_t > string)
Handle< Object > NewTypeError(const char *message, Vector< Handle< Object > > args)
Definition: factory.cc:1039
const Address kZapValue
Definition: v8globals.h:82
static void ConfigureInstance(Isolate *isolate, Handle< Object > instance, Handle< Object > data, bool *exc)
Definition: execution.cc:866
static uintptr_t JsLimitFromCLimit(v8::internal::Isolate *isolate, uintptr_t c_limit)
Definition: simulator-arm.h:71
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
static FunctionTemplateInfo * cast(Object *obj)
static void DeoptimizeAll(Isolate *isolate)
Definition: deoptimizer.cc:450
static Handle< Object > ToInteger(Isolate *isolate, Handle< Object > obj, bool *exc)
Definition: execution.cc:738
static Handle< Object > TryGetConstructorDelegate(Isolate *isolate, Handle< Object > object, bool *has_pending_exception)
Definition: execution.cc:322
static Handle< JSRegExp > NewJSRegExp(Handle< String > pattern, Handle< String > flags, bool *exc)
Definition: execution.cc:765
#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4)
Definition: simulator-arm.h:48
bool has_pending_exception()
Definition: isolate.h:587
static void EnqueueMicrotask(Isolate *isolate, Handle< Object > microtask)
Definition: execution.cc:371
Handle< JSBuiltinsObject > js_builtins_object()
Definition: isolate.h:680
Failure * Throw(Object *exception, MessageLocation *location=NULL)
Definition: isolate.cc:923
V8_INLINE bool IsUndefined() const
Definition: v8.h:6229
static v8::internal::Handle< To > OpenHandle(v8::Local< From > handle)
Definition: api.h:308
V8_INLINE bool IsString() const
Definition: v8.h:6265
Handle< Object > NewNumberFromInt(int32_t value, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:1006
static Handle< JSFunction > InstantiateFunction(Handle< FunctionTemplateInfo > data, bool *exc)
Definition: execution.cc:807
static Handle< Object > Call(Isolate *isolate, Handle< Object > callable, Handle< Object > receiver, int argc, Handle< Object > argv[], bool *pending_exception, bool convert_receiver=false)
Definition: execution.cc:153
void Continue(InterruptFlag after_what)
Definition: execution.cc:561
static Handle< Object > ToInt32(Isolate *isolate, Handle< Object > obj, bool *exc)
Definition: execution.cc:750
static Handle< Object > GetConstructorDelegate(Isolate *isolate, Handle< Object > object)
Definition: execution.cc:296
static Handle< T > null()
Definition: handles.h:80
#define RETURN_NATIVE_CALL(name, args, has_pending_exception)
Definition: execution.cc:701
void(* InterruptCallback)(Isolate *isolate, void *data)
Definition: v8.h:4083
static Handle< Object > ToUint32(Isolate *isolate, Handle< Object > obj, bool *exc)
Definition: execution.cc:744
Counters * counters()
Definition: isolate.h:859
static Handle< JSObject > InstantiateObject(Handle< ObjectTemplateInfo > data, bool *exc)
Definition: execution.cc:832
Failure * TerminateExecution()
Definition: isolate.cc:900
OptimizingCompilerThread * optimizing_compiler_thread()
Definition: isolate.h:1076
static Handle< String > GetStackTraceLine(Handle< Object > recv, Handle< JSFunction > fun, Handle< Object > pos, Handle< Object > is_global)
Definition: execution.cc:880
HeapObject * obj
Handle< Context > native_context()
Definition: isolate.cc:1372
static void RunMicrotasks(Isolate *isolate)
Definition: execution.cc:357
void SetStackLimit(uintptr_t limit)
Definition: execution.cc:400
static Handle< Object > ToString(Isolate *isolate, Handle< Object > obj, bool *exc)
Definition: execution.cc:719
#define ARRAY_SIZE(a)
Definition: globals.h:333
static JSObject * cast(Object *obj)
void CancelTerminateExecution()
Definition: isolate.cc:906
void InitThread(const ExecutionAccess &lock)
Definition: execution.cc:687
static JSFunction * cast(Object *obj)