12f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved.
22f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
32f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org// found in the LICENSE file.
42f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org
5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/execution.h"
62f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org
7196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/bootstrapper.h"
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h"
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/deoptimizer.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/isolate-inl.h"
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/vm-state-inl.h"
1237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
1371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
1471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
16ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgStackGuard::StackGuard()
17ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    : isolate_(NULL) {
18ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
19ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
20ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
21ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid StackGuard::set_interrupt_limits(const ExecutionAccess& lock) {
22e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(isolate_ != NULL);
23ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  thread_local_.jslimit_ = kInterruptLimit;
24ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  thread_local_.climit_ = kInterruptLimit;
25ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->heap()->SetStackLimits();
26ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
27ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
28ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
29ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid StackGuard::reset_limits(const ExecutionAccess& lock) {
30e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(isolate_ != NULL);
31ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  thread_local_.jslimit_ = thread_local_.real_jslimit_;
32ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  thread_local_.climit_ = thread_local_.real_climit_;
33ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->heap()->SetStackLimits();
34ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
35ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
36ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
372ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMUST_USE_RESULT static MaybeHandle<Object> Invoke(
382ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    bool is_construct,
392ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<JSFunction> function,
402ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<Object> receiver,
412ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    int argc,
422ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<Object> args[]) {
43a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  Isolate* isolate = function->GetIsolate();
44ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
4543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Entering JavaScript.
46ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org  VMState<JS> state(isolate);
475697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org  CHECK(AllowJavascriptExecution::IsAllowed(isolate));
485697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org  if (!ThrowOnJavascriptExecution::IsAllowed(isolate)) {
495697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org    isolate->ThrowIllegalOperation();
505697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org    isolate->ReportPendingMessages();
512ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    return MaybeHandle<Object>();
525697144afb43181fed170b81c194fe1cc0fce3b6machenbach@chromium.org  }
5343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Placeholder for return value.
55a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  Object* value = NULL;
5643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
57a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  typedef Object* (*JSEntryFunction)(byte* entry,
58a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org                                     Object* function,
59a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org                                     Object* receiver,
60a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org                                     int argc,
61a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org                                     Object*** args);
6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
63a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  Handle<Code> code = is_construct
64a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org      ? isolate->factory()->js_construct_entry_code()
65a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org      : isolate->factory()->js_entry_code();
6643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
678d96e6d90778041ec5681fece475f7a0c22650ddsgjesse@chromium.org  // Convert calls on global objects to be calls on the global
688d96e6d90778041ec5681fece475f7a0c22650ddsgjesse@chromium.org  // receiver instead to avoid having a 'this' pointer which refers
698d96e6d90778041ec5681fece475f7a0c22650ddsgjesse@chromium.org  // directly to a global object.
708d96e6d90778041ec5681fece475f7a0c22650ddsgjesse@chromium.org  if (receiver->IsGlobalObject()) {
7158a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org    receiver = handle(Handle<GlobalObject>::cast(receiver)->global_proxy());
728d96e6d90778041ec5681fece475f7a0c22650ddsgjesse@chromium.org  }
738d96e6d90778041ec5681fece475f7a0c22650ddsgjesse@chromium.org
747b9eafd3a796ae40fdd9b130bb931c71c8a622d2kasperl@chromium.org  // Make sure that the global object of the context we're about to
757b9eafd3a796ae40fdd9b130bb931c71c8a622d2kasperl@chromium.org  // make the current one is indeed a global object.
76e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(function->context()->global_object()->IsGlobalObject());
777b9eafd3a796ae40fdd9b130bb931c71c8a622d2kasperl@chromium.org
7844510671e908d0efc639513d81efcd81e7f14240kasper.lund  {
7944510671e908d0efc639513d81efcd81e7f14240kasper.lund    // Save and restore context around invocation and block the
8043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // allocation of handles without explicit handle scopes.
81ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    SaveContext save(isolate);
8279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    SealHandleScope shs(isolate);
83a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
8443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // Call the function through the right JS entry stub.
86a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    byte* function_entry = function->code()->entry();
87a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    JSFunction* func = *function;
88a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    Object* recv = *receiver;
89a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    Object*** argv = reinterpret_cast<Object***>(args);
90a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    value =
91a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org        CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
9243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
94c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org#ifdef VERIFY_HEAP
95a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  value->ObjectVerify();
9643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif
9743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Update the pending exception flag and return the value.
992ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  bool has_exception = value->IsException();
100e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(has_exception == isolate->has_pending_exception());
1012ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (has_exception) {
102ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate->ReportPendingMessages();
10381cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org    // Reset stepping state when script exits with uncaught exception.
104d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    if (isolate->debug()->is_active()) {
10581cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org      isolate->debug()->ClearStepping();
10681cac2ba397bd57f2967c8b4b677bef08a869991danno@chromium.org    }
1072ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    return MaybeHandle<Object>();
1088bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  } else {
109ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    isolate->clear_pending_message();
11043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
11143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
112b67f96038c787a6bd6a835e6c436c82e1b245486machenbach@chromium.org  return Handle<Object>(value, isolate);
11343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
11443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1162ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<Object> Execution::Call(Isolate* isolate,
1172ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                    Handle<Object> callable,
1182ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                    Handle<Object> receiver,
1192ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                    int argc,
1202ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                    Handle<Object> argv[],
1212ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                    bool convert_receiver) {
122c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  if (!callable->IsJSFunction()) {
1232ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    ASSIGN_RETURN_ON_EXCEPTION(
1242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        isolate, callable, TryGetFunctionDelegate(isolate, callable), Object);
125c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  }
126c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
12734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
128486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  // In sloppy mode, convert receiver.
12934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (convert_receiver && !receiver->IsJSReceiver() &&
130486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      !func->shared()->native() &&
131486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      func->shared()->strict_mode() == SLOPPY) {
13234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    if (receiver->IsUndefined() || receiver->IsNull()) {
13358a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org      receiver = handle(func->global_proxy());
134e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(!receiver->IsJSBuiltinsObject());
13534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    } else {
1362ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      ASSIGN_RETURN_ON_EXCEPTION(
1372ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org          isolate, receiver, ToObject(isolate, receiver), Object);
13834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    }
13934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  }
14034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
1412ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return Invoke(false, func, receiver, argc, argv);
14243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
14343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<Object> Execution::New(Handle<JSFunction> func,
1462ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                   int argc,
1472ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                   Handle<Object> argv[]) {
14858a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org  return Invoke(true, func, handle(func->global_proxy()), argc, argv);
14943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
15043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
15143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1522ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<Object> Execution::TryCall(Handle<JSFunction> func,
153ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                       Handle<Object> receiver, int argc,
1542ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                       Handle<Object> args[],
155ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                       MaybeHandle<Object>* exception_out) {
156ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  bool is_termination = false;
157ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  Isolate* isolate = func->GetIsolate();
158ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  MaybeHandle<Object> maybe_result;
159ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  if (exception_out != NULL) *exception_out = MaybeHandle<Object>();
16043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Enter a try-block while executing the JavaScript code. To avoid
1619258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // duplicate error printing it must be non-verbose.  Also, to avoid
1629258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // creating message objects during stack overflow we shouldn't
1639258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org  // capture messages.
164ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  {
165ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    v8::TryCatch catcher;
166ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    catcher.SetVerbose(false);
167ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    catcher.SetCaptureMessage(false);
168ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org
169ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    maybe_result = Invoke(false, func, receiver, argc, args);
170ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org
171ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    if (maybe_result.is_null()) {
172ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      DCHECK(catcher.HasCaught());
173ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      DCHECK(isolate->has_pending_exception());
174ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      DCHECK(isolate->external_caught_exception());
175ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      if (exception_out != NULL) {
176ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org        if (isolate->pending_exception() ==
177ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org            isolate->heap()->termination_exception()) {
178ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org          is_termination = true;
179ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org        } else {
180ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org          *exception_out = v8::Utils::OpenHandle(*catcher.Exception());
181ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org        }
1822ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      }
183ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      isolate->OptionalRescheduleException(true);
18418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org    }
18543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
186ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    DCHECK(!isolate->has_pending_exception());
187ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    DCHECK(!isolate->external_caught_exception());
188ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  }
189ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  if (is_termination) isolate->TerminateExecution();
1902ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return maybe_result;
19143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
19243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
19343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
194e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.orgHandle<Object> Execution::GetFunctionDelegate(Isolate* isolate,
195e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org                                              Handle<Object> object) {
196e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->IsJSFunction());
197c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Factory* factory = isolate->factory();
19843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
19943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If you return a function from here, it will be called when an
20043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // attempt is made to call the given object as a function.
20143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
20234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // If object is a function proxy, get its handler. Iterate if necessary.
20334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  Object* fun = *object;
20434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  while (fun->IsJSFunctionProxy()) {
20534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    fun = JSFunctionProxy::cast(fun)->call_trap();
20634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  }
20709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
20834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
20943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Objects created through the API can have an instance-call handler
21043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // that should be used when calling the object as a function.
21134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (fun->IsHeapObject() &&
21234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      HeapObject::cast(fun)->map()->has_instance_call_handler()) {
21343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    return Handle<JSFunction>(
21446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        isolate->native_context()->call_as_function_delegate());
21543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
21643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
217c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  return factory->undefined_value();
21843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
21943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
22043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2212ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<Object> Execution::TryGetFunctionDelegate(Isolate* isolate,
2222ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                                      Handle<Object> object) {
223e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->IsJSFunction());
2241c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
22534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // If object is a function proxy, get its handler. Iterate if necessary.
22634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  Object* fun = *object;
22734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  while (fun->IsJSFunctionProxy()) {
22834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    fun = JSFunctionProxy::cast(fun)->call_trap();
22934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  }
23009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
23134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
2321c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  // Objects created through the API can have an instance-call handler
2331c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  // that should be used when calling the object as a function.
23434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (fun->IsHeapObject() &&
23534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      HeapObject::cast(fun)->map()->has_instance_call_handler()) {
2361c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org    return Handle<JSFunction>(
23746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        isolate->native_context()->call_as_function_delegate());
2381c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  }
2391c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
2401c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  // If the Object doesn't have an instance-call handler we should
2411c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  // throw a non-callable exception.
242ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  THROW_NEW_ERROR(isolate, NewTypeError("called_non_callable",
243ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                        i::HandleVector<i::Object>(&object, 1)),
244ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                  Object);
2451c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org}
2461c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
2471c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
248e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.orgHandle<Object> Execution::GetConstructorDelegate(Isolate* isolate,
249e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org                                                 Handle<Object> object) {
250e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->IsJSFunction());
25105521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org
25205521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org  // If you return a function from here, it will be called when an
25305521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org  // attempt is made to call the given object as a constructor.
25405521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org
25534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // If object is a function proxies, get its handler. Iterate if necessary.
25634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  Object* fun = *object;
25734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  while (fun->IsJSFunctionProxy()) {
25834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    fun = JSFunctionProxy::cast(fun)->call_trap();
25934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  }
26009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
26134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
26205521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org  // Objects created through the API can have an instance-call handler
26305521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org  // that should be used when calling the object as a function.
26434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (fun->IsHeapObject() &&
26534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      HeapObject::cast(fun)->map()->has_instance_call_handler()) {
26605521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org    return Handle<JSFunction>(
26746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        isolate->native_context()->call_as_constructor_delegate());
26805521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org  }
26905521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org
270c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  return isolate->factory()->undefined_value();
27105521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org}
27205521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org
27305521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org
2742ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<Object> Execution::TryGetConstructorDelegate(
2752ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Isolate* isolate, Handle<Object> object) {
276e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!object->IsJSFunction());
2771c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
2781c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  // If you return a function from here, it will be called when an
2791c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  // attempt is made to call the given object as a constructor.
2801c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
28134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // If object is a function proxies, get its handler. Iterate if necessary.
28234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  Object* fun = *object;
28334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  while (fun->IsJSFunctionProxy()) {
28434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org    fun = JSFunctionProxy::cast(fun)->call_trap();
28534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  }
28609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  if (fun->IsJSFunction()) return Handle<Object>(fun, isolate);
28734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org
2881c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  // Objects created through the API can have an instance-call handler
2891c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  // that should be used when calling the object as a function.
29034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (fun->IsHeapObject() &&
29134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      HeapObject::cast(fun)->map()->has_instance_call_handler()) {
2921c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org    return Handle<JSFunction>(
29346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        isolate->native_context()->call_as_constructor_delegate());
2941c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  }
2951c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
2961c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  // If the Object doesn't have an instance-call handler we should
2971c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  // throw a non-callable exception.
298ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  THROW_NEW_ERROR(isolate, NewTypeError("called_non_callable",
299ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                        i::HandleVector<i::Object>(&object, 1)),
300ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                  Object);
3011c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org}
3021c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
3031c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
30443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid StackGuard::EnableInterrupts() {
305ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ExecutionAccess access(isolate_);
306b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  if (has_pending_interrupts(access)) {
307b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org    set_interrupt_limits(access);
30843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
30943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
31043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid StackGuard::SetStackLimit(uintptr_t limit) {
313ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ExecutionAccess access(isolate_);
3142efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // If the current limits are special (e.g. due to a pending interrupt) then
31543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // leave them alone.
3161c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit);
317c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  if (thread_local_.jslimit_ == thread_local_.real_jslimit_) {
318c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    thread_local_.jslimit_ = jslimit;
31943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
320c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  if (thread_local_.climit_ == thread_local_.real_climit_) {
32143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    thread_local_.climit_ = limit;
32243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
323c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  thread_local_.real_climit_ = limit;
324c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  thread_local_.real_jslimit_ = jslimit;
32543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
32643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
32843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid StackGuard::DisableInterrupts() {
329ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ExecutionAccess access(isolate_);
33043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  reset_limits(access);
33143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
33243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
33343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
334d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgvoid StackGuard::PushPostponeInterruptsScope(PostponeInterruptsScope* scope) {
335bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com  ExecutionAccess access(isolate_);
336d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Intercept already requested interrupts.
337d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  int intercepted = thread_local_.interrupt_flags_ & scope->intercept_mask_;
338d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  scope->intercepted_flags_ = intercepted;
339d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  thread_local_.interrupt_flags_ &= ~intercepted;
340d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  if (!has_pending_interrupts(access)) reset_limits(access);
341d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Add scope to the chain.
342d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  scope->prev_ = thread_local_.postpone_interrupts_;
343d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  thread_local_.postpone_interrupts_ = scope;
344bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com}
345bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
346bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com
347d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgvoid StackGuard::PopPostponeInterruptsScope() {
348ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ExecutionAccess access(isolate_);
349d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  PostponeInterruptsScope* top = thread_local_.postpone_interrupts_;
350d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Make intercepted interrupts active.
351e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK((thread_local_.interrupt_flags_ & top->intercept_mask_) == 0);
352d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  thread_local_.interrupt_flags_ |= top->intercepted_flags_;
353d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  if (has_pending_interrupts(access)) set_interrupt_limits(access);
354d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Remove scope from chain.
355d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  thread_local_.postpone_interrupts_ = top->prev_;
356d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org}
357d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
358d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
359d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgbool StackGuard::CheckInterrupt(InterruptFlag flag) {
360d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  ExecutionAccess access(isolate_);
361d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  return thread_local_.interrupt_flags_ & flag;
362d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org}
363d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
364d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
365d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgvoid StackGuard::RequestInterrupt(InterruptFlag flag) {
366d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  ExecutionAccess access(isolate_);
367d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Check the chain of PostponeInterruptsScopes for interception.
368d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  if (thread_local_.postpone_interrupts_ &&
369d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org      thread_local_.postpone_interrupts_->Intercept(flag)) {
370d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    return;
371d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  }
372d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
373d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Not intercepted.  Set as active interrupt flag.
374d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  thread_local_.interrupt_flags_ |= flag;
375b6e43bb9b1cd7673592be9dfd0a036fe8dab4dcdwhesse@chromium.org  set_interrupt_limits(access);
37643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
37743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
37843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
379d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgvoid StackGuard::ClearInterrupt(InterruptFlag flag) {
380ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ExecutionAccess access(isolate_);
381d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Clear the interrupt flag from the chain of PostponeInterruptsScopes.
382d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  for (PostponeInterruptsScope* current = thread_local_.postpone_interrupts_;
383d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org       current != NULL;
384d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org       current = current->prev_) {
385d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    current->intercepted_flags_ &= ~flag;
38643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
387d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
388d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Clear the interrupt flag from the active interrupt flags.
389d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  thread_local_.interrupt_flags_ &= ~flag;
390d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  if (!has_pending_interrupts(access)) reset_limits(access);
39143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
39243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
39343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3948d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.orgbool StackGuard::CheckAndClearInterrupt(InterruptFlag flag) {
3958d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  ExecutionAccess access(isolate_);
396d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  bool result = (thread_local_.interrupt_flags_ & flag);
397d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  thread_local_.interrupt_flags_ &= ~flag;
398d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  if (!has_pending_interrupts(access)) reset_limits(access);
3993c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  return result;
400ea9b8ba58955b7efcc3e1550dd33a44fb4530136hpayer@chromium.org}
401ea9b8ba58955b7efcc3e1550dd33a44fb4530136hpayer@chromium.org
402ea9b8ba58955b7efcc3e1550dd33a44fb4530136hpayer@chromium.org
40343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenchar* StackGuard::ArchiveStackGuard(char* to) {
404ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ExecutionAccess access(isolate_);
405d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
40643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  ThreadLocal blank;
407ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
408ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Set the stack limits using the old thread_local_.
409ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // TODO(isolates): This was the old semantics of constructing a ThreadLocal
410ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  //                 (as the ctor called SetStackLimits, which looked at the
411ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  //                 current thread_local_ from StackGuard)-- but is this
412ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  //                 really what was intended?
413ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->heap()->SetStackLimits();
41443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  thread_local_ = blank;
415ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
41643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return to + sizeof(ThreadLocal);
41743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
41843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
42043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenchar* StackGuard::RestoreStackGuard(char* from) {
421ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  ExecutionAccess access(isolate_);
422d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
423ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->heap()->SetStackLimits();
42443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return from + sizeof(ThreadLocal);
42543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
42643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
42743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
428c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.orgvoid StackGuard::FreeThreadResources() {
429ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  Isolate::PerIsolateThreadData* per_thread =
430ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org      isolate_->FindOrAllocatePerThreadDataForThisThread();
431ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  per_thread->set_stack_limit(thread_local_.real_climit_);
432c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}
433c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
434c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
435c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.orgvoid StackGuard::ThreadLocal::Clear() {
436c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  real_jslimit_ = kIllegalLimit;
437c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  jslimit_ = kIllegalLimit;
438c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  real_climit_ = kIllegalLimit;
439c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  climit_ = kIllegalLimit;
440d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  postpone_interrupts_ = NULL;
441c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  interrupt_flags_ = 0;
442c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}
443c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
444c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
4451c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.orgbool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
446ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool should_set_stack_limits = false;
447c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  if (real_climit_ == kIllegalLimit) {
448496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org    const uintptr_t kLimitSize = FLAG_stack_size * KB;
449e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(GetCurrentStackPosition() > kLimitSize);
450d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org    uintptr_t limit = GetCurrentStackPosition() - kLimitSize;
4511c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org    real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
4521c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org    jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
453c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    real_climit_ = limit;
454c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org    climit_ = limit;
455ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    should_set_stack_limits = true;
456c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  }
457d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  postpone_interrupts_ = NULL;
458c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  interrupt_flags_ = 0;
459ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return should_set_stack_limits;
460c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}
461c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
462c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
463c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.orgvoid StackGuard::ClearThread(const ExecutionAccess& lock) {
464c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  thread_local_.Clear();
465ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  isolate_->heap()->SetStackLimits();
466c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}
467c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
468c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
469c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.orgvoid StackGuard::InitThread(const ExecutionAccess& lock) {
4701c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  if (thread_local_.Initialize(isolate_)) isolate_->heap()->SetStackLimits();
4711c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  Isolate::PerIsolateThreadData* per_thread =
4721c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org      isolate_->FindOrAllocatePerThreadDataForThisThread();
4731c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  uintptr_t stored_limit = per_thread->stack_limit();
474c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // You should hold the ExecutionAccess lock when you call this.
475ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (stored_limit != 0) {
476ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    SetStackLimit(stored_limit);
477c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  }
478c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org}
479c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
480c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
48143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// --- C a l l s   t o   n a t i v e s ---
48243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4832ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org#define RETURN_NATIVE_CALL(name, args)                                  \
484a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  do {                                                                  \
485a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    Handle<Object> argv[] = args;                                       \
4862c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org    return Call(isolate,                                                \
4872c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org                isolate->name##_fun(),                                  \
488a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org                isolate->js_builtins_object(),                          \
489fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org                arraysize(argv), argv);                                \
49043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } while (false)
49143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
49243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4932ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<Object> Execution::ToNumber(
4942ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Isolate* isolate, Handle<Object> obj) {
4952ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  RETURN_NATIVE_CALL(to_number, { obj });
49643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
49743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
49843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
4992ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<Object> Execution::ToString(
5002ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Isolate* isolate, Handle<Object> obj) {
5012ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  RETURN_NATIVE_CALL(to_string, { obj });
50243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
50343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
50443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5052ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<Object> Execution::ToDetailString(
5062ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Isolate* isolate, Handle<Object> obj) {
5072ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  RETURN_NATIVE_CALL(to_detail_string, { obj });
50843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
50943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
51043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5112ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<Object> Execution::ToObject(
5122ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Isolate* isolate, Handle<Object> obj) {
51334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  if (obj->IsSpecObject()) return obj;
5142ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  RETURN_NATIVE_CALL(to_object, { obj });
51543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
51643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
51743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5182ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<Object> Execution::ToInteger(
5192ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Isolate* isolate, Handle<Object> obj) {
5202ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  RETURN_NATIVE_CALL(to_integer, { obj });
52143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
52243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<Object> Execution::ToUint32(
5252ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Isolate* isolate, Handle<Object> obj) {
5262ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  RETURN_NATIVE_CALL(to_uint32, { obj });
52743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
52843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
52943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5302ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<Object> Execution::ToInt32(
5312ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Isolate* isolate, Handle<Object> obj) {
5322ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  RETURN_NATIVE_CALL(to_int32, { obj });
53343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
53443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
53543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5362ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<Object> Execution::NewDate(Isolate* isolate, double time) {
537d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Handle<Object> time_obj = isolate->factory()->NewNumber(time);
5382ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  RETURN_NATIVE_CALL(create_date, { time_obj });
53943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
54043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
54143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
54243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef RETURN_NATIVE_CALL
54343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
54443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern,
5462ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                                             Handle<String> flags) {
5472ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Isolate* isolate = pattern->GetIsolate();
548ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<JSFunction> function = Handle<JSFunction>(
5492ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate->native_context()->regexp_function());
5502ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> re_obj;
5512ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
5522ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, re_obj,
5532ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      RegExpImpl::CreateRegExpLiteral(function, pattern, flags),
5542ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      JSRegExp);
555b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org  return Handle<JSRegExp>::cast(re_obj);
556b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org}
557b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org
558b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.org
55943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<Object> Execution::CharAt(Handle<String> string, uint32_t index) {
560c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Isolate* isolate = string->GetIsolate();
561c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Factory* factory = isolate->factory();
562c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
56343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int int_index = static_cast<int>(index);
56443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (int_index < 0 || int_index >= string->length()) {
565c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    return factory->undefined_value();
56643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
56743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5682f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org  Handle<Object> char_at = Object::GetProperty(
5692ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate->js_builtins_object(),
5702ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      factory->char_at_string()).ToHandleChecked();
57143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!char_at->IsJSFunction()) {
572c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    return factory->undefined_value();
57343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
57443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
575c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Handle<Object> index_object = factory->NewNumberFromInt(int_index);
576a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  Handle<Object> index_arg[] = { index_object };
5772ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> result;
578e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  if (!TryCall(Handle<JSFunction>::cast(char_at),
579e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org               string,
580fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org               arraysize(index_arg),
581e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org               index_arg).ToHandle(&result)) {
582e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org    return factory->undefined_value();
583e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  }
58443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
58543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
58643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
58743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5882ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<JSFunction> Execution::InstantiateFunction(
5892ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<FunctionTemplateInfo> data) {
590c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Isolate* isolate = data->GetIsolate();
591639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  if (!data->do_not_cache()) {
592639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    // Fast case: see if the function has already been instantiated
593639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org    int serial_number = Smi::cast(data->serial_number())->value();
5947010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org    Handle<JSObject> cache(isolate->native_context()->function_cache());
5957010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org    Handle<Object> elm =
5962ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        Object::GetElement(isolate, cache, serial_number).ToHandleChecked();
5977010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org    if (elm->IsJSFunction()) return Handle<JSFunction>::cast(elm);
598639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  }
59943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // The function has not yet been instantiated in this context; do it.
600a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  Handle<Object> args[] = { data };
6012ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> result;
6022ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_ON_EXCEPTION(
6032ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, result,
6042ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Call(isolate,
6052ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org           isolate->instantiate_fun(),
6062ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org           isolate->js_builtins_object(),
607fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org           arraysize(args),
6082ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org           args),
6092ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      JSFunction);
61043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Handle<JSFunction>::cast(result);
61143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
61243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
61343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6142ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<JSObject> Execution::InstantiateObject(
6152ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<ObjectTemplateInfo> data) {
616c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Isolate* isolate = data->GetIsolate();
6172ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> result;
61843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (data->property_list()->IsUndefined() &&
61943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      !data->constructor()->IsUndefined()) {
6202ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<FunctionTemplateInfo> cons_template =
6212ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        Handle<FunctionTemplateInfo>(
6222ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org            FunctionTemplateInfo::cast(data->constructor()));
6232ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<JSFunction> cons;
6242ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    ASSIGN_RETURN_ON_EXCEPTION(
6252ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        isolate, cons, InstantiateFunction(cons_template), JSObject);
6262ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    ASSIGN_RETURN_ON_EXCEPTION(isolate, result, New(cons, 0, NULL), JSObject);
62743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  } else {
628a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    Handle<Object> args[] = { data };
6292ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    ASSIGN_RETURN_ON_EXCEPTION(
6302ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        isolate, result,
6312ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        Call(isolate,
6322ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org             isolate->instantiate_fun(),
6332ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org             isolate->js_builtins_object(),
634fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org             arraysize(args),
6352ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org             args),
6362ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        JSObject);
63743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
6382ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return Handle<JSObject>::cast(result);
63943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
64043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
64143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6422ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgMaybeHandle<Object> Execution::ConfigureInstance(
6432ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Isolate* isolate,
6442ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<Object> instance,
6452ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    Handle<Object> instance_template) {
646a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  Handle<Object> args[] = { instance, instance_template };
6472ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  return Execution::Call(isolate,
6482ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                         isolate->configure_instance_fun(),
6492ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                         isolate->js_builtins_object(),
650fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org                         arraysize(args),
6512ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                         args);
65243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
65343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
65443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
65543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenHandle<String> Execution::GetStackTraceLine(Handle<Object> recv,
65643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                            Handle<JSFunction> fun,
65743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                            Handle<Object> pos,
65843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                            Handle<Object> is_global) {
659c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Isolate* isolate = fun->GetIsolate();
660a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  Handle<Object> args[] = { recv, fun, pos, is_global };
6612ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  MaybeHandle<Object> maybe_result =
6622ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      TryCall(isolate->get_stack_trace_line_fun(),
6632ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org              isolate->js_builtins_object(),
664fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org              arraysize(args),
6652ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org              args);
6662ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> result;
6672ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  if (!maybe_result.ToHandle(&result) || !result->IsString()) {
6682ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    return isolate->factory()->empty_string();
669c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
670c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
67143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return Handle<String>::cast(result);
67243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
67343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
67443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6753c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.orgObject* StackGuard::HandleInterrupts() {
6768d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (CheckAndClearInterrupt(GC_REQUEST)) {
6778d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt");
6788d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
6793c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org
6808d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (CheckDebugBreak() || CheckDebugCommand()) {
6818d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    isolate_->debug()->HandleDebugBreak();
6828d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
6836a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
6848d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (CheckAndClearInterrupt(TERMINATE_EXECUTION)) {
6858d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    return isolate_->TerminateExecution();
6868d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
6873c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org
6888d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (CheckAndClearInterrupt(DEOPT_MARKED_ALLOCATION_SITES)) {
6898d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    isolate_->heap()->DeoptMarkedAllocationSites();
6908d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
6916a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
6928d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (CheckAndClearInterrupt(INSTALL_CODE)) {
693e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(isolate_->concurrent_recompilation_enabled());
6948d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    isolate_->optimizing_compiler_thread()->InstallOptimizedFunctions();
6955c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  }
6963c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org
6978d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  if (CheckAndClearInterrupt(API_INTERRUPT)) {
6986a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    // Callback must be invoked outside of ExecusionAccess lock.
6996a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org    isolate_->InvokeApiInterruptCallback();
7004a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  }
7013c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org
7028d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  isolate_->counters()->stack_interrupts()->Increment();
7038d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  isolate_->counters()->runtime_profiler_ticks()->Increment();
7048d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  isolate_->runtime_profiler()->OptimizeNow();
7058d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
7063c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  return isolate_->heap()->undefined_value();
70737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com}
70837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com
70943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
710