Chromium Code Reviews| 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 <utility> | 5 #include <utility> |
| 6 | 6 |
| 7 #include "src/compiler/pipeline.h" | 7 #include "src/compiler/pipeline.h" |
| 8 #include "src/execution.h" | 8 #include "src/execution.h" |
| 9 #include "src/handles.h" | 9 #include "src/handles.h" |
| 10 #include "src/interpreter/bytecode-array-builder.h" | 10 #include "src/interpreter/bytecode-array-builder.h" |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 193 {"return false;", {factory->false_value()}}, | 193 {"return false;", {factory->false_value()}}, |
| 194 {"return 0;", {factory->NewNumberFromInt(0)}}, | 194 {"return 0;", {factory->NewNumberFromInt(0)}}, |
| 195 {"return +1;", {factory->NewNumberFromInt(1)}}, | 195 {"return +1;", {factory->NewNumberFromInt(1)}}, |
| 196 {"return -1;", {factory->NewNumberFromInt(-1)}}, | 196 {"return -1;", {factory->NewNumberFromInt(-1)}}, |
| 197 {"return +127;", {factory->NewNumberFromInt(127)}}, | 197 {"return +127;", {factory->NewNumberFromInt(127)}}, |
| 198 {"return -128;", {factory->NewNumberFromInt(-128)}}, | 198 {"return -128;", {factory->NewNumberFromInt(-128)}}, |
| 199 {"return 0.001;", {factory->NewNumber(0.001)}}, | 199 {"return 0.001;", {factory->NewNumber(0.001)}}, |
| 200 {"return 3.7e-60;", {factory->NewNumber(3.7e-60)}}, | 200 {"return 3.7e-60;", {factory->NewNumber(3.7e-60)}}, |
| 201 {"return -3.7e60;", {factory->NewNumber(-3.7e60)}}, | 201 {"return -3.7e60;", {factory->NewNumber(-3.7e60)}}, |
| 202 {"return '';", {factory->NewStringFromStaticChars("")}}, | 202 {"return '';", {factory->NewStringFromStaticChars("")}}, |
| 203 {"return 'catfood';", {factory->NewStringFromStaticChars("catfood")}} | 203 {"return 'catfood';", {factory->NewStringFromStaticChars("catfood")}}, |
| 204 // TODO(oth): {"return NaN;", {factory->NewNumber(NAN)}} | 204 {"return NaN;", {factory->NewNumber(NAN)}}}; |
| 205 }; | |
| 206 | 205 |
| 207 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); | 206 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
| 208 for (size_t i = 0; i < num_snippets; i++) { | 207 for (size_t i = 0; i < num_snippets; i++) { |
| 209 ScopedVector<char> script(1024); | 208 ScopedVector<char> script(1024); |
| 210 SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, | 209 SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, |
| 211 snippets[i].code_snippet, kFunctionName); | 210 snippets[i].code_snippet, kFunctionName); |
| 212 | 211 |
| 213 BytecodeGraphTester tester(isolate, zone, script.start()); | 212 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 214 auto callable = tester.GetCallable<>(); | 213 auto callable = tester.GetCallable<>(); |
| 215 Handle<Object> return_value = callable().ToHandleChecked(); | 214 Handle<Object> return_value = callable().ToHandleChecked(); |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 685 {factory->NewStringFromStaticChars("xyz")}}, | 684 {factory->NewStringFromStaticChars("xyz")}}, |
| 686 {"var global = 'abc'; var global_obj = {val:123};\n" | 685 {"var global = 'abc'; var global_obj = {val:123};\n" |
| 687 "function f() {\n" REPEAT_127( | 686 "function f() {\n" REPEAT_127( |
| 688 SPACE, " var b = global_obj.name;\n") "return global; };\n f();\n", | 687 SPACE, " var b = global_obj.name;\n") "return global; };\n f();\n", |
| 689 {factory->NewStringFromStaticChars("abc")}}, | 688 {factory->NewStringFromStaticChars("abc")}}, |
| 690 {"var global = 'abc'; var global_obj = {val:123};\n" | 689 {"var global = 'abc'; var global_obj = {val:123};\n" |
| 691 "function f() { 'use strict';\n" REPEAT_127( | 690 "function f() { 'use strict';\n" REPEAT_127( |
| 692 SPACE, " var b = global_obj.name;\n") "global = 'xyz'; return " | 691 SPACE, " var b = global_obj.name;\n") "global = 'xyz'; return " |
| 693 "global };\n f();\n", | 692 "global };\n f();\n", |
| 694 {factory->NewStringFromStaticChars("xyz")}}, | 693 {factory->NewStringFromStaticChars("xyz")}}, |
| 695 // TODO(rmcilroy): Add tests for typeof_mode once we have typeof support. | 694 {"function f() { return typeof(undeclared_var); }\n; f();\n", |
| 695 {factory->NewStringFromStaticChars("undefined")}}, | |
| 696 {"var defined_var = 10; function f() { return typeof(defined_var); }\n; " | |
| 697 "f();\n", | |
| 698 {factory->NewStringFromStaticChars("number")}}, | |
| 696 }; | 699 }; |
| 697 | 700 |
| 698 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); | 701 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
| 699 for (size_t i = 0; i < num_snippets; i++) { | 702 for (size_t i = 0; i < num_snippets; i++) { |
| 700 BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet); | 703 BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet); |
| 701 auto callable = tester.GetCallable<>(); | 704 auto callable = tester.GetCallable<>(); |
| 702 Handle<Object> return_value = callable().ToHandleChecked(); | 705 Handle<Object> return_value = callable().ToHandleChecked(); |
| 703 CHECK(return_value->SameValue(*snippets[i].return_value())); | 706 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 704 } | 707 } |
| 705 } | 708 } |
| 706 | 709 |
| 707 | 710 |
| 708 TEST(BytecodeGraphBuilderCast) { | 711 TEST(BytecodeGraphBuilderCast) { |
|
Michael Starzinger
2015/12/09 16:12:48
nit: We could rename this test to something like "
mythria
2015/12/09 17:19:47
Done.
| |
| 709 // TODO(mythria): tests for ToBoolean, ToObject, ToName, ToNumber. | 712 // TODO(mythria): tests for ToObject. Needs ForIn. |
| 710 // They need other unimplemented features to test. | 713 HandleAndZoneScope scope; |
| 711 // ToBoolean -> If | 714 Isolate* isolate = scope.main_isolate(); |
| 712 // ToObject -> ForIn | 715 Zone* zone = scope.main_zone(); |
| 713 // ToNumber -> Inc/Dec | 716 Factory* factory = isolate->factory(); |
| 714 // ToName -> CreateObjectLiteral | 717 |
| 718 ExpectedSnippet<0> snippets[] = { | |
| 719 {"var a = 'val'; var obj = {[a] : 10}; return obj.val;", | |
| 720 {factory->NewNumberFromInt(10)}}, | |
| 721 {"var a = 20; var obj = {[a] : 10}; return obj['20'];", | |
| 722 {factory->NewNumberFromInt(10)}}, | |
| 723 {"var a = 20; var obj = {[a] : 10}; return obj[20];", | |
| 724 {factory->NewNumberFromInt(10)}}, | |
| 725 {"var a = {val:23}; var obj = {[a] : 10}; return obj[a];", | |
| 726 {factory->NewNumberFromInt(10)}}, | |
| 727 {"var a = {val:23}; var obj = {[a] : 10}; return obj['[object Object]'];", | |
| 728 {factory->NewNumberFromInt(10)}}, | |
|
mythria
2015/12/09 14:14:54
Is this test Ok? I will remove it if ToName of an
Michael Starzinger
2015/12/09 16:12:49
Acknowledged. Should be fine as it is.
You could
mythria
2015/12/09 17:19:47
Thanks for the tests. Done.
| |
| 729 }; | |
| 730 | |
| 731 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); | |
| 732 for (size_t i = 0; i < num_snippets; i++) { | |
| 733 ScopedVector<char> script(1024); | |
| 734 SNPrintF(script, "function %s() { %s }\n%s({});", kFunctionName, | |
| 735 snippets[i].code_snippet, kFunctionName); | |
| 736 | |
| 737 BytecodeGraphTester tester(isolate, zone, script.start()); | |
| 738 auto callable = tester.GetCallable<>(); | |
| 739 Handle<Object> return_value = callable().ToHandleChecked(); | |
| 740 CHECK(return_value->SameValue(*snippets[i].return_value())); | |
| 741 } | |
| 715 } | 742 } |
| 716 | 743 |
| 717 | 744 |
| 718 TEST(BytecodeGraphBuilderLogicalNot) { | 745 TEST(BytecodeGraphBuilderLogicalNot) { |
| 719 HandleAndZoneScope scope; | 746 HandleAndZoneScope scope; |
| 720 Isolate* isolate = scope.main_isolate(); | 747 Isolate* isolate = scope.main_isolate(); |
| 721 Zone* zone = scope.main_zone(); | 748 Zone* zone = scope.main_zone(); |
| 722 Factory* factory = isolate->factory(); | 749 Factory* factory = isolate->factory(); |
| 723 | 750 |
| 724 ExpectedSnippet<1> snippets[] = { | 751 ExpectedSnippet<1> snippets[] = { |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 857 {factory->NewNumberFromInt(10), | 884 {factory->NewNumberFromInt(10), |
| 858 BytecodeGraphTester::NewObject("({val : 10, name:'abc'})")}}, | 885 BytecodeGraphTester::NewObject("({val : 10, name:'abc'})")}}, |
| 859 {"'use strict'; return delete p1.val;", | 886 {"'use strict'; return delete p1.val;", |
| 860 {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})")}}, | 887 {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})")}}, |
| 861 {"'use strict'; delete p1.val; return p1.val;", | 888 {"'use strict'; delete p1.val; return p1.val;", |
| 862 {factory->undefined_value(), | 889 {factory->undefined_value(), |
| 863 BytecodeGraphTester::NewObject("({val : 10})")}}, | 890 BytecodeGraphTester::NewObject("({val : 10})")}}, |
| 864 {"'use strict'; delete p1.name; return p1.val;", | 891 {"'use strict'; delete p1.name; return p1.val;", |
| 865 {factory->NewNumberFromInt(10), | 892 {factory->NewNumberFromInt(10), |
| 866 BytecodeGraphTester::NewObject("({val : 10, name:'abc'})")}}, | 893 BytecodeGraphTester::NewObject("({val : 10, name:'abc'})")}}, |
| 867 // TODO(mythria): Add tests for global and unallocated when we have | |
| 868 // support for LdaContextSlot | |
| 869 }; | 894 }; |
| 870 | 895 |
| 871 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); | 896 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
| 872 for (size_t i = 0; i < num_snippets; i++) { | 897 for (size_t i = 0; i < num_snippets; i++) { |
| 873 ScopedVector<char> script(1024); | 898 ScopedVector<char> script(1024); |
| 874 SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName, | 899 SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName, |
| 875 snippets[i].code_snippet, kFunctionName); | 900 snippets[i].code_snippet, kFunctionName); |
| 876 | 901 |
| 877 BytecodeGraphTester tester(isolate, zone, script.start()); | 902 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 878 auto callable = tester.GetCallable<Handle<Object>>(); | 903 auto callable = tester.GetCallable<Handle<Object>>(); |
| 879 Handle<Object> return_value = | 904 Handle<Object> return_value = |
| 880 callable(snippets[i].parameter(0)).ToHandleChecked(); | 905 callable(snippets[i].parameter(0)).ToHandleChecked(); |
| 881 CHECK(return_value->SameValue(*snippets[i].return_value())); | 906 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 882 } | 907 } |
| 883 } | 908 } |
| 884 | 909 |
| 885 | 910 |
| 911 TEST(BytecodeGraphBuilderDeleteGlobal) { | |
| 912 HandleAndZoneScope scope; | |
| 913 Isolate* isolate = scope.main_isolate(); | |
| 914 Zone* zone = scope.main_zone(); | |
| 915 Factory* factory = isolate->factory(); | |
| 916 | |
| 917 ExpectedSnippet<0> snippets[] = { | |
| 918 {"var obj = {val : 10, type : 'int'};" | |
| 919 "function f() {return delete obj;};", | |
| 920 {factory->false_value()}}, | |
| 921 {"var obj = {val : 10, type : 'int'};" | |
| 922 "function f() {return delete this;};", | |
| 923 {factory->true_value()}}, | |
| 924 {"var obj = {val : 10, type : 'int'};" | |
| 925 "function f() {return delete obj.val;};", | |
| 926 {factory->true_value()}}, | |
| 927 {"var obj = {val : 10, type : 'int'};" | |
| 928 "function f() {'use strict'; return delete obj.val;};", | |
| 929 {factory->true_value()}}, | |
| 930 {"var obj = {val : 10, type : 'int'};" | |
| 931 "function f() {delete obj.val; return obj.val;};", | |
| 932 {factory->undefined_value()}}, | |
| 933 {"var obj = {val : 10, type : 'int'};" | |
| 934 "function f() {'use strict'; delete obj.val; return obj.val;};", | |
| 935 {factory->undefined_value()}}, | |
| 936 {"var obj = {1 : 10, 2 : 20};" | |
| 937 "function f() { return delete obj[1]; };", | |
| 938 {factory->true_value()}}, | |
| 939 {"var obj = {1 : 10, 2 : 20};" | |
| 940 "function f() { 'use strict'; return delete obj[1];};", | |
| 941 {factory->true_value()}}, | |
| 942 {"obj = {1 : 10, 2 : 20};" | |
| 943 "function f() { delete obj[1]; return obj[2];};", | |
| 944 {factory->NewNumberFromInt(20)}}, | |
| 945 {"function f() {" | |
| 946 " var obj = {1 : 10, 2 : 20};" | |
| 947 " function inner() { return obj[1]; };" | |
| 948 " return delete obj[1];" | |
| 949 "}", | |
| 950 {factory->true_value()}}, | |
| 951 }; | |
| 952 | |
| 953 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); | |
| 954 for (size_t i = 0; i < num_snippets; i++) { | |
| 955 ScopedVector<char> script(1024); | |
| 956 SNPrintF(script, "%s %s({});", snippets[i].code_snippet, kFunctionName); | |
| 957 | |
| 958 BytecodeGraphTester tester(isolate, zone, script.start()); | |
| 959 auto callable = tester.GetCallable<>(); | |
| 960 Handle<Object> return_value = callable().ToHandleChecked(); | |
| 961 CHECK(return_value->SameValue(*snippets[i].return_value())); | |
| 962 } | |
| 963 } | |
| 964 | |
| 965 | |
| 886 bool get_compare_result(Token::Value opcode, Handle<Object> lhs_value, | 966 bool get_compare_result(Token::Value opcode, Handle<Object> lhs_value, |
| 887 Handle<Object> rhs_value) { | 967 Handle<Object> rhs_value) { |
| 888 switch (opcode) { | 968 switch (opcode) { |
| 889 case Token::Value::EQ: | 969 case Token::Value::EQ: |
| 890 return Object::Equals(lhs_value, rhs_value).FromJust(); | 970 return Object::Equals(lhs_value, rhs_value).FromJust(); |
| 891 case Token::Value::NE: | 971 case Token::Value::NE: |
| 892 return !Object::Equals(lhs_value, rhs_value).FromJust(); | 972 return !Object::Equals(lhs_value, rhs_value).FromJust(); |
| 893 case Token::Value::EQ_STRICT: | 973 case Token::Value::EQ_STRICT: |
| 894 return lhs_value->StrictEquals(*rhs_value); | 974 return lhs_value->StrictEquals(*rhs_value); |
| 895 case Token::Value::NE_STRICT: | 975 case Token::Value::NE_STRICT: |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1015 auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>(); | 1095 auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>(); |
| 1016 Handle<Object> return_value = | 1096 Handle<Object> return_value = |
| 1017 callable(snippets[i].parameter(0), snippets[i].parameter(1)) | 1097 callable(snippets[i].parameter(0), snippets[i].parameter(1)) |
| 1018 .ToHandleChecked(); | 1098 .ToHandleChecked(); |
| 1019 CHECK(return_value->SameValue(*snippets[i].return_value())); | 1099 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 1020 } | 1100 } |
| 1021 } | 1101 } |
| 1022 | 1102 |
| 1023 | 1103 |
| 1024 TEST(BytecodeGraphBuilderTestInstanceOf) { | 1104 TEST(BytecodeGraphBuilderTestInstanceOf) { |
| 1025 // TODO(mythria): Add tests when CreateLiterals/CreateClousre are supported. | 1105 HandleAndZoneScope scope; |
| 1106 Isolate* isolate = scope.main_isolate(); | |
| 1107 Zone* zone = scope.main_zone(); | |
| 1108 Factory* factory = isolate->factory(); | |
| 1109 | |
| 1110 ExpectedSnippet<1> snippets[] = { | |
| 1111 {"return p1 instanceof Object;", | |
| 1112 {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})")}}, | |
| 1113 {"return p1 instanceof String;", | |
| 1114 {factory->false_value(), factory->NewStringFromStaticChars("string")}}, | |
| 1115 {"var cons = function() { this.val = 10; this.type = 'int'; };" | |
|
Michael Starzinger
2015/12/09 16:12:48
nit: Properties are never used, empty function wou
mythria
2015/12/09 17:19:47
Done.
| |
| 1116 "var obj = new cons();" | |
| 1117 "return obj instanceof cons;", | |
| 1118 {factory->true_value(), factory->undefined_value()}}, | |
| 1119 {"return typeof p1;", | |
| 1120 {factory->NewStringFromStaticChars("boolean"), factory->true_value()}}, | |
| 1121 {"return typeof p1;", | |
| 1122 {factory->NewStringFromStaticChars("string"), | |
| 1123 factory->NewStringFromStaticChars("abc")}}, | |
| 1124 }; | |
| 1125 | |
| 1126 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); | |
| 1127 for (size_t i = 0; i < num_snippets; i++) { | |
| 1128 ScopedVector<char> script(1024); | |
| 1129 SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName, | |
| 1130 snippets[i].code_snippet, kFunctionName); | |
| 1131 | |
| 1132 BytecodeGraphTester tester(isolate, zone, script.start()); | |
| 1133 auto callable = tester.GetCallable<Handle<Object>>(); | |
| 1134 Handle<Object> return_value = | |
| 1135 callable(snippets[i].parameter(0)).ToHandleChecked(); | |
| 1136 CHECK(return_value->SameValue(*snippets[i].return_value())); | |
| 1137 } | |
| 1026 } | 1138 } |
| 1027 | 1139 |
| 1028 | 1140 |
| 1029 TEST(BytecodeGraphBuilderThrow) { | 1141 TEST(BytecodeGraphBuilderThrow) { |
| 1030 HandleAndZoneScope scope; | 1142 HandleAndZoneScope scope; |
| 1031 Isolate* isolate = scope.main_isolate(); | 1143 Isolate* isolate = scope.main_isolate(); |
| 1032 Zone* zone = scope.main_zone(); | 1144 Zone* zone = scope.main_zone(); |
| 1033 | 1145 |
| 1034 // TODO(mythria): Add more tests when real try-catch and deoptimization | 1146 // TODO(mythria): Add more tests when real try-catch and deoptimization |
| 1035 // information are supported. | 1147 // information are supported. |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1323 BytecodeGraphTester tester(isolate, zone, script.start()); | 1435 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 1324 auto callable = tester.GetCallable<>(); | 1436 auto callable = tester.GetCallable<>(); |
| 1325 Handle<Object> return_value = callable().ToHandleChecked(); | 1437 Handle<Object> return_value = callable().ToHandleChecked(); |
| 1326 CHECK(return_value->SameValue(*snippets[i].return_value())); | 1438 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 1327 } | 1439 } |
| 1328 } | 1440 } |
| 1329 | 1441 |
| 1330 } // namespace compiler | 1442 } // namespace compiler |
| 1331 } // namespace internal | 1443 } // namespace internal |
| 1332 } // namespace v8 | 1444 } // namespace v8 |
| OLD | NEW |