execution.cc 29.9 KB
Newer Older
1
// Copyright 2012 the V8 project authors. All rights reserved.
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <stdlib.h>

#include "v8.h"

#include "api.h"
33
#include "bootstrapper.h"
34
#include "codegen.h"
35
#include "debug.h"
36
#include "isolate-inl.h"
37
#include "runtime-profiler.h"
38
#include "simulator.h"
39
#include "v8threads.h"
40
#include "vm-state-inl.h"
41

42 43
namespace v8 {
namespace internal {
44 45


46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
StackGuard::StackGuard()
    : isolate_(NULL) {
}


void StackGuard::set_interrupt_limits(const ExecutionAccess& lock) {
  ASSERT(isolate_ != NULL);
  // Ignore attempts to interrupt when interrupts are postponed.
  if (should_postpone_interrupts(lock)) return;
  thread_local_.jslimit_ = kInterruptLimit;
  thread_local_.climit_ = kInterruptLimit;
  isolate_->heap()->SetStackLimits();
}


void StackGuard::reset_limits(const ExecutionAccess& lock) {
  ASSERT(isolate_ != NULL);
  thread_local_.jslimit_ = thread_local_.real_jslimit_;
  thread_local_.climit_ = thread_local_.real_climit_;
  isolate_->heap()->SetStackLimits();
}


69 70
static Handle<Object> Invoke(bool is_construct,
                             Handle<JSFunction> function,
71 72
                             Handle<Object> receiver,
                             int argc,
73
                             Handle<Object> args[],
74
                             bool* has_pending_exception) {
75
  Isolate* isolate = function->GetIsolate();
76

77
  // Entering JavaScript.
78
  VMState state(isolate, JS);
79 80

  // Placeholder for return value.
81
  MaybeObject* value = reinterpret_cast<Object*>(kZapValue);
82

83 84 85 86 87
  typedef Object* (*JSEntryFunction)(byte* entry,
                                     Object* function,
                                     Object* receiver,
                                     int argc,
                                     Object*** args);
88

89 90 91
  Handle<Code> code = is_construct
      ? isolate->factory()->js_construct_entry_code()
      : isolate->factory()->js_entry_code();
92

93 94 95 96 97 98 99 100
  // Convert calls on global objects to be calls on the global
  // receiver instead to avoid having a 'this' pointer which refers
  // directly to a global object.
  if (receiver->IsGlobalObject()) {
    Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
    receiver = Handle<JSObject>(global->global_receiver());
  }

101 102
  // Make sure that the global object of the context we're about to
  // make the current one is indeed a global object.
103
  ASSERT(function->context()->global()->IsGlobalObject());
104

105 106
  {
    // Save and restore context around invocation and block the
107
    // allocation of handles without explicit handle scopes.
108
    SaveContext save(isolate);
109
    NoHandleAllocation na;
110
    JSEntryFunction stub_entry = FUNCTION_CAST<JSEntryFunction>(code->entry());
111 112

    // Call the function through the right JS entry stub.
113 114 115 116 117 118
    byte* function_entry = function->code()->entry();
    JSFunction* func = *function;
    Object* recv = *receiver;
    Object*** argv = reinterpret_cast<Object***>(args);
    value =
        CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
119 120 121 122 123 124
  }

#ifdef DEBUG
  value->Verify();
#endif

125
  // Update the pending exception flag and return the value.
126
  *has_pending_exception = value->IsException();
127
  ASSERT(*has_pending_exception == Isolate::Current()->has_pending_exception());
128
  if (*has_pending_exception) {
129 130
    isolate->ReportPendingMessages();
    if (isolate->pending_exception() == Failure::OutOfMemoryException()) {
131
      if (!isolate->ignore_out_of_memory()) {
132 133 134
        V8::FatalProcessOutOfMemory("JS", true);
      }
    }
135
    return Handle<Object>();
136
  } else {
137
    isolate->clear_pending_message();
138 139
  }

140
  return Handle<Object>(value->ToObjectUnchecked(), isolate);
141 142 143
}


144
Handle<Object> Execution::Call(Handle<Object> callable,
145 146
                               Handle<Object> receiver,
                               int argc,
147
                               Handle<Object> argv[],
148 149
                               bool* pending_exception,
                               bool convert_receiver) {
150 151
  *pending_exception = false;

152 153 154 155 156
  if (!callable->IsJSFunction()) {
    callable = TryGetFunctionDelegate(callable, pending_exception);
    if (*pending_exception) return callable;
  }
  Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
157 158 159

  // In non-strict mode, convert receiver.
  if (convert_receiver && !receiver->IsJSReceiver() &&
160
      !func->shared()->native() && func->shared()->is_classic_mode()) {
161
    if (receiver->IsUndefined() || receiver->IsNull()) {
162
      Object* global = func->context()->global()->global_receiver();
163 164 165
      // Under some circumstances, 'global' can be the JSBuiltinsObject
      // In that case, don't rewrite.
      // (FWIW, the same holds for GetIsolate()->global()->global_receiver().)
166
      if (!global->IsJSBuiltinsObject()) receiver = Handle<Object>(global);
167 168 169 170 171 172
    } else {
      receiver = ToObject(receiver, pending_exception);
    }
    if (*pending_exception) return callable;
  }

173
  return Invoke(false, func, receiver, argc, argv, pending_exception);
174 175 176
}


177 178 179 180 181
Handle<Object> Execution::New(Handle<JSFunction> func,
                              int argc,
                              Handle<Object> argv[],
                              bool* pending_exception) {
  return Invoke(true, func, Isolate::Current()->global(), argc, argv,
182
                pending_exception);
183 184 185 186 187 188
}


Handle<Object> Execution::TryCall(Handle<JSFunction> func,
                                  Handle<Object> receiver,
                                  int argc,
189
                                  Handle<Object> args[],
190 191
                                  bool* caught_exception) {
  // Enter a try-block while executing the JavaScript code. To avoid
192 193 194
  // duplicate error printing it must be non-verbose.  Also, to avoid
  // creating message objects during stack overflow we shouldn't
  // capture messages.
195 196
  v8::TryCatch catcher;
  catcher.SetVerbose(false);
197
  catcher.SetCaptureMessage(false);
198
  *caught_exception = false;
199 200 201 202 203 204

  Handle<Object> result = Invoke(false, func, receiver, argc, args,
                                 caught_exception);

  if (*caught_exception) {
    ASSERT(catcher.HasCaught());
205 206 207 208 209 210
    Isolate* isolate = Isolate::Current();
    ASSERT(isolate->has_pending_exception());
    ASSERT(isolate->external_caught_exception());
    if (isolate->pending_exception() ==
        isolate->heap()->termination_exception()) {
      result = isolate->factory()->termination_exception();
211 212 213
    } else {
      result = v8::Utils::OpenHandle(*catcher.Exception());
    }
214
    isolate->OptionalRescheduleException(true);
215 216
  }

217 218
  ASSERT(!Isolate::Current()->has_pending_exception());
  ASSERT(!Isolate::Current()->external_caught_exception());
219 220 221 222 223 224
  return result;
}


Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) {
  ASSERT(!object->IsJSFunction());
225 226
  Isolate* isolate = Isolate::Current();
  Factory* factory = isolate->factory();
227 228 229 230

  // If you return a function from here, it will be called when an
  // attempt is made to call the given object as a function.

231
  // If object is a function proxy, get its handler. Iterate if necessary.
232 233 234 235 236 237
  Object* fun = *object;
  while (fun->IsJSFunctionProxy()) {
    fun = JSFunctionProxy::cast(fun)->call_trap();
  }
  if (fun->IsJSFunction()) return Handle<Object>(fun);

238 239
  // Objects created through the API can have an instance-call handler
  // that should be used when calling the object as a function.
240 241
  if (fun->IsHeapObject() &&
      HeapObject::cast(fun)->map()->has_instance_call_handler()) {
242
    return Handle<JSFunction>(
243
        isolate->global_context()->call_as_function_delegate());
244 245
  }

246
  return factory->undefined_value();
247 248 249
}


250 251 252 253 254
Handle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object,
                                                 bool* has_pending_exception) {
  ASSERT(!object->IsJSFunction());
  Isolate* isolate = Isolate::Current();

255
  // If object is a function proxy, get its handler. Iterate if necessary.
256 257 258 259 260 261
  Object* fun = *object;
  while (fun->IsJSFunctionProxy()) {
    fun = JSFunctionProxy::cast(fun)->call_trap();
  }
  if (fun->IsJSFunction()) return Handle<Object>(fun);

262 263
  // Objects created through the API can have an instance-call handler
  // that should be used when calling the object as a function.
264 265
  if (fun->IsHeapObject() &&
      HeapObject::cast(fun)->map()->has_instance_call_handler()) {
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
    return Handle<JSFunction>(
        isolate->global_context()->call_as_function_delegate());
  }

  // If the Object doesn't have an instance-call handler we should
  // throw a non-callable exception.
  i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
      "called_non_callable", i::HandleVector<i::Object>(&object, 1));
  isolate->Throw(*error_obj);
  *has_pending_exception = true;

  return isolate->factory()->undefined_value();
}


