OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/execution.h" | 7 #include "src/execution.h" |
8 #include "src/handles.h" | 8 #include "src/handles.h" |
9 #include "src/interpreter/bytecode-array-builder.h" | 9 #include "src/interpreter/bytecode-array-builder.h" |
10 #include "src/interpreter/interpreter.h" | 10 #include "src/interpreter/interpreter.h" |
(...skipping 2613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2624 InterpreterTester tester(handles.main_isolate(), source.c_str()); | 2624 InterpreterTester tester(handles.main_isolate(), source.c_str()); |
2625 auto callable = tester.GetCallable<>(); | 2625 auto callable = tester.GetCallable<>(); |
2626 | 2626 |
2627 Handle<i::Object> return_value = callable().ToHandleChecked(); | 2627 Handle<i::Object> return_value = callable().ToHandleChecked(); |
2628 CHECK(return_value->SameValue(*loops[i].second)); | 2628 CHECK(return_value->SameValue(*loops[i].second)); |
2629 } | 2629 } |
2630 } | 2630 } |
2631 | 2631 |
2632 | 2632 |
2633 TEST(InterpreterForIn) { | 2633 TEST(InterpreterForIn) { |
2634 HandleAndZoneScope handles; | |
2635 | |
2636 std::pair<const char*, int> for_in_samples[] = { | 2634 std::pair<const char*, int> for_in_samples[] = { |
2637 {"function f() {\n" | 2635 {"var r = -1;\n" |
2638 " var r = -1;\n" | 2636 "for (var a in null) { r = a; }\n" |
2639 " for (var a in null) { r = a; }\n" | 2637 "return r;\n", |
2640 " return r;\n" | |
2641 "}", | |
2642 -1}, | 2638 -1}, |
2643 {"function f() {\n" | 2639 {"var r = -1;\n" |
2644 " var r = -1;\n" | 2640 "for (var a in undefined) { r = a; }\n" |
2645 " for (var a in undefined) { r = a; }\n" | 2641 "return r;\n", |
2646 " return r;\n" | |
2647 "}", | |
2648 -1}, | 2642 -1}, |
2649 {"function f() {\n" | 2643 {"var r = 0;\n" |
2650 " var r = 0;\n" | 2644 "for (var a in [0,6,7,9]) { r = r + (1 << a); }\n" |
2651 " for (var a in [0,6,7,9]) { r = r + (1 << a); }\n" | 2645 "return r;\n", |
2652 " return r;\n" | |
2653 "}", | |
2654 0xf}, | 2646 0xf}, |
2655 {"function f() {\n" | 2647 {"var r = 0;\n" |
2656 " var r = 0;\n" | 2648 "for (var a in [0,6,7,9]) { r = r + (1 << a); }\n" |
2657 " for (var a in [0,6,7,9]) { r = r + (1 << a); }\n" | 2649 "var r = 0;\n" |
2658 " var r = 0;\n" | 2650 "for (var a in [0,6,7,9]) { r = r + (1 << a); }\n" |
2659 " for (var a in [0,6,7,9]) { r = r + (1 << a); }\n" | 2651 "return r;\n", |
2660 " return r;\n" | |
2661 "}", | |
2662 0xf}, | 2652 0xf}, |
2663 {"function f() {\n" | 2653 {"var r = 0;\n" |
2664 " var r = 0;\n" | 2654 "for (var a in 'foobar') { r = r + (1 << a); }\n" |
2665 " for (var a in 'foobar') { r = r + (1 << a); }\n" | 2655 "return r;\n", |
2666 " return r;\n" | |
2667 "}", | |
2668 0x3f}, | 2656 0x3f}, |
2669 {"function f() {\n" | 2657 {"var r = 0;\n" |
2670 " var r = 0;\n" | 2658 "for (var a in {1:0, 10:1, 100:2, 1000:3}) {\n" |
2671 " for (var a in {1:0, 10:1, 100:2, 1000:3}) {\n" | 2659 " r = r + Number(a);\n" |
2672 " r = r + Number(a);\n" | 2660 " }\n" |
2673 " }\n" | 2661 " return r;\n", |
2674 " return r;\n" | |
2675 "}", | |
2676 1111}, | 2662 1111}, |
2677 {"function f() {\n" | 2663 {"var r = 0;\n" |
2678 " var r = 0;\n" | 2664 "var data = {1:0, 10:1, 100:2, 1000:3};\n" |
2679 " var data = {1:0, 10:1, 100:2, 1000:3};\n" | 2665 "for (var a in data) {\n" |
2680 " for (var a in data) {\n" | 2666 " if (a == 1) delete data[1];\n" |
2681 " if (a == 1) delete data[1];\n" | 2667 " r = r + Number(a);\n" |
2682 " r = r + Number(a);\n" | 2668 " }\n" |
2683 " }\n" | 2669 " return r;\n", |
2684 " return r;\n" | |
2685 "}", | |
2686 1111}, | 2670 1111}, |
2687 {"function f() {\n" | 2671 {"var r = 0;\n" |
2688 " var r = 0;\n" | 2672 "var data = {1:0, 10:1, 100:2, 1000:3};\n" |
2689 " var data = {1:0, 10:1, 100:2, 1000:3};\n" | 2673 "for (var a in data) {\n" |
2690 " for (var a in data) {\n" | 2674 " if (a == 10) delete data[100];\n" |
2691 " if (a == 10) delete data[100];\n" | 2675 " r = r + Number(a);\n" |
2692 " r = r + Number(a);\n" | 2676 " }\n" |
2693 " }\n" | 2677 " return r;\n", |
2694 " return r;\n" | |
2695 "}", | |
2696 1011}, | 2678 1011}, |
2697 {"function f() {\n" | 2679 {"var r = 0;\n" |
2698 " var r = 0;\n" | 2680 "var data = {1:0, 10:1, 100:2, 1000:3};\n" |
2699 " var data = {1:0, 10:1, 100:2, 1000:3};\n" | 2681 "for (var a in data) {\n" |
2700 " for (var a in data) {\n" | 2682 " if (a == 10) data[10000] = 4;\n" |
2701 " if (a == 10) data[10000] = 4;\n" | 2683 " r = r + Number(a);\n" |
2702 " r = r + Number(a);\n" | 2684 " }\n" |
2703 " }\n" | 2685 " return r;\n", |
2704 " return r;\n" | |
2705 "}", | |
2706 1111}, | 2686 1111}, |
2707 {"function f() {\n" | 2687 {"var r = 0;\n" |
2708 " var r = 0;\n" | |
2709 " var input = 'foobar';\n" | |
2710 " for (var a in input) {\n" | |
2711 " if (input[a] == 'b') break;\n" | |
2712 " r = r + (1 << a);\n" | |
2713 " }\n" | |
2714 " return r;\n" | |
2715 "}", | |
2716 0x7}, | |
2717 {"function f() {\n" | |
2718 "var r = 0;\n" | |
2719 "var input = 'foobar';\n" | 2688 "var input = 'foobar';\n" |
2720 "for (var a in input) {\n" | 2689 "for (var a in input) {\n" |
2721 " if (input[a] == 'b') continue;\n" | 2690 " if (input[a] == 'b') break;\n" |
2722 " r = r + (1 << a);\n" | 2691 " r = r + (1 << a);\n" |
2723 "}\n" | 2692 "}\n" |
2724 "return r;\n" | 2693 "return r;\n", |
2725 "}", | 2694 0x7}, |
| 2695 {"var r = 0;\n" |
| 2696 "var input = 'foobar';\n" |
| 2697 "for (var a in input) {\n" |
| 2698 " if (input[a] == 'b') continue;\n" |
| 2699 " r = r + (1 << a);\n" |
| 2700 "}\n" |
| 2701 "return r;\n", |
2726 0x37}, | 2702 0x37}, |
2727 {"function f() {\n" | 2703 {"var r = 0;\n" |
2728 " var r = 0;\n" | 2704 "var data = {1:0, 10:1, 100:2, 1000:3};\n" |
2729 " var data = {1:0, 10:1, 100:2, 1000:3};\n" | 2705 "for (var a in data) {\n" |
2730 " for (var a in data) {\n" | 2706 " if (a == 10) {\n" |
2731 " if (a == 10) {\n" | 2707 " data[10000] = 4;\n" |
2732 " data[10000] = 4;\n" | 2708 " }\n" |
| 2709 " r = r + Number(a);\n" |
| 2710 "}\n" |
| 2711 "return r;\n", |
| 2712 1111}, |
| 2713 {"var r = [ 3 ];\n" |
| 2714 "var data = {1:0, 10:1, 100:2, 1000:3};\n" |
| 2715 "for (r[10] in data) {\n" |
| 2716 "}\n" |
| 2717 "return Number(r[10]);\n", |
| 2718 1000}, |
| 2719 {"var r = [ 3 ];\n" |
| 2720 "var data = {1:0, 10:1, 100:2, 1000:3};\n" |
| 2721 "for (r['100'] in data) {\n" |
| 2722 "}\n" |
| 2723 "return Number(r['100']);\n", |
| 2724 1000}, |
| 2725 {"var obj = {}\n" |
| 2726 "var descObj = new Boolean(false);\n" |
| 2727 "var accessed = 0;\n" |
| 2728 "descObj.enumerable = true;\n" |
| 2729 "Object.defineProperties(obj, { prop:descObj });\n" |
| 2730 "for (var p in obj) {\n" |
| 2731 " if (p === 'prop') { accessed = 1; }\n" |
| 2732 "}\n" |
| 2733 "return accessed;", |
| 2734 1}, |
| 2735 {"var appointment = {};\n" |
| 2736 "Object.defineProperty(appointment, 'startTime', {\n" |
| 2737 " value: 1001,\n" |
| 2738 " writable: false,\n" |
| 2739 " enumerable: false,\n" |
| 2740 " configurable: true\n" |
| 2741 "});\n" |
| 2742 "Object.defineProperty(appointment, 'name', {\n" |
| 2743 " value: 'NAME',\n" |
| 2744 " writable: false,\n" |
| 2745 " enumerable: false,\n" |
| 2746 " configurable: true\n" |
| 2747 "});\n" |
| 2748 "var meeting = Object.create(appointment);\n" |
| 2749 "Object.defineProperty(meeting, 'conferenceCall', {\n" |
| 2750 " value: 'In-person meeting',\n" |
| 2751 " writable: false,\n" |
| 2752 " enumerable: false,\n" |
| 2753 " configurable: true\n" |
| 2754 "});\n" |
| 2755 "\n" |
| 2756 "var teamMeeting = Object.create(meeting);\n" |
| 2757 "\n" |
| 2758 "var flags = 0;\n" |
| 2759 "for (var p in teamMeeting) {\n" |
| 2760 " if (p === 'startTime') {\n" |
| 2761 " flags |= 1;\n" |
2733 " }\n" | 2762 " }\n" |
2734 " r = r + Number(a);\n" | 2763 " if (p === 'name') {\n" |
2735 " }\n" | 2764 " flags |= 2;\n" |
2736 " return r;\n" | 2765 " }\n" |
2737 "}", | 2766 " if (p === 'conferenceCall') {\n" |
2738 1111}, | 2767 " flags |= 4;\n" |
2739 {"function f() {\n" | 2768 " }\n" |
2740 " var r = [ 3 ];\n" | 2769 "}\n" |
2741 " var data = {1:0, 10:1, 100:2, 1000:3};\n" | |
2742 " for (r[10] in data) {\n" | |
2743 " }\n" | |
2744 " return Number(r[10]);\n" | |
2745 "}", | |
2746 1000}, | |
2747 {"function f() {\n" | |
2748 " var r = [ 3 ];\n" | |
2749 " var data = {1:0, 10:1, 100:2, 1000:3};\n" | |
2750 " for (r['100'] in data) {\n" | |
2751 " }\n" | |
2752 " return Number(r['100']);\n" | |
2753 "}", | |
2754 1000}, | |
2755 {"function f() {\n" | |
2756 " var obj = {}\n" | |
2757 " var descObj = new Boolean(false);\n" | |
2758 " var accessed = 0;\n" | |
2759 " descObj.enumerable = true;\n" | |
2760 " Object.defineProperties(obj, { prop:descObj });\n" | |
2761 " for (var p in obj) {\n" | |
2762 " if (p === 'prop') { accessed = 1; }\n" | |
2763 " }\n" | |
2764 " return accessed;" | |
2765 "}", | |
2766 1}, | |
2767 {"function f() {\n" | |
2768 " var appointment = {};\n" | |
2769 " Object.defineProperty(appointment, 'startTime', {\n" | |
2770 " value: 1001,\n" | |
2771 " writable: false,\n" | |
2772 " enumerable: false,\n" | |
2773 " configurable: true\n" | |
2774 " });\n" | |
2775 " Object.defineProperty(appointment, 'name', {\n" | |
2776 " value: 'NAME',\n" | |
2777 " writable: false,\n" | |
2778 " enumerable: false,\n" | |
2779 " configurable: true\n" | |
2780 " });\n" | |
2781 " var meeting = Object.create(appointment);\n" | |
2782 " Object.defineProperty(meeting, 'conferenceCall', {\n" | |
2783 " value: 'In-person meeting',\n" | |
2784 " writable: false,\n" | |
2785 " enumerable: false,\n" | |
2786 " configurable: true\n" | |
2787 " });\n" | |
2788 "\n" | 2770 "\n" |
2789 " var teamMeeting = Object.create(meeting);\n" | 2771 "var hasOwnProperty = !teamMeeting.hasOwnProperty('name') &&\n" |
2790 "\n" | 2772 " !teamMeeting.hasOwnProperty('startTime') &&\n" |
2791 " var flags = 0;\n" | 2773 " !teamMeeting.hasOwnProperty('conferenceCall');\n" |
2792 " for (var p in teamMeeting) {\n" | 2774 "if (!hasOwnProperty) {\n" |
2793 " if (p === 'startTime') {\n" | 2775 " flags |= 8;\n" |
2794 " flags |= 1;\n" | 2776 "}\n" |
2795 " }\n" | 2777 "return flags;\n", |
2796 " if (p === 'name') {\n" | |
2797 " flags |= 2;\n" | |
2798 " }\n" | |
2799 " if (p === 'conferenceCall') {\n" | |
2800 " flags |= 4;\n" | |
2801 " }\n" | |
2802 " }\n" | |
2803 "\n" | |
2804 " var hasOwnProperty = !teamMeeting.hasOwnProperty('name') &&\n" | |
2805 " !teamMeeting.hasOwnProperty('startTime') &&\n" | |
2806 " !teamMeeting.hasOwnProperty('conferenceCall');\n" | |
2807 " if (!hasOwnProperty) {\n" | |
2808 " flags |= 8;\n" | |
2809 " }\n" | |
2810 " return flags;\n" | |
2811 " }", | |
2812 0}, | 2778 0}, |
2813 {"function f() {\n" | 2779 {"var data = {x:23, y:34};\n" |
2814 " var data = {x:23, y:34};\n" | |
2815 " var result = 0;\n" | 2780 " var result = 0;\n" |
2816 " var o = {};\n" | 2781 "var o = {};\n" |
2817 " var arr = [o];\n" | 2782 "var arr = [o];\n" |
2818 " for (arr[0].p in data)\n" // This is to test if value is loaded | 2783 "for (arr[0].p in data)\n" // This is to test if value is loaded |
2819 " result += data[arr[0].p];\n" // back from accumulator before storing | 2784 " result += data[arr[0].p];\n" // back from accumulator before storing |
2820 " return result;\n" // named properties. | 2785 "return result;\n", // named properties. |
2821 "}", | |
2822 57}, | 2786 57}, |
2823 {"function f() {\n" | 2787 {"var data = {x:23, y:34};\n" |
2824 " var data = {x:23, y:34};\n" | 2788 "var result = 0;\n" |
2825 " var result = 0;\n" | 2789 "var o = {};\n" |
2826 " var o = {};\n" | 2790 "var i = 0;\n" |
2827 " var i = 0;\n" | 2791 "for (o[i++] in data)\n" // This is to test if value is loaded |
2828 " for (o[i++] in data)\n" // This is to test if value is loaded | |
2829 " result += data[o[i-1]];\n" // back from accumulator before | 2792 " result += data[o[i-1]];\n" // back from accumulator before |
2830 " return result;\n" // storing keyed properties. | 2793 "return result;\n", // storing keyed properties. |
2831 "}", | |
2832 57}}; | 2794 57}}; |
2833 | 2795 |
2834 for (size_t i = 0; i < arraysize(for_in_samples); i++) { | 2796 // Two passes are made for this test. On the first, 8-bit register |
2835 InterpreterTester tester(handles.main_isolate(), for_in_samples[i].first); | 2797 // operands are employed, and on the 16-bit register operands are |
2836 auto callable = tester.GetCallable<>(); | 2798 // used. |
2837 Handle<Object> return_val = callable().ToHandleChecked(); | 2799 for (int pass = 0; pass < 2; pass++) { |
2838 CHECK_EQ(Handle<Smi>::cast(return_val)->value(), for_in_samples[i].second); | 2800 HandleAndZoneScope handles; |
| 2801 std::ostringstream wide_os; |
| 2802 if (pass == 1) { |
| 2803 for (int i = 0; i < 200; i++) { |
| 2804 wide_os << "var local" << i << " = 0;\n"; |
| 2805 } |
| 2806 } |
| 2807 |
| 2808 for (size_t i = 0; i < arraysize(for_in_samples); i++) { |
| 2809 std::ostringstream body_os; |
| 2810 body_os << wide_os.str() << for_in_samples[i].first; |
| 2811 std::string body(body_os.str()); |
| 2812 std::string function = InterpreterTester::SourceForBody(body.c_str()); |
| 2813 InterpreterTester tester(handles.main_isolate(), function.c_str()); |
| 2814 auto callable = tester.GetCallable<>(); |
| 2815 Handle<Object> return_val = callable().ToHandleChecked(); |
| 2816 CHECK_EQ(Handle<Smi>::cast(return_val)->value(), |
| 2817 for_in_samples[i].second); |
| 2818 } |
2839 } | 2819 } |
2840 } | 2820 } |
2841 | 2821 |
2842 | 2822 |
2843 TEST(InterpreterForOf) { | 2823 TEST(InterpreterForOf) { |
2844 HandleAndZoneScope handles; | 2824 HandleAndZoneScope handles; |
2845 i::Isolate* isolate = handles.main_isolate(); | 2825 i::Isolate* isolate = handles.main_isolate(); |
2846 i::Factory* factory = isolate->factory(); | 2826 i::Factory* factory = isolate->factory(); |
2847 | 2827 |
2848 std::pair<const char*, Handle<Object>> for_of[] = { | 2828 std::pair<const char*, Handle<Object>> for_of[] = { |
(...skipping 967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3816 auto callable = tester.GetCallable<Handle<Object>>(); | 3796 auto callable = tester.GetCallable<Handle<Object>>(); |
3817 for (int i = 0; i < kParameterCount; i++) { | 3797 for (int i = 0; i < kParameterCount; i++) { |
3818 Handle<Object> arg = handle(Smi::FromInt(i), isolate); | 3798 Handle<Object> arg = handle(Smi::FromInt(i), isolate); |
3819 Handle<Object> return_value = callable(arg).ToHandleChecked(); | 3799 Handle<Object> return_value = callable(arg).ToHandleChecked(); |
3820 int expected = kBaseValue + i * (i + 1) / 2; | 3800 int expected = kBaseValue + i * (i + 1) / 2; |
3821 Handle<Smi> actual = Handle<Smi>::cast(return_value); | 3801 Handle<Smi> actual = Handle<Smi>::cast(return_value); |
3822 CHECK_EQ(actual->value(), expected); | 3802 CHECK_EQ(actual->value(), expected); |
3823 } | 3803 } |
3824 } | 3804 } |
3825 | 3805 |
3826 // TODO(oth): Test for..in with wide registers. | |
3827 | |
3828 } // namespace interpreter | 3806 } // namespace interpreter |
3829 } // namespace internal | 3807 } // namespace internal |
3830 } // namespace v8 | 3808 } // namespace v8 |
OLD | NEW |