13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <stdlib.h>
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "api.h"
33e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#include "bootstrapper.h"
348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#include "codegen.h"
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "debug.h"
363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "isolate-inl.h"
37b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "runtime-profiler.h"
38d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include "simulator.h"
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8threads.h"
40b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "vm-state-inl.h"
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4644f0eee88ff00398ff7f715fab053374d808c90dSteve BlockStackGuard::StackGuard()
4744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    : isolate_(NULL) {
4844f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
4944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid StackGuard::set_interrupt_limits(const ExecutionAccess& lock) {
5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(isolate_ != NULL);
5344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Ignore attempts to interrupt when interrupts are postponed.
5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (should_postpone_interrupts(lock)) return;
5544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  thread_local_.jslimit_ = kInterruptLimit;
5644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  thread_local_.climit_ = kInterruptLimit;
5744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate_->heap()->SetStackLimits();
5844f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
6144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid StackGuard::reset_limits(const ExecutionAccess& lock) {
6244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(isolate_ != NULL);
6344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  thread_local_.jslimit_ = thread_local_.real_jslimit_;
6444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  thread_local_.climit_ = thread_local_.real_climit_;
6544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate_->heap()->SetStackLimits();
6644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
6744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
6844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic Handle<Object> Invoke(bool is_construct,
703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             Handle<JSFunction> function,
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                             Handle<Object> receiver,
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                             int argc,
733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                             Handle<Object> args[],
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                             bool* has_pending_exception) {
753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Isolate* isolate = function->GetIsolate();
7644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Entering JavaScript.
7844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  VMState state(isolate, JS);
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Placeholder for return value.
815913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MaybeObject* value = reinterpret_cast<Object*>(kZapValue);
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  typedef Object* (*JSEntryFunction)(byte* entry,
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     Object* function,
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     Object* receiver,
863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     int argc,
873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     Object*** args);
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Code> code = is_construct
903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ? isolate->factory()->js_construct_entry_code()
913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      : isolate->factory()->js_entry_code();
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Convert calls on global objects to be calls on the global
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // receiver instead to avoid having a 'this' pointer which refers
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // directly to a global object.
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (receiver->IsGlobalObject()) {
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    receiver = Handle<JSObject>(global->global_receiver());
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
101e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Make sure that the global object of the context we're about to
102e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // make the current one is indeed a global object.
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ASSERT(function->context()->global()->IsGlobalObject());
104e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Save and restore context around invocation and block the
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // allocation of handles without explicit handle scopes.
10844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    SaveContext save(isolate);
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    NoHandleAllocation na;
1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Call the function through the right JS entry stub.
1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    byte* function_entry = function->code()->entry();
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    JSFunction* func = *function;
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object* recv = *receiver;
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Object*** argv = reinterpret_cast<Object***>(args);
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    value =
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  value->Verify();
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Update the pending exception flag and return the value.
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *has_pending_exception = value->IsException();
12744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(*has_pending_exception == Isolate::Current()->has_pending_exception());
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (*has_pending_exception) {
12944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate->ReportPendingMessages();
13044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (isolate->pending_exception() == Failure::OutOfMemoryException()) {
13169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      if (!isolate->ignore_out_of_memory()) {
132e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        V8::FatalProcessOutOfMemory("JS", true);
133e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      }
134e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    }
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<Object>();
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
13744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate->clear_pending_message();
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
14044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return Handle<Object>(value->ToObjectUnchecked(), isolate);
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
144257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochHandle<Object> Execution::Call(Handle<Object> callable,
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Handle<Object> receiver,
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               int argc,
1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               Handle<Object> argv[],
148589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                               bool* pending_exception,
149589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                               bool convert_receiver) {
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  *pending_exception = false;
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
152257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!callable->IsJSFunction()) {
153257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    callable = TryGetFunctionDelegate(callable, pending_exception);
154257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (*pending_exception) return callable;
155257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
156257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
157589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
158589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // In non-strict mode, convert receiver.
159589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (convert_receiver && !receiver->IsJSReceiver() &&
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      !func->shared()->native() && func->shared()->is_classic_mode()) {
161589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (receiver->IsUndefined() || receiver->IsNull()) {
162589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      Object* global = func->context()->global()->global_receiver();
163589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // Under some circumstances, 'global' can be the JSBuiltinsObject
164589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // In that case, don't rewrite.
165589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // (FWIW, the same holds for GetIsolate()->global()->global_receiver().)
166589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (!global->IsJSBuiltinsObject()) receiver = Handle<Object>(global);
167589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    } else {
168589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      receiver = ToObject(receiver, pending_exception);
169589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
170589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (*pending_exception) return callable;
171589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
172589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return Invoke(false, func, receiver, argc, argv, pending_exception);
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Object> Execution::New(Handle<JSFunction> func,
1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              int argc,
1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              Handle<Object> argv[],
1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              bool* pending_exception) {
1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return Invoke(true, func, Isolate::Current()->global(), argc, argv,
18244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                pending_exception);
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::TryCall(Handle<JSFunction> func,
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Handle<Object> receiver,
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  int argc,
1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Handle<Object> args[],
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  bool* caught_exception) {
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Enter a try-block while executing the JavaScript code. To avoid
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // duplicate error printing it must be non-verbose.  Also, to avoid
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // creating message objects during stack overflow we shouldn't
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // capture messages.
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::TryCatch catcher;
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  catcher.SetVerbose(false);
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  catcher.SetCaptureMessage(false);
1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  *caught_exception = false;
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> result = Invoke(false, func, receiver, argc, args,
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 caught_exception);
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (*caught_exception) {
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(catcher.HasCaught());
20544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Isolate* isolate = Isolate::Current();
20644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ASSERT(isolate->has_pending_exception());
20744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ASSERT(isolate->external_caught_exception());
20844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (isolate->pending_exception() ==
20944f0eee88ff00398ff7f715fab053374d808c90dSteve Block        isolate->heap()->termination_exception()) {
21044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      result = isolate->factory()->termination_exception();
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = v8::Utils::OpenHandle(*catcher.Exception());
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
21444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate->OptionalRescheduleException(true);
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
21744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(!Isolate::Current()->has_pending_exception());
21844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(!Isolate::Current()->external_caught_exception());
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::GetFunctionDelegate(Handle<Object> object) {
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(!object->IsJSFunction());
2258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Isolate* isolate = Isolate::Current();
2268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Factory* factory = isolate->factory();
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If you return a function from here, it will be called when an
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // attempt is made to call the given object as a function.
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
231589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // If object is a function proxy, get its handler. Iterate if necessary.
232589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Object* fun = *object;
233589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  while (fun->IsJSFunctionProxy()) {
234589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    fun = JSFunctionProxy::cast(fun)->call_trap();
235589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
236589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (fun->IsJSFunction()) return Handle<Object>(fun);
237589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Objects created through the API can have an instance-call handler
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // that should be used when calling the object as a function.
240589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (fun->IsHeapObject() &&
241589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      HeapObject::cast(fun)->map()->has_instance_call_handler()) {
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<JSFunction>(
2438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        isolate->global_context()->call_as_function_delegate());
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  return factory->undefined_value();
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
250257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochHandle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object,
251257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                                 bool* has_pending_exception) {
252257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ASSERT(!object->IsJSFunction());
253257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Isolate* isolate = Isolate::Current();
254257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
255589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // If object is a function proxy, get its handler. Iterate if necessary.
256589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Object* fun = *object;
257589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  while (fun->IsJSFunctionProxy()) {
258589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    fun = JSFunctionProxy::cast(fun)->call_trap();
259589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
260589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (fun->IsJSFunction()) return Handle<Object>(fun);
261589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
262257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Objects created through the API can have an instance-call handler
263257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // that should be used when calling the object as a function.
264589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (fun->IsHeapObject() &&
265589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      HeapObject::cast(fun)->map()->has_instance_call_handler()) {
266257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Handle<JSFunction>(
267257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        isolate->global_context()->call_as_function_delegate());
268257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
269257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
270257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // If the Object doesn't have an instance-call handler we should
271257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // throw a non-callable exception.
272257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
273257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      "called_non_callable", i::HandleVector<i::Object>(&object, 1));
274257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  isolate->Throw(*error_obj);
275257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  *has_pending_exception = true;
276257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
277257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return isolate->factory()->undefined_value();
278257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
279257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
280257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::GetConstructorDelegate(Handle<Object> object) {
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(!object->IsJSFunction());
2838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Isolate* isolate = Isolate::Current();
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If you return a function from here, it will be called when an
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // attempt is made to call the given object as a constructor.
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
288589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // If object is a function proxies, get its handler. Iterate if necessary.
289589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Object* fun = *object;
290589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  while (fun->IsJSFunctionProxy()) {
291589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    fun = JSFunctionProxy::cast(fun)->call_trap();
292589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
293589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (fun->IsJSFunction()) return Handle<Object>(fun);
294589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Objects created through the API can have an instance-call handler
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // that should be used when calling the object as a function.
297589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (fun->IsHeapObject() &&
298589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      HeapObject::cast(fun)->map()->has_instance_call_handler()) {
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<JSFunction>(
3008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch        isolate->global_context()->call_as_constructor_delegate());
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  return isolate->factory()->undefined_value();
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
307257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochHandle<Object> Execution::TryGetConstructorDelegate(
308257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Handle<Object> object,
309257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    bool* has_pending_exception) {
310257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ASSERT(!object->IsJSFunction());
311257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Isolate* isolate = Isolate::Current();
312257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
313257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // If you return a function from here, it will be called when an
314257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // attempt is made to call the given object as a constructor.
315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
316589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // If object is a function proxies, get its handler. Iterate if necessary.
317589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Object* fun = *object;
318589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  while (fun->IsJSFunctionProxy()) {
319589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    fun = JSFunctionProxy::cast(fun)->call_trap();
320589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
321589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (fun->IsJSFunction()) return Handle<Object>(fun);
322589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
323257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Objects created through the API can have an instance-call handler
324257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // that should be used when calling the object as a function.
325589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (fun->IsHeapObject() &&
326589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      HeapObject::cast(fun)->map()->has_instance_call_handler()) {
327257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Handle<JSFunction>(
328257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        isolate->global_context()->call_as_constructor_delegate());
329257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
330257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
331257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // If the Object doesn't have an instance-call handler we should
332257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // throw a non-callable exception.
333257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
334257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      "called_non_callable", i::HandleVector<i::Object>(&object, 1));
335257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  isolate->Throw(*error_obj);
336257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  *has_pending_exception = true;
337257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
338257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return isolate->factory()->undefined_value();
339257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
340257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
341257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsStackOverflow() {
34344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return (thread_local_.jslimit_ != kInterruptLimit &&
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          thread_local_.climit_ != kInterruptLimit);
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::EnableInterrupts() {
35044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
3516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (has_pending_interrupts(access)) {
3526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    set_interrupt_limits(access);
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::SetStackLimit(uintptr_t limit) {
35844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // If the current limits are special (e.g. due to a pending interrupt) then
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // leave them alone.
361257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit);
362d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (thread_local_.jslimit_ == thread_local_.real_jslimit_) {
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    thread_local_.jslimit_ = jslimit;
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
365d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (thread_local_.climit_ == thread_local_.real_climit_) {
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    thread_local_.climit_ = limit;
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
368d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  thread_local_.real_climit_ = limit;
369d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  thread_local_.real_jslimit_ = jslimit;
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::DisableInterrupts() {
37444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  reset_limits(access);
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool StackGuard::ShouldPostponeInterrupts() {
3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ExecutionAccess access(isolate_);
3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return should_postpone_interrupts(access);
3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsInterrupted() {
38644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return (thread_local_.interrupt_flags_ & INTERRUPT) != 0;
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::Interrupt() {
39244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  thread_local_.interrupt_flags_ |= INTERRUPT;
3946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  set_interrupt_limits(access);
395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsPreempted() {
39944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return thread_local_.interrupt_flags_ & PREEMPT;
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::Preempt() {
40544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  thread_local_.interrupt_flags_ |= PREEMPT;
4076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  set_interrupt_limits(access);
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsTerminateExecution() {
41244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return (thread_local_.interrupt_flags_ & TERMINATE) != 0;
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::TerminateExecution() {
41844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  thread_local_.interrupt_flags_ |= TERMINATE;
4206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  set_interrupt_limits(access);
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
424b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochbool StackGuard::IsRuntimeProfilerTick() {
42544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return (thread_local_.interrupt_flags_ & RUNTIME_PROFILER_TICK) != 0;
427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
428b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
429b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid StackGuard::RequestRuntimeProfilerTick() {
431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Ignore calls if we're not optimizing or if we can't get the lock.
43244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (FLAG_opt && ExecutionAccess::TryLock(isolate_)) {
433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    thread_local_.interrupt_flags_ |= RUNTIME_PROFILER_TICK;
434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (thread_local_.postpone_interrupts_nesting_ == 0) {
435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
43644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate_->heap()->SetStackLimits();
437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
43844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ExecutionAccess::Unlock(isolate_);
439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
442b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool StackGuard::IsGCRequest() {
4443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ExecutionAccess access(isolate_);
4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return (thread_local_.interrupt_flags_ & GC_REQUEST) != 0;
4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
4473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid StackGuard::RequestGC() {
4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ExecutionAccess access(isolate_);
4513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  thread_local_.interrupt_flags_ |= GC_REQUEST;
4523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (thread_local_.postpone_interrupts_nesting_ == 0) {
4533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
4543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    isolate_->heap()->SetStackLimits();
4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsDebugBreak() {
46144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return thread_local_.interrupt_flags_ & DEBUGBREAK;
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::DebugBreak() {
46744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  thread_local_.interrupt_flags_ |= DEBUGBREAK;
4696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  set_interrupt_limits(access);
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsDebugCommand() {
47444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return thread_local_.interrupt_flags_ & DEBUGCOMMAND;
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::DebugCommand() {
480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (FLAG_debugger_auto_break) {
48144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ExecutionAccess access(isolate_);
482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
4836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    set_interrupt_limits(access);
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::Continue(InterruptFlag after_what) {
48944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what);
4916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    reset_limits(access);
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar* StackGuard::ArchiveStackGuard(char* to) {
49844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ThreadLocal blank;
50144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
50244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Set the stack limits using the old thread_local_.
50344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // TODO(isolates): This was the old semantics of constructing a ThreadLocal
50444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  //                 (as the ctor called SetStackLimits, which looked at the
50544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  //                 current thread_local_ from StackGuard)-- but is this
50644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  //                 really what was intended?
50744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate_->heap()->SetStackLimits();
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  thread_local_ = blank;
50944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return to + sizeof(ThreadLocal);
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar* StackGuard::RestoreStackGuard(char* from) {
51544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ExecutionAccess access(isolate_);
516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
51744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate_->heap()->SetStackLimits();
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return from + sizeof(ThreadLocal);
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::FreeThreadResources() {
5233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Isolate::PerIsolateThreadData* per_thread =
5243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      isolate_->FindOrAllocatePerThreadDataForThisThread();
5253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  per_thread->set_stack_limit(thread_local_.real_climit_);
526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::ThreadLocal::Clear() {
530d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  real_jslimit_ = kIllegalLimit;
531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  jslimit_ = kIllegalLimit;
532d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  real_climit_ = kIllegalLimit;
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  climit_ = kIllegalLimit;
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  nesting_ = 0;
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  postpone_interrupts_nesting_ = 0;
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  interrupt_flags_ = 0;
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
540257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochbool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
54144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool should_set_stack_limits = false;
542d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (real_climit_ == kIllegalLimit) {
543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Takes the address of the limit variable in order to find out where
544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // the top of stack is right now.
5451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    const uintptr_t kLimitSize = FLAG_stack_size * KB;
5463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize;
5473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize);
548257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
549257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
550d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    real_climit_ = limit;
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    climit_ = limit;
55244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    should_set_stack_limits = true;
553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  nesting_ = 0;
555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  postpone_interrupts_nesting_ = 0;
556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  interrupt_flags_ = 0;
55744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return should_set_stack_limits;
558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::ClearThread(const ExecutionAccess& lock) {
562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  thread_local_.Clear();
56344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate_->heap()->SetStackLimits();
564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::InitThread(const ExecutionAccess& lock) {
568257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (thread_local_.Initialize(isolate_)) isolate_->heap()->SetStackLimits();
569257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Isolate::PerIsolateThreadData* per_thread =
570257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      isolate_->FindOrAllocatePerThreadDataForThisThread();
571257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  uintptr_t stored_limit = per_thread->stack_limit();
572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // You should hold the ExecutionAccess lock when you call this.
57344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (stored_limit != 0) {
5743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    SetStackLimit(stored_limit);
575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- C a l l s   t o   n a t i v e s ---
580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define RETURN_NATIVE_CALL(name, args, has_pending_exception)           \
5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  do {                                                                  \
5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Isolate* isolate = Isolate::Current();                              \
5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<Object> argv[] = args;                                       \
5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT(has_pending_exception != NULL);                              \
5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return Call(isolate->name##_fun(),                                  \
5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                isolate->js_builtins_object(),                          \
5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                ARRAY_SIZE(argv), argv,                                 \
5893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                has_pending_exception);                                 \
590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } while (false)
591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToBoolean(Handle<Object> obj) {
594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // See the similar code in runtime.js:ToBoolean.
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsBoolean()) return obj;
596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool result = true;
597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsString()) {
598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = Handle<String>::cast(obj)->length() != 0;
599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (obj->IsNull() || obj->IsUndefined()) {
600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = false;
601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (obj->IsNumber()) {
602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    double value = obj->Number();
603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = !((value == 0) || isnan(value));
604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
60544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return Handle<Object>(HEAP->ToBoolean(result));
606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToNumber(Handle<Object> obj, bool* exc) {
6103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  RETURN_NATIVE_CALL(to_number, { obj }, exc);
611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToString(Handle<Object> obj, bool* exc) {
6153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  RETURN_NATIVE_CALL(to_string, { obj }, exc);
616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToDetailString(Handle<Object> obj, bool* exc) {
6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  RETURN_NATIVE_CALL(to_detail_string, { obj }, exc);
621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToObject(Handle<Object> obj, bool* exc) {
625589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (obj->IsSpecObject()) return obj;
6263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  RETURN_NATIVE_CALL(to_object, { obj }, exc);
627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToInteger(Handle<Object> obj, bool* exc) {
6313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  RETURN_NATIVE_CALL(to_integer, { obj }, exc);
632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToUint32(Handle<Object> obj, bool* exc) {
6363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  RETURN_NATIVE_CALL(to_uint32, { obj }, exc);
637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToInt32(Handle<Object> obj, bool* exc) {
6413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  RETURN_NATIVE_CALL(to_int32, { obj }, exc);
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::NewDate(double time, bool* exc) {
64644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<Object> time_obj = FACTORY->NewNumber(time);
6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  RETURN_NATIVE_CALL(create_date, { time_obj }, exc);
648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef RETURN_NATIVE_CALL
652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
654f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochHandle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern,
655f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch                                        Handle<String> flags,
656f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch                                        bool* exc) {
65744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<JSFunction> function = Handle<JSFunction>(
65844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      pattern->GetIsolate()->global_context()->regexp_function());
659f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  Handle<Object> re_obj = RegExpImpl::CreateRegExpLiteral(
66044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      function, pattern, flags, exc);
661f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  if (*exc) return Handle<JSRegExp>();
662f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return Handle<JSRegExp>::cast(re_obj);
663f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
664f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
665f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::CharAt(Handle<String> string, uint32_t index) {
6678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Isolate* isolate = string->GetIsolate();
6688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Factory* factory = isolate->factory();
6698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int int_index = static_cast<int>(index);
671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (int_index < 0 || int_index >= string->length()) {
6728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    return factory->undefined_value();
673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> char_at =
6768b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      GetProperty(isolate->js_builtins_object(),
6778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                  factory->char_at_symbol());
678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!char_at->IsJSFunction()) {
6798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    return factory->undefined_value();
680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool caught_exception;
6838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Handle<Object> index_object = factory->NewNumberFromInt(int_index);
6843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> index_arg[] = { index_object };
685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> result = TryCall(Handle<JSFunction>::cast(char_at),
686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  string,
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  ARRAY_SIZE(index_arg),
688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  index_arg,
689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  &caught_exception);
690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (caught_exception) {
6918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    return factory->undefined_value();
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<JSFunction> Execution::InstantiateFunction(
6983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<FunctionTemplateInfo> data,
6993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    bool* exc) {
7008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Isolate* isolate = data->GetIsolate();
701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Fast case: see if the function has already been instantiated
702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int serial_number = Smi::cast(data->serial_number())->value();
70344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object* elm =
7048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      isolate->global_context()->function_cache()->
70544f0eee88ff00398ff7f715fab053374d808c90dSteve Block          GetElementNoExceptionThrown(serial_number);
706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (elm->IsJSFunction()) return Handle<JSFunction>(JSFunction::cast(elm));
707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The function has not yet been instantiated in this context; do it.
7083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> args[] = { data };
7093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> result = Call(isolate->instantiate_fun(),
7103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               isolate->js_builtins_object(),
7113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               ARRAY_SIZE(args),
7123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               args,
7133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               exc);
714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (*exc) return Handle<JSFunction>::null();
715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Handle<JSFunction>::cast(result);
716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<JSObject> Execution::InstantiateObject(Handle<ObjectTemplateInfo> data,
720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                              bool* exc) {
7218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Isolate* isolate = data->GetIsolate();
722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (data->property_list()->IsUndefined() &&
723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      !data->constructor()->IsUndefined()) {
724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Initialization to make gcc happy.
725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object* result = NULL;
726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    {
7278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      HandleScope scope(isolate);
728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<FunctionTemplateInfo> cons_template =
729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          Handle<FunctionTemplateInfo>(
730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block              FunctionTemplateInfo::cast(data->constructor()));
731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<JSFunction> cons = InstantiateFunction(cons_template, exc);
732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (*exc) return Handle<JSObject>::null();
733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<Object> value = New(cons, 0, NULL, exc);
734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (*exc) return Handle<JSObject>::null();
735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = *value;
736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(!*exc);
738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<JSObject>(JSObject::cast(result));
739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
7403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<Object> args[] = { data };
7413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Handle<Object> result = Call(isolate->instantiate_fun(),
7423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 isolate->js_builtins_object(),
7433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 ARRAY_SIZE(args),
7443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 args,
7453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 exc);
746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (*exc) return Handle<JSObject>::null();
747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<JSObject>::cast(result);
748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Execution::ConfigureInstance(Handle<Object> instance,
753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Handle<Object> instance_template,
754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  bool* exc) {
7558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Isolate* isolate = Isolate::Current();
7563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> args[] = { instance, instance_template };
7578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Execution::Call(isolate->configure_instance_fun(),
7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  isolate->js_builtins_object(),
7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  ARRAY_SIZE(args),
7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  args,
7613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  exc);
762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<String> Execution::GetStackTraceLine(Handle<Object> recv,
766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            Handle<JSFunction> fun,
767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            Handle<Object> pos,
768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            Handle<Object> is_global) {
7698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Isolate* isolate = fun->GetIsolate();
7703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> args[] = { recv, fun, pos, is_global };
7713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool caught_exception;
7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<Object> result = TryCall(isolate->get_stack_trace_line_fun(),
7733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  isolate->js_builtins_object(),
7743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  ARRAY_SIZE(args),
7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  args,
7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  &caught_exception);
7778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  if (caught_exception || !result->IsString()) {
7788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      return isolate->factory()->empty_symbol();
7798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
7808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Handle<String>::cast(result);
782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic Object* RuntimePreempt() {
78644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = Isolate::Current();
78744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Clear the preempt request flag.
78944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->stack_guard()->Continue(PREEMPT);
790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ContextSwitcher::PreemptionReceived();
792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
79444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (isolate->debug()->InDebugger()) {
795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If currently in the debugger don't do any actual preemption but record
796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // that preemption occoured while in the debugger.
79744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate->debug()->PreemptionWhileInDebugger();
798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Perform preemption.
800257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Thread::YieldCPU();
802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else
80444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  { // NOLINT
80544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Perform preemption.
806257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
80744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Thread::YieldCPU();
80844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
81144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return isolate->heap()->undefined_value();
812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* Execution::DebugBreakHelper() {
81744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = Isolate::Current();
81844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Just continue if breaks are disabled.
82044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (isolate->debug()->disable_break()) {
82144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return isolate->heap()->undefined_value();
822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
824e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Ignore debug break during bootstrapping.
82544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (isolate->bootstrapper()->IsActive()) {
82644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return isolate->heap()->undefined_value();
827e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
828e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
8293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StackLimitCheck check(isolate);
8303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (check.HasOverflowed()) {
8313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return isolate->heap()->undefined_value();
8323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
8333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {
8358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    JavaScriptFrameIterator it(isolate);
836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(!it.done());
837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object* fun = it.frame()->function();
838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (fun && fun->IsJSFunction()) {
839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Don't stop in builtin functions.
840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (JSFunction::cast(fun)->IsBuiltin()) {
84144f0eee88ff00398ff7f715fab053374d808c90dSteve Block        return isolate->heap()->undefined_value();
842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      GlobalObject* global = JSFunction::cast(fun)->context()->global();
844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Don't stop in debugger functions.
84544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      if (isolate->debug()->IsDebugGlobal(global)) {
84644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        return isolate->heap()->undefined_value();
847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Collect the break state before clearing the flags.
852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool debug_command_only =
85344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate->stack_guard()->IsDebugCommand() &&
85444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      !isolate->stack_guard()->IsDebugBreak();
855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
856e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Clear the debug break request flag.
85744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->stack_guard()->Continue(DEBUGBREAK);
858e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
8593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ProcessDebugMessages(debug_command_only);
860e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
861e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Return to continue execution.
86244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return isolate->heap()->undefined_value();
863e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
864e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
8653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Execution::ProcessDebugMessages(bool debug_command_only) {
8668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Isolate* isolate = Isolate::Current();
867e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Clear the debug command request flag.
8688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  isolate->stack_guard()->Continue(DEBUGCOMMAND);
869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  StackLimitCheck check(isolate);
8713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (check.HasOverflowed()) {
8723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return;
8733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
8743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  HandleScope scope(isolate);
876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Enter the debugger. Just continue if we fail to enter the debugger.
877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EnterDebugger debugger;
878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (debugger.FailedToEnter()) {
879e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return;
880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Notify the debug event listeners. Indicate auto continue if the break was
883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // a debug command break.
8848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  isolate->debugger()->OnDebugBreak(isolate->factory()->undefined_value(),
8858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                                    debug_command_only);
886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
887e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
888e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8913ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) {
89244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  StackGuard* stack_guard = isolate->stack_guard();
8933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (stack_guard->ShouldPostponeInterrupts()) {
8943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return isolate->heap()->undefined_value();
8953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
8963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (stack_guard->IsGCRequest()) {
8983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
8993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                       "StackGuard GC request");
9003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    stack_guard->Continue(GC_REQUEST);
9013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
9023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
90344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->counters()->stack_interrupts()->Increment();
9043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // If FLAG_count_based_interrupts, every interrupt is a profiler interrupt.
9053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (FLAG_count_based_interrupts ||
9063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      stack_guard->IsRuntimeProfilerTick()) {
90744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate->counters()->runtime_profiler_ticks()->Increment();
90844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    stack_guard->Continue(RUNTIME_PROFILER_TICK);
90944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate->runtime_profiler()->OptimizeNow();
910b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
91244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) {
913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    DebugBreakHelper();
914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
91644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (stack_guard->IsPreempted()) RuntimePreempt();
91744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (stack_guard->IsTerminateExecution()) {
91844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    stack_guard->Continue(TERMINATE);
91944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return isolate->TerminateExecution();
920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
92144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (stack_guard->IsInterrupted()) {
92244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    stack_guard->Continue(INTERRUPT);
92344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return isolate->StackOverflow();
924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
92544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return isolate->heap()->undefined_value();
926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
930