281 282
Handle<Object> Execution::GetConstructorDelegate(Handle<Object> object) {
  ASSERT(!object->IsJSFunction());
283
  Isolate* isolate = Isolate::Current();
284 285 286 287

  // If you return a function from here, it will be called when an
  // attempt is made to call the given object as a constructor.

288 289 290 291 292 293 294
  // If object is a function proxies, get its handler. Iterate if necessary.
  Object* fun = *object;
  while (fun->IsJSFunctionProxy()) {
    fun = JSFunctionProxy::cast(fun)->call_trap();
  }
  if (fun->IsJSFunction()) return Handle<Object>(fun);

295 296
  // Objects created through the API can have an instance-call handler
  // that should be used when calling the object as a function.
297 298
  if (fun->IsHeapObject() &&
      HeapObject::cast(fun)->map()->has_instance_call_handler()) {
299
    return Handle<JSFunction>(
300
        isolate->global_context()->call_as_constructor_delegate());
301 302
  }

303
  return isolate->factory()->undefined_value();
304 305 306
}


307 308 309 310 311 312 313 314 315
Handle<Object> Execution::TryGetConstructorDelegate(
    Handle<Object> object,
    bool* has_pending_exception) {
  ASSERT(!object->IsJSFunction());
  Isolate* isolate = Isolate::Current();

  // If you return a function from here, it will be called when an
  // attempt is made to call the given object as a constructor.

316 317 318 319 320 321 322
  // If object is a function proxies, get its handler. Iterate if necessary.
  Object* fun = *object;
  while (fun->IsJSFunctionProxy()) {
    fun = JSFunctionProxy::cast(fun)->call_trap();
  }
  if (fun->IsJSFunction()) return Handle<Object>(fun);

323 324
  // Objects created through the API can have an instance-call handler
  // that should be used when calling the object as a function.
325 326
  if (fun->IsHeapObject() &&
      HeapObject::cast(fun)->map()->has_instance_call_handler()) {
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
    return Handle<JSFunction>(
        isolate->global_context()->call_as_constructor_delegate());
  }

  // If the Object doesn't have an instance-call handler we should
  // throw a non-callable exception.
  i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError(
      "called_non_callable", i::HandleVector<i::Object>(&object, 1));
  isolate->Throw(*error_obj);
  *has_pending_exception = true;

  return isolate->factory()->undefined_value();
}


