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)}}}; |
Michael Starzinger
2015/12/09 17:29:53
If this is giving you trouble, just use Factory::n
mythria
2015/12/10 13:16:49
Thanks :). Done.
| |
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(BytecodeGraphBuilderToObject) { |
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. | |
711 // ToBoolean -> If | |
712 // ToObject -> ForIn | |
713 // ToNumber -> Inc/Dec | |
714 // ToName -> CreateObjectLiteral | |
715 } | 713 } |
716 | 714 |
717 | 715 |
716 TEST(BytecodeGraphBuilderToName) { | |
717 HandleAndZoneScope scope; | |
718 Isolate* isolate = scope.main_isolate(); | |
719 Zone* zone = scope.main_zone(); | |
720 Factory* factory = isolate->factory(); | |
721 | |
722 ExpectedSnippet<0> snippets[] = { | |
723 {"var a = 'val'; var obj = {[a] : 10}; return obj.val;", | |
724 {factory->NewNumberFromInt(10)}}, | |
725 {"var a = 20; var obj = {[a] : 10}; return obj['20'];", | |
726 {factory->NewNumberFromInt(10)}}, | |
727 {"var a = 20; var obj = {[a] : 10}; return obj[20];", | |
728 {factory->NewNumberFromInt(10)}}, | |
729 {"var a = {val:23}; var obj = {[a] : 10}; return obj[a];", | |
730 {factory->NewNumberFromInt(10)}}, | |
731 {"var a = {val:23}; var obj = {[a] : 10}; return obj['[object Object]'];", | |
732 {factory->NewNumberFromInt(10)}}, | |
733 {"var a = {toString : function() { return 'x'}};\n" | |
734 "var obj = {[a] : 10};\n" | |
735 "return obj.x;", | |
736 {factory->NewNumberFromInt(10)}}, | |
737 {"var a = {valueOf : function() { return 'x'}};\n" | |
738 "var obj = {[a] : 10};\n" | |
739 "return obj.x;", | |
740 {factory->undefined_value()}}, | |
741 {"var a = {toString : function() { return 'x'}};\n" | |
742 "var obj = {[a] : 10};\n" | |
743 "return obj.x;", | |
744 {factory->NewNumberFromInt(10)}}, | |
745 {"var a = {[Symbol.toPrimitive] : function() { return 'x'}};\n" | |
746 "var obj = {[a] : 10};\n" | |
747 "return obj.x;", | |
rmcilroy
2015/12/10 11:39:30
If you could add these new tests to test-interpret
mythria
2015/12/10 13:16:49
Done.
| |
748 {factory->NewNumberFromInt(10)}}, | |
749 }; | |
750 | |
751 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); | |
752 for (size_t i = 0; i < num_snippets; i++) { | |
753 ScopedVector<char> script(1024); | |
754 SNPrintF(script, "function %s() { %s }\n%s({});", kFunctionName, | |
755 snippets[i].code_snippet, kFunctionName); | |
756 | |
757 BytecodeGraphTester tester(isolate, zone, script.start()); | |
758 auto callable = tester.GetCallable<>(); | |
759 Handle<Object> return_value = callable().ToHandleChecked(); | |
760 CHECK(return_value->SameValue(*snippets[i].return_value())); | |
761 } | |
762 } | |
763 | |
764 | |
718 TEST(BytecodeGraphBuilderLogicalNot) { | 765 TEST(BytecodeGraphBuilderLogicalNot) { |
719 HandleAndZoneScope scope; | 766 HandleAndZoneScope scope; |
720 Isolate* isolate = scope.main_isolate(); | 767 Isolate* isolate = scope.main_isolate(); |
721 Zone* zone = scope.main_zone(); | 768 Zone* zone = scope.main_zone(); |
722 Factory* factory = isolate->factory(); | 769 Factory* factory = isolate->factory(); |
723 | 770 |
724 ExpectedSnippet<1> snippets[] = { | 771 ExpectedSnippet<1> snippets[] = { |
725 {"return !p1;", | 772 {"return !p1;", |
726 {factory->false_value(), | 773 {factory->false_value(), |
727 BytecodeGraphTester::NewObject("({val : 10})")}}, | 774 BytecodeGraphTester::NewObject("({val : 10})")}}, |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
857 {factory->NewNumberFromInt(10), | 904 {factory->NewNumberFromInt(10), |
858 BytecodeGraphTester::NewObject("({val : 10, name:'abc'})")}}, | 905 BytecodeGraphTester::NewObject("({val : 10, name:'abc'})")}}, |
859 {"'use strict'; return delete p1.val;", | 906 {"'use strict'; return delete p1.val;", |
860 {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})")}}, | 907 {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})")}}, |
861 {"'use strict'; delete p1.val; return p1.val;", | 908 {"'use strict'; delete p1.val; return p1.val;", |
862 {factory->undefined_value(), | 909 {factory->undefined_value(), |
863 BytecodeGraphTester::NewObject("({val : 10})")}}, | 910 BytecodeGraphTester::NewObject("({val : 10})")}}, |
864 {"'use strict'; delete p1.name; return p1.val;", | 911 {"'use strict'; delete p1.name; return p1.val;", |
865 {factory->NewNumberFromInt(10), | 912 {factory->NewNumberFromInt(10), |
866 BytecodeGraphTester::NewObject("({val : 10, name:'abc'})")}}, | 913 BytecodeGraphTester::NewObject("({val : 10, name:'abc'})")}}, |
867 // TODO(mythria): Add tests for global and unallocated when we have | |
868 // support for LdaContextSlot | |
869 }; | 914 }; |
870 | 915 |
871 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); | 916 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
872 for (size_t i = 0; i < num_snippets; i++) { | 917 for (size_t i = 0; i < num_snippets; i++) { |
873 ScopedVector<char> script(1024); | 918 ScopedVector<char> script(1024); |
874 SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName, | 919 SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName, |
875 snippets[i].code_snippet, kFunctionName); | 920 snippets[i].code_snippet, kFunctionName); |
876 | 921 |
877 BytecodeGraphTester tester(isolate, zone, script.start()); | 922 BytecodeGraphTester tester(isolate, zone, script.start()); |
878 auto callable = tester.GetCallable<Handle<Object>>(); | 923 auto callable = tester.GetCallable<Handle<Object>>(); |
879 Handle<Object> return_value = | 924 Handle<Object> return_value = |
880 callable(snippets[i].parameter(0)).ToHandleChecked(); | 925 callable(snippets[i].parameter(0)).ToHandleChecked(); |
881 CHECK(return_value->SameValue(*snippets[i].return_value())); | 926 CHECK(return_value->SameValue(*snippets[i].return_value())); |
882 } | 927 } |
883 } | 928 } |
884 | 929 |
885 | 930 |
931 TEST(BytecodeGraphBuilderDeleteGlobal) { | |
932 HandleAndZoneScope scope; | |
933 Isolate* isolate = scope.main_isolate(); | |
934 Zone* zone = scope.main_zone(); | |
935 Factory* factory = isolate->factory(); | |
936 | |
937 ExpectedSnippet<0> snippets[] = { | |
938 {"var obj = {val : 10, type : 'int'};" | |
939 "function f() {return delete obj;};", | |
940 {factory->false_value()}}, | |
941 {"var obj = {val : 10, type : 'int'};" | |
942 "function f() {return delete this;};", | |
943 {factory->true_value()}}, | |
944 {"var obj = {val : 10, type : 'int'};" | |
945 "function f() {return delete obj.val;};", | |
946 {factory->true_value()}}, | |
947 {"var obj = {val : 10, type : 'int'};" | |
948 "function f() {'use strict'; return delete obj.val;};", | |
949 {factory->true_value()}}, | |
950 {"var obj = {val : 10, type : 'int'};" | |
951 "function f() {delete obj.val; return obj.val;};", | |
952 {factory->undefined_value()}}, | |
953 {"var obj = {val : 10, type : 'int'};" | |
954 "function f() {'use strict'; delete obj.val; return obj.val;};", | |
955 {factory->undefined_value()}}, | |
956 {"var obj = {1 : 10, 2 : 20};" | |
957 "function f() { return delete obj[1]; };", | |
958 {factory->true_value()}}, | |
959 {"var obj = {1 : 10, 2 : 20};" | |
960 "function f() { 'use strict'; return delete obj[1];};", | |
961 {factory->true_value()}}, | |
962 {"obj = {1 : 10, 2 : 20};" | |
963 "function f() { delete obj[1]; return obj[2];};", | |
964 {factory->NewNumberFromInt(20)}}, | |
965 {"function f() {" | |
966 " var obj = {1 : 10, 2 : 20};" | |
967 " function inner() { return obj[1]; };" | |
968 " return delete obj[1];" | |
969 "}", | |
970 {factory->true_value()}}, | |
971 }; | |
972 | |
973 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); | |
974 for (size_t i = 0; i < num_snippets; i++) { | |
975 ScopedVector<char> script(1024); | |
976 SNPrintF(script, "%s %s({});", snippets[i].code_snippet, kFunctionName); | |
977 | |
978 BytecodeGraphTester tester(isolate, zone, script.start()); | |
979 auto callable = tester.GetCallable<>(); | |
980 Handle<Object> return_value = callable().ToHandleChecked(); | |
981 CHECK(return_value->SameValue(*snippets[i].return_value())); | |
982 } | |
983 } | |
984 | |
985 | |
886 bool get_compare_result(Token::Value opcode, Handle<Object> lhs_value, | 986 bool get_compare_result(Token::Value opcode, Handle<Object> lhs_value, |
887 Handle<Object> rhs_value) { | 987 Handle<Object> rhs_value) { |
888 switch (opcode) { | 988 switch (opcode) { |
889 case Token::Value::EQ: | 989 case Token::Value::EQ: |
890 return Object::Equals(lhs_value, rhs_value).FromJust(); | 990 return Object::Equals(lhs_value, rhs_value).FromJust(); |
891 case Token::Value::NE: | 991 case Token::Value::NE: |
892 return !Object::Equals(lhs_value, rhs_value).FromJust(); | 992 return !Object::Equals(lhs_value, rhs_value).FromJust(); |
893 case Token::Value::EQ_STRICT: | 993 case Token::Value::EQ_STRICT: |
894 return lhs_value->StrictEquals(*rhs_value); | 994 return lhs_value->StrictEquals(*rhs_value); |
895 case Token::Value::NE_STRICT: | 995 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>>(); | 1115 auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>(); |
1016 Handle<Object> return_value = | 1116 Handle<Object> return_value = |
1017 callable(snippets[i].parameter(0), snippets[i].parameter(1)) | 1117 callable(snippets[i].parameter(0), snippets[i].parameter(1)) |
1018 .ToHandleChecked(); | 1118 .ToHandleChecked(); |
1019 CHECK(return_value->SameValue(*snippets[i].return_value())); | 1119 CHECK(return_value->SameValue(*snippets[i].return_value())); |
1020 } | 1120 } |
1021 } | 1121 } |
1022 | 1122 |
1023 | 1123 |
1024 TEST(BytecodeGraphBuilderTestInstanceOf) { | 1124 TEST(BytecodeGraphBuilderTestInstanceOf) { |
1025 // TODO(mythria): Add tests when CreateLiterals/CreateClousre are supported. | 1125 HandleAndZoneScope scope; |
1126 Isolate* isolate = scope.main_isolate(); | |
1127 Zone* zone = scope.main_zone(); | |
1128 Factory* factory = isolate->factory(); | |
1129 | |
1130 ExpectedSnippet<1> snippets[] = { | |
1131 {"return p1 instanceof Object;", | |
1132 {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})")}}, | |
1133 {"return p1 instanceof String;", | |
1134 {factory->false_value(), factory->NewStringFromStaticChars("string")}}, | |
1135 {"var cons = function() {};" | |
1136 "var obj = new cons();" | |
1137 "return obj instanceof cons;", | |
1138 {factory->true_value(), factory->undefined_value()}}, | |
1139 {"return typeof p1;", | |
rmcilroy
2015/12/10 11:39:30
Should the typeof tests be a separate test?
mythria
2015/12/10 13:16:49
oops, copy-paste error. These tests are already a
| |
1140 {factory->NewStringFromStaticChars("boolean"), factory->true_value()}}, | |
1141 {"return typeof p1;", | |
1142 {factory->NewStringFromStaticChars("string"), | |
1143 factory->NewStringFromStaticChars("abc")}}, | |
1144 }; | |
1145 | |
1146 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); | |
1147 for (size_t i = 0; i < num_snippets; i++) { | |
1148 ScopedVector<char> script(1024); | |
1149 SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName, | |
1150 snippets[i].code_snippet, kFunctionName); | |
1151 | |
1152 BytecodeGraphTester tester(isolate, zone, script.start()); | |
1153 auto callable = tester.GetCallable<Handle<Object>>(); | |
1154 Handle<Object> return_value = | |
1155 callable(snippets[i].parameter(0)).ToHandleChecked(); | |
1156 CHECK(return_value->SameValue(*snippets[i].return_value())); | |
1157 } | |
1026 } | 1158 } |
1027 | 1159 |
1028 | 1160 |
1029 TEST(BytecodeGraphBuilderThrow) { | 1161 TEST(BytecodeGraphBuilderThrow) { |
1030 HandleAndZoneScope scope; | 1162 HandleAndZoneScope scope; |
1031 Isolate* isolate = scope.main_isolate(); | 1163 Isolate* isolate = scope.main_isolate(); |
1032 Zone* zone = scope.main_zone(); | 1164 Zone* zone = scope.main_zone(); |
1033 | 1165 |
1034 // TODO(mythria): Add more tests when real try-catch and deoptimization | 1166 // TODO(mythria): Add more tests when real try-catch and deoptimization |
1035 // information are supported. | 1167 // information are supported. |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1323 BytecodeGraphTester tester(isolate, zone, script.start()); | 1455 BytecodeGraphTester tester(isolate, zone, script.start()); |
1324 auto callable = tester.GetCallable<>(); | 1456 auto callable = tester.GetCallable<>(); |
1325 Handle<Object> return_value = callable().ToHandleChecked(); | 1457 Handle<Object> return_value = callable().ToHandleChecked(); |
1326 CHECK(return_value->SameValue(*snippets[i].return_value())); | 1458 CHECK(return_value->SameValue(*snippets[i].return_value())); |
1327 } | 1459 } |
1328 } | 1460 } |
1329 | 1461 |
1330 } // namespace compiler | 1462 } // namespace compiler |
1331 } // namespace internal | 1463 } // namespace internal |
1332 } // namespace v8 | 1464 } // namespace v8 |
OLD | NEW |