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