342
bool StackGuard::IsStackOverflow() {
343
  ExecutionAccess access(isolate_);
344 345 346 347 348 349
  return (thread_local_.jslimit_ != kInterruptLimit &&
          thread_local_.climit_ != kInterruptLimit);
}


void StackGuard::EnableInterrupts() {
350
  ExecutionAccess access(isolate_);
351 352
  if (has_pending_interrupts(access)) {
    set_interrupt_limits(access);
353 354 355 356 357
  }
}


void StackGuard::SetStackLimit(uintptr_t limit) {
358
  ExecutionAccess access(isolate_);
359
  // If the current limits are special (e.g. due to a pending interrupt) then
360
  // leave them alone.
361
  uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit);
362
  if (thread_local_.jslimit_ == thread_local_.real_jslimit_) {
363
    thread_local_.jslimit_ = jslimit;
364
  }
365
  if (thread_local_.climit_ == thread_local_.real_climit_) {
366 367
    thread_local_.climit_ = limit;
  }
368 369
  thread_local_.real_climit_ = limit;
  thread_local_.real_jslimit_ = jslimit;
370 371 372 373
}


void StackGuard::DisableInterrupts() {
374
  ExecutionAccess access(isolate_);
375 376 377 378
  reset_limits(access);
}


379 380 381 382 383 384
bool StackGuard::ShouldPostponeInterrupts() {
  ExecutionAccess access(isolate_);
  return should_postpone_interrupts(access);
}


