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 // TODO(jochen): Remove this after the setting is turned on globally. | 5 // TODO(jochen): Remove this after the setting is turned on globally. |
6 #define V8_IMMINENT_DEPRECATION_WARNINGS | 6 #define V8_IMMINENT_DEPRECATION_WARNINGS |
7 | 7 |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "src/compiler/pipeline.h" | 10 #include "src/compiler/pipeline.h" |
11 #include "src/execution.h" | 11 #include "src/execution.h" |
12 #include "src/handles.h" | 12 #include "src/handles.h" |
13 #include "src/interpreter/bytecode-array-builder.h" | 13 #include "src/interpreter/bytecode-array-builder.h" |
14 #include "src/interpreter/interpreter.h" | 14 #include "src/interpreter/interpreter.h" |
15 #include "src/parser.h" | 15 #include "src/parser.h" |
16 #include "test/cctest/cctest.h" | 16 #include "test/cctest/cctest.h" |
17 | 17 |
18 namespace v8 { | 18 namespace v8 { |
19 namespace internal { | 19 namespace internal { |
20 namespace compiler { | 20 namespace compiler { |
21 | 21 |
22 | 22 |
23 static const char kFunctionName[] = "f"; | 23 static const char kFunctionName[] = "f"; |
24 | 24 |
| 25 static const Token::Value kCompareOperators[] = { |
| 26 Token::Value::EQ, Token::Value::NE, Token::Value::EQ_STRICT, |
| 27 Token::Value::NE_STRICT, Token::Value::LT, Token::Value::LTE, |
| 28 Token::Value::GT, Token::Value::GTE}; |
| 29 |
| 30 static const int SMI_MAX = (1 << 30) - 1; |
| 31 static const int SMI_MIN = -(1 << 30); |
25 | 32 |
26 static MaybeHandle<Object> CallFunction(Isolate* isolate, | 33 static MaybeHandle<Object> CallFunction(Isolate* isolate, |
27 Handle<JSFunction> function) { | 34 Handle<JSFunction> function) { |
28 return Execution::Call(isolate, function, | 35 return Execution::Call(isolate, function, |
29 isolate->factory()->undefined_value(), 0, nullptr); | 36 isolate->factory()->undefined_value(), 0, nullptr); |
30 } | 37 } |
31 | 38 |
32 | 39 |
33 template <class... A> | 40 template <class... A> |
34 static MaybeHandle<Object> CallFunction(Isolate* isolate, | 41 static MaybeHandle<Object> CallFunction(Isolate* isolate, |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 snippets[i].code_snippet, kFunctionName); | 762 snippets[i].code_snippet, kFunctionName); |
756 | 763 |
757 BytecodeGraphTester tester(isolate, zone, script.start()); | 764 BytecodeGraphTester tester(isolate, zone, script.start()); |
758 auto callable = tester.GetCallable<Handle<Object>>(); | 765 auto callable = tester.GetCallable<Handle<Object>>(); |
759 Handle<Object> return_value = | 766 Handle<Object> return_value = |
760 callable(snippets[i].parameter(0)).ToHandleChecked(); | 767 callable(snippets[i].parameter(0)).ToHandleChecked(); |
761 CHECK(return_value->SameValue(*snippets[i].return_value())); | 768 CHECK(return_value->SameValue(*snippets[i].return_value())); |
762 } | 769 } |
763 } | 770 } |
764 | 771 |
| 772 |
| 773 bool get_compare_result(Token::Value opcode, Handle<Object> lhs_value, |
| 774 Handle<Object> rhs_value) { |
| 775 switch (opcode) { |
| 776 case Token::Value::EQ: |
| 777 return Object::Equals(lhs_value, rhs_value).FromJust(); |
| 778 case Token::Value::NE: |
| 779 return !Object::Equals(lhs_value, rhs_value).FromJust(); |
| 780 case Token::Value::EQ_STRICT: |
| 781 return lhs_value->StrictEquals(*rhs_value); |
| 782 case Token::Value::NE_STRICT: |
| 783 return !lhs_value->StrictEquals(*rhs_value); |
| 784 case Token::Value::LT: |
| 785 return Object::LessThan(lhs_value, rhs_value).FromJust(); |
| 786 case Token::Value::LTE: |
| 787 return Object::LessThanOrEqual(lhs_value, rhs_value).FromJust(); |
| 788 case Token::Value::GT: |
| 789 return Object::GreaterThan(lhs_value, rhs_value).FromJust(); |
| 790 case Token::Value::GTE: |
| 791 return Object::GreaterThanOrEqual(lhs_value, rhs_value).FromJust(); |
| 792 default: |
| 793 UNREACHABLE(); |
| 794 return false; |
| 795 } |
| 796 } |
| 797 |
| 798 |
| 799 const char* get_code_snippet(Token::Value opcode) { |
| 800 switch (opcode) { |
| 801 case Token::Value::EQ: |
| 802 return "return p1 == p2;"; |
| 803 case Token::Value::NE: |
| 804 return "return p1 != p2;"; |
| 805 case Token::Value::EQ_STRICT: |
| 806 return "return p1 === p2;"; |
| 807 case Token::Value::NE_STRICT: |
| 808 return "return p1 !== p2;"; |
| 809 case Token::Value::LT: |
| 810 return "return p1 < p2;"; |
| 811 case Token::Value::LTE: |
| 812 return "return p1 <= p2;"; |
| 813 case Token::Value::GT: |
| 814 return "return p1 > p2;"; |
| 815 case Token::Value::GTE: |
| 816 return "return p1 >= p2;"; |
| 817 default: |
| 818 UNREACHABLE(); |
| 819 return ""; |
| 820 } |
| 821 } |
| 822 |
| 823 |
| 824 TEST(BytecodeGraphBuilderCompare) { |
| 825 HandleAndZoneScope scope; |
| 826 Isolate* isolate = scope.main_isolate(); |
| 827 Zone* zone = scope.main_zone(); |
| 828 Factory* factory = isolate->factory(); |
| 829 Handle<Object> lhs_values[] = { |
| 830 factory->NewNumberFromInt(10), factory->NewHeapNumber(3.45), |
| 831 factory->NewStringFromStaticChars("abc"), |
| 832 factory->NewNumberFromInt(SMI_MAX), factory->NewNumberFromInt(SMI_MIN)}; |
| 833 Handle<Object> rhs_values[] = {factory->NewNumberFromInt(10), |
| 834 factory->NewStringFromStaticChars("10"), |
| 835 factory->NewNumberFromInt(20), |
| 836 factory->NewStringFromStaticChars("abc"), |
| 837 factory->NewHeapNumber(3.45), |
| 838 factory->NewNumberFromInt(SMI_MAX), |
| 839 factory->NewNumberFromInt(SMI_MIN)}; |
| 840 |
| 841 for (size_t i = 0; i < arraysize(kCompareOperators); i++) { |
| 842 ScopedVector<char> script(1024); |
| 843 SNPrintF(script, "function %s(p1, p2) { %s }\n%s({}, {});", kFunctionName, |
| 844 get_code_snippet(kCompareOperators[i]), kFunctionName); |
| 845 |
| 846 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 847 auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>(); |
| 848 for (size_t j = 0; j < arraysize(lhs_values); j++) { |
| 849 for (size_t k = 0; k < arraysize(rhs_values); k++) { |
| 850 Handle<Object> return_value = |
| 851 callable(lhs_values[j], rhs_values[k]).ToHandleChecked(); |
| 852 bool result = get_compare_result(kCompareOperators[i], lhs_values[j], |
| 853 rhs_values[k]); |
| 854 CHECK(return_value->SameValue(*factory->ToBoolean(result))); |
| 855 } |
| 856 } |
| 857 } |
| 858 } |
| 859 |
| 860 |
| 861 TEST(BytecodeGraphBuilderTestIn) { |
| 862 HandleAndZoneScope scope; |
| 863 Isolate* isolate = scope.main_isolate(); |
| 864 Zone* zone = scope.main_zone(); |
| 865 Factory* factory = isolate->factory(); |
| 866 |
| 867 ExpectedSnippet<2> snippets[] = { |
| 868 {"return p2 in p1;", |
| 869 {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})"), |
| 870 factory->NewStringFromStaticChars("val")}}, |
| 871 {"return p2 in p1;", |
| 872 {factory->true_value(), BytecodeGraphTester::NewObject("[]"), |
| 873 factory->NewStringFromStaticChars("length")}}, |
| 874 {"return p2 in p1;", |
| 875 {factory->true_value(), BytecodeGraphTester::NewObject("[]"), |
| 876 factory->NewStringFromStaticChars("toString")}}, |
| 877 {"return p2 in p1;", |
| 878 {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})"), |
| 879 factory->NewStringFromStaticChars("toString")}}, |
| 880 {"return p2 in p1;", |
| 881 {factory->false_value(), BytecodeGraphTester::NewObject("({val : 10})"), |
| 882 factory->NewStringFromStaticChars("abc")}}, |
| 883 {"return p2 in p1;", |
| 884 {factory->false_value(), BytecodeGraphTester::NewObject("({val : 10})"), |
| 885 factory->NewNumberFromInt(10)}}, |
| 886 {"return p2 in p1;", |
| 887 {factory->true_value(), BytecodeGraphTester::NewObject("({10 : 'val'})"), |
| 888 factory->NewNumberFromInt(10)}}, |
| 889 {"return p2 in p1;", |
| 890 {factory->false_value(), |
| 891 BytecodeGraphTester::NewObject("({10 : 'val'})"), |
| 892 factory->NewNumberFromInt(1)}}, |
| 893 }; |
| 894 |
| 895 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
| 896 for (size_t i = 0; i < num_snippets; i++) { |
| 897 ScopedVector<char> script(1024); |
| 898 SNPrintF(script, "function %s(p1, p2) { %s }\n%s({}, {});", kFunctionName, |
| 899 snippets[i].code_snippet, kFunctionName); |
| 900 |
| 901 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 902 auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>(); |
| 903 Handle<Object> return_value = |
| 904 callable(snippets[i].parameter(0), snippets[i].parameter(1)) |
| 905 .ToHandleChecked(); |
| 906 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 907 } |
| 908 } |
| 909 |
| 910 |
| 911 TEST(BytecodeGraphBuilderTestInstanceOf) { |
| 912 // TODO(mythria): Add tests when CreateLiterals/CreateClousre are supported. |
| 913 } |
| 914 |
765 } // namespace compiler | 915 } // namespace compiler |
766 } // namespace internal | 916 } // namespace internal |
767 } // namespace v8 | 917 } // namespace v8 |
OLD | NEW |