Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(284)

Side by Side Diff: src/runtime/runtime.cc

Issue 612023002: Split even more runtime functions into separate files. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects-inl.h ('k') | src/runtime/runtime-compiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdlib.h> 5 #include <stdlib.h>
6 #include <limits> 6 #include <limits>
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/accessors.h" 10 #include "src/accessors.h"
11 #include "src/allocation-site-scopes.h" 11 #include "src/allocation-site-scopes.h"
12 #include "src/api.h" 12 #include "src/api.h"
13 #include "src/arguments.h" 13 #include "src/arguments.h"
14 #include "src/bailout-reason.h" 14 #include "src/bailout-reason.h"
15 #include "src/base/cpu.h" 15 #include "src/base/cpu.h"
16 #include "src/base/platform/platform.h" 16 #include "src/base/platform/platform.h"
17 #include "src/bootstrapper.h" 17 #include "src/bootstrapper.h"
18 #include "src/codegen.h" 18 #include "src/codegen.h"
19 #include "src/compilation-cache.h" 19 #include "src/compilation-cache.h"
20 #include "src/compiler.h" 20 #include "src/compiler.h"
21 #include "src/conversions.h" 21 #include "src/conversions.h"
22 #include "src/cpu-profiler.h"
23 #include "src/date.h"
24 #include "src/dateparser-inl.h"
25 #include "src/debug.h"
26 #include "src/deoptimizer.h" 22 #include "src/deoptimizer.h"
27 #include "src/execution.h" 23 #include "src/execution.h"
28 #include "src/full-codegen.h" 24 #include "src/full-codegen.h"
29 #include "src/global-handles.h" 25 #include "src/global-handles.h"
30 #include "src/isolate-inl.h" 26 #include "src/isolate-inl.h"
31 #include "src/liveedit.h"
32 #include "src/misc-intrinsics.h"
33 #include "src/parser.h" 27 #include "src/parser.h"
34 #include "src/prototype.h" 28 #include "src/prototype.h"
35 #include "src/runtime/runtime.h" 29 #include "src/runtime/runtime.h"
36 #include "src/runtime/runtime-utils.h" 30 #include "src/runtime/runtime-utils.h"
37 #include "src/runtime-profiler.h"
38 #include "src/scopeinfo.h" 31 #include "src/scopeinfo.h"
39 #include "src/smart-pointers.h" 32 #include "src/smart-pointers.h"
40 #include "src/utils.h" 33 #include "src/utils.h"
41 #include "src/v8threads.h" 34 #include "src/v8threads.h"
42 #include "src/vm-state-inl.h"
43 35
44 36
45 namespace v8 { 37 namespace v8 {
46 namespace internal { 38 namespace internal {
47 39
48 // Header of runtime functions. 40 // Header of runtime functions.
49 #define F(name, number_of_args, result_size) \ 41 #define F(name, number_of_args, result_size) \
50 Object* Runtime_##name(int args_length, Object** args_object, \ 42 Object* Runtime_##name(int args_length, Object** args_object, \
51 Isolate* isolate); 43 Isolate* isolate);
52 44
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 } 652 }
661 iter.AdvanceIgnoringProxies(); 653 iter.AdvanceIgnoringProxies();
662 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { 654 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
663 return *PrototypeIterator::GetCurrent(iter); 655 return *PrototypeIterator::GetCurrent(iter);
664 } 656 }
665 } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)); 657 } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
666 return *PrototypeIterator::GetCurrent(iter); 658 return *PrototypeIterator::GetCurrent(iter);
667 } 659 }
668 660
669 661
670 static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
671 Isolate* isolate, Handle<Object> receiver) {
672 PrototypeIterator iter(isolate, receiver);
673 while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
674 if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
675 return PrototypeIterator::GetCurrent(iter);
676 }
677 iter.Advance();
678 }
679 return PrototypeIterator::GetCurrent(iter);
680 }
681
682
683 RUNTIME_FUNCTION(Runtime_InternalSetPrototype) { 662 RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
684 HandleScope scope(isolate); 663 HandleScope scope(isolate);
685 DCHECK(args.length() == 2); 664 DCHECK(args.length() == 2);
686 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); 665 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
687 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); 666 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
688 DCHECK(!obj->IsAccessCheckNeeded()); 667 DCHECK(!obj->IsAccessCheckNeeded());
689 DCHECK(!obj->map()->is_observed()); 668 DCHECK(!obj->map()->is_observed());
690 Handle<Object> result; 669 Handle<Object> result;
691 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 670 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
692 isolate, result, JSObject::SetPrototype(obj, prototype, false)); 671 isolate, result, JSObject::SetPrototype(obj, prototype, false));
693 return *result; 672 return *result;
694 } 673 }
695 674
696 675
697 RUNTIME_FUNCTION(Runtime_SetPrototype) { 676 RUNTIME_FUNCTION(Runtime_SetPrototype) {
698 HandleScope scope(isolate); 677 HandleScope scope(isolate);
699 DCHECK(args.length() == 2); 678 DCHECK(args.length() == 2);
700 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); 679 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
701 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); 680 CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
702 if (obj->IsAccessCheckNeeded() && 681 if (obj->IsAccessCheckNeeded() &&
703 !isolate->MayNamedAccess(obj, isolate->factory()->proto_string(), 682 !isolate->MayNamedAccess(obj, isolate->factory()->proto_string(),
704 v8::ACCESS_SET)) { 683 v8::ACCESS_SET)) {
705 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET); 684 isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET);
706 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); 685 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
707 return isolate->heap()->undefined_value(); 686 return isolate->heap()->undefined_value();
708 } 687 }
709 if (obj->map()->is_observed()) { 688 if (obj->map()->is_observed()) {
710 Handle<Object> old_value = GetPrototypeSkipHiddenPrototypes(isolate, obj); 689 Handle<Object> old_value =
690 Object::GetPrototypeSkipHiddenPrototypes(isolate, obj);
711 Handle<Object> result; 691 Handle<Object> result;
712 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 692 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
713 isolate, result, JSObject::SetPrototype(obj, prototype, true)); 693 isolate, result, JSObject::SetPrototype(obj, prototype, true));
714 694
715 Handle<Object> new_value = GetPrototypeSkipHiddenPrototypes(isolate, obj); 695 Handle<Object> new_value =
696 Object::GetPrototypeSkipHiddenPrototypes(isolate, obj);
716 if (!new_value->SameValue(*old_value)) { 697 if (!new_value->SameValue(*old_value)) {
717 JSObject::EnqueueChangeRecord( 698 JSObject::EnqueueChangeRecord(
718 obj, "setPrototype", isolate->factory()->proto_string(), old_value); 699 obj, "setPrototype", isolate->factory()->proto_string(), old_value);
719 } 700 }
720 return *result; 701 return *result;
721 } 702 }
722 Handle<Object> result; 703 Handle<Object> result;
723 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 704 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
724 isolate, result, JSObject::SetPrototype(obj, prototype, true)); 705 isolate, result, JSObject::SetPrototype(obj, prototype, true));
725 return *result; 706 return *result;
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after
1475 1456
1476 RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) { 1457 RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
1477 SealHandleScope shs(isolate); 1458 SealHandleScope shs(isolate);
1478 DCHECK(args.length() == 1); 1459 DCHECK(args.length() == 1);
1479 CONVERT_ARG_CHECKED(JSFunction, f, 0); 1460 CONVERT_ARG_CHECKED(JSFunction, f, 0);
1480 f->shared()->set_name_should_print_as_anonymous(true); 1461 f->shared()->set_name_should_print_as_anonymous(true);
1481 return isolate->heap()->undefined_value(); 1462 return isolate->heap()->undefined_value();
1482 } 1463 }
1483 1464
1484 1465
1485 RUNTIME_FUNCTION(Runtime_FunctionIsGenerator) {
1486 SealHandleScope shs(isolate);
1487 DCHECK(args.length() == 1);
1488 CONVERT_ARG_CHECKED(JSFunction, f, 0);
1489 return isolate->heap()->ToBoolean(f->shared()->is_generator());
1490 }
1491
1492
1493 RUNTIME_FUNCTION(Runtime_FunctionIsArrow) { 1466 RUNTIME_FUNCTION(Runtime_FunctionIsArrow) {
1494 SealHandleScope shs(isolate); 1467 SealHandleScope shs(isolate);
1495 DCHECK(args.length() == 1); 1468 DCHECK(args.length() == 1);
1496 CONVERT_ARG_CHECKED(JSFunction, f, 0); 1469 CONVERT_ARG_CHECKED(JSFunction, f, 0);
1497 return isolate->heap()->ToBoolean(f->shared()->is_arrow()); 1470 return isolate->heap()->ToBoolean(f->shared()->is_arrow());
1498 } 1471 }
1499 1472
1500 1473
1501 RUNTIME_FUNCTION(Runtime_FunctionIsConciseMethod) { 1474 RUNTIME_FUNCTION(Runtime_FunctionIsConciseMethod) {
1502 SealHandleScope shs(isolate); 1475 SealHandleScope shs(isolate);
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1676 if (isolate->logger()->is_logging_code_events() || 1649 if (isolate->logger()->is_logging_code_events() ||
1677 isolate->cpu_profiler()->is_profiling()) { 1650 isolate->cpu_profiler()->is_profiling()) {
1678 isolate->logger()->LogExistingFunction(source_shared, 1651 isolate->logger()->LogExistingFunction(source_shared,
1679 Handle<Code>(source_shared->code())); 1652 Handle<Code>(source_shared->code()));
1680 } 1653 }
1681 1654
1682 return *target; 1655 return *target;
1683 } 1656 }
1684 1657
1685 1658
1686 RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) {
1687 HandleScope scope(isolate);
1688 DCHECK(args.length() == 0);
1689
1690 JavaScriptFrameIterator it(isolate);
1691 JavaScriptFrame* frame = it.frame();
1692 Handle<JSFunction> function(frame->function());
1693 RUNTIME_ASSERT(function->shared()->is_generator());
1694
1695 Handle<JSGeneratorObject> generator;
1696 if (frame->IsConstructor()) {
1697 generator = handle(JSGeneratorObject::cast(frame->receiver()));
1698 } else {
1699 generator = isolate->factory()->NewJSGeneratorObject(function);
1700 }
1701 generator->set_function(*function);
1702 generator->set_context(Context::cast(frame->context()));
1703 generator->set_receiver(frame->receiver());
1704 generator->set_continuation(0);
1705 generator->set_operand_stack(isolate->heap()->empty_fixed_array());
1706 generator->set_stack_handler_index(-1);
1707
1708 return *generator;
1709 }
1710
1711
1712 RUNTIME_FUNCTION(Runtime_SuspendJSGeneratorObject) {
1713 HandleScope handle_scope(isolate);
1714 DCHECK(args.length() == 1);
1715 CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0);
1716
1717 JavaScriptFrameIterator stack_iterator(isolate);
1718 JavaScriptFrame* frame = stack_iterator.frame();
1719 RUNTIME_ASSERT(frame->function()->shared()->is_generator());
1720 DCHECK_EQ(frame->function(), generator_object->function());
1721
1722 // The caller should have saved the context and continuation already.
1723 DCHECK_EQ(generator_object->context(), Context::cast(frame->context()));
1724 DCHECK_LT(0, generator_object->continuation());
1725
1726 // We expect there to be at least two values on the operand stack: the return
1727 // value of the yield expression, and the argument to this runtime call.
1728 // Neither of those should be saved.
1729 int operands_count = frame->ComputeOperandsCount();
1730 DCHECK_GE(operands_count, 2);
1731 operands_count -= 2;
1732
1733 if (operands_count == 0) {
1734 // Although it's semantically harmless to call this function with an
1735 // operands_count of zero, it is also unnecessary.
1736 DCHECK_EQ(generator_object->operand_stack(),
1737 isolate->heap()->empty_fixed_array());
1738 DCHECK_EQ(generator_object->stack_handler_index(), -1);
1739 // If there are no operands on the stack, there shouldn't be a handler
1740 // active either.
1741 DCHECK(!frame->HasHandler());
1742 } else {
1743 int stack_handler_index = -1;
1744 Handle<FixedArray> operand_stack =
1745 isolate->factory()->NewFixedArray(operands_count);
1746 frame->SaveOperandStack(*operand_stack, &stack_handler_index);
1747 generator_object->set_operand_stack(*operand_stack);
1748 generator_object->set_stack_handler_index(stack_handler_index);
1749 }
1750
1751 return isolate->heap()->undefined_value();
1752 }
1753
1754
1755 // Note that this function is the slow path for resuming generators. It is only
1756 // called if the suspended activation had operands on the stack, stack handlers
1757 // needing rewinding, or if the resume should throw an exception. The fast path
1758 // is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is
1759 // inlined into GeneratorNext and GeneratorThrow. EmitGeneratorResumeResume is
1760 // called in any case, as it needs to reconstruct the stack frame and make space
1761 // for arguments and operands.
1762 RUNTIME_FUNCTION(Runtime_ResumeJSGeneratorObject) {
1763 SealHandleScope shs(isolate);
1764 DCHECK(args.length() == 3);
1765 CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
1766 CONVERT_ARG_CHECKED(Object, value, 1);
1767 CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2);
1768 JavaScriptFrameIterator stack_iterator(isolate);
1769 JavaScriptFrame* frame = stack_iterator.frame();
1770
1771 DCHECK_EQ(frame->function(), generator_object->function());
1772 DCHECK(frame->function()->is_compiled());
1773
1774 STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
1775 STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
1776
1777 Address pc = generator_object->function()->code()->instruction_start();
1778 int offset = generator_object->continuation();
1779 DCHECK(offset > 0);
1780 frame->set_pc(pc + offset);
1781 if (FLAG_enable_ool_constant_pool) {
1782 frame->set_constant_pool(
1783 generator_object->function()->code()->constant_pool());
1784 }
1785 generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
1786
1787 FixedArray* operand_stack = generator_object->operand_stack();
1788 int operands_count = operand_stack->length();
1789 if (operands_count != 0) {
1790 frame->RestoreOperandStack(operand_stack,
1791 generator_object->stack_handler_index());
1792 generator_object->set_operand_stack(isolate->heap()->empty_fixed_array());
1793 generator_object->set_stack_handler_index(-1);
1794 }
1795
1796 JSGeneratorObject::ResumeMode resume_mode =
1797 static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
1798 switch (resume_mode) {
1799 case JSGeneratorObject::NEXT:
1800 return value;
1801 case JSGeneratorObject::THROW:
1802 return isolate->Throw(value);
1803 }
1804
1805 UNREACHABLE();
1806 return isolate->ThrowIllegalOperation();
1807 }
1808
1809
1810 RUNTIME_FUNCTION(Runtime_ThrowGeneratorStateError) {
1811 HandleScope scope(isolate);
1812 DCHECK(args.length() == 1);
1813 CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
1814 int continuation = generator->continuation();
1815 const char* message = continuation == JSGeneratorObject::kGeneratorClosed
1816 ? "generator_finished"
1817 : "generator_running";
1818 Vector<Handle<Object> > argv = HandleVector<Object>(NULL, 0);
1819 THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewError(message, argv));
1820 }
1821
1822
1823 RUNTIME_FUNCTION(Runtime_ObjectFreeze) { 1659 RUNTIME_FUNCTION(Runtime_ObjectFreeze) {
1824 HandleScope scope(isolate); 1660 HandleScope scope(isolate);
1825 DCHECK(args.length() == 1); 1661 DCHECK(args.length() == 1);
1826 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 1662 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
1827 1663
1828 // %ObjectFreeze is a fast path and these cases are handled elsewhere. 1664 // %ObjectFreeze is a fast path and these cases are handled elsewhere.
1829 RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() && 1665 RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() &&
1830 !object->map()->is_observed() && !object->IsJSProxy()); 1666 !object->map()->is_observed() && !object->IsJSProxy());
1831 1667
1832 Handle<Object> result; 1668 Handle<Object> result;
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after
2584 JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind); 2420 JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
2585 } 2421 }
2586 } 2422 }
2587 FixedArray* object_array = FixedArray::cast(object->elements()); 2423 FixedArray* object_array = FixedArray::cast(object->elements());
2588 object_array->set(store_index, *value); 2424 object_array->set(store_index, *value);
2589 } 2425 }
2590 return *object; 2426 return *object;
2591 } 2427 }
2592 2428
2593 2429
2594 // Check whether debugger and is about to step into the callback that is passed
2595 // to a built-in function such as Array.forEach.
2596 RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) {
2597 DCHECK(args.length() == 1);
2598 if (!isolate->debug()->is_active() || !isolate->debug()->StepInActive()) {
2599 return isolate->heap()->false_value();
2600 }
2601 CONVERT_ARG_CHECKED(Object, callback, 0);
2602 // We do not step into the callback if it's a builtin or not even a function.
2603 return isolate->heap()->ToBoolean(callback->IsJSFunction() &&
2604 !JSFunction::cast(callback)->IsBuiltin());
2605 }
2606
2607
2608 // Set one shot breakpoints for the callback function that is passed to a
2609 // built-in function such as Array.forEach to enable stepping into the callback.
2610 RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
2611 DCHECK(args.length() == 1);
2612 Debug* debug = isolate->debug();
2613 if (!debug->IsStepping()) return isolate->heap()->undefined_value();
2614
2615 HandleScope scope(isolate);
2616 CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
2617 RUNTIME_ASSERT(object->IsJSFunction() || object->IsJSGeneratorObject());
2618 Handle<JSFunction> fun;
2619 if (object->IsJSFunction()) {
2620 fun = Handle<JSFunction>::cast(object);
2621 } else {
2622 fun = Handle<JSFunction>(
2623 Handle<JSGeneratorObject>::cast(object)->function(), isolate);
2624 }
2625 // When leaving the function, step out has been activated, but not performed
2626 // if we do not leave the builtin. To be able to step into the function
2627 // again, we need to clear the step out at this point.
2628 debug->ClearStepOut();
2629 debug->FloodWithOneShot(fun);
2630 return isolate->heap()->undefined_value();
2631 }
2632
2633
2634 RUNTIME_FUNCTION(Runtime_DebugPushPromise) {
2635 DCHECK(args.length() == 1);
2636 HandleScope scope(isolate);
2637 CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
2638 isolate->PushPromise(promise);
2639 return isolate->heap()->undefined_value();
2640 }
2641
2642
2643 RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
2644 DCHECK(args.length() == 0);
2645 SealHandleScope shs(isolate);
2646 isolate->PopPromise();
2647 return isolate->heap()->undefined_value();
2648 }
2649
2650
2651 RUNTIME_FUNCTION(Runtime_DebugPromiseEvent) {
2652 DCHECK(args.length() == 1);
2653 HandleScope scope(isolate);
2654 CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
2655 isolate->debug()->OnPromiseEvent(data);
2656 return isolate->heap()->undefined_value();
2657 }
2658
2659
2660 RUNTIME_FUNCTION(Runtime_DebugPromiseRejectEvent) { 2430 RUNTIME_FUNCTION(Runtime_DebugPromiseRejectEvent) {
2661 DCHECK(args.length() == 2); 2431 DCHECK(args.length() == 2);
2662 HandleScope scope(isolate); 2432 HandleScope scope(isolate);
2663 CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); 2433 CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
2664 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); 2434 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
2665 isolate->debug()->OnPromiseReject(promise, value); 2435 isolate->debug()->OnPromiseReject(promise, value);
2666 return isolate->heap()->undefined_value(); 2436 return isolate->heap()->undefined_value();
2667 } 2437 }
2668 2438
2669 2439
2670 RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) {
2671 DCHECK(args.length() == 1);
2672 HandleScope scope(isolate);
2673 CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
2674 isolate->debug()->OnAsyncTaskEvent(data);
2675 return isolate->heap()->undefined_value();
2676 }
2677
2678
2679 RUNTIME_FUNCTION(Runtime_DeleteProperty) { 2440 RUNTIME_FUNCTION(Runtime_DeleteProperty) {
2680 HandleScope scope(isolate); 2441 HandleScope scope(isolate);
2681 DCHECK(args.length() == 3); 2442 DCHECK(args.length() == 3);
2682 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); 2443 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
2683 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); 2444 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
2684 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2); 2445 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
2685 JSReceiver::DeleteMode delete_mode = strict_mode == STRICT 2446 JSReceiver::DeleteMode delete_mode = strict_mode == STRICT
2686 ? JSReceiver::STRICT_DELETION 2447 ? JSReceiver::STRICT_DELETION
2687 : JSReceiver::NORMAL_DELETION; 2448 : JSReceiver::NORMAL_DELETION;
2688 Handle<Object> result; 2449 Handle<Object> result;
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
3266 } 3027 }
3267 3028
3268 3029
3269 RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) { 3030 RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
3270 HandleScope scope(isolate); 3031 HandleScope scope(isolate);
3271 DCHECK(args.length() == 0); 3032 DCHECK(args.length() == 0);
3272 return *isolate->factory()->NewHeapNumber(0); 3033 return *isolate->factory()->NewHeapNumber(0);
3273 } 3034 }
3274 3035
3275 3036
3276
3277
3278
3279 RUNTIME_FUNCTION(Runtime_DateMakeDay) {
3280 SealHandleScope shs(isolate);
3281 DCHECK(args.length() == 2);
3282
3283 CONVERT_SMI_ARG_CHECKED(year, 0);
3284 CONVERT_SMI_ARG_CHECKED(month, 1);
3285
3286 int days = isolate->date_cache()->DaysFromYearMonth(year, month);
3287 RUNTIME_ASSERT(Smi::IsValid(days));
3288 return Smi::FromInt(days);
3289 }
3290
3291
3292 RUNTIME_FUNCTION(Runtime_DateSetValue) {
3293 HandleScope scope(isolate);
3294 DCHECK(args.length() == 3);
3295
3296 CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0);
3297 CONVERT_DOUBLE_ARG_CHECKED(time, 1);
3298 CONVERT_SMI_ARG_CHECKED(is_utc, 2);
3299
3300 DateCache* date_cache = isolate->date_cache();
3301
3302 Handle<Object> value;
3303 ;
3304 bool is_value_nan = false;
3305 if (std::isnan(time)) {
3306 value = isolate->factory()->nan_value();
3307 is_value_nan = true;
3308 } else if (!is_utc && (time < -DateCache::kMaxTimeBeforeUTCInMs ||
3309 time > DateCache::kMaxTimeBeforeUTCInMs)) {
3310 value = isolate->factory()->nan_value();
3311 is_value_nan = true;
3312 } else {
3313 time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time));
3314 if (time < -DateCache::kMaxTimeInMs || time > DateCache::kMaxTimeInMs) {
3315 value = isolate->factory()->nan_value();
3316 is_value_nan = true;
3317 } else {
3318 value = isolate->factory()->NewNumber(DoubleToInteger(time));
3319 }
3320 }
3321 date->SetValue(*value, is_value_nan);
3322 return *value;
3323 }
3324
3325
3326 static Handle<JSObject> NewSloppyArguments(Isolate* isolate, 3037 static Handle<JSObject> NewSloppyArguments(Isolate* isolate,
3327 Handle<JSFunction> callee, 3038 Handle<JSFunction> callee,
3328 Object** parameters, 3039 Object** parameters,
3329 int argument_count) { 3040 int argument_count) {
3330 Handle<JSObject> result = 3041 Handle<JSObject> result =
3331 isolate->factory()->NewArgumentsObject(callee, argument_count); 3042 isolate->factory()->NewArgumentsObject(callee, argument_count);
3332 3043
3333 // Allocate the elements if needed. 3044 // Allocate the elements if needed.
3334 int parameter_count = callee->shared()->formal_parameter_count(); 3045 int parameter_count = callee->shared()->formal_parameter_count();
3335 if (argument_count > 0) { 3046 if (argument_count > 0) {
(...skipping 1003 matching lines...) Expand 10 before | Expand all | Expand 10 after
4339 4050
4340 RUNTIME_FUNCTION(Runtime_ThrowUnsupportedSuperError) { 4051 RUNTIME_FUNCTION(Runtime_ThrowUnsupportedSuperError) {
4341 HandleScope scope(isolate); 4052 HandleScope scope(isolate);
4342 DCHECK(args.length() == 0); 4053 DCHECK(args.length() == 0);
4343 THROW_NEW_ERROR_RETURN_FAILURE( 4054 THROW_NEW_ERROR_RETURN_FAILURE(
4344 isolate, 4055 isolate,
4345 NewReferenceError("unsupported_super", HandleVector<Object>(NULL, 0))); 4056 NewReferenceError("unsupported_super", HandleVector<Object>(NULL, 0)));
4346 } 4057 }
4347 4058
4348 4059
4349 RUNTIME_FUNCTION(Runtime_ThrowNotDateError) {
4350 HandleScope scope(isolate);
4351 DCHECK(args.length() == 0);
4352 THROW_NEW_ERROR_RETURN_FAILURE(
4353 isolate, NewTypeError("not_date_object", HandleVector<Object>(NULL, 0)));
4354 }
4355
4356
4357 RUNTIME_FUNCTION(Runtime_StackGuard) { 4060 RUNTIME_FUNCTION(Runtime_StackGuard) {
4358 SealHandleScope shs(isolate); 4061 SealHandleScope shs(isolate);
4359 DCHECK(args.length() == 0); 4062 DCHECK(args.length() == 0);
4360 4063
4361 // First check if this is a real stack overflow. 4064 // First check if this is a real stack overflow.
4362 StackLimitCheck check(isolate); 4065 StackLimitCheck check(isolate);
4363 if (check.JsHasOverflowed()) { 4066 if (check.JsHasOverflowed()) {
4364 return isolate->StackOverflow(); 4067 return isolate->StackOverflow();
4365 } 4068 }
4366 4069
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4415 4118
4416 RUNTIME_FUNCTION(Runtime_TraceExit) { 4119 RUNTIME_FUNCTION(Runtime_TraceExit) {
4417 SealHandleScope shs(isolate); 4120 SealHandleScope shs(isolate);
4418 DCHECK(args.length() == 1); 4121 DCHECK(args.length() == 1);
4419 CONVERT_ARG_CHECKED(Object, obj, 0); 4122 CONVERT_ARG_CHECKED(Object, obj, 0);
4420 PrintTransition(isolate, obj); 4123 PrintTransition(isolate, obj);
4421 return obj; // return TOS 4124 return obj; // return TOS
4422 } 4125 }
4423 4126
4424 4127
4425 RUNTIME_FUNCTION(Runtime_DateCurrentTime) {
4426 HandleScope scope(isolate);
4427 DCHECK(args.length() == 0);
4428 if (FLAG_log_timer_events) LOG(isolate, CurrentTimeEvent());
4429
4430 // According to ECMA-262, section 15.9.1, page 117, the precision of
4431 // the number in a Date object representing a particular instant in
4432 // time is milliseconds. Therefore, we floor the result of getting
4433 // the OS time.
4434 double millis;
4435 if (FLAG_verify_predictable) {
4436 millis = 1388534400000.0; // Jan 1 2014 00:00:00 GMT+0000
4437 millis += Floor(isolate->heap()->synthetic_time());
4438 } else {
4439 millis = Floor(base::OS::TimeCurrentMillis());
4440 }
4441 return *isolate->factory()->NewNumber(millis);
4442 }
4443
4444
4445 RUNTIME_FUNCTION(Runtime_DateParseString) {
4446 HandleScope scope(isolate);
4447 DCHECK(args.length() == 2);
4448 CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
4449 CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
4450
4451 RUNTIME_ASSERT(output->HasFastElements());
4452 JSObject::EnsureCanContainHeapObjectElements(output);
4453 RUNTIME_ASSERT(output->HasFastObjectElements());
4454 Handle<FixedArray> output_array(FixedArray::cast(output->elements()));
4455 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
4456
4457 str = String::Flatten(str);
4458 DisallowHeapAllocation no_gc;
4459
4460 bool result;
4461 String::FlatContent str_content = str->GetFlatContent();
4462 if (str_content.IsOneByte()) {
4463 result = DateParser::Parse(str_content.ToOneByteVector(), *output_array,
4464 isolate->unicode_cache());
4465 } else {
4466 DCHECK(str_content.IsTwoByte());
4467 result = DateParser::Parse(str_content.ToUC16Vector(), *output_array,
4468 isolate->unicode_cache());
4469 }
4470
4471 if (result) {
4472 return *output;
4473 } else {
4474 return isolate->heap()->null_value();
4475 }
4476 }
4477
4478
4479 RUNTIME_FUNCTION(Runtime_DateLocalTimezone) {
4480 HandleScope scope(isolate);
4481 DCHECK(args.length() == 1);
4482
4483 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4484 RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
4485 x <= DateCache::kMaxTimeBeforeUTCInMs);
4486 const char* zone =
4487 isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x));
4488 Handle<String> result =
4489 isolate->factory()->NewStringFromUtf8(CStrVector(zone)).ToHandleChecked();
4490 return *result;
4491 }
4492
4493
4494 RUNTIME_FUNCTION(Runtime_DateToUTC) {
4495 HandleScope scope(isolate);
4496 DCHECK(args.length() == 1);
4497
4498 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
4499 RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
4500 x <= DateCache::kMaxTimeBeforeUTCInMs);
4501 int64_t time = isolate->date_cache()->ToUTC(static_cast<int64_t>(x));
4502
4503 return *isolate->factory()->NewNumber(static_cast<double>(time));
4504 }
4505
4506
4507 RUNTIME_FUNCTION(Runtime_DateCacheVersion) {
4508 HandleScope hs(isolate);
4509 DCHECK(args.length() == 0);
4510 if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
4511 Handle<FixedArray> date_cache_version =
4512 isolate->factory()->NewFixedArray(1, TENURED);
4513 date_cache_version->set(0, Smi::FromInt(0));
4514 isolate->eternal_handles()->CreateSingleton(
4515 isolate, *date_cache_version, EternalHandles::DATE_CACHE_VERSION);
4516 }
4517 Handle<FixedArray> date_cache_version =
4518 Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton(
4519 EternalHandles::DATE_CACHE_VERSION));
4520 // Return result as a JS array.
4521 Handle<JSObject> result =
4522 isolate->factory()->NewJSObject(isolate->array_function());
4523 JSArray::SetContent(Handle<JSArray>::cast(result), date_cache_version);
4524 return *result;
4525 }
4526
4527
4528 RUNTIME_FUNCTION(Runtime_GlobalProxy) { 4128 RUNTIME_FUNCTION(Runtime_GlobalProxy) {
4529 SealHandleScope shs(isolate); 4129 SealHandleScope shs(isolate);
4530 DCHECK(args.length() == 1); 4130 DCHECK(args.length() == 1);
4531 CONVERT_ARG_CHECKED(Object, global, 0); 4131 CONVERT_ARG_CHECKED(Object, global, 0);
4532 if (!global->IsJSGlobalObject()) return isolate->heap()->null_value(); 4132 if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
4533 return JSGlobalObject::cast(global)->global_proxy(); 4133 return JSGlobalObject::cast(global)->global_proxy();
4534 } 4134 }
4535 4135
4536 4136
4537 RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) { 4137 RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) {
(...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after
5417 AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER; 5017 AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
5418 if (!receiver->IsJSObject()) return isolate->heap()->undefined_value(); 5018 if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
5419 Handle<Object> result; 5019 Handle<Object> result;
5420 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 5020 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5421 isolate, result, 5021 isolate, result,
5422 JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component)); 5022 JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component));
5423 return *result; 5023 return *result;
5424 } 5024 }
5425 5025
5426 5026
5427 RUNTIME_FUNCTION(Runtime_DebugBreak) {
5428 SealHandleScope shs(isolate);
5429 DCHECK(args.length() == 0);
5430 isolate->debug()->HandleDebugBreak();
5431 return isolate->heap()->undefined_value();
5432 }
5433
5434
5435 // Helper functions for wrapping and unwrapping stack frame ids.
5436 static Smi* WrapFrameId(StackFrame::Id id) {
5437 DCHECK(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
5438 return Smi::FromInt(id >> 2);
5439 }
5440
5441
5442 static StackFrame::Id UnwrapFrameId(int wrapped) {
5443 return static_cast<StackFrame::Id>(wrapped << 2);
5444 }
5445
5446
5447 // Adds a JavaScript function as a debug event listener.
5448 // args[0]: debug event listener function to set or null or undefined for
5449 // clearing the event listener function
5450 // args[1]: object supplied during callback
5451 RUNTIME_FUNCTION(Runtime_SetDebugEventListener) {
5452 SealHandleScope shs(isolate);
5453 DCHECK(args.length() == 2);
5454 RUNTIME_ASSERT(args[0]->IsJSFunction() || args[0]->IsUndefined() ||
5455 args[0]->IsNull());
5456 CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0);
5457 CONVERT_ARG_HANDLE_CHECKED(Object, data, 1);
5458 isolate->debug()->SetEventListener(callback, data);
5459
5460 return isolate->heap()->undefined_value();
5461 }
5462
5463
5464 RUNTIME_FUNCTION(Runtime_Break) {
5465 SealHandleScope shs(isolate);
5466 DCHECK(args.length() == 0);
5467 isolate->stack_guard()->RequestDebugBreak();
5468 return isolate->heap()->undefined_value();
5469 }
5470
5471
5472 static Handle<Object> DebugGetProperty(LookupIterator* it,
5473 bool* has_caught = NULL) {
5474 for (; it->IsFound(); it->Next()) {
5475 switch (it->state()) {
5476 case LookupIterator::NOT_FOUND:
5477 case LookupIterator::TRANSITION:
5478 UNREACHABLE();
5479 case LookupIterator::ACCESS_CHECK:
5480 // Ignore access checks.
5481 break;
5482 case LookupIterator::INTERCEPTOR:
5483 case LookupIterator::JSPROXY:
5484 return it->isolate()->factory()->undefined_value();
5485 case LookupIterator::ACCESSOR: {
5486 Handle<Object> accessors = it->GetAccessors();
5487 if (!accessors->IsAccessorInfo()) {
5488 return it->isolate()->factory()->undefined_value();
5489 }
5490 MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithAccessor(
5491 it->GetReceiver(), it->name(), it->GetHolder<JSObject>(),
5492 accessors);
5493 Handle<Object> result;
5494 if (!maybe_result.ToHandle(&result)) {
5495 result = handle(it->isolate()->pending_exception(), it->isolate());
5496 it->isolate()->clear_pending_exception();
5497 if (has_caught != NULL) *has_caught = true;
5498 }
5499 return result;
5500 }
5501
5502 case LookupIterator::DATA:
5503 return it->GetDataValue();
5504 }
5505 }
5506
5507 return it->isolate()->factory()->undefined_value();
5508 }
5509
5510
5511 // Get debugger related details for an object property, in the following format:
5512 // 0: Property value
5513 // 1: Property details
5514 // 2: Property value is exception
5515 // 3: Getter function if defined
5516 // 4: Setter function if defined
5517 // Items 2-4 are only filled if the property has either a getter or a setter.
5518 RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
5519 HandleScope scope(isolate);
5520
5521 DCHECK(args.length() == 2);
5522
5523 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5524 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
5525
5526 // Make sure to set the current context to the context before the debugger was
5527 // entered (if the debugger is entered). The reason for switching context here
5528 // is that for some property lookups (accessors and interceptors) callbacks
5529 // into the embedding application can occour, and the embedding application
5530 // could have the assumption that its own native context is the current
5531 // context and not some internal debugger context.
5532 SaveContext save(isolate);
5533 if (isolate->debug()->in_debug_scope()) {
5534 isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
5535 }
5536
5537 // Check if the name is trivially convertible to an index and get the element
5538 // if so.
5539 uint32_t index;
5540 if (name->AsArrayIndex(&index)) {
5541 Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
5542 Handle<Object> element_or_char;
5543 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5544 isolate, element_or_char,
5545 Runtime::GetElementOrCharAt(isolate, obj, index));
5546 details->set(0, *element_or_char);
5547 details->set(1,
5548 PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi());
5549 return *isolate->factory()->NewJSArrayWithElements(details);
5550 }
5551
5552 LookupIterator it(obj, name, LookupIterator::HIDDEN);
5553 bool has_caught = false;
5554 Handle<Object> value = DebugGetProperty(&it, &has_caught);
5555 if (!it.IsFound()) return isolate->heap()->undefined_value();
5556
5557 Handle<Object> maybe_pair;
5558 if (it.state() == LookupIterator::ACCESSOR) {
5559 maybe_pair = it.GetAccessors();
5560 }
5561
5562 // If the callback object is a fixed array then it contains JavaScript
5563 // getter and/or setter.
5564 bool has_js_accessors = !maybe_pair.is_null() && maybe_pair->IsAccessorPair();
5565 Handle<FixedArray> details =
5566 isolate->factory()->NewFixedArray(has_js_accessors ? 6 : 3);
5567 details->set(0, *value);
5568 // TODO(verwaest): Get rid of this random way of handling interceptors.
5569 PropertyDetails d = it.state() == LookupIterator::INTERCEPTOR
5570 ? PropertyDetails(NONE, NORMAL, 0)
5571 : it.property_details();
5572 details->set(1, d.AsSmi());
5573 details->set(
5574 2, isolate->heap()->ToBoolean(it.state() == LookupIterator::INTERCEPTOR));
5575 if (has_js_accessors) {
5576 AccessorPair* accessors = AccessorPair::cast(*maybe_pair);
5577 details->set(3, isolate->heap()->ToBoolean(has_caught));
5578 details->set(4, accessors->GetComponent(ACCESSOR_GETTER));
5579 details->set(5, accessors->GetComponent(ACCESSOR_SETTER));
5580 }
5581
5582 return *isolate->factory()->NewJSArrayWithElements(details);
5583 }
5584
5585
5586 RUNTIME_FUNCTION(Runtime_DebugGetProperty) {
5587 HandleScope scope(isolate);
5588
5589 DCHECK(args.length() == 2);
5590
5591 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5592 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
5593
5594 LookupIterator it(obj, name);
5595 return *DebugGetProperty(&it);
5596 }
5597
5598
5599 // Return the property type calculated from the property details.
5600 // args[0]: smi with property details.
5601 RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) {
5602 SealHandleScope shs(isolate);
5603 DCHECK(args.length() == 1);
5604 CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
5605 return Smi::FromInt(static_cast<int>(details.type()));
5606 }
5607
5608
5609 // Return the property attribute calculated from the property details.
5610 // args[0]: smi with property details.
5611 RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) {
5612 SealHandleScope shs(isolate);
5613 DCHECK(args.length() == 1);
5614 CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
5615 return Smi::FromInt(static_cast<int>(details.attributes()));
5616 }
5617
5618
5619 // Return the property insertion index calculated from the property details.
5620 // args[0]: smi with property details.
5621 RUNTIME_FUNCTION(Runtime_DebugPropertyIndexFromDetails) {
5622 SealHandleScope shs(isolate);
5623 DCHECK(args.length() == 1);
5624 CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
5625 // TODO(verwaest): Depends on the type of details.
5626 return Smi::FromInt(details.dictionary_index());
5627 }
5628
5629
5630 // Return property value from named interceptor.
5631 // args[0]: object
5632 // args[1]: property name
5633 RUNTIME_FUNCTION(Runtime_DebugNamedInterceptorPropertyValue) {
5634 HandleScope scope(isolate);
5635 DCHECK(args.length() == 2);
5636 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5637 RUNTIME_ASSERT(obj->HasNamedInterceptor());
5638 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
5639
5640 Handle<Object> result;
5641 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
5642 JSObject::GetProperty(obj, name));
5643 return *result;
5644 }
5645
5646
5647 // Return element value from indexed interceptor.
5648 // args[0]: object
5649 // args[1]: index
5650 RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
5651 HandleScope scope(isolate);
5652 DCHECK(args.length() == 2);
5653 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
5654 RUNTIME_ASSERT(obj->HasIndexedInterceptor());
5655 CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
5656 Handle<Object> result;
5657 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5658 isolate, result, JSObject::GetElementWithInterceptor(obj, obj, index));
5659 return *result;
5660 }
5661
5662
5663 static bool CheckExecutionState(Isolate* isolate, int break_id) {
5664 return !isolate->debug()->debug_context().is_null() &&
5665 isolate->debug()->break_id() != 0 &&
5666 isolate->debug()->break_id() == break_id;
5667 }
5668
5669
5670 RUNTIME_FUNCTION(Runtime_CheckExecutionState) {
5671 SealHandleScope shs(isolate);
5672 DCHECK(args.length() == 1);
5673 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
5674 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
5675 return isolate->heap()->true_value();
5676 }
5677
5678
5679 RUNTIME_FUNCTION(Runtime_GetFrameCount) {
5680 HandleScope scope(isolate);
5681 DCHECK(args.length() == 1);
5682 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
5683 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
5684
5685 // Count all frames which are relevant to debugging stack trace.
5686 int n = 0;
5687 StackFrame::Id id = isolate->debug()->break_frame_id();
5688 if (id == StackFrame::NO_ID) {
5689 // If there is no JavaScript stack frame count is 0.
5690 return Smi::FromInt(0);
5691 }
5692
5693 for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
5694 List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
5695 it.frame()->Summarize(&frames);
5696 for (int i = frames.length() - 1; i >= 0; i--) {
5697 // Omit functions from native scripts.
5698 if (!frames[i].function()->IsFromNativeScript()) n++;
5699 }
5700 }
5701 return Smi::FromInt(n);
5702 }
5703
5704
5705 class FrameInspector {
5706 public:
5707 FrameInspector(JavaScriptFrame* frame, int inlined_jsframe_index,
5708 Isolate* isolate)
5709 : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
5710 // Calculate the deoptimized frame.
5711 if (frame->is_optimized()) {
5712 deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
5713 frame, inlined_jsframe_index, isolate);
5714 }
5715 has_adapted_arguments_ = frame_->has_adapted_arguments();
5716 is_bottommost_ = inlined_jsframe_index == 0;
5717 is_optimized_ = frame_->is_optimized();
5718 }
5719
5720 ~FrameInspector() {
5721 // Get rid of the calculated deoptimized frame if any.
5722 if (deoptimized_frame_ != NULL) {
5723 Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_, isolate_);
5724 }
5725 }
5726
5727 int GetParametersCount() {
5728 return is_optimized_ ? deoptimized_frame_->parameters_count()
5729 : frame_->ComputeParametersCount();
5730 }
5731 int expression_count() { return deoptimized_frame_->expression_count(); }
5732 Object* GetFunction() {
5733 return is_optimized_ ? deoptimized_frame_->GetFunction()
5734 : frame_->function();
5735 }
5736 Object* GetParameter(int index) {
5737 return is_optimized_ ? deoptimized_frame_->GetParameter(index)
5738 : frame_->GetParameter(index);
5739 }
5740 Object* GetExpression(int index) {
5741 return is_optimized_ ? deoptimized_frame_->GetExpression(index)
5742 : frame_->GetExpression(index);
5743 }
5744 int GetSourcePosition() {
5745 return is_optimized_ ? deoptimized_frame_->GetSourcePosition()
5746 : frame_->LookupCode()->SourcePosition(frame_->pc());
5747 }
5748 bool IsConstructor() {
5749 return is_optimized_ && !is_bottommost_
5750 ? deoptimized_frame_->HasConstructStub()
5751 : frame_->IsConstructor();
5752 }
5753 Object* GetContext() {
5754 return is_optimized_ ? deoptimized_frame_->GetContext() : frame_->context();
5755 }
5756
5757 // To inspect all the provided arguments the frame might need to be
5758 // replaced with the arguments frame.
5759 void SetArgumentsFrame(JavaScriptFrame* frame) {
5760 DCHECK(has_adapted_arguments_);
5761 frame_ = frame;
5762 is_optimized_ = frame_->is_optimized();
5763 DCHECK(!is_optimized_);
5764 }
5765
5766 private:
5767 JavaScriptFrame* frame_;
5768 DeoptimizedFrameInfo* deoptimized_frame_;
5769 Isolate* isolate_;
5770 bool is_optimized_;
5771 bool is_bottommost_;
5772 bool has_adapted_arguments_;
5773
5774 DISALLOW_COPY_AND_ASSIGN(FrameInspector);
5775 };
5776
5777
5778 static const int kFrameDetailsFrameIdIndex = 0;
5779 static const int kFrameDetailsReceiverIndex = 1;
5780 static const int kFrameDetailsFunctionIndex = 2;
5781 static const int kFrameDetailsArgumentCountIndex = 3;
5782 static const int kFrameDetailsLocalCountIndex = 4;
5783 static const int kFrameDetailsSourcePositionIndex = 5;
5784 static const int kFrameDetailsConstructCallIndex = 6;
5785 static const int kFrameDetailsAtReturnIndex = 7;
5786 static const int kFrameDetailsFlagsIndex = 8;
5787 static const int kFrameDetailsFirstDynamicIndex = 9;
5788
5789
5790 static SaveContext* FindSavedContextForFrame(Isolate* isolate,
5791 JavaScriptFrame* frame) {
5792 SaveContext* save = isolate->save_context();
5793 while (save != NULL && !save->IsBelowFrame(frame)) {
5794 save = save->prev();
5795 }
5796 DCHECK(save != NULL);
5797 return save;
5798 }
5799
5800
5801 // Advances the iterator to the frame that matches the index and returns the
5802 // inlined frame index, or -1 if not found. Skips native JS functions.
5803 static int FindIndexedNonNativeFrame(JavaScriptFrameIterator* it, int index) {
5804 int count = -1;
5805 for (; !it->done(); it->Advance()) {
5806 List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
5807 it->frame()->Summarize(&frames);
5808 for (int i = frames.length() - 1; i >= 0; i--) {
5809 // Omit functions from native scripts.
5810 if (frames[i].function()->IsFromNativeScript()) continue;
5811 if (++count == index) return i;
5812 }
5813 }
5814 return -1;
5815 }
5816
5817
5818 // Return an array with frame details
5819 // args[0]: number: break id
5820 // args[1]: number: frame index
5821 //
5822 // The array returned contains the following information:
5823 // 0: Frame id
5824 // 1: Receiver
5825 // 2: Function
5826 // 3: Argument count
5827 // 4: Local count
5828 // 5: Source position
5829 // 6: Constructor call
5830 // 7: Is at return
5831 // 8: Flags
5832 // Arguments name, value
5833 // Locals name, value
5834 // Return value if any
5835 RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
5836 HandleScope scope(isolate);
5837 DCHECK(args.length() == 2);
5838 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
5839 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
5840
5841 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
5842 Heap* heap = isolate->heap();
5843
5844 // Find the relevant frame with the requested index.
5845 StackFrame::Id id = isolate->debug()->break_frame_id();
5846 if (id == StackFrame::NO_ID) {
5847 // If there are no JavaScript stack frames return undefined.
5848 return heap->undefined_value();
5849 }
5850
5851 JavaScriptFrameIterator it(isolate, id);
5852 // Inlined frame index in optimized frame, starting from outer function.
5853 int inlined_jsframe_index = FindIndexedNonNativeFrame(&it, index);
5854 if (inlined_jsframe_index == -1) return heap->undefined_value();
5855
5856 FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
5857 bool is_optimized = it.frame()->is_optimized();
5858
5859 // Traverse the saved contexts chain to find the active context for the
5860 // selected frame.
5861 SaveContext* save = FindSavedContextForFrame(isolate, it.frame());
5862
5863 // Get the frame id.
5864 Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
5865
5866 // Find source position in unoptimized code.
5867 int position = frame_inspector.GetSourcePosition();
5868
5869 // Check for constructor frame.
5870 bool constructor = frame_inspector.IsConstructor();
5871
5872 // Get scope info and read from it for local variable information.
5873 Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
5874 Handle<SharedFunctionInfo> shared(function->shared());
5875 Handle<ScopeInfo> scope_info(shared->scope_info());
5876 DCHECK(*scope_info != ScopeInfo::Empty(isolate));
5877
5878 // Get the locals names and values into a temporary array.
5879 int local_count = scope_info->LocalCount();
5880 for (int slot = 0; slot < scope_info->LocalCount(); ++slot) {
5881 // Hide compiler-introduced temporary variables, whether on the stack or on
5882 // the context.
5883 if (scope_info->LocalIsSynthetic(slot)) local_count--;
5884 }
5885
5886 Handle<FixedArray> locals =
5887 isolate->factory()->NewFixedArray(local_count * 2);
5888
5889 // Fill in the values of the locals.
5890 int local = 0;
5891 int i = 0;
5892 for (; i < scope_info->StackLocalCount(); ++i) {
5893 // Use the value from the stack.
5894 if (scope_info->LocalIsSynthetic(i)) continue;
5895 locals->set(local * 2, scope_info->LocalName(i));
5896 locals->set(local * 2 + 1, frame_inspector.GetExpression(i));
5897 local++;
5898 }
5899 if (local < local_count) {
5900 // Get the context containing declarations.
5901 Handle<Context> context(
5902 Context::cast(frame_inspector.GetContext())->declaration_context());
5903 for (; i < scope_info->LocalCount(); ++i) {
5904 if (scope_info->LocalIsSynthetic(i)) continue;
5905 Handle<String> name(scope_info->LocalName(i));
5906 VariableMode mode;
5907 InitializationFlag init_flag;
5908 MaybeAssignedFlag maybe_assigned_flag;
5909 locals->set(local * 2, *name);
5910 int context_slot_index = ScopeInfo::ContextSlotIndex(
5911 scope_info, name, &mode, &init_flag, &maybe_assigned_flag);
5912 Object* value = context->get(context_slot_index);
5913 locals->set(local * 2 + 1, value);
5914 local++;
5915 }
5916 }
5917
5918 // Check whether this frame is positioned at return. If not top
5919 // frame or if the frame is optimized it cannot be at a return.
5920 bool at_return = false;
5921 if (!is_optimized && index == 0) {
5922 at_return = isolate->debug()->IsBreakAtReturn(it.frame());
5923 }
5924
5925 // If positioned just before return find the value to be returned and add it
5926 // to the frame information.
5927 Handle<Object> return_value = isolate->factory()->undefined_value();
5928 if (at_return) {
5929 StackFrameIterator it2(isolate);
5930 Address internal_frame_sp = NULL;
5931 while (!it2.done()) {
5932 if (it2.frame()->is_internal()) {
5933 internal_frame_sp = it2.frame()->sp();
5934 } else {
5935 if (it2.frame()->is_java_script()) {
5936 if (it2.frame()->id() == it.frame()->id()) {
5937 // The internal frame just before the JavaScript frame contains the
5938 // value to return on top. A debug break at return will create an
5939 // internal frame to store the return value (eax/rax/r0) before
5940 // entering the debug break exit frame.
5941 if (internal_frame_sp != NULL) {
5942 return_value =
5943 Handle<Object>(Memory::Object_at(internal_frame_sp), isolate);
5944 break;
5945 }
5946 }
5947 }
5948
5949 // Indicate that the previous frame was not an internal frame.
5950 internal_frame_sp = NULL;
5951 }
5952 it2.Advance();
5953 }
5954 }
5955
5956 // Now advance to the arguments adapter frame (if any). It contains all
5957 // the provided parameters whereas the function frame always have the number
5958 // of arguments matching the functions parameters. The rest of the
5959 // information (except for what is collected above) is the same.
5960 if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
5961 it.AdvanceToArgumentsFrame();
5962 frame_inspector.SetArgumentsFrame(it.frame());
5963 }
5964
5965 // Find the number of arguments to fill. At least fill the number of
5966 // parameters for the function and fill more if more parameters are provided.
5967 int argument_count = scope_info->ParameterCount();
5968 if (argument_count < frame_inspector.GetParametersCount()) {
5969 argument_count = frame_inspector.GetParametersCount();
5970 }
5971
5972 // Calculate the size of the result.
5973 int details_size = kFrameDetailsFirstDynamicIndex +
5974 2 * (argument_count + local_count) + (at_return ? 1 : 0);
5975 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
5976
5977 // Add the frame id.
5978 details->set(kFrameDetailsFrameIdIndex, *frame_id);
5979
5980 // Add the function (same as in function frame).
5981 details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
5982
5983 // Add the arguments count.
5984 details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
5985
5986 // Add the locals count
5987 details->set(kFrameDetailsLocalCountIndex, Smi::FromInt(local_count));
5988
5989 // Add the source position.
5990 if (position != RelocInfo::kNoPosition) {
5991 details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
5992 } else {
5993 details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
5994 }
5995
5996 // Add the constructor information.
5997 details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
5998
5999 // Add the at return information.
6000 details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
6001
6002 // Add flags to indicate information on whether this frame is
6003 // bit 0: invoked in the debugger context.
6004 // bit 1: optimized frame.
6005 // bit 2: inlined in optimized frame
6006 int flags = 0;
6007 if (*save->context() == *isolate->debug()->debug_context()) {
6008 flags |= 1 << 0;
6009 }
6010 if (is_optimized) {
6011 flags |= 1 << 1;
6012 flags |= inlined_jsframe_index << 2;
6013 }
6014 details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
6015
6016 // Fill the dynamic part.
6017 int details_index = kFrameDetailsFirstDynamicIndex;
6018
6019 // Add arguments name and value.
6020 for (int i = 0; i < argument_count; i++) {
6021 // Name of the argument.
6022 if (i < scope_info->ParameterCount()) {
6023 details->set(details_index++, scope_info->ParameterName(i));
6024 } else {
6025 details->set(details_index++, heap->undefined_value());
6026 }
6027
6028 // Parameter value.
6029 if (i < frame_inspector.GetParametersCount()) {
6030 // Get the value from the stack.
6031 details->set(details_index++, frame_inspector.GetParameter(i));
6032 } else {
6033 details->set(details_index++, heap->undefined_value());
6034 }
6035 }
6036
6037 // Add locals name and value from the temporary copy from the function frame.
6038 for (int i = 0; i < local_count * 2; i++) {
6039 details->set(details_index++, locals->get(i));
6040 }
6041
6042 // Add the value being returned.
6043 if (at_return) {
6044 details->set(details_index++, *return_value);
6045 }
6046
6047 // Add the receiver (same as in function frame).
6048 // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
6049 // THE FRAME ITERATOR TO WRAP THE RECEIVER.
6050 Handle<Object> receiver(it.frame()->receiver(), isolate);
6051 if (!receiver->IsJSObject() && shared->strict_mode() == SLOPPY &&
6052 !function->IsBuiltin()) {
6053 // If the receiver is not a JSObject and the function is not a
6054 // builtin or strict-mode we have hit an optimization where a
6055 // value object is not converted into a wrapped JS objects. To
6056 // hide this optimization from the debugger, we wrap the receiver
6057 // by creating correct wrapper object based on the calling frame's
6058 // native context.
6059 it.Advance();
6060 if (receiver->IsUndefined()) {
6061 receiver = handle(function->global_proxy());
6062 } else {
6063 Context* context = Context::cast(it.frame()->context());
6064 Handle<Context> native_context(Context::cast(context->native_context()));
6065 if (!Object::ToObject(isolate, receiver, native_context)
6066 .ToHandle(&receiver)) {
6067 // This only happens if the receiver is forcibly set in %_CallFunction.
6068 return heap->undefined_value();
6069 }
6070 }
6071 }
6072 details->set(kFrameDetailsReceiverIndex, *receiver);
6073
6074 DCHECK_EQ(details_size, details_index);
6075 return *isolate->factory()->NewJSArrayWithElements(details);
6076 }
6077
6078
6079 static bool ParameterIsShadowedByContextLocal(Handle<ScopeInfo> info,
6080 Handle<String> parameter_name) {
6081 VariableMode mode;
6082 InitializationFlag init_flag;
6083 MaybeAssignedFlag maybe_assigned_flag;
6084 return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &init_flag,
6085 &maybe_assigned_flag) != -1;
6086 }
6087
6088
6089 // Create a plain JSObject which materializes the local scope for the specified
6090 // frame.
6091 MUST_USE_RESULT
6092 static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector(
6093 Isolate* isolate, Handle<JSObject> target, Handle<JSFunction> function,
6094 FrameInspector* frame_inspector) {
6095 Handle<SharedFunctionInfo> shared(function->shared());
6096 Handle<ScopeInfo> scope_info(shared->scope_info());
6097
6098 // First fill all parameters.
6099 for (int i = 0; i < scope_info->ParameterCount(); ++i) {
6100 // Do not materialize the parameter if it is shadowed by a context local.
6101 Handle<String> name(scope_info->ParameterName(i));
6102 if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
6103
6104 HandleScope scope(isolate);
6105 Handle<Object> value(i < frame_inspector->GetParametersCount()
6106 ? frame_inspector->GetParameter(i)
6107 : isolate->heap()->undefined_value(),
6108 isolate);
6109 DCHECK(!value->IsTheHole());
6110
6111 RETURN_ON_EXCEPTION(isolate, Runtime::SetObjectProperty(
6112 isolate, target, name, value, SLOPPY),
6113 JSObject);
6114 }
6115
6116 // Second fill all stack locals.
6117 for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
6118 if (scope_info->LocalIsSynthetic(i)) continue;
6119 Handle<String> name(scope_info->StackLocalName(i));
6120 Handle<Object> value(frame_inspector->GetExpression(i), isolate);
6121 if (value->IsTheHole()) continue;
6122
6123 RETURN_ON_EXCEPTION(isolate, Runtime::SetObjectProperty(
6124 isolate, target, name, value, SLOPPY),
6125 JSObject);
6126 }
6127
6128 return target;
6129 }
6130
6131
6132 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate,
6133 Handle<JSObject> target,
6134 Handle<JSFunction> function,
6135 JavaScriptFrame* frame,
6136 int inlined_jsframe_index) {
6137 if (inlined_jsframe_index != 0 || frame->is_optimized()) {
6138 // Optimized frames are not supported.
6139 // TODO(yangguo): make sure all code deoptimized when debugger is active
6140 // and assert that this cannot happen.
6141 return;
6142 }
6143
6144 Handle<SharedFunctionInfo> shared(function->shared());
6145 Handle<ScopeInfo> scope_info(shared->scope_info());
6146
6147 // Parameters.
6148 for (int i = 0; i < scope_info->ParameterCount(); ++i) {
6149 // Shadowed parameters were not materialized.
6150 Handle<String> name(scope_info->ParameterName(i));
6151 if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
6152
6153 DCHECK(!frame->GetParameter(i)->IsTheHole());
6154 HandleScope scope(isolate);
6155 Handle<Object> value =
6156 Object::GetPropertyOrElement(target, name).ToHandleChecked();
6157 frame->SetParameterValue(i, *value);
6158 }
6159
6160 // Stack locals.
6161 for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
6162 if (scope_info->LocalIsSynthetic(i)) continue;
6163 if (frame->GetExpression(i)->IsTheHole()) continue;
6164 HandleScope scope(isolate);
6165 Handle<Object> value = Object::GetPropertyOrElement(
6166 target, handle(scope_info->StackLocalName(i),
6167 isolate)).ToHandleChecked();
6168 frame->SetExpression(i, *value);
6169 }
6170 }
6171
6172
6173 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext(
6174 Isolate* isolate, Handle<JSObject> target, Handle<JSFunction> function,
6175 JavaScriptFrame* frame) {
6176 HandleScope scope(isolate);
6177 Handle<SharedFunctionInfo> shared(function->shared());
6178 Handle<ScopeInfo> scope_info(shared->scope_info());
6179
6180 if (!scope_info->HasContext()) return target;
6181
6182 // Third fill all context locals.
6183 Handle<Context> frame_context(Context::cast(frame->context()));
6184 Handle<Context> function_context(frame_context->declaration_context());
6185 if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, function_context,
6186 target)) {
6187 return MaybeHandle<JSObject>();
6188 }
6189
6190 // Finally copy any properties from the function context extension.
6191 // These will be variables introduced by eval.
6192 if (function_context->closure() == *function) {
6193 if (function_context->has_extension() &&
6194 !function_context->IsNativeContext()) {
6195 Handle<JSObject> ext(JSObject::cast(function_context->extension()));
6196 Handle<FixedArray> keys;
6197 ASSIGN_RETURN_ON_EXCEPTION(
6198 isolate, keys, JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS),
6199 JSObject);
6200
6201 for (int i = 0; i < keys->length(); i++) {
6202 // Names of variables introduced by eval are strings.
6203 DCHECK(keys->get(i)->IsString());
6204 Handle<String> key(String::cast(keys->get(i)));
6205 Handle<Object> value;
6206 ASSIGN_RETURN_ON_EXCEPTION(
6207 isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
6208 RETURN_ON_EXCEPTION(isolate, Runtime::SetObjectProperty(
6209 isolate, target, key, value, SLOPPY),
6210 JSObject);
6211 }
6212 }
6213 }
6214
6215 return target;
6216 }
6217
6218
6219 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope(
6220 Isolate* isolate, JavaScriptFrame* frame, int inlined_jsframe_index) {
6221 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
6222 Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
6223
6224 Handle<JSObject> local_scope =
6225 isolate->factory()->NewJSObject(isolate->object_function());
6226 ASSIGN_RETURN_ON_EXCEPTION(
6227 isolate, local_scope,
6228 MaterializeStackLocalsWithFrameInspector(isolate, local_scope, function,
6229 &frame_inspector),
6230 JSObject);
6231
6232 return MaterializeLocalContext(isolate, local_scope, function, frame);
6233 }
6234
6235
6236 // Set the context local variable value.
6237 static bool SetContextLocalValue(Isolate* isolate, Handle<ScopeInfo> scope_info,
6238 Handle<Context> context,
6239 Handle<String> variable_name,
6240 Handle<Object> new_value) {
6241 for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
6242 Handle<String> next_name(scope_info->ContextLocalName(i));
6243 if (String::Equals(variable_name, next_name)) {
6244 VariableMode mode;
6245 InitializationFlag init_flag;
6246 MaybeAssignedFlag maybe_assigned_flag;
6247 int context_index = ScopeInfo::ContextSlotIndex(
6248 scope_info, next_name, &mode, &init_flag, &maybe_assigned_flag);
6249 context->set(context_index, *new_value);
6250 return true;
6251 }
6252 }
6253
6254 return false;
6255 }
6256
6257
6258 static bool SetLocalVariableValue(Isolate* isolate, JavaScriptFrame* frame,
6259 int inlined_jsframe_index,
6260 Handle<String> variable_name,
6261 Handle<Object> new_value) {
6262 if (inlined_jsframe_index != 0 || frame->is_optimized()) {
6263 // Optimized frames are not supported.
6264 return false;
6265 }
6266
6267 Handle<JSFunction> function(frame->function());
6268 Handle<SharedFunctionInfo> shared(function->shared());
6269 Handle<ScopeInfo> scope_info(shared->scope_info());
6270
6271 bool default_result = false;
6272
6273 // Parameters.
6274 for (int i = 0; i < scope_info->ParameterCount(); ++i) {
6275 HandleScope scope(isolate);
6276 if (String::Equals(handle(scope_info->ParameterName(i)), variable_name)) {
6277 frame->SetParameterValue(i, *new_value);
6278 // Argument might be shadowed in heap context, don't stop here.
6279 default_result = true;
6280 }
6281 }
6282
6283 // Stack locals.
6284 for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
6285 HandleScope scope(isolate);
6286 if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
6287 frame->SetExpression(i, *new_value);
6288 return true;
6289 }
6290 }
6291
6292 if (scope_info->HasContext()) {
6293 // Context locals.
6294 Handle<Context> frame_context(Context::cast(frame->context()));
6295 Handle<Context> function_context(frame_context->declaration_context());
6296 if (SetContextLocalValue(isolate, scope_info, function_context,
6297 variable_name, new_value)) {
6298 return true;
6299 }
6300
6301 // Function context extension. These are variables introduced by eval.
6302 if (function_context->closure() == *function) {
6303 if (function_context->has_extension() &&
6304 !function_context->IsNativeContext()) {
6305 Handle<JSObject> ext(JSObject::cast(function_context->extension()));
6306
6307 Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
6308 DCHECK(maybe.has_value);
6309 if (maybe.value) {
6310 // We don't expect this to do anything except replacing
6311 // property value.
6312 Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
6313 SLOPPY).Assert();
6314 return true;
6315 }
6316 }
6317 }
6318 }
6319
6320 return default_result;
6321 }
6322
6323
6324 // Create a plain JSObject which materializes the closure content for the
6325 // context.
6326 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure(
6327 Isolate* isolate, Handle<Context> context) {
6328 DCHECK(context->IsFunctionContext());
6329
6330 Handle<SharedFunctionInfo> shared(context->closure()->shared());
6331 Handle<ScopeInfo> scope_info(shared->scope_info());
6332
6333 // Allocate and initialize a JSObject with all the content of this function
6334 // closure.
6335 Handle<JSObject> closure_scope =
6336 isolate->factory()->NewJSObject(isolate->object_function());
6337
6338 // Fill all context locals to the context extension.
6339 if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
6340 closure_scope)) {
6341 return MaybeHandle<JSObject>();
6342 }
6343
6344 // Finally copy any properties from the function context extension. This will
6345 // be variables introduced by eval.
6346 if (context->has_extension()) {
6347 Handle<JSObject> ext(JSObject::cast(context->extension()));
6348 Handle<FixedArray> keys;
6349 ASSIGN_RETURN_ON_EXCEPTION(
6350 isolate, keys, JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS),
6351 JSObject);
6352
6353 for (int i = 0; i < keys->length(); i++) {
6354 HandleScope scope(isolate);
6355 // Names of variables introduced by eval are strings.
6356 DCHECK(keys->get(i)->IsString());
6357 Handle<String> key(String::cast(keys->get(i)));
6358 Handle<Object> value;
6359 ASSIGN_RETURN_ON_EXCEPTION(
6360 isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
6361 RETURN_ON_EXCEPTION(isolate, Runtime::DefineObjectProperty(
6362 closure_scope, key, value, NONE),
6363 JSObject);
6364 }
6365 }
6366
6367 return closure_scope;
6368 }
6369
6370
6371 // This method copies structure of MaterializeClosure method above.
6372 static bool SetClosureVariableValue(Isolate* isolate, Handle<Context> context,
6373 Handle<String> variable_name,
6374 Handle<Object> new_value) {
6375 DCHECK(context->IsFunctionContext());
6376
6377 Handle<SharedFunctionInfo> shared(context->closure()->shared());
6378 Handle<ScopeInfo> scope_info(shared->scope_info());
6379
6380 // Context locals to the context extension.
6381 if (SetContextLocalValue(isolate, scope_info, context, variable_name,
6382 new_value)) {
6383 return true;
6384 }
6385
6386 // Properties from the function context extension. This will
6387 // be variables introduced by eval.
6388 if (context->has_extension()) {
6389 Handle<JSObject> ext(JSObject::cast(context->extension()));
6390 Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
6391 DCHECK(maybe.has_value);
6392 if (maybe.value) {
6393 // We don't expect this to do anything except replacing property value.
6394 Runtime::DefineObjectProperty(ext, variable_name, new_value, NONE)
6395 .Assert();
6396 return true;
6397 }
6398 }
6399
6400 return false;
6401 }
6402
6403
6404 // Create a plain JSObject which materializes the scope for the specified
6405 // catch context.
6406 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
6407 Isolate* isolate, Handle<Context> context) {
6408 DCHECK(context->IsCatchContext());
6409 Handle<String> name(String::cast(context->extension()));
6410 Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
6411 isolate);
6412 Handle<JSObject> catch_scope =
6413 isolate->factory()->NewJSObject(isolate->object_function());
6414 RETURN_ON_EXCEPTION(isolate, Runtime::DefineObjectProperty(
6415 catch_scope, name, thrown_object, NONE),
6416 JSObject);
6417 return catch_scope;
6418 }
6419
6420
6421 static bool SetCatchVariableValue(Isolate* isolate, Handle<Context> context,
6422 Handle<String> variable_name,
6423 Handle<Object> new_value) {
6424 DCHECK(context->IsCatchContext());
6425 Handle<String> name(String::cast(context->extension()));
6426 if (!String::Equals(name, variable_name)) {
6427 return false;
6428 }
6429 context->set(Context::THROWN_OBJECT_INDEX, *new_value);
6430 return true;
6431 }
6432
6433
6434 // Create a plain JSObject which materializes the block scope for the specified
6435 // block context.
6436 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope(
6437 Isolate* isolate, Handle<Context> context) {
6438 DCHECK(context->IsBlockContext());
6439 Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
6440
6441 // Allocate and initialize a JSObject with all the arguments, stack locals
6442 // heap locals and extension properties of the debugged function.
6443 Handle<JSObject> block_scope =
6444 isolate->factory()->NewJSObject(isolate->object_function());
6445
6446 // Fill all context locals.
6447 if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
6448 block_scope)) {
6449 return MaybeHandle<JSObject>();
6450 }
6451
6452 return block_scope;
6453 }
6454
6455
6456 // Create a plain JSObject which materializes the module scope for the specified
6457 // module context.
6458 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope(
6459 Isolate* isolate, Handle<Context> context) {
6460 DCHECK(context->IsModuleContext());
6461 Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
6462
6463 // Allocate and initialize a JSObject with all the members of the debugged
6464 // module.
6465 Handle<JSObject> module_scope =
6466 isolate->factory()->NewJSObject(isolate->object_function());
6467
6468 // Fill all context locals.
6469 if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
6470 module_scope)) {
6471 return MaybeHandle<JSObject>();
6472 }
6473
6474 return module_scope;
6475 }
6476
6477
6478 // Iterate over the actual scopes visible from a stack frame or from a closure.
6479 // The iteration proceeds from the innermost visible nested scope outwards.
6480 // All scopes are backed by an actual context except the local scope,
6481 // which is inserted "artificially" in the context chain.
6482 class ScopeIterator {
6483 public:
6484 enum ScopeType {
6485 ScopeTypeGlobal = 0,
6486 ScopeTypeLocal,
6487 ScopeTypeWith,
6488 ScopeTypeClosure,
6489 ScopeTypeCatch,
6490 ScopeTypeBlock,
6491 ScopeTypeModule
6492 };
6493
6494 ScopeIterator(Isolate* isolate, JavaScriptFrame* frame,
6495 int inlined_jsframe_index, bool ignore_nested_scopes = false)
6496 : isolate_(isolate),
6497 frame_(frame),
6498 inlined_jsframe_index_(inlined_jsframe_index),
6499 function_(frame->function()),
6500 context_(Context::cast(frame->context())),
6501 nested_scope_chain_(4),
6502 failed_(false) {
6503 // Catch the case when the debugger stops in an internal function.
6504 Handle<SharedFunctionInfo> shared_info(function_->shared());
6505 Handle<ScopeInfo> scope_info(shared_info->scope_info());
6506 if (shared_info->script() == isolate->heap()->undefined_value()) {
6507 while (context_->closure() == *function_) {
6508 context_ = Handle<Context>(context_->previous(), isolate_);
6509 }
6510 return;
6511 }
6512
6513 // Get the debug info (create it if it does not exist).
6514 if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) {
6515 // Return if ensuring debug info failed.
6516 return;
6517 }
6518
6519 // Currently it takes too much time to find nested scopes due to script
6520 // parsing. Sometimes we want to run the ScopeIterator as fast as possible
6521 // (for example, while collecting async call stacks on every
6522 // addEventListener call), even if we drop some nested scopes.
6523 // Later we may optimize getting the nested scopes (cache the result?)
6524 // and include nested scopes into the "fast" iteration case as well.
6525 if (!ignore_nested_scopes) {
6526 Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info);
6527
6528 // Find the break point where execution has stopped.
6529 BreakLocationIterator break_location_iterator(debug_info,
6530 ALL_BREAK_LOCATIONS);
6531 // pc points to the instruction after the current one, possibly a break
6532 // location as well. So the "- 1" to exclude it from the search.
6533 break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
6534
6535 // Within the return sequence at the moment it is not possible to
6536 // get a source position which is consistent with the current scope chain.
6537 // Thus all nested with, catch and block contexts are skipped and we only
6538 // provide the function scope.
6539 ignore_nested_scopes = break_location_iterator.IsExit();
6540 }
6541
6542 if (ignore_nested_scopes) {
6543 if (scope_info->HasContext()) {
6544 context_ = Handle<Context>(context_->declaration_context(), isolate_);
6545 } else {
6546 while (context_->closure() == *function_) {
6547 context_ = Handle<Context>(context_->previous(), isolate_);
6548 }
6549 }
6550 if (scope_info->scope_type() == FUNCTION_SCOPE) {
6551 nested_scope_chain_.Add(scope_info);
6552 }
6553 } else {
6554 // Reparse the code and analyze the scopes.
6555 Handle<Script> script(Script::cast(shared_info->script()));
6556 Scope* scope = NULL;
6557
6558 // Check whether we are in global, eval or function code.
6559 Handle<ScopeInfo> scope_info(shared_info->scope_info());
6560 if (scope_info->scope_type() != FUNCTION_SCOPE) {
6561 // Global or eval code.
6562 CompilationInfoWithZone info(script);
6563 if (scope_info->scope_type() == GLOBAL_SCOPE) {
6564 info.MarkAsGlobal();
6565 } else {
6566 DCHECK(scope_info->scope_type() == EVAL_SCOPE);
6567 info.MarkAsEval();
6568 info.SetContext(Handle<Context>(function_->context()));
6569 }
6570 if (Parser::Parse(&info) && Scope::Analyze(&info)) {
6571 scope = info.function()->scope();
6572 }
6573 RetrieveScopeChain(scope, shared_info);
6574 } else {
6575 // Function code
6576 CompilationInfoWithZone info(shared_info);
6577 if (Parser::Parse(&info) && Scope::Analyze(&info)) {
6578 scope = info.function()->scope();
6579 }
6580 RetrieveScopeChain(scope, shared_info);
6581 }
6582 }
6583 }
6584
6585 ScopeIterator(Isolate* isolate, Handle<JSFunction> function)
6586 : isolate_(isolate),
6587 frame_(NULL),
6588 inlined_jsframe_index_(0),
6589 function_(function),
6590 context_(function->context()),
6591 failed_(false) {
6592 if (function->IsBuiltin()) {
6593 context_ = Handle<Context>();
6594 }
6595 }
6596
6597 // More scopes?
6598 bool Done() {
6599 DCHECK(!failed_);
6600 return context_.is_null();
6601 }
6602
6603 bool Failed() { return failed_; }
6604
6605 // Move to the next scope.
6606 void Next() {
6607 DCHECK(!failed_);
6608 ScopeType scope_type = Type();
6609 if (scope_type == ScopeTypeGlobal) {
6610 // The global scope is always the last in the chain.
6611 DCHECK(context_->IsNativeContext());
6612 context_ = Handle<Context>();
6613 return;
6614 }
6615 if (nested_scope_chain_.is_empty()) {
6616 context_ = Handle<Context>(context_->previous(), isolate_);
6617 } else {
6618 if (nested_scope_chain_.last()->HasContext()) {
6619 DCHECK(context_->previous() != NULL);
6620 context_ = Handle<Context>(context_->previous(), isolate_);
6621 }
6622 nested_scope_chain_.RemoveLast();
6623 }
6624 }
6625
6626 // Return the type of the current scope.
6627 ScopeType Type() {
6628 DCHECK(!failed_);
6629 if (!nested_scope_chain_.is_empty()) {
6630 Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
6631 switch (scope_info->scope_type()) {
6632 case FUNCTION_SCOPE:
6633 DCHECK(context_->IsFunctionContext() || !scope_info->HasContext());
6634 return ScopeTypeLocal;
6635 case MODULE_SCOPE:
6636 DCHECK(context_->IsModuleContext());
6637 return ScopeTypeModule;
6638 case GLOBAL_SCOPE:
6639 DCHECK(context_->IsNativeContext());
6640 return ScopeTypeGlobal;
6641 case WITH_SCOPE:
6642 DCHECK(context_->IsWithContext());
6643 return ScopeTypeWith;
6644 case CATCH_SCOPE:
6645 DCHECK(context_->IsCatchContext());
6646 return ScopeTypeCatch;
6647 case BLOCK_SCOPE:
6648 DCHECK(!scope_info->HasContext() || context_->IsBlockContext());
6649 return ScopeTypeBlock;
6650 case EVAL_SCOPE:
6651 UNREACHABLE();
6652 }
6653 }
6654 if (context_->IsNativeContext()) {
6655 DCHECK(context_->global_object()->IsGlobalObject());
6656 return ScopeTypeGlobal;
6657 }
6658 if (context_->IsFunctionContext()) {
6659 return ScopeTypeClosure;
6660 }
6661 if (context_->IsCatchContext()) {
6662 return ScopeTypeCatch;
6663 }
6664 if (context_->IsBlockContext()) {
6665 return ScopeTypeBlock;
6666 }
6667 if (context_->IsModuleContext()) {
6668 return ScopeTypeModule;
6669 }
6670 DCHECK(context_->IsWithContext());
6671 return ScopeTypeWith;
6672 }
6673
6674 // Return the JavaScript object with the content of the current scope.
6675 MaybeHandle<JSObject> ScopeObject() {
6676 DCHECK(!failed_);
6677 switch (Type()) {
6678 case ScopeIterator::ScopeTypeGlobal:
6679 return Handle<JSObject>(CurrentContext()->global_object());
6680 case ScopeIterator::ScopeTypeLocal:
6681 // Materialize the content of the local scope into a JSObject.
6682 DCHECK(nested_scope_chain_.length() == 1);
6683 return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
6684 case ScopeIterator::ScopeTypeWith:
6685 // Return the with object.
6686 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
6687 case ScopeIterator::ScopeTypeCatch:
6688 return MaterializeCatchScope(isolate_, CurrentContext());
6689 case ScopeIterator::ScopeTypeClosure:
6690 // Materialize the content of the closure scope into a JSObject.
6691 return MaterializeClosure(isolate_, CurrentContext());
6692 case ScopeIterator::ScopeTypeBlock:
6693 return MaterializeBlockScope(isolate_, CurrentContext());
6694 case ScopeIterator::ScopeTypeModule:
6695 return MaterializeModuleScope(isolate_, CurrentContext());
6696 }
6697 UNREACHABLE();
6698 return Handle<JSObject>();
6699 }
6700
6701 bool SetVariableValue(Handle<String> variable_name,
6702 Handle<Object> new_value) {
6703 DCHECK(!failed_);
6704 switch (Type()) {
6705 case ScopeIterator::ScopeTypeGlobal:
6706 break;
6707 case ScopeIterator::ScopeTypeLocal:
6708 return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_,
6709 variable_name, new_value);
6710 case ScopeIterator::ScopeTypeWith:
6711 break;
6712 case ScopeIterator::ScopeTypeCatch:
6713 return SetCatchVariableValue(isolate_, CurrentContext(), variable_name,
6714 new_value);
6715 case ScopeIterator::ScopeTypeClosure:
6716 return SetClosureVariableValue(isolate_, CurrentContext(),
6717 variable_name, new_value);
6718 case ScopeIterator::ScopeTypeBlock:
6719 // TODO(2399): should we implement it?
6720 break;
6721 case ScopeIterator::ScopeTypeModule:
6722 // TODO(2399): should we implement it?
6723 break;
6724 }
6725 return false;
6726 }
6727
6728 Handle<ScopeInfo> CurrentScopeInfo() {
6729 DCHECK(!failed_);
6730 if (!nested_scope_chain_.is_empty()) {
6731 return nested_scope_chain_.last();
6732 } else if (context_->IsBlockContext()) {
6733 return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
6734 } else if (context_->IsFunctionContext()) {
6735 return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
6736 }
6737 return Handle<ScopeInfo>::null();
6738 }
6739
6740 // Return the context for this scope. For the local context there might not
6741 // be an actual context.
6742 Handle<Context> CurrentContext() {
6743 DCHECK(!failed_);
6744 if (Type() == ScopeTypeGlobal || nested_scope_chain_.is_empty()) {
6745 return context_;
6746 } else if (nested_scope_chain_.last()->HasContext()) {
6747 return context_;
6748 } else {
6749 return Handle<Context>();
6750 }
6751 }
6752
6753 #ifdef DEBUG
6754 // Debug print of the content of the current scope.
6755 void DebugPrint() {
6756 OFStream os(stdout);
6757 DCHECK(!failed_);
6758 switch (Type()) {
6759 case ScopeIterator::ScopeTypeGlobal:
6760 os << "Global:\n";
6761 CurrentContext()->Print(os);
6762 break;
6763
6764 case ScopeIterator::ScopeTypeLocal: {
6765 os << "Local:\n";
6766 function_->shared()->scope_info()->Print();
6767 if (!CurrentContext().is_null()) {
6768 CurrentContext()->Print(os);
6769 if (CurrentContext()->has_extension()) {
6770 Handle<Object> extension(CurrentContext()->extension(), isolate_);
6771 if (extension->IsJSContextExtensionObject()) {
6772 extension->Print(os);
6773 }
6774 }
6775 }
6776 break;
6777 }
6778
6779 case ScopeIterator::ScopeTypeWith:
6780 os << "With:\n";
6781 CurrentContext()->extension()->Print(os);
6782 break;
6783
6784 case ScopeIterator::ScopeTypeCatch:
6785 os << "Catch:\n";
6786 CurrentContext()->extension()->Print(os);
6787 CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print(os);
6788 break;
6789
6790 case ScopeIterator::ScopeTypeClosure:
6791 os << "Closure:\n";
6792 CurrentContext()->Print(os);
6793 if (CurrentContext()->has_extension()) {
6794 Handle<Object> extension(CurrentContext()->extension(), isolate_);
6795 if (extension->IsJSContextExtensionObject()) {
6796 extension->Print(os);
6797 }
6798 }
6799 break;
6800
6801 default:
6802 UNREACHABLE();
6803 }
6804 PrintF("\n");
6805 }
6806 #endif
6807
6808 private:
6809 Isolate* isolate_;
6810 JavaScriptFrame* frame_;
6811 int inlined_jsframe_index_;
6812 Handle<JSFunction> function_;
6813 Handle<Context> context_;
6814 List<Handle<ScopeInfo> > nested_scope_chain_;
6815 bool failed_;
6816
6817 void RetrieveScopeChain(Scope* scope,
6818 Handle<SharedFunctionInfo> shared_info) {
6819 if (scope != NULL) {
6820 int source_position = shared_info->code()->SourcePosition(frame_->pc());
6821 scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
6822 } else {
6823 // A failed reparse indicates that the preparser has diverged from the
6824 // parser or that the preparse data given to the initial parse has been
6825 // faulty. We fail in debug mode but in release mode we only provide the
6826 // information we get from the context chain but nothing about
6827 // completely stack allocated scopes or stack allocated locals.
6828 // Or it could be due to stack overflow.
6829 DCHECK(isolate_->has_pending_exception());
6830 failed_ = true;
6831 }
6832 }
6833
6834 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
6835 };
6836
6837
6838 RUNTIME_FUNCTION(Runtime_GetScopeCount) {
6839 HandleScope scope(isolate);
6840 DCHECK(args.length() == 2);
6841 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
6842 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
6843
6844 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
6845
6846 // Get the frame where the debugging is performed.
6847 StackFrame::Id id = UnwrapFrameId(wrapped_id);
6848 JavaScriptFrameIterator it(isolate, id);
6849 JavaScriptFrame* frame = it.frame();
6850
6851 // Count the visible scopes.
6852 int n = 0;
6853 for (ScopeIterator it(isolate, frame, 0); !it.Done(); it.Next()) {
6854 n++;
6855 }
6856
6857 return Smi::FromInt(n);
6858 }
6859
6860
6861 // Returns the list of step-in positions (text offset) in a function of the
6862 // stack frame in a range from the current debug break position to the end
6863 // of the corresponding statement.
6864 RUNTIME_FUNCTION(Runtime_GetStepInPositions) {
6865 HandleScope scope(isolate);
6866 DCHECK(args.length() == 2);
6867 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
6868 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
6869
6870 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
6871
6872 // Get the frame where the debugging is performed.
6873 StackFrame::Id id = UnwrapFrameId(wrapped_id);
6874 JavaScriptFrameIterator frame_it(isolate, id);
6875 RUNTIME_ASSERT(!frame_it.done());
6876
6877 JavaScriptFrame* frame = frame_it.frame();
6878
6879 Handle<JSFunction> fun = Handle<JSFunction>(frame->function());
6880 Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>(fun->shared());
6881
6882 if (!isolate->debug()->EnsureDebugInfo(shared, fun)) {
6883 return isolate->heap()->undefined_value();
6884 }
6885
6886 Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared);
6887
6888 int len = 0;
6889 Handle<JSArray> array(isolate->factory()->NewJSArray(10));
6890 // Find the break point where execution has stopped.
6891 BreakLocationIterator break_location_iterator(debug_info,
6892 ALL_BREAK_LOCATIONS);
6893
6894 break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
6895 int current_statement_pos = break_location_iterator.statement_position();
6896
6897 while (!break_location_iterator.Done()) {
6898 bool accept;
6899 if (break_location_iterator.pc() > frame->pc()) {
6900 accept = true;
6901 } else {
6902 StackFrame::Id break_frame_id = isolate->debug()->break_frame_id();
6903 // The break point is near our pc. Could be a step-in possibility,
6904 // that is currently taken by active debugger call.
6905 if (break_frame_id == StackFrame::NO_ID) {
6906 // We are not stepping.
6907 accept = false;
6908 } else {
6909 JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id);
6910 // If our frame is a top frame and we are stepping, we can do step-in
6911 // at this place.
6912 accept = additional_frame_it.frame()->id() == id;
6913 }
6914 }
6915 if (accept) {
6916 if (break_location_iterator.IsStepInLocation(isolate)) {
6917 Smi* position_value = Smi::FromInt(break_location_iterator.position());
6918 RETURN_FAILURE_ON_EXCEPTION(
6919 isolate, JSObject::SetElement(
6920 array, len, Handle<Object>(position_value, isolate),
6921 NONE, SLOPPY));
6922 len++;
6923 }
6924 }
6925 // Advance iterator.
6926 break_location_iterator.Next();
6927 if (current_statement_pos != break_location_iterator.statement_position()) {
6928 break;
6929 }
6930 }
6931 return *array;
6932 }
6933
6934
6935 static const int kScopeDetailsTypeIndex = 0;
6936 static const int kScopeDetailsObjectIndex = 1;
6937 static const int kScopeDetailsSize = 2;
6938
6939
6940 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScopeDetails(
6941 Isolate* isolate, ScopeIterator* it) {
6942 // Calculate the size of the result.
6943 int details_size = kScopeDetailsSize;
6944 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
6945
6946 // Fill in scope details.
6947 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type()));
6948 Handle<JSObject> scope_object;
6949 ASSIGN_RETURN_ON_EXCEPTION(isolate, scope_object, it->ScopeObject(),
6950 JSObject);
6951 details->set(kScopeDetailsObjectIndex, *scope_object);
6952
6953 return isolate->factory()->NewJSArrayWithElements(details);
6954 }
6955
6956
6957 // Return an array with scope details
6958 // args[0]: number: break id
6959 // args[1]: number: frame index
6960 // args[2]: number: inlined frame index
6961 // args[3]: number: scope index
6962 //
6963 // The array returned contains the following information:
6964 // 0: Scope type
6965 // 1: Scope object
6966 RUNTIME_FUNCTION(Runtime_GetScopeDetails) {
6967 HandleScope scope(isolate);
6968 DCHECK(args.length() == 4);
6969 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
6970 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
6971
6972 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
6973 CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
6974 CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
6975
6976 // Get the frame where the debugging is performed.
6977 StackFrame::Id id = UnwrapFrameId(wrapped_id);
6978 JavaScriptFrameIterator frame_it(isolate, id);
6979 JavaScriptFrame* frame = frame_it.frame();
6980
6981 // Find the requested scope.
6982 int n = 0;
6983 ScopeIterator it(isolate, frame, inlined_jsframe_index);
6984 for (; !it.Done() && n < index; it.Next()) {
6985 n++;
6986 }
6987 if (it.Done()) {
6988 return isolate->heap()->undefined_value();
6989 }
6990 Handle<JSObject> details;
6991 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details,
6992 MaterializeScopeDetails(isolate, &it));
6993 return *details;
6994 }
6995
6996
6997 // Return an array of scope details
6998 // args[0]: number: break id
6999 // args[1]: number: frame index
7000 // args[2]: number: inlined frame index
7001 // args[3]: boolean: ignore nested scopes
7002 //
7003 // The array returned contains arrays with the following information:
7004 // 0: Scope type
7005 // 1: Scope object
7006 RUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
7007 HandleScope scope(isolate);
7008 DCHECK(args.length() == 3 || args.length() == 4);
7009 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
7010 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
7011
7012 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
7013 CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
7014
7015 bool ignore_nested_scopes = false;
7016 if (args.length() == 4) {
7017 CONVERT_BOOLEAN_ARG_CHECKED(flag, 3);
7018 ignore_nested_scopes = flag;
7019 }
7020
7021 // Get the frame where the debugging is performed.
7022 StackFrame::Id id = UnwrapFrameId(wrapped_id);
7023 JavaScriptFrameIterator frame_it(isolate, id);
7024 JavaScriptFrame* frame = frame_it.frame();
7025
7026 List<Handle<JSObject> > result(4);
7027 ScopeIterator it(isolate, frame, inlined_jsframe_index, ignore_nested_scopes);
7028 for (; !it.Done(); it.Next()) {
7029 Handle<JSObject> details;
7030 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details,
7031 MaterializeScopeDetails(isolate, &it));
7032 result.Add(details);
7033 }
7034
7035 Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length());
7036 for (int i = 0; i < result.length(); ++i) {
7037 array->set(i, *result[i]);
7038 }
7039 return *isolate->factory()->NewJSArrayWithElements(array);
7040 }
7041
7042
7043 RUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) {
7044 HandleScope scope(isolate);
7045 DCHECK(args.length() == 1);
7046
7047 // Check arguments.
7048 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
7049
7050 // Count the visible scopes.
7051 int n = 0;
7052 for (ScopeIterator it(isolate, fun); !it.Done(); it.Next()) {
7053 n++;
7054 }
7055
7056 return Smi::FromInt(n);
7057 }
7058
7059
7060 RUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) {
7061 HandleScope scope(isolate);
7062 DCHECK(args.length() == 2);
7063
7064 // Check arguments.
7065 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
7066 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
7067
7068 // Find the requested scope.
7069 int n = 0;
7070 ScopeIterator it(isolate, fun);
7071 for (; !it.Done() && n < index; it.Next()) {
7072 n++;
7073 }
7074 if (it.Done()) {
7075 return isolate->heap()->undefined_value();
7076 }
7077
7078 Handle<JSObject> details;
7079 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details,
7080 MaterializeScopeDetails(isolate, &it));
7081 return *details;
7082 }
7083
7084
7085 static bool SetScopeVariableValue(ScopeIterator* it, int index,
7086 Handle<String> variable_name,
7087 Handle<Object> new_value) {
7088 for (int n = 0; !it->Done() && n < index; it->Next()) {
7089 n++;
7090 }
7091 if (it->Done()) {
7092 return false;
7093 }
7094 return it->SetVariableValue(variable_name, new_value);
7095 }
7096
7097
7098 // Change variable value in closure or local scope
7099 // args[0]: number or JsFunction: break id or function
7100 // args[1]: number: frame index (when arg[0] is break id)
7101 // args[2]: number: inlined frame index (when arg[0] is break id)
7102 // args[3]: number: scope index
7103 // args[4]: string: variable name
7104 // args[5]: object: new value
7105 //
7106 // Return true if success and false otherwise
7107 RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
7108 HandleScope scope(isolate);
7109 DCHECK(args.length() == 6);
7110
7111 // Check arguments.
7112 CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
7113 CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
7114 CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 5);
7115
7116 bool res;
7117 if (args[0]->IsNumber()) {
7118 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
7119 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
7120
7121 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
7122 CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
7123
7124 // Get the frame where the debugging is performed.
7125 StackFrame::Id id = UnwrapFrameId(wrapped_id);
7126 JavaScriptFrameIterator frame_it(isolate, id);
7127 JavaScriptFrame* frame = frame_it.frame();
7128
7129 ScopeIterator it(isolate, frame, inlined_jsframe_index);
7130 res = SetScopeVariableValue(&it, index, variable_name, new_value);
7131 } else {
7132 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
7133 ScopeIterator it(isolate, fun);
7134 res = SetScopeVariableValue(&it, index, variable_name, new_value);
7135 }
7136
7137 return isolate->heap()->ToBoolean(res);
7138 }
7139
7140
7141 RUNTIME_FUNCTION(Runtime_DebugPrintScopes) {
7142 HandleScope scope(isolate);
7143 DCHECK(args.length() == 0);
7144
7145 #ifdef DEBUG
7146 // Print the scopes for the top frame.
7147 StackFrameLocator locator(isolate);
7148 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
7149 for (ScopeIterator it(isolate, frame, 0); !it.Done(); it.Next()) {
7150 it.DebugPrint();
7151 }
7152 #endif
7153 return isolate->heap()->undefined_value();
7154 }
7155
7156
7157 RUNTIME_FUNCTION(Runtime_GetThreadCount) {
7158 HandleScope scope(isolate);
7159 DCHECK(args.length() == 1);
7160 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
7161 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
7162
7163 // Count all archived V8 threads.
7164 int n = 0;
7165 for (ThreadState* thread = isolate->thread_manager()->FirstThreadStateInUse();
7166 thread != NULL; thread = thread->Next()) {
7167 n++;
7168 }
7169
7170 // Total number of threads is current thread and archived threads.
7171 return Smi::FromInt(n + 1);
7172 }
7173
7174
7175 static const int kThreadDetailsCurrentThreadIndex = 0;
7176 static const int kThreadDetailsThreadIdIndex = 1;
7177 static const int kThreadDetailsSize = 2;
7178
7179 // Return an array with thread details
7180 // args[0]: number: break id
7181 // args[1]: number: thread index
7182 //
7183 // The array returned contains the following information:
7184 // 0: Is current thread?
7185 // 1: Thread id
7186 RUNTIME_FUNCTION(Runtime_GetThreadDetails) {
7187 HandleScope scope(isolate);
7188 DCHECK(args.length() == 2);
7189 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
7190 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
7191
7192 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
7193
7194 // Allocate array for result.
7195 Handle<FixedArray> details =
7196 isolate->factory()->NewFixedArray(kThreadDetailsSize);
7197
7198 // Thread index 0 is current thread.
7199 if (index == 0) {
7200 // Fill the details.
7201 details->set(kThreadDetailsCurrentThreadIndex,
7202 isolate->heap()->true_value());
7203 details->set(kThreadDetailsThreadIdIndex,
7204 Smi::FromInt(ThreadId::Current().ToInteger()));
7205 } else {
7206 // Find the thread with the requested index.
7207 int n = 1;
7208 ThreadState* thread = isolate->thread_manager()->FirstThreadStateInUse();
7209 while (index != n && thread != NULL) {
7210 thread = thread->Next();
7211 n++;
7212 }
7213 if (thread == NULL) {
7214 return isolate->heap()->undefined_value();
7215 }
7216
7217 // Fill the details.
7218 details->set(kThreadDetailsCurrentThreadIndex,
7219 isolate->heap()->false_value());
7220 details->set(kThreadDetailsThreadIdIndex,
7221 Smi::FromInt(thread->id().ToInteger()));
7222 }
7223
7224 // Convert to JS array and return.
7225 return *isolate->factory()->NewJSArrayWithElements(details);
7226 }
7227
7228
7229 // Sets the disable break state
7230 // args[0]: disable break state
7231 RUNTIME_FUNCTION(Runtime_SetDisableBreak) {
7232 HandleScope scope(isolate);
7233 DCHECK(args.length() == 1);
7234 CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
7235 isolate->debug()->set_disable_break(disable_break);
7236 return isolate->heap()->undefined_value();
7237 }
7238
7239
7240 static bool IsPositionAlignmentCodeCorrect(int alignment) {
7241 return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
7242 }
7243
7244
7245 RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
7246 HandleScope scope(isolate);
7247 DCHECK(args.length() == 2);
7248
7249 CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
7250 CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
7251
7252 if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
7253 return isolate->ThrowIllegalOperation();
7254 }
7255 BreakPositionAlignment alignment =
7256 static_cast<BreakPositionAlignment>(statement_aligned_code);
7257
7258 Handle<SharedFunctionInfo> shared(fun->shared());
7259 // Find the number of break points
7260 Handle<Object> break_locations =
7261 Debug::GetSourceBreakLocations(shared, alignment);
7262 if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
7263 // Return array as JS array
7264 return *isolate->factory()->NewJSArrayWithElements(
7265 Handle<FixedArray>::cast(break_locations));
7266 }
7267
7268
7269 // Set a break point in a function.
7270 // args[0]: function
7271 // args[1]: number: break source position (within the function source)
7272 // args[2]: number: break point object
7273 RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
7274 HandleScope scope(isolate);
7275 DCHECK(args.length() == 3);
7276 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
7277 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
7278 RUNTIME_ASSERT(source_position >= function->shared()->start_position() &&
7279 source_position <= function->shared()->end_position());
7280 CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
7281
7282 // Set break point.
7283 RUNTIME_ASSERT(isolate->debug()->SetBreakPoint(
7284 function, break_point_object_arg, &source_position));
7285
7286 return Smi::FromInt(source_position);
7287 }
7288
7289
7290 // Changes the state of a break point in a script and returns source position
7291 // where break point was set. NOTE: Regarding performance see the NOTE for
7292 // GetScriptFromScriptData.
7293 // args[0]: script to set break point in
7294 // args[1]: number: break source position (within the script source)
7295 // args[2]: number, breakpoint position alignment
7296 // args[3]: number: break point object
7297 RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
7298 HandleScope scope(isolate);
7299 DCHECK(args.length() == 4);
7300 CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
7301 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
7302 RUNTIME_ASSERT(source_position >= 0);
7303 CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
7304 CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 3);
7305
7306 if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
7307 return isolate->ThrowIllegalOperation();
7308 }
7309 BreakPositionAlignment alignment =
7310 static_cast<BreakPositionAlignment>(statement_aligned_code);
7311
7312 // Get the script from the script wrapper.
7313 RUNTIME_ASSERT(wrapper->value()->IsScript());
7314 Handle<Script> script(Script::cast(wrapper->value()));
7315
7316 // Set break point.
7317 if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
7318 &source_position, alignment)) {
7319 return isolate->heap()->undefined_value();
7320 }
7321
7322 return Smi::FromInt(source_position);
7323 }
7324
7325
7326 // Clear a break point
7327 // args[0]: number: break point object
7328 RUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
7329 HandleScope scope(isolate);
7330 DCHECK(args.length() == 1);
7331 CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
7332
7333 // Clear break point.
7334 isolate->debug()->ClearBreakPoint(break_point_object_arg);
7335
7336 return isolate->heap()->undefined_value();
7337 }
7338
7339
7340 // Change the state of break on exceptions.
7341 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
7342 // args[1]: Boolean indicating on/off.
7343 RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) {
7344 HandleScope scope(isolate);
7345 DCHECK(args.length() == 2);
7346 CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
7347 CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
7348
7349 // If the number doesn't match an enum value, the ChangeBreakOnException
7350 // function will default to affecting caught exceptions.
7351 ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
7352 // Update break point state.
7353 isolate->debug()->ChangeBreakOnException(type, enable);
7354 return isolate->heap()->undefined_value();
7355 }
7356
7357
7358 // Returns the state of break on exceptions
7359 // args[0]: boolean indicating uncaught exceptions
7360 RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
7361 HandleScope scope(isolate);
7362 DCHECK(args.length() == 1);
7363 CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
7364
7365 ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
7366 bool result = isolate->debug()->IsBreakOnException(type);
7367 return Smi::FromInt(result);
7368 }
7369
7370
7371 // Prepare for stepping
7372 // args[0]: break id for checking execution state
7373 // args[1]: step action from the enumeration StepAction
7374 // args[2]: number of times to perform the step, for step out it is the number
7375 // of frames to step down.
7376 RUNTIME_FUNCTION(Runtime_PrepareStep) {
7377 HandleScope scope(isolate);
7378 DCHECK(args.length() == 4);
7379 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
7380 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
7381
7382 if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
7383 return isolate->Throw(isolate->heap()->illegal_argument_string());
7384 }
7385
7386 CONVERT_NUMBER_CHECKED(int, wrapped_frame_id, Int32, args[3]);
7387
7388 StackFrame::Id frame_id;
7389 if (wrapped_frame_id == 0) {
7390 frame_id = StackFrame::NO_ID;
7391 } else {
7392 frame_id = UnwrapFrameId(wrapped_frame_id);
7393 }
7394
7395 // Get the step action and check validity.
7396 StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
7397 if (step_action != StepIn && step_action != StepNext &&
7398 step_action != StepOut && step_action != StepInMin &&
7399 step_action != StepMin) {
7400 return isolate->Throw(isolate->heap()->illegal_argument_string());
7401 }
7402
7403 if (frame_id != StackFrame::NO_ID && step_action != StepNext &&
7404 step_action != StepMin && step_action != StepOut) {
7405 return isolate->ThrowIllegalOperation();
7406 }
7407
7408 // Get the number of steps.
7409 int step_count = NumberToInt32(args[2]);
7410 if (step_count < 1) {
7411 return isolate->Throw(isolate->heap()->illegal_argument_string());
7412 }
7413
7414 // Clear all current stepping setup.
7415 isolate->debug()->ClearStepping();
7416
7417 // Prepare step.
7418 isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
7419 step_count, frame_id);
7420 return isolate->heap()->undefined_value();
7421 }
7422
7423
7424 // Clear all stepping set by PrepareStep.
7425 RUNTIME_FUNCTION(Runtime_ClearStepping) {
7426 HandleScope scope(isolate);
7427 DCHECK(args.length() == 0);
7428 isolate->debug()->ClearStepping();
7429 return isolate->heap()->undefined_value();
7430 }
7431
7432
7433 // Helper function to find or create the arguments object for
7434 // Runtime_DebugEvaluate.
7435 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject(
7436 Isolate* isolate, Handle<JSObject> target, Handle<JSFunction> function) {
7437 // Do not materialize the arguments object for eval or top-level code.
7438 // Skip if "arguments" is already taken.
7439 if (!function->shared()->is_function()) return target;
7440 Maybe<bool> maybe = JSReceiver::HasOwnProperty(
7441 target, isolate->factory()->arguments_string());
7442 if (!maybe.has_value) return MaybeHandle<JSObject>();
7443 if (maybe.value) return target;
7444
7445 // FunctionGetArguments can't throw an exception.
7446 Handle<JSObject> arguments =
7447 Handle<JSObject>::cast(Accessors::FunctionGetArguments(function));
7448 Handle<String> arguments_str = isolate->factory()->arguments_string();
7449 RETURN_ON_EXCEPTION(isolate, Runtime::DefineObjectProperty(
7450 target, arguments_str, arguments, NONE),
7451 JSObject);
7452 return target;
7453 }
7454
7455
7456 // Compile and evaluate source for the given context.
7457 static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
7458 Handle<Context> context,
7459 Handle<Object> context_extension,
7460 Handle<Object> receiver,
7461 Handle<String> source) {
7462 if (context_extension->IsJSObject()) {
7463 Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
7464 Handle<JSFunction> closure(context->closure(), isolate);
7465 context = isolate->factory()->NewWithContext(closure, context, extension);
7466 }
7467
7468 Handle<JSFunction> eval_fun;
7469 ASSIGN_RETURN_ON_EXCEPTION(
7470 isolate, eval_fun, Compiler::GetFunctionFromEval(source, context, SLOPPY,
7471 NO_PARSE_RESTRICTION,
7472 RelocInfo::kNoPosition),
7473 Object);
7474
7475 Handle<Object> result;
7476 ASSIGN_RETURN_ON_EXCEPTION(
7477 isolate, result, Execution::Call(isolate, eval_fun, receiver, 0, NULL),
7478 Object);
7479
7480 // Skip the global proxy as it has no properties and always delegates to the
7481 // real global object.
7482 if (result->IsJSGlobalProxy()) {
7483 PrototypeIterator iter(isolate, result);
7484 // TODO(verwaest): This will crash when the global proxy is detached.
7485 result = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
7486 }
7487
7488 // Clear the oneshot breakpoints so that the debugger does not step further.
7489 isolate->debug()->ClearStepping();
7490 return result;
7491 }
7492
7493
7494 static Handle<JSObject> NewJSObjectWithNullProto(Isolate* isolate) {
7495 Handle<JSObject> result =
7496 isolate->factory()->NewJSObject(isolate->object_function());
7497 Handle<Map> new_map = Map::Copy(Handle<Map>(result->map()));
7498 new_map->set_prototype(*isolate->factory()->null_value());
7499 JSObject::MigrateToMap(result, new_map);
7500 return result;
7501 }
7502
7503
7504 // Evaluate a piece of JavaScript in the context of a stack frame for
7505 // debugging. Things that need special attention are:
7506 // - Parameters and stack-allocated locals need to be materialized. Altered
7507 // values need to be written back to the stack afterwards.
7508 // - The arguments object needs to materialized.
7509 RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
7510 HandleScope scope(isolate);
7511
7512 // Check the execution state and decode arguments frame and source to be
7513 // evaluated.
7514 DCHECK(args.length() == 6);
7515 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
7516 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
7517
7518 CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
7519 CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
7520 CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
7521 CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
7522 CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 5);
7523
7524 // Handle the processing of break.
7525 DisableBreak disable_break_scope(isolate->debug(), disable_break);
7526
7527 // Get the frame where the debugging is performed.
7528 StackFrame::Id id = UnwrapFrameId(wrapped_id);
7529 JavaScriptFrameIterator it(isolate, id);
7530 JavaScriptFrame* frame = it.frame();
7531 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
7532 Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
7533
7534 // Traverse the saved contexts chain to find the active context for the
7535 // selected frame.
7536 SaveContext* save = FindSavedContextForFrame(isolate, frame);
7537
7538 SaveContext savex(isolate);
7539 isolate->set_context(*(save->context()));
7540
7541 // Materialize stack locals and the arguments object.
7542 Handle<JSObject> materialized = NewJSObjectWithNullProto(isolate);
7543
7544 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7545 isolate, materialized,
7546 MaterializeStackLocalsWithFrameInspector(isolate, materialized, function,
7547 &frame_inspector));
7548
7549 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7550 isolate, materialized,
7551 MaterializeArgumentsObject(isolate, materialized, function));
7552
7553 // At this point, the lookup chain may look like this:
7554 // [inner context] -> [function stack]+[function context] -> [outer context]
7555 // The function stack is not an actual context, it complements the function
7556 // context. In order to have the same lookup chain when debug-evaluating,
7557 // we materialize the stack and insert it into the context chain as a
7558 // with-context before the function context.
7559 // [inner context] -> [with context] -> [function context] -> [outer context]
7560 // Ordering the with-context before the function context forces a dynamic
7561 // lookup instead of a static lookup that could fail as the scope info is
7562 // outdated and may expect variables to still be stack-allocated.
7563 // Afterwards, we write changes to the with-context back to the stack
7564 // and remove it from the context chain.
7565 // This could cause lookup failures if debug-evaluate creates a closure that
7566 // uses this temporary context chain.
7567
7568 Handle<Context> eval_context(Context::cast(frame_inspector.GetContext()));
7569 DCHECK(!eval_context.is_null());
7570 Handle<Context> function_context = eval_context;
7571 Handle<Context> outer_context(function->context(), isolate);
7572 Handle<Context> inner_context;
7573 // We iterate to find the function's context. If the function has no
7574 // context-allocated variables, we iterate until we hit the outer context.
7575 while (!function_context->IsFunctionContext() &&
7576 !function_context.is_identical_to(outer_context)) {
7577 inner_context = function_context;
7578 function_context = Handle<Context>(function_context->previous(), isolate);
7579 }
7580
7581 Handle<Context> materialized_context = isolate->factory()->NewWithContext(
7582 function, function_context, materialized);
7583
7584 if (inner_context.is_null()) {
7585 // No inner context. The with-context is now inner-most.
7586 eval_context = materialized_context;
7587 } else {
7588 inner_context->set_previous(*materialized_context);
7589 }
7590
7591 Handle<Object> receiver(frame->receiver(), isolate);
7592 MaybeHandle<Object> maybe_result =
7593 DebugEvaluate(isolate, eval_context, context_extension, receiver, source);
7594
7595 // Remove with-context if it was inserted in between.
7596 if (!inner_context.is_null()) inner_context->set_previous(*function_context);
7597
7598 Handle<Object> result;
7599 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
7600
7601 // Write back potential changes to materialized stack locals to the stack.
7602 UpdateStackLocalsFromMaterializedObject(isolate, materialized, function,
7603 frame, inlined_jsframe_index);
7604
7605 return *result;
7606 }
7607
7608
7609 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
7610 HandleScope scope(isolate);
7611
7612 // Check the execution state and decode arguments frame and source to be
7613 // evaluated.
7614 DCHECK(args.length() == 4);
7615 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
7616 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
7617
7618 CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
7619 CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
7620 CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 3);
7621
7622 // Handle the processing of break.
7623 DisableBreak disable_break_scope(isolate->debug(), disable_break);
7624
7625 // Enter the top context from before the debugger was invoked.
7626 SaveContext save(isolate);
7627 SaveContext* top = &save;
7628 while (top != NULL && *top->context() == *isolate->debug()->debug_context()) {
7629 top = top->prev();
7630 }
7631 if (top != NULL) {
7632 isolate->set_context(*top->context());
7633 }
7634
7635 // Get the native context now set to the top context from before the
7636 // debugger was invoked.
7637 Handle<Context> context = isolate->native_context();
7638 Handle<JSObject> receiver(context->global_proxy());
7639 Handle<Object> result;
7640 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
7641 isolate, result,
7642 DebugEvaluate(isolate, context, context_extension, receiver, source));
7643 return *result;
7644 }
7645
7646
7647 RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
7648 HandleScope scope(isolate);
7649 DCHECK(args.length() == 0);
7650
7651 // Fill the script objects.
7652 Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
7653
7654 // Convert the script objects to proper JS objects.
7655 for (int i = 0; i < instances->length(); i++) {
7656 Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
7657 // Get the script wrapper in a local handle before calling GetScriptWrapper,
7658 // because using
7659 // instances->set(i, *GetScriptWrapper(script))
7660 // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
7661 // already have dereferenced the instances handle.
7662 Handle<JSObject> wrapper = Script::GetWrapper(script);
7663 instances->set(i, *wrapper);
7664 }
7665
7666 // Return result as a JS array.
7667 Handle<JSObject> result =
7668 isolate->factory()->NewJSObject(isolate->array_function());
7669 JSArray::SetContent(Handle<JSArray>::cast(result), instances);
7670 return *result;
7671 }
7672
7673
7674 // Helper function used by Runtime_DebugReferencedBy below.
7675 static int DebugReferencedBy(HeapIterator* iterator, JSObject* target,
7676 Object* instance_filter, int max_references,
7677 FixedArray* instances, int instances_size,
7678 JSFunction* arguments_function) {
7679 Isolate* isolate = target->GetIsolate();
7680 SealHandleScope shs(isolate);
7681 DisallowHeapAllocation no_allocation;
7682
7683 // Iterate the heap.
7684 int count = 0;
7685 JSObject* last = NULL;
7686 HeapObject* heap_obj = NULL;
7687 while (((heap_obj = iterator->next()) != NULL) &&
7688 (max_references == 0 || count < max_references)) {
7689 // Only look at all JSObjects.
7690 if (heap_obj->IsJSObject()) {
7691 // Skip context extension objects and argument arrays as these are
7692 // checked in the context of functions using them.
7693 JSObject* obj = JSObject::cast(heap_obj);
7694 if (obj->IsJSContextExtensionObject() ||
7695 obj->map()->constructor() == arguments_function) {
7696 continue;
7697 }
7698
7699 // Check if the JS object has a reference to the object looked for.
7700 if (obj->ReferencesObject(target)) {
7701 // Check instance filter if supplied. This is normally used to avoid
7702 // references from mirror objects (see Runtime_IsInPrototypeChain).
7703 if (!instance_filter->IsUndefined()) {
7704 for (PrototypeIterator iter(isolate, obj); !iter.IsAtEnd();
7705 iter.Advance()) {
7706 if (iter.GetCurrent() == instance_filter) {
7707 obj = NULL; // Don't add this object.
7708 break;
7709 }
7710 }
7711 }
7712
7713 if (obj != NULL) {
7714 // Valid reference found add to instance array if supplied an update
7715 // count.
7716 if (instances != NULL && count < instances_size) {
7717 instances->set(count, obj);
7718 }
7719 last = obj;
7720 count++;
7721 }
7722 }
7723 }
7724 }
7725
7726 // Check for circular reference only. This can happen when the object is only
7727 // referenced from mirrors and has a circular reference in which case the
7728 // object is not really alive and would have been garbage collected if not
7729 // referenced from the mirror.
7730 if (count == 1 && last == target) {
7731 count = 0;
7732 }
7733
7734 // Return the number of referencing objects found.
7735 return count;
7736 }
7737
7738
7739 // Scan the heap for objects with direct references to an object
7740 // args[0]: the object to find references to
7741 // args[1]: constructor function for instances to exclude (Mirror)
7742 // args[2]: the the maximum number of objects to return
7743 RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
7744 HandleScope scope(isolate);
7745 DCHECK(args.length() == 3);
7746
7747 // Check parameters.
7748 CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
7749 CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1);
7750 RUNTIME_ASSERT(instance_filter->IsUndefined() ||
7751 instance_filter->IsJSObject());
7752 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
7753 RUNTIME_ASSERT(max_references >= 0);
7754
7755
7756 // Get the constructor function for context extension and arguments array.
7757 Handle<JSFunction> arguments_function(
7758 JSFunction::cast(isolate->sloppy_arguments_map()->constructor()));
7759
7760 // Get the number of referencing objects.
7761 int count;
7762 // First perform a full GC in order to avoid dead objects and to make the heap
7763 // iterable.
7764 Heap* heap = isolate->heap();
7765 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
7766 {
7767 HeapIterator heap_iterator(heap);
7768 count = DebugReferencedBy(&heap_iterator, *target, *instance_filter,
7769 max_references, NULL, 0, *arguments_function);
7770 }
7771
7772 // Allocate an array to hold the result.
7773 Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
7774
7775 // Fill the referencing objects.
7776 {
7777 HeapIterator heap_iterator(heap);
7778 count = DebugReferencedBy(&heap_iterator, *target, *instance_filter,
7779 max_references, *instances, count,
7780 *arguments_function);
7781 }
7782
7783 // Return result as JS array.
7784 Handle<JSFunction> constructor = isolate->array_function();
7785
7786 Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
7787 JSArray::SetContent(Handle<JSArray>::cast(result), instances);
7788 return *result;
7789 }
7790
7791
7792 // Helper function used by Runtime_DebugConstructedBy below.
7793 static int DebugConstructedBy(HeapIterator* iterator, JSFunction* constructor,
7794 int max_references, FixedArray* instances,
7795 int instances_size) {
7796 DisallowHeapAllocation no_allocation;
7797
7798 // Iterate the heap.
7799 int count = 0;
7800 HeapObject* heap_obj = NULL;
7801 while (((heap_obj = iterator->next()) != NULL) &&
7802 (max_references == 0 || count < max_references)) {
7803 // Only look at all JSObjects.
7804 if (heap_obj->IsJSObject()) {
7805 JSObject* obj = JSObject::cast(heap_obj);
7806 if (obj->map()->constructor() == constructor) {
7807 // Valid reference found add to instance array if supplied an update
7808 // count.
7809 if (instances != NULL && count < instances_size) {
7810 instances->set(count, obj);
7811 }
7812 count++;
7813 }
7814 }
7815 }
7816
7817 // Return the number of referencing objects found.
7818 return count;
7819 }
7820
7821
7822 // Scan the heap for objects constructed by a specific function.
7823 // args[0]: the constructor to find instances of
7824 // args[1]: the the maximum number of objects to return
7825 RUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
7826 HandleScope scope(isolate);
7827 DCHECK(args.length() == 2);
7828
7829
7830 // Check parameters.
7831 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
7832 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
7833 RUNTIME_ASSERT(max_references >= 0);
7834
7835 // Get the number of referencing objects.
7836 int count;
7837 // First perform a full GC in order to avoid dead objects and to make the heap
7838 // iterable.
7839 Heap* heap = isolate->heap();
7840 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
7841 {
7842 HeapIterator heap_iterator(heap);
7843 count = DebugConstructedBy(&heap_iterator, *constructor, max_references,
7844 NULL, 0);
7845 }
7846
7847 // Allocate an array to hold the result.
7848 Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
7849
7850 // Fill the referencing objects.
7851 {
7852 HeapIterator heap_iterator2(heap);
7853 count = DebugConstructedBy(&heap_iterator2, *constructor, max_references,
7854 *instances, count);
7855 }
7856
7857 // Return result as JS array.
7858 Handle<JSFunction> array_function = isolate->array_function();
7859 Handle<JSObject> result = isolate->factory()->NewJSObject(array_function);
7860 JSArray::SetContent(Handle<JSArray>::cast(result), instances);
7861 return *result;
7862 }
7863
7864
7865 // Find the effective prototype object as returned by __proto__.
7866 // args[0]: the object to find the prototype for.
7867 RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
7868 HandleScope shs(isolate);
7869 DCHECK(args.length() == 1);
7870 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
7871 return *GetPrototypeSkipHiddenPrototypes(isolate, obj);
7872 }
7873
7874
7875 // Patches script source (should be called upon BeforeCompile event).
7876 RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
7877 HandleScope scope(isolate);
7878 DCHECK(args.length() == 2);
7879
7880 CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
7881 CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
7882
7883 RUNTIME_ASSERT(script_wrapper->value()->IsScript());
7884 Handle<Script> script(Script::cast(script_wrapper->value()));
7885
7886 int compilation_state = script->compilation_state();
7887 RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
7888 script->set_source(*source);
7889
7890 return isolate->heap()->undefined_value();
7891 }
7892
7893
7894 RUNTIME_FUNCTION(Runtime_DebugDisassembleFunction) {
7895 HandleScope scope(isolate);
7896 #ifdef DEBUG
7897 DCHECK(args.length() == 1);
7898 // Get the function and make sure it is compiled.
7899 CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
7900 if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
7901 return isolate->heap()->exception();
7902 }
7903 OFStream os(stdout);
7904 func->code()->Print(os);
7905 os << endl;
7906 #endif // DEBUG
7907 return isolate->heap()->undefined_value();
7908 }
7909
7910
7911 RUNTIME_FUNCTION(Runtime_DebugDisassembleConstructor) {
7912 HandleScope scope(isolate);
7913 #ifdef DEBUG
7914 DCHECK(args.length() == 1);
7915 // Get the function and make sure it is compiled.
7916 CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
7917 if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
7918 return isolate->heap()->exception();
7919 }
7920 OFStream os(stdout);
7921 func->shared()->construct_stub()->Print(os);
7922 os << endl;
7923 #endif // DEBUG
7924 return isolate->heap()->undefined_value();
7925 }
7926
7927
7928 RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
7929 SealHandleScope shs(isolate);
7930 DCHECK(args.length() == 1);
7931
7932 CONVERT_ARG_CHECKED(JSFunction, f, 0);
7933 return f->shared()->inferred_name();
7934 }
7935
7936
7937 static int FindSharedFunctionInfosForScript(HeapIterator* iterator,
7938 Script* script,
7939 FixedArray* buffer) {
7940 DisallowHeapAllocation no_allocation;
7941 int counter = 0;
7942 int buffer_size = buffer->length();
7943 for (HeapObject* obj = iterator->next(); obj != NULL;
7944 obj = iterator->next()) {
7945 DCHECK(obj != NULL);
7946 if (!obj->IsSharedFunctionInfo()) {
7947 continue;
7948 }
7949 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
7950 if (shared->script() != script) {
7951 continue;
7952 }
7953 if (counter < buffer_size) {
7954 buffer->set(counter, shared);
7955 }
7956 counter++;
7957 }
7958 return counter;
7959 }
7960
7961
7962 // For a script finds all SharedFunctionInfo's in the heap that points
7963 // to this script. Returns JSArray of SharedFunctionInfo wrapped
7964 // in OpaqueReferences.
7965 RUNTIME_FUNCTION(Runtime_LiveEditFindSharedFunctionInfosForScript) {
7966 HandleScope scope(isolate);
7967 CHECK(isolate->debug()->live_edit_enabled());
7968 DCHECK(args.length() == 1);
7969 CONVERT_ARG_CHECKED(JSValue, script_value, 0);
7970
7971 RUNTIME_ASSERT(script_value->value()->IsScript());
7972 Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
7973
7974 const int kBufferSize = 32;
7975
7976 Handle<FixedArray> array;
7977 array = isolate->factory()->NewFixedArray(kBufferSize);
7978 int number;
7979 Heap* heap = isolate->heap();
7980 {
7981 HeapIterator heap_iterator(heap);
7982 Script* scr = *script;
7983 FixedArray* arr = *array;
7984 number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
7985 }
7986 if (number > kBufferSize) {
7987 array = isolate->factory()->NewFixedArray(number);
7988 HeapIterator heap_iterator(heap);
7989 Script* scr = *script;
7990 FixedArray* arr = *array;
7991 FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
7992 }
7993
7994 Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array);
7995 result->set_length(Smi::FromInt(number));
7996
7997 LiveEdit::WrapSharedFunctionInfos(result);
7998
7999 return *result;
8000 }
8001
8002
8003 // For a script calculates compilation information about all its functions.
8004 // The script source is explicitly specified by the second argument.
8005 // The source of the actual script is not used, however it is important that
8006 // all generated code keeps references to this particular instance of script.
8007 // Returns a JSArray of compilation infos. The array is ordered so that
8008 // each function with all its descendant is always stored in a continues range
8009 // with the function itself going first. The root function is a script function.
8010 RUNTIME_FUNCTION(Runtime_LiveEditGatherCompileInfo) {
8011 HandleScope scope(isolate);
8012 CHECK(isolate->debug()->live_edit_enabled());
8013 DCHECK(args.length() == 2);
8014 CONVERT_ARG_CHECKED(JSValue, script, 0);
8015 CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
8016
8017 RUNTIME_ASSERT(script->value()->IsScript());
8018 Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
8019
8020 Handle<JSArray> result;
8021 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
8022 isolate, result, LiveEdit::GatherCompileInfo(script_handle, source));
8023 return *result;
8024 }
8025
8026
8027 // Changes the source of the script to a new_source.
8028 // If old_script_name is provided (i.e. is a String), also creates a copy of
8029 // the script with its original source and sends notification to debugger.
8030 RUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) {
8031 HandleScope scope(isolate);
8032 CHECK(isolate->debug()->live_edit_enabled());
8033 DCHECK(args.length() == 3);
8034 CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
8035 CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
8036 CONVERT_ARG_HANDLE_CHECKED(Object, old_script_name, 2);
8037
8038 RUNTIME_ASSERT(original_script_value->value()->IsScript());
8039 Handle<Script> original_script(Script::cast(original_script_value->value()));
8040
8041 Handle<Object> old_script = LiveEdit::ChangeScriptSource(
8042 original_script, new_source, old_script_name);
8043
8044 if (old_script->IsScript()) {
8045 Handle<Script> script_handle = Handle<Script>::cast(old_script);
8046 return *Script::GetWrapper(script_handle);
8047 } else {
8048 return isolate->heap()->null_value();
8049 }
8050 }
8051
8052
8053 RUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) {
8054 HandleScope scope(isolate);
8055 CHECK(isolate->debug()->live_edit_enabled());
8056 DCHECK(args.length() == 1);
8057 CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
8058 RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
8059
8060 LiveEdit::FunctionSourceUpdated(shared_info);
8061 return isolate->heap()->undefined_value();
8062 }
8063
8064
8065 // Replaces code of SharedFunctionInfo with a new one.
8066 RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) {
8067 HandleScope scope(isolate);
8068 CHECK(isolate->debug()->live_edit_enabled());
8069 DCHECK(args.length() == 2);
8070 CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
8071 CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
8072 RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
8073
8074 LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
8075 return isolate->heap()->undefined_value();
8076 }
8077
8078
8079 // Connects SharedFunctionInfo to another script.
8080 RUNTIME_FUNCTION(Runtime_LiveEditFunctionSetScript) {
8081 HandleScope scope(isolate);
8082 CHECK(isolate->debug()->live_edit_enabled());
8083 DCHECK(args.length() == 2);
8084 CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
8085 CONVERT_ARG_HANDLE_CHECKED(Object, script_object, 1);
8086
8087 if (function_object->IsJSValue()) {
8088 Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
8089 if (script_object->IsJSValue()) {
8090 RUNTIME_ASSERT(JSValue::cast(*script_object)->value()->IsScript());
8091 Script* script = Script::cast(JSValue::cast(*script_object)->value());
8092 script_object = Handle<Object>(script, isolate);
8093 }
8094 RUNTIME_ASSERT(function_wrapper->value()->IsSharedFunctionInfo());
8095 LiveEdit::SetFunctionScript(function_wrapper, script_object);
8096 } else {
8097 // Just ignore this. We may not have a SharedFunctionInfo for some functions
8098 // and we check it in this function.
8099 }
8100
8101 return isolate->heap()->undefined_value();
8102 }
8103
8104
8105 // In a code of a parent function replaces original function as embedded object
8106 // with a substitution one.
8107 RUNTIME_FUNCTION(Runtime_LiveEditReplaceRefToNestedFunction) {
8108 HandleScope scope(isolate);
8109 CHECK(isolate->debug()->live_edit_enabled());
8110 DCHECK(args.length() == 3);
8111
8112 CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
8113 CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
8114 CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
8115 RUNTIME_ASSERT(parent_wrapper->value()->IsSharedFunctionInfo());
8116 RUNTIME_ASSERT(orig_wrapper->value()->IsSharedFunctionInfo());
8117 RUNTIME_ASSERT(subst_wrapper->value()->IsSharedFunctionInfo());
8118
8119 LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper,
8120 subst_wrapper);
8121 return isolate->heap()->undefined_value();
8122 }
8123
8124
8125 // Updates positions of a shared function info (first parameter) according
8126 // to script source change. Text change is described in second parameter as
8127 // array of groups of 3 numbers:
8128 // (change_begin, change_end, change_end_new_position).
8129 // Each group describes a change in text; groups are sorted by change_begin.
8130 RUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) {
8131 HandleScope scope(isolate);
8132 CHECK(isolate->debug()->live_edit_enabled());
8133 DCHECK(args.length() == 2);
8134 CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
8135 CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
8136 RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_array))
8137
8138 LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
8139 return isolate->heap()->undefined_value();
8140 }
8141
8142
8143 // For array of SharedFunctionInfo's (each wrapped in JSValue)
8144 // checks that none of them have activations on stacks (of any thread).
8145 // Returns array of the same length with corresponding results of
8146 // LiveEdit::FunctionPatchabilityStatus type.
8147 RUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) {
8148 HandleScope scope(isolate);
8149 CHECK(isolate->debug()->live_edit_enabled());
8150 DCHECK(args.length() == 2);
8151 CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
8152 CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
8153 RUNTIME_ASSERT(shared_array->length()->IsSmi());
8154 RUNTIME_ASSERT(shared_array->HasFastElements())
8155 int array_length = Smi::cast(shared_array->length())->value();
8156 for (int i = 0; i < array_length; i++) {
8157 Handle<Object> element =
8158 Object::GetElement(isolate, shared_array, i).ToHandleChecked();
8159 RUNTIME_ASSERT(
8160 element->IsJSValue() &&
8161 Handle<JSValue>::cast(element)->value()->IsSharedFunctionInfo());
8162 }
8163
8164 return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
8165 }
8166
8167
8168 // Compares 2 strings line-by-line, then token-wise and returns diff in form
8169 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
8170 // of diff chunks.
8171 RUNTIME_FUNCTION(Runtime_LiveEditCompareStrings) {
8172 HandleScope scope(isolate);
8173 CHECK(isolate->debug()->live_edit_enabled());
8174 DCHECK(args.length() == 2);
8175 CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
8176 CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
8177
8178 return *LiveEdit::CompareStrings(s1, s2);
8179 }
8180
8181
8182 // Restarts a call frame and completely drops all frames above.
8183 // Returns true if successful. Otherwise returns undefined or an error message.
8184 RUNTIME_FUNCTION(Runtime_LiveEditRestartFrame) {
8185 HandleScope scope(isolate);
8186 CHECK(isolate->debug()->live_edit_enabled());
8187 DCHECK(args.length() == 2);
8188 CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
8189 RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
8190
8191 CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
8192 Heap* heap = isolate->heap();
8193
8194 // Find the relevant frame with the requested index.
8195 StackFrame::Id id = isolate->debug()->break_frame_id();
8196 if (id == StackFrame::NO_ID) {
8197 // If there are no JavaScript stack frames return undefined.
8198 return heap->undefined_value();
8199 }
8200
8201 JavaScriptFrameIterator it(isolate, id);
8202 int inlined_jsframe_index = FindIndexedNonNativeFrame(&it, index);
8203 if (inlined_jsframe_index == -1) return heap->undefined_value();
8204 // We don't really care what the inlined frame index is, since we are
8205 // throwing away the entire frame anyways.
8206 const char* error_message = LiveEdit::RestartFrame(it.frame());
8207 if (error_message) {
8208 return *(isolate->factory()->InternalizeUtf8String(error_message));
8209 }
8210 return heap->true_value();
8211 }
8212
8213
8214 // A testing entry. Returns statement position which is the closest to
8215 // source_position.
8216 RUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) {
8217 HandleScope scope(isolate);
8218 CHECK(isolate->debug()->live_edit_enabled());
8219 DCHECK(args.length() == 2);
8220 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8221 CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
8222
8223 Handle<Code> code(function->code(), isolate);
8224
8225 if (code->kind() != Code::FUNCTION &&
8226 code->kind() != Code::OPTIMIZED_FUNCTION) {
8227 return isolate->heap()->undefined_value();
8228 }
8229
8230 RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
8231 int closest_pc = 0;
8232 int distance = kMaxInt;
8233 while (!it.done()) {
8234 int statement_position = static_cast<int>(it.rinfo()->data());
8235 // Check if this break point is closer that what was previously found.
8236 if (source_position <= statement_position &&
8237 statement_position - source_position < distance) {
8238 closest_pc =
8239 static_cast<int>(it.rinfo()->pc() - code->instruction_start());
8240 distance = statement_position - source_position;
8241 // Check whether we can't get any closer.
8242 if (distance == 0) break;
8243 }
8244 it.next();
8245 }
8246
8247 return Smi::FromInt(closest_pc);
8248 }
8249
8250
8251 // Calls specified function with or without entering the debugger.
8252 // This is used in unit tests to run code as if debugger is entered or simply
8253 // to have a stack with C++ frame in the middle.
8254 RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) {
8255 HandleScope scope(isolate);
8256 DCHECK(args.length() == 2);
8257 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
8258 CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
8259
8260 MaybeHandle<Object> maybe_result;
8261 if (without_debugger) {
8262 maybe_result = Execution::Call(isolate, function,
8263 handle(function->global_proxy()), 0, NULL);
8264 } else {
8265 DebugScope debug_scope(isolate->debug());
8266 maybe_result = Execution::Call(isolate, function,
8267 handle(function->global_proxy()), 0, NULL);
8268 }
8269 Handle<Object> result;
8270 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
8271 return *result;
8272 }
8273
8274
8275 // Performs a GC.
8276 // Presently, it only does a full GC.
8277 RUNTIME_FUNCTION(Runtime_CollectGarbage) {
8278 SealHandleScope shs(isolate);
8279 DCHECK(args.length() == 1);
8280 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
8281 return isolate->heap()->undefined_value();
8282 }
8283
8284
8285 // Gets the current heap usage.
8286 RUNTIME_FUNCTION(Runtime_GetHeapUsage) {
8287 SealHandleScope shs(isolate);
8288 DCHECK(args.length() == 0);
8289 int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
8290 if (!Smi::IsValid(usage)) {
8291 return *isolate->factory()->NewNumberFromInt(usage);
8292 }
8293 return Smi::FromInt(usage);
8294 }
8295
8296
8297 // Finds the script object from the script data. NOTE: This operation uses
8298 // heap traversal to find the function generated for the source position
8299 // for the requested break point. For lazily compiled functions several heap
8300 // traversals might be required rendering this operation as a rather slow
8301 // operation. However for setting break points which is normally done through
8302 // some kind of user interaction the performance is not crucial.
8303 static Handle<Object> Runtime_GetScriptFromScriptName(
8304 Handle<String> script_name) {
8305 // Scan the heap for Script objects to find the script with the requested
8306 // script data.
8307 Handle<Script> script;
8308 Factory* factory = script_name->GetIsolate()->factory();
8309 Heap* heap = script_name->GetHeap();
8310 HeapIterator iterator(heap);
8311 HeapObject* obj = NULL;
8312 while (script.is_null() && ((obj = iterator.next()) != NULL)) {
8313 // If a script is found check if it has the script data requested.
8314 if (obj->IsScript()) {
8315 if (Script::cast(obj)->name()->IsString()) {
8316 if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) {
8317 script = Handle<Script>(Script::cast(obj));
8318 }
8319 }
8320 }
8321 }
8322
8323 // If no script with the requested script data is found return undefined.
8324 if (script.is_null()) return factory->undefined_value();
8325
8326 // Return the script found.
8327 return Script::GetWrapper(script);
8328 }
8329
8330
8331 // Get the script object from script data. NOTE: Regarding performance
8332 // see the NOTE for GetScriptFromScriptData.
8333 // args[0]: script data for the script to find the source for
8334 RUNTIME_FUNCTION(Runtime_GetScript) {
8335 HandleScope scope(isolate);
8336
8337 DCHECK(args.length() == 1);
8338
8339 CONVERT_ARG_CHECKED(String, script_name, 0);
8340
8341 // Find the requested script.
8342 Handle<Object> result =
8343 Runtime_GetScriptFromScriptName(Handle<String>(script_name));
8344 return *result;
8345 }
8346
8347
8348 // Collect the raw data for a stack trace. Returns an array of 4 5027 // Collect the raw data for a stack trace. Returns an array of 4
8349 // element segments each containing a receiver, function, code and 5028 // element segments each containing a receiver, function, code and
8350 // native code offset. 5029 // native code offset.
8351 RUNTIME_FUNCTION(Runtime_CollectStackTrace) { 5030 RUNTIME_FUNCTION(Runtime_CollectStackTrace) {
8352 HandleScope scope(isolate); 5031 HandleScope scope(isolate);
8353 DCHECK(args.length() == 2); 5032 DCHECK(args.length() == 2);
8354 CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0); 5033 CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
8355 CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1); 5034 CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1);
8356 5035
8357 if (!isolate->bootstrapper()->IsActive()) { 5036 if (!isolate->bootstrapper()->IsActive()) {
8358 // Optionally capture a more detailed stack trace for the message. 5037 // Optionally capture a more detailed stack trace for the message.
8359 isolate->CaptureAndSetDetailedStackTrace(error_object); 5038 isolate->CaptureAndSetDetailedStackTrace(error_object);
8360 // Capture a simple stack trace for the stack property. 5039 // Capture a simple stack trace for the stack property.
8361 isolate->CaptureAndSetSimpleStackTrace(error_object, caller); 5040 isolate->CaptureAndSetSimpleStackTrace(error_object, caller);
8362 } 5041 }
8363 return isolate->heap()->undefined_value(); 5042 return isolate->heap()->undefined_value();
8364 } 5043 }
8365 5044
8366 5045
8367 // Returns V8 version as a string.
8368 RUNTIME_FUNCTION(Runtime_GetV8Version) {
8369 HandleScope scope(isolate);
8370 DCHECK(args.length() == 0);
8371
8372 const char* version_string = v8::V8::GetVersion();
8373
8374 return *isolate->factory()->NewStringFromAsciiChecked(version_string);
8375 }
8376
8377
8378 // Returns function of generator activation.
8379 RUNTIME_FUNCTION(Runtime_GeneratorGetFunction) {
8380 HandleScope scope(isolate);
8381 DCHECK(args.length() == 1);
8382 CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
8383
8384 return generator->function();
8385 }
8386
8387
8388 // Returns context of generator activation.
8389 RUNTIME_FUNCTION(Runtime_GeneratorGetContext) {
8390 HandleScope scope(isolate);
8391 DCHECK(args.length() == 1);
8392 CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
8393
8394 return generator->context();
8395 }
8396
8397
8398 // Returns receiver of generator activation.
8399 RUNTIME_FUNCTION(Runtime_GeneratorGetReceiver) {
8400 HandleScope scope(isolate);
8401 DCHECK(args.length() == 1);
8402 CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
8403
8404 return generator->receiver();
8405 }
8406
8407
8408 // Returns generator continuation as a PC offset, or the magic -1 or 0 values.
8409 RUNTIME_FUNCTION(Runtime_GeneratorGetContinuation) {
8410 HandleScope scope(isolate);
8411 DCHECK(args.length() == 1);
8412 CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
8413
8414 return Smi::FromInt(generator->continuation());
8415 }
8416
8417
8418 RUNTIME_FUNCTION(Runtime_GeneratorGetSourcePosition) {
8419 HandleScope scope(isolate);
8420 DCHECK(args.length() == 1);
8421 CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
8422
8423 if (generator->is_suspended()) {
8424 Handle<Code> code(generator->function()->code(), isolate);
8425 int offset = generator->continuation();
8426
8427 RUNTIME_ASSERT(0 <= offset && offset < code->Size());
8428 Address pc = code->address() + offset;
8429
8430 return Smi::FromInt(code->SourcePosition(pc));
8431 }
8432
8433 return isolate->heap()->undefined_value();
8434 }
8435
8436
8437 RUNTIME_FUNCTION(Runtime_LoadMutableDouble) { 5046 RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
8438 HandleScope scope(isolate); 5047 HandleScope scope(isolate);
8439 DCHECK(args.length() == 2); 5048 DCHECK(args.length() == 2);
8440 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 5049 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
8441 CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1); 5050 CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
8442 RUNTIME_ASSERT((index->value() & 1) == 1); 5051 RUNTIME_ASSERT((index->value() & 1) == 1);
8443 FieldIndex field_index = 5052 FieldIndex field_index =
8444 FieldIndex::ForLoadByFieldIndex(object->map(), index->value()); 5053 FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
8445 if (field_index.is_inobject()) { 5054 if (field_index.is_inobject()) {
8446 RUNTIME_ASSERT(field_index.property_index() < 5055 RUNTIME_ASSERT(field_index.property_index() <
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
8576 5185
8577 5186
8578 RUNTIME_FUNCTION(Runtime_MessageGetScript) { 5187 RUNTIME_FUNCTION(Runtime_MessageGetScript) {
8579 SealHandleScope shs(isolate); 5188 SealHandleScope shs(isolate);
8580 DCHECK(args.length() == 1); 5189 DCHECK(args.length() == 1);
8581 CONVERT_ARG_CHECKED(JSMessageObject, message, 0); 5190 CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
8582 return message->script(); 5191 return message->script();
8583 } 5192 }
8584 5193
8585 5194
8586 #ifdef DEBUG
8587 // ListNatives is ONLY used by the fuzz-natives.js in debug mode
8588 // Exclude the code in release mode.
8589 RUNTIME_FUNCTION(Runtime_ListNatives) {
8590 HandleScope scope(isolate);
8591 DCHECK(args.length() == 0);
8592 #define COUNT_ENTRY(Name, argc, ressize) +1
8593 int entry_count =
8594 0 RUNTIME_FUNCTION_LIST(COUNT_ENTRY) INLINE_FUNCTION_LIST(COUNT_ENTRY)
8595 INLINE_OPTIMIZED_FUNCTION_LIST(COUNT_ENTRY);
8596 #undef COUNT_ENTRY
8597 Factory* factory = isolate->factory();
8598 Handle<FixedArray> elements = factory->NewFixedArray(entry_count);
8599 int index = 0;
8600 bool inline_runtime_functions = false;
8601 #define ADD_ENTRY(Name, argc, ressize) \
8602 { \
8603 HandleScope inner(isolate); \
8604 Handle<String> name; \
8605 /* Inline runtime functions have an underscore in front of the name. */ \
8606 if (inline_runtime_functions) { \
8607 name = factory->NewStringFromStaticChars("_" #Name); \
8608 } else { \
8609 name = factory->NewStringFromStaticChars(#Name); \
8610 } \
8611 Handle<FixedArray> pair_elements = factory->NewFixedArray(2); \
8612 pair_elements->set(0, *name); \
8613 pair_elements->set(1, Smi::FromInt(argc)); \
8614 Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements); \
8615 elements->set(index++, *pair); \
8616 }
8617 inline_runtime_functions = false;
8618 RUNTIME_FUNCTION_LIST(ADD_ENTRY)
8619 INLINE_OPTIMIZED_FUNCTION_LIST(ADD_ENTRY)
8620 inline_runtime_functions = true;
8621 INLINE_FUNCTION_LIST(ADD_ENTRY)
8622 #undef ADD_ENTRY
8623 DCHECK_EQ(index, entry_count);
8624 Handle<JSArray> result = factory->NewJSArrayWithElements(elements);
8625 return *result;
8626 }
8627 #endif
8628
8629
8630 RUNTIME_FUNCTION(Runtime_IS_VAR) { 5195 RUNTIME_FUNCTION(Runtime_IS_VAR) {
8631 UNREACHABLE(); // implemented as macro in the parser 5196 UNREACHABLE(); // implemented as macro in the parser
8632 return NULL; 5197 return NULL;
8633 } 5198 }
8634 5199
8635 5200
8636 #define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size) \
8637 RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) { \
8638 CONVERT_ARG_CHECKED(JSObject, obj, 0); \
8639 return isolate->heap()->ToBoolean(obj->HasExternal##Type##Elements()); \
8640 }
8641
8642 TYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
8643
8644 #undef TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
8645
8646
8647 #define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s) \
8648 RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) { \
8649 CONVERT_ARG_CHECKED(JSObject, obj, 0); \
8650 return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements()); \
8651 }
8652
8653 TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
8654
8655 #undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
8656
8657
8658 RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) { 5201 RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
8659 SealHandleScope shs(isolate); 5202 SealHandleScope shs(isolate);
8660 DCHECK(args.length() == 1); 5203 DCHECK(args.length() == 1);
8661 CONVERT_ARG_CHECKED(Object, obj, 0); 5204 CONVERT_ARG_CHECKED(Object, obj, 0);
8662 return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy()); 5205 return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
8663 } 5206 }
8664 5207
8665 5208
8666 RUNTIME_FUNCTION(Runtime_IsObserved) { 5209 RUNTIME_FUNCTION(Runtime_IsObserved) {
8667 SealHandleScope shs(isolate); 5210 SealHandleScope shs(isolate);
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
9105 SealHandleScope shs(isolate); 5648 SealHandleScope shs(isolate);
9106 DCHECK(args.length() == 2); 5649 DCHECK(args.length() == 2);
9107 CONVERT_ARG_CHECKED(Object, obj, 0); 5650 CONVERT_ARG_CHECKED(Object, obj, 0);
9108 CONVERT_ARG_CHECKED(Object, value, 1); 5651 CONVERT_ARG_CHECKED(Object, value, 1);
9109 if (!obj->IsJSValue()) return value; 5652 if (!obj->IsJSValue()) return value;
9110 JSValue::cast(obj)->set_value(value); 5653 JSValue::cast(obj)->set_value(value);
9111 return value; 5654 return value;
9112 } 5655 }
9113 5656
9114 5657
9115 RUNTIME_FUNCTION(RuntimeReference_DateField) {
9116 SealHandleScope shs(isolate);
9117 DCHECK(args.length() == 2);
9118 CONVERT_ARG_CHECKED(Object, obj, 0);
9119 CONVERT_SMI_ARG_CHECKED(index, 1);
9120 if (!obj->IsJSDate()) {
9121 HandleScope scope(isolate);
9122 THROW_NEW_ERROR_RETURN_FAILURE(
9123 isolate,
9124 NewTypeError("not_date_object", HandleVector<Object>(NULL, 0)));
9125 }
9126 JSDate* date = JSDate::cast(obj);
9127 if (index == 0) return date->value();
9128 return JSDate::GetField(date, Smi::FromInt(index));
9129 }
9130
9131
9132 RUNTIME_FUNCTION(RuntimeReference_ObjectEquals) { 5658 RUNTIME_FUNCTION(RuntimeReference_ObjectEquals) {
9133 SealHandleScope shs(isolate); 5659 SealHandleScope shs(isolate);
9134 DCHECK(args.length() == 2); 5660 DCHECK(args.length() == 2);
9135 CONVERT_ARG_CHECKED(Object, obj1, 0); 5661 CONVERT_ARG_CHECKED(Object, obj1, 0);
9136 CONVERT_ARG_CHECKED(Object, obj2, 1); 5662 CONVERT_ARG_CHECKED(Object, obj2, 1);
9137 return isolate->heap()->ToBoolean(obj1 == obj2); 5663 return isolate->heap()->ToBoolean(obj1 == obj2);
9138 } 5664 }
9139 5665
9140 5666
9141 RUNTIME_FUNCTION(RuntimeReference_IsObject) { 5667 RUNTIME_FUNCTION(RuntimeReference_IsObject) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
9191 } 5717 }
9192 5718
9193 5719
9194 RUNTIME_FUNCTION(RuntimeReference_FastOneByteArrayJoin) { 5720 RUNTIME_FUNCTION(RuntimeReference_FastOneByteArrayJoin) {
9195 SealHandleScope shs(isolate); 5721 SealHandleScope shs(isolate);
9196 DCHECK(args.length() == 2); 5722 DCHECK(args.length() == 2);
9197 return isolate->heap()->undefined_value(); 5723 return isolate->heap()->undefined_value();
9198 } 5724 }
9199 5725
9200 5726
9201 RUNTIME_FUNCTION(RuntimeReference_GeneratorNext) {
9202 UNREACHABLE(); // Optimization disabled in SetUpGenerators().
9203 return NULL;
9204 }
9205
9206
9207 RUNTIME_FUNCTION(RuntimeReference_GeneratorThrow) {
9208 UNREACHABLE(); // Optimization disabled in SetUpGenerators().
9209 return NULL;
9210 }
9211
9212
9213 RUNTIME_FUNCTION(RuntimeReference_ClassOf) { 5727 RUNTIME_FUNCTION(RuntimeReference_ClassOf) {
9214 SealHandleScope shs(isolate); 5728 SealHandleScope shs(isolate);
9215 DCHECK(args.length() == 1); 5729 DCHECK(args.length() == 1);
9216 CONVERT_ARG_CHECKED(Object, obj, 0); 5730 CONVERT_ARG_CHECKED(Object, obj, 0);
9217 if (!obj->IsJSReceiver()) return isolate->heap()->null_value(); 5731 if (!obj->IsJSReceiver()) return isolate->heap()->null_value();
9218 return JSReceiver::cast(obj)->class_name(); 5732 return JSReceiver::cast(obj)->class_name();
9219 } 5733 }
9220 5734
9221 5735
9222 RUNTIME_FUNCTION(RuntimeReference_GetFromCache) { 5736 RUNTIME_FUNCTION(RuntimeReference_GetFromCache) {
9223 HandleScope scope(isolate); 5737 HandleScope scope(isolate);
9224 DCHECK(args.length() == 2); 5738 DCHECK(args.length() == 2);
9225 CONVERT_SMI_ARG_CHECKED(id, 0); 5739 CONVERT_SMI_ARG_CHECKED(id, 0);
9226 args[0] = isolate->native_context()->jsfunction_result_caches()->get(id); 5740 args[0] = isolate->native_context()->jsfunction_result_caches()->get(id);
9227 return __RT_impl_Runtime_GetFromCache(args, isolate); 5741 return __RT_impl_Runtime_GetFromCache(args, isolate);
9228 } 5742 }
9229 5743
9230 5744
9231 RUNTIME_FUNCTION(RuntimeReference_DebugIsActive) {
9232 SealHandleScope shs(isolate);
9233 return Smi::FromInt(isolate->debug()->is_active());
9234 }
9235
9236
9237 // ---------------------------------------------------------------------------- 5745 // ----------------------------------------------------------------------------
9238 // Implementation of Runtime 5746 // Implementation of Runtime
9239 5747
9240 #define F(name, number_of_args, result_size) \ 5748 #define F(name, number_of_args, result_size) \
9241 { \ 5749 { \
9242 Runtime::k##name, Runtime::RUNTIME, #name, FUNCTION_ADDR(Runtime_##name), \ 5750 Runtime::k##name, Runtime::RUNTIME, #name, FUNCTION_ADDR(Runtime_##name), \
9243 number_of_args, result_size \ 5751 number_of_args, result_size \
9244 } \ 5752 } \
9245 , 5753 ,
9246 5754
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
9307 } 5815 }
9308 return NULL; 5816 return NULL;
9309 } 5817 }
9310 5818
9311 5819
9312 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { 5820 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
9313 return &(kIntrinsicFunctions[static_cast<int>(id)]); 5821 return &(kIntrinsicFunctions[static_cast<int>(id)]);
9314 } 5822 }
9315 } 5823 }
9316 } // namespace v8::internal 5824 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects-inl.h ('k') | src/runtime/runtime-compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698