385
bool StackGuard::IsInterrupted() {
386
  ExecutionAccess access(isolate_);
387
  return (thread_local_.interrupt_flags_ & INTERRUPT) != 0;
388 389 390 391
}


void StackGuard::Interrupt() {
392
  ExecutionAccess access(isolate_);
393
  thread_local_.interrupt_flags_ |= INTERRUPT;
394
  set_interrupt_limits(access);
395 396 397 398
}


bool StackGuard::IsPreempted() {
399
  ExecutionAccess access(isolate_);
400 401 402 403 404
  return thread_local_.interrupt_flags_ & PREEMPT;
}


void StackGuard::Preempt() {
405
  ExecutionAccess access(isolate_);
406
  thread_local_.interrupt_flags_ |= PREEMPT;
407
  set_interrupt_limits(access);
408 409 410
}


411
bool StackGuard::IsTerminateExecution() {
412
  ExecutionAccess access(isolate_);
413
  return (thread_local_.interrupt_flags_ & TERMINATE) != 0;
414 415 416 417
}


void StackGuard::TerminateExecution() {
418
  ExecutionAccess access(isolate_);
419
  thread_local_.interrupt_flags_ |= TERMINATE;
420
  set_interrupt_limits(access);
421 422 423
}


424
bool StackGuard::IsRuntimeProfilerTick() {
425
  ExecutionAccess access(isolate_);
426
  return (thread_local_.interrupt_flags_ & RUNTIME_PROFILER_TICK) != 0;
427 428 429 430 431
}


void StackGuard::RequestRuntimeProfilerTick() {
  // Ignore calls if we're not optimizing or if we can't get the lock.
432
  if (FLAG_opt && ExecutionAccess::TryLock(isolate_)) {
433 434 435
    thread_local_.interrupt_flags_ |= RUNTIME_PROFILER_TICK;
    if (thread_local_.postpone_interrupts_nesting_ == 0) {
      thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
436
      isolate_->heap()->SetStackLimits();
437
    }
438
    ExecutionAccess::Unlock(isolate_);
439 440 441 442
  }
}


443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
bool StackGuard::IsGCRequest() {
  ExecutionAccess access(isolate_);
  return (thread_local_.interrupt_flags_ & GC_REQUEST) != 0;
}


void StackGuard::RequestGC() {
  ExecutionAccess access(isolate_);
  thread_local_.interrupt_flags_ |= GC_REQUEST;
  if (thread_local_.postpone_interrupts_nesting_ == 0) {
    thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit;
    isolate_->heap()->SetStackLimits();
  }
}


459
#ifdef ENABLE_DEBUGGER_SUPPORT
460
bool StackGuard::IsDebugBreak() {
461
  ExecutionAccess access(isolate_);
462 463 464
  return thread_local_.interrupt_flags_ & DEBUGBREAK;
}

465

466
void StackGuard::DebugBreak() {
467
  ExecutionAccess access(isolate_);
468
  thread_local_.interrupt_flags_ |= DEBUGBREAK;
469
  set_interrupt_limits(access);
470 471 472
}


473
bool StackGuard::IsDebugCommand() {
474
  ExecutionAccess access(isolate_);
475 476 477 478 479 480
  return thread_local_.interrupt_flags_ & DEBUGCOMMAND;
}


void StackGuard::DebugCommand() {
  if (FLAG_debugger_auto_break) {
481
    ExecutionAccess access(isolate_);
482
    thread_local_.interrupt_flags_ |= DEBUGCOMMAND;
483
    set_interrupt_limits(access);
484 485
  }
}
486
#endif
487

488
void StackGuard::Continue(InterruptFlag after_what) {
489
  ExecutionAccess access(isolate_);
490
  thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what);
491
  if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) {
492 493 494 495 496 497
    reset_limits(access);
  }
}


char* StackGuard::ArchiveStackGuard(char* to) {
498
  ExecutionAccess access(isolate_);
499 500
  memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
  ThreadLocal blank;
501 502 503 504 505 506 507

  // Set the stack limits using the old thread_local_.
  // TODO(isolates): This was the old semantics of constructing a ThreadLocal
  //                 (as the ctor called SetStackLimits, which looked at the
  //                 current thread_local_ from StackGuard)-- but is this
  //                 really what was intended?
  isolate_->heap()->SetStackLimits();
508
  thread_local_ = blank;
509

510 511 512 513 514
  return to + sizeof(ThreadLocal);
}


char* StackGuard::RestoreStackGuard(char* from) {
515
  ExecutionAccess access(isolate_);
516
  memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
517
  isolate_->heap()->SetStackLimits();
518 519 520 521
  return from + sizeof(ThreadLocal);
}


522
void StackGuard::FreeThreadResources() {
523 524 525
  Isolate::PerIsolateThreadData* per_thread =
      isolate_->FindOrAllocatePerThreadDataForThisThread();
  per_thread->set_stack_limit(thread_local_.real_climit_);
526 527 528 529
}


void StackGuard::ThreadLocal::Clear() {
530
  real_jslimit_ = kIllegalLimit;
531
  jslimit_ = kIllegalLimit;
532
  real_climit_ = kIllegalLimit;
533 534 535 536 537 538 539
  climit_ = kIllegalLimit;
  nesting_ = 0;
  postpone_interrupts_nesting_ = 0;
  interrupt_flags_ = 0;
}


540
bool StackGuard::ThreadLocal::Initialize(Isolate* isolate) {
541
  bool should_set_stack_limits = false;
542
  if (real_climit_ == kIllegalLimit) {
543 544
    // Takes the address of the limit variable in order to find out where
    // the top of stack is right now.
545
    const uintptr_t kLimitSize = FLAG_stack_size * KB;
546 547
    uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize;
    ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize);
548 549
    real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
    jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit);
550
    real_climit_ = limit;
551
    climit_ = limit;
552
    should_set_stack_limits = true;
553 554 555 556
  }
  nesting_ = 0;
  postpone_interrupts_nesting_ = 0;
  interrupt_flags_ = 0;
557
  return should_set_stack_limits;
558 559 560 561 562
}


void StackGuard::ClearThread(const ExecutionAccess& lock) {
  thread_local_.Clear();
563
  isolate_->heap()->SetStackLimits();
564 565 566 567
}


void StackGuard::InitThread(const ExecutionAccess& lock) {
568 569 570 571
  if (thread_local_.Initialize(isolate_)) isolate_->heap()->SetStackLimits();
  Isolate::PerIsolateThreadData* per_thread =
      isolate_->FindOrAllocatePerThreadDataForThisThread();
  uintptr_t stored_limit = per_thread->stack_limit();
572
  // You should hold the ExecutionAccess lock when you call this.
573
  if (stored_limit != 0) {
574
    SetStackLimit(stored_limit);
575
  }
576 577 578
}


579 580
// --- C a l l s   t o   n a t i v e s ---

581 582 583 584 585 586 587 588 589
#define RETURN_NATIVE_CALL(name, args, has_pending_exception)           \
  do {                                                                  \
    Isolate* isolate = Isolate::Current();                              \
    Handle<Object> argv[] = args;                                       \
    ASSERT(has_pending_exception != NULL);                              \
    return Call(isolate->name##_fun(),                                  \
                isolate->js_builtins_object(),                          \
                ARRAY_SIZE(argv), argv,                                 \
                has_pending_exception);                                 \
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604
  } while (false)


Handle<Object> Execution::ToBoolean(Handle<Object> obj) {
  // See the similar code in runtime.js:ToBoolean.
  if (obj->IsBoolean()) return obj;
  bool result = true;
  if (obj->IsString()) {
    result = Handle<String>::cast(obj)->length() != 0;
  } else if (obj->IsNull() || obj->IsUndefined()) {
    result = false;
  } else if (obj->IsNumber()) {
    double value = obj->Number();
    result = !((value == 0) || isnan(value));
  }
605
  return Handle<Object>(HEAP->ToBoolean(result));
606 607 608 609
}


Handle<Object> Execution::ToNumber(Handle<Object> obj, bool* exc) {
610
  RETURN_NATIVE_CALL(to_number, { obj }, exc);
611 612 613 614
}


Handle<Object> Execution::ToString(Handle<Object> obj, bool* exc) {
615
  RETURN_NATIVE_CALL(to_string, { obj }, exc);
616 617 618 619
}


Handle<Object> Execution::ToDetailString(Handle<Object> obj, bool* exc) {
620
  RETURN_NATIVE_CALL(to_detail_string, { obj }, exc);
621 622 623 624
}


Handle<Object> Execution::ToObject(Handle<Object> obj, bool* exc) {
625
  if (obj->IsSpecObject()) return obj;
626
  RETURN_NATIVE_CALL(to_object, { obj }, exc);
627 628 629 630
}


Handle<Object> Execution::ToInteger(Handle<Object> obj, bool* exc) {
631
  RETURN_NATIVE_CALL(to_integer, { obj }, exc);
632 633 634 635
}


Handle<Object> Execution::ToUint32(Handle<Object> obj, bool* exc) {
636
  RETURN_NATIVE_CALL(to_uint32, { obj }, exc);
637 638 639 640
}


Handle<Object> Execution::ToInt32(Handle<Object> obj, bool* exc) {
641
  RETURN_NATIVE_CALL(to_int32, { obj }, exc);
642 643 644 645
}


Handle<Object> Execution::NewDate(double time, bool* exc) {
646
  Handle<Object> time_obj = FACTORY->NewNumber(time);
647
  RETURN_NATIVE_CALL(create_date, { time_obj }, exc);
648 649 650 651 652 653
}


#undef RETURN_NATIVE_CALL


654 655 656
Handle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern,
                                        Handle<String> flags,
                                        bool* exc) {
657 658
  Handle<JSFunction> function = Handle<JSFunction>(
      pattern->GetIsolate()->global_context()->regexp_function());
659
  Handle<Object> re_obj = RegExpImpl::CreateRegExpLiteral(
660
      function, pattern, flags, exc);
661 662 663 664 665
  if (*exc) return Handle<JSRegExp>();
  return Handle<JSRegExp>::cast(re_obj);
}


666
Handle<Object> Execution::CharAt(Handle<String> string, uint32_t index) {
667 668 669
  Isolate* isolate = string->GetIsolate();
  Factory* factory = isolate->factory();

670 671
  int int_index = static_cast<int>(index);
  if (int_index < 0 || int_index >= string->length()) {
672
    return factory->undefined_value();
673 674 675
  }

  Handle<Object> char_at =
676 677
      GetProperty(isolate->js_builtins_object(),
                  factory->char_at_symbol());
678
  if (!char_at->IsJSFunction()) {
679
    return factory->undefined_value();
680 681 682
  }

  bool caught_exception;
683
  Handle<Object> index_object = factory->NewNumberFromInt(int_index);
684
  Handle<Object> index_arg[] = { index_object };
685 686 687 688 689 690
  Handle<Object> result = TryCall(Handle<JSFunction>::cast(char_at),
                                  string,
                                  ARRAY_SIZE(index_arg),
                                  index_arg,
                                  &caught_exception);
  if (caught_exception) {
691
    return factory->undefined_value();
692 693 694 695 696 697
  }
  return result;
}


Handle<JSFunction> Execution::InstantiateFunction(
698 699
    Handle<FunctionTemplateInfo> data,
    bool* exc) {
700
  Isolate* isolate = data->GetIsolate();
701 702
  // Fast case: see if the function has already been instantiated
  int serial_number = Smi::cast(data->serial_number())->value();
703
  Object* elm =
704
      isolate->global_context()->function_cache()->
705
          GetElementNoExceptionThrown(serial_number);
706
  if (elm->IsJSFunction()) return Handle<JSFunction>(JSFunction::cast(elm));
707
  // The function has not yet been instantiated in this context; do it.
708 709 710 711 712 713
  Handle<Object> args[] = { data };
  Handle<Object> result = Call(isolate->instantiate_fun(),
                               isolate->js_builtins_object(),
                               ARRAY_SIZE(args),
                               args,
                               exc);
714 715 716 717 718 719 720
  if (*exc) return Handle<JSFunction>::null();
  return Handle<JSFunction>::cast(result);
}


Handle<JSObject> Execution::InstantiateObject(Handle<ObjectTemplateInfo> data,
                                              bool* exc) {
721
  Isolate* isolate = data->GetIsolate();
722 723
  if (data->property_list()->IsUndefined() &&
      !data->constructor()->IsUndefined()) {
724 725
    // Initialization to make gcc happy.
    Object* result = NULL;
726
    {
727
      HandleScope scope(isolate);
728 729 730 731 732 733 734 735 736 737 738 739
      Handle<FunctionTemplateInfo> cons_template =
          Handle<FunctionTemplateInfo>(
              FunctionTemplateInfo::cast(data->constructor()));
      Handle<JSFunction> cons = InstantiateFunction(cons_template, exc);
      if (*exc) return Handle<JSObject>::null();
      Handle<Object> value = New(cons, 0, NULL, exc);
      if (*exc) return Handle<JSObject>::null();
      result = *value;
    }
    ASSERT(!*exc);
    return Handle<JSObject>(JSObject::cast(result));
  } else {
740 741 742 743 744 745
    Handle<Object> args[] = { data };
    Handle<Object> result = Call(isolate->instantiate_fun(),
                                 isolate->js_builtins_object(),
                                 ARRAY_SIZE(args),
                                 args,
                                 exc);
746 747 748 749 750 751 752 753 754
    if (*exc) return Handle<JSObject>::null();
    return Handle<JSObject>::cast(result);
  }
}


void Execution::ConfigureInstance(Handle<Object> instance,
                                  Handle<Object> instance_template,
                                  bool* exc) {
755
  Isolate* isolate = Isolate::Current();
756
  Handle<Object> args[] = { instance, instance_template };
757
  Execution::Call(isolate->configure_instance_fun(),
758 759 760 761
                  isolate->js_builtins_object(),
                  ARRAY_SIZE(args),
                  args,
                  exc);
762 763 764 765 766 767 768
}


Handle<String> Execution::GetStackTraceLine(Handle<Object> recv,
                                            Handle<JSFunction> fun,
                                            Handle<Object> pos,
                                            Handle<Object> is_global) {
769
  Isolate* isolate = fun->GetIsolate();
770
  Handle<Object> args[] = { recv, fun, pos, is_global };
771
  bool caught_exception;
772 773 774 775 776
  Handle<Object> result = TryCall(isolate->get_stack_trace_line_fun(),
                                  isolate->js_builtins_object(),
                                  ARRAY_SIZE(args),
                                  args,
                                  &caught_exception);
777 778 779 780
  if (caught_exception || !result->IsString()) {
      return isolate->factory()->empty_symbol();
  }

781 782 783 784
  return Handle<String>::cast(result);
}


785
static Object* RuntimePreempt() {
786 787
  Isolate* isolate = Isolate::Current();

788
  // Clear the preempt request flag.
789
  isolate->stack_guard()->Continue(PREEMPT);
790 791 792

  ContextSwitcher::PreemptionReceived();

793
#ifdef ENABLE_DEBUGGER_SUPPORT
794
  if (isolate->debug()->InDebugger()) {
795 796
    // If currently in the debugger don't do any actual preemption but record
    // that preemption occoured while in the debugger.
797
    isolate->debug()->PreemptionWhileInDebugger();
798 799
  } else {
    // Perform preemption.
800
    v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
801 802
    Thread::YieldCPU();
  }
803
#else
804 805
  { // NOLINT
    // Perform preemption.
806
    v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate));
807 808
    Thread::YieldCPU();
  }
809
#endif
810

811
  return isolate->heap()->undefined_value();
812 813 814
}


815
#ifdef ENABLE_DEBUGGER_SUPPORT
816
Object* Execution::DebugBreakHelper() {
817 818
  Isolate* isolate = Isolate::Current();

819
  // Just continue if breaks are disabled.
820 821
  if (isolate->debug()->disable_break()) {
    return isolate->heap()->undefined_value();
822 823
  }

824
  // Ignore debug break during bootstrapping.
825 826
  if (isolate->bootstrapper()->IsActive()) {
    return isolate->heap()->undefined_value();
827 828
  }

829 830 831 832 833
  StackLimitCheck check(isolate);
  if (check.HasOverflowed()) {
    return isolate->heap()->undefined_value();
  }

834
  {
835
    JavaScriptFrameIterator it(isolate);
836 837 838 839
    ASSERT(!it.done());
    Object* fun = it.frame()->function();
    if (fun && fun->IsJSFunction()) {
      // Don't stop in builtin functions.
840
      if (JSFunction::cast(fun)->IsBuiltin()) {
841
        return isolate->heap()->undefined_value();
842
      }
843
      GlobalObject* global = JSFunction::cast(fun)->context()->global();
844
      // Don't stop in debugger functions.
845 846
      if (isolate->debug()->IsDebugGlobal(global)) {
        return isolate->heap()->undefined_value();
847 848 849 850
      }
    }
  }

851
  // Collect the break state before clearing the flags.
852
  bool debug_command_only =
853 854
      isolate->stack_guard()->IsDebugCommand() &&
      !isolate->stack_guard()->IsDebugBreak();
855

856
  // Clear the debug break request flag.
857
  isolate->stack_guard()->Continue(DEBUGBREAK);
858

859
  ProcessDebugMessages(debug_command_only);
860 861

  // Return to continue execution.
862
  return isolate->heap()->undefined_value();
863 864
}

865
void Execution::ProcessDebugMessages(bool debug_command_only) {
866
  Isolate* isolate = Isolate::Current();
867
  // Clear the debug command request flag.
868
  isolate->stack_guard()->Continue(DEBUGCOMMAND);
869

870 871 872 873 874
  StackLimitCheck check(isolate);
  if (check.HasOverflowed()) {
    return;
  }

875
  HandleScope scope(isolate);
876 877 878
  // Enter the debugger. Just continue if we fail to enter the debugger.
  EnterDebugger debugger;
  if (debugger.FailedToEnter()) {
879
    return;
880 881
  }

882 883
  // Notify the debug event listeners. Indicate auto continue if the break was
  // a debug command break.
884 885
  isolate->debugger()->OnDebugBreak(isolate->factory()->undefined_value(),
                                    debug_command_only);
886
}
887 888


889
#endif
890

891
MaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) {
892
  StackGuard* stack_guard = isolate->stack_guard();
893 894 895
  if (stack_guard->ShouldPostponeInterrupts()) {
    return isolate->heap()->undefined_value();
  }
896 897

  if (stack_guard->IsGCRequest()) {
898 899
    isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
                                       "StackGuard GC request");
900 901 902
    stack_guard->Continue(GC_REQUEST);
  }

903
  isolate->counters()->stack_interrupts()->Increment();
904 905 906
  // If FLAG_count_based_interrupts, every interrupt is a profiler interrupt.
  if (FLAG_count_based_interrupts ||
      stack_guard->IsRuntimeProfilerTick()) {
907 908 909
    isolate->counters()->runtime_profiler_ticks()->Increment();
    stack_guard->Continue(RUNTIME_PROFILER_TICK);
    isolate->runtime_profiler()->OptimizeNow();
910
  }
911
#ifdef ENABLE_DEBUGGER_SUPPORT
912
  if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) {
913 914
    DebugBreakHelper();
  }
915
#endif
916 917 918 919
  if (stack_guard->IsPreempted()) RuntimePreempt();
  if (stack_guard->IsTerminateExecution()) {
    stack_guard->Continue(TERMINATE);
    return isolate->TerminateExecution();
920
  }
921 922 923
  if (stack_guard->IsInterrupted()) {
    stack_guard->Continue(INTERRUPT);
    return isolate->StackOverflow();
924
  }
925
  return isolate->heap()->undefined_value();
926 927
}

928

929
} }  // namespace v8::internal