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/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/interpreter/bytecode-array-iterator.h" | 8 #include "src/interpreter/bytecode-array-iterator.h" |
9 #include "src/interpreter/bytecode-generator.h" | 9 #include "src/interpreter/bytecode-generator.h" |
10 #include "src/interpreter/interpreter.h" | 10 #include "src/interpreter/interpreter.h" |
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
738 ExpectedSnippet<Handle<Object>> snippets[] = { | 738 ExpectedSnippet<Handle<Object>> snippets[] = { |
739 {"function f() { if (0) { return 1; } else { return -1; } } f()", | 739 {"function f() { if (0) { return 1; } else { return -1; } } f()", |
740 0, | 740 0, |
741 1, | 741 1, |
742 14, | 742 14, |
743 {B(LdaZero), // | 743 {B(LdaZero), // |
744 B(ToBoolean), // | 744 B(ToBoolean), // |
745 B(JumpIfFalse), U8(7), // | 745 B(JumpIfFalse), U8(7), // |
746 B(LdaSmi8), U8(1), // | 746 B(LdaSmi8), U8(1), // |
747 B(Return), // | 747 B(Return), // |
748 B(Jump), U8(5), // TODO(oth): Unreachable jump after return | 748 B(Jump), U8(5), // |
749 B(LdaSmi8), U8(-1), // | 749 B(LdaSmi8), U8(-1), // |
750 B(Return), // | 750 B(Return), // |
751 B(LdaUndefined), // | 751 B(LdaUndefined), // |
752 B(Return)}, // | 752 B(Return)}, // |
753 0, | 753 0, |
754 {unused, unused, unused, unused}}, | 754 {unused, unused, unused, unused}}, |
755 {"function f() { if ('lucky') { return 1; } else { return -1; } } f();", | 755 {"function f() { if ('lucky') { return 1; } else { return -1; } } f();", |
756 0, | 756 0, |
757 1, | 757 1, |
758 15, | 758 15, |
759 {B(LdaConstant), U8(0), // | 759 {B(LdaConstant), U8(0), // |
760 B(ToBoolean), // | 760 B(ToBoolean), // |
761 B(JumpIfFalse), U8(7), // | 761 B(JumpIfFalse), U8(7), // |
762 B(LdaSmi8), U8(1), // | 762 B(LdaSmi8), U8(1), // |
763 B(Return), // | 763 B(Return), // |
764 B(Jump), U8(5), // TODO(oth): Unreachable jump after return | 764 B(Jump), U8(5), // |
765 B(LdaSmi8), U8(-1), // | 765 B(LdaSmi8), U8(-1), // |
766 B(Return), // | 766 B(Return), // |
767 B(LdaUndefined), // | 767 B(LdaUndefined), // |
768 B(Return)}, // | 768 B(Return)}, // |
769 1, | 769 1, |
770 {helper.factory()->NewStringFromStaticChars("lucky"), unused, unused, | 770 {helper.factory()->NewStringFromStaticChars("lucky"), unused, unused, |
771 unused}}, | 771 unused}}, |
772 {"function f() { if (false) { return 1; } else { return -1; } } f();", | 772 {"function f() { if (false) { return 1; } else { return -1; } } f();", |
773 0, | 773 0, |
774 1, | 774 1, |
775 13, | 775 13, |
776 {B(LdaFalse), // | 776 {B(LdaFalse), // |
777 B(JumpIfFalse), U8(7), // | 777 B(JumpIfFalse), U8(7), // |
778 B(LdaSmi8), U8(1), // | 778 B(LdaSmi8), U8(1), // |
779 B(Return), // | 779 B(Return), // |
780 B(Jump), U8(5), // TODO(oth): Unreachable jump after return | 780 B(Jump), U8(5), // |
781 B(LdaSmi8), U8(-1), // | 781 B(LdaSmi8), U8(-1), // |
782 B(Return), // | 782 B(Return), // |
783 B(LdaUndefined), // | 783 B(LdaUndefined), // |
784 B(Return)}, // | 784 B(Return)}, // |
785 0, | 785 0, |
786 {unused, unused, unused, unused}}, | 786 {unused, unused, unused, unused}}, |
787 {"function f(a) { if (a <= 0) { return 200; } else { return -200; } }" | 787 {"function f(a) { if (a <= 0) { return 200; } else { return -200; } }" |
788 "f(99);", | 788 "f(99);", |
789 kPointerSize, | 789 kPointerSize, |
790 2, | 790 2, |
791 19, | 791 19, |
792 {B(Ldar), R(-5), // | 792 {B(Ldar), R(-5), // |
793 B(Star), R(0), // | 793 B(Star), R(0), // |
794 B(LdaZero), // | 794 B(LdaZero), // |
795 B(TestLessThanOrEqual), R(0), // | 795 B(TestLessThanOrEqual), R(0), // |
796 B(JumpIfFalse), U8(7), // | 796 B(JumpIfFalse), U8(7), // |
797 B(LdaConstant), U8(0), // | 797 B(LdaConstant), U8(0), // |
798 B(Return), // | 798 B(Return), // |
799 B(Jump), U8(5), // TODO(oth): Unreachable jump after return | 799 B(Jump), U8(5), // |
800 B(LdaConstant), U8(1), // | 800 B(LdaConstant), U8(1), // |
801 B(Return), // | 801 B(Return), // |
802 B(LdaUndefined), // | 802 B(LdaUndefined), // |
803 B(Return)}, // | 803 B(Return)}, // |
804 2, | 804 2, |
805 {helper.factory()->NewNumberFromInt(200), | 805 {helper.factory()->NewNumberFromInt(200), |
806 helper.factory()->NewNumberFromInt(-200), unused, unused}}, | 806 helper.factory()->NewNumberFromInt(-200), unused, unused}}, |
807 {"function f(a, b) { if (a in b) { return 200; } }" | 807 {"function f(a, b) { if (a in b) { return 200; } }" |
808 "f('prop', { prop: 'yes'});", | 808 "f('prop', { prop: 'yes'});", |
809 kPointerSize, | 809 kPointerSize, |
810 3, | 810 3, |
811 17, | 811 15, |
812 {B(Ldar), R(-6), // | 812 {B(Ldar), R(-6), // |
813 B(Star), R(0), // | 813 B(Star), R(0), // |
814 B(Ldar), R(-5), // | 814 B(Ldar), R(-5), // |
815 B(TestIn), R(0), // | 815 B(TestIn), R(0), // |
816 B(JumpIfFalse), U8(7), // | 816 B(JumpIfFalse), U8(5), // |
817 B(LdaConstant), U8(0), // | 817 B(LdaConstant), U8(0), // |
818 B(Return), // | 818 B(Return), // |
819 B(Jump), U8(2), // TODO(oth): Unreachable jump after return | |
820 B(LdaUndefined), // | 819 B(LdaUndefined), // |
821 B(Return)}, // | 820 B(Return)}, // |
822 1, | 821 1, |
823 {helper.factory()->NewNumberFromInt(200), unused, unused, unused}}, | 822 {helper.factory()->NewNumberFromInt(200), unused, unused, unused}}, |
824 {"function f(z) { var a = 0; var b = 0; if (a === 0.01) { " | 823 {"function f(z) { var a = 0; var b = 0; if (a === 0.01) { " |
825 #define X "b = a; a = b; " | 824 #define X "b = a; a = b; " |
826 X X X X X X X X X X X X X X X X X X X X X X X X | 825 X X X X X X X X X X X X X X X X X X X X X X X X |
827 #undef X | 826 #undef X |
828 " return 200; } else { return -200; } } f(0.001)", | 827 " return 200; } else { return -200; } } f(0.001)", |
829 3 * kPointerSize, | 828 3 * kPointerSize, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
862 " if (a <= b) { return 1; }\n" | 861 " if (a <= b) { return 1; }\n" |
863 " if (a >= b) { return 1; }\n" | 862 " if (a >= b) { return 1; }\n" |
864 " if (a in b) { return 1; }\n" | 863 " if (a in b) { return 1; }\n" |
865 " if (a instanceof b) { return 1; }\n" | 864 " if (a instanceof b) { return 1; }\n" |
866 " /* if (a != b) { return 1; } */" // TODO(oth) Ast visitor yields | 865 " /* if (a != b) { return 1; } */" // TODO(oth) Ast visitor yields |
867 " /* if (a !== b) { return 1; } */" // UNARY NOT, rather than !=/!==. | 866 " /* if (a !== b) { return 1; } */" // UNARY NOT, rather than !=/!==. |
868 " return 0;\n" | 867 " return 0;\n" |
869 "} f(1, 1);", | 868 "} f(1, 1);", |
870 kPointerSize, | 869 kPointerSize, |
871 3, | 870 3, |
872 122, | 871 106, |
873 { | 872 { |
874 #define IF_CONDITION_RETURN(condition) \ | 873 #define IF_CONDITION_RETURN(condition) \ |
875 B(Ldar), R(-6), \ | 874 B(Ldar), R(-6), \ |
876 B(Star), R(0), \ | 875 B(Star), R(0), \ |
877 B(Ldar), R(-5), \ | 876 B(Ldar), R(-5), \ |
878 B(condition), R(0), \ | 877 B(condition), R(0), \ |
879 B(JumpIfFalse), U8(7), \ | 878 B(JumpIfFalse), U8(5), \ |
880 B(LdaSmi8), U8(1), \ | 879 B(LdaSmi8), U8(1), \ |
881 B(Return), \ | 880 B(Return), |
882 B(Jump), U8(2), | |
883 IF_CONDITION_RETURN(TestEqual) // | 881 IF_CONDITION_RETURN(TestEqual) // |
884 IF_CONDITION_RETURN(TestEqualStrict) // | 882 IF_CONDITION_RETURN(TestEqualStrict) // |
885 IF_CONDITION_RETURN(TestLessThan) // | 883 IF_CONDITION_RETURN(TestLessThan) // |
886 IF_CONDITION_RETURN(TestGreaterThan) // | 884 IF_CONDITION_RETURN(TestGreaterThan) // |
887 IF_CONDITION_RETURN(TestLessThanOrEqual) // | 885 IF_CONDITION_RETURN(TestLessThanOrEqual) // |
888 IF_CONDITION_RETURN(TestGreaterThanOrEqual) // | 886 IF_CONDITION_RETURN(TestGreaterThanOrEqual) // |
889 IF_CONDITION_RETURN(TestIn) // | 887 IF_CONDITION_RETURN(TestIn) // |
890 IF_CONDITION_RETURN(TestInstanceOf) // | 888 IF_CONDITION_RETURN(TestInstanceOf) // |
891 #undef IF_CONDITION_RETURN | 889 #undef IF_CONDITION_RETURN |
892 B(LdaZero), // | 890 B(LdaZero), // |
893 B(Return)}, // | 891 B(Return)}, // |
894 0, | 892 0, |
895 {unused, unused, unused, unused}}, | 893 {unused, unused, unused, unused}}, |
896 }; | 894 }; |
897 | 895 |
898 for (size_t i = 0; i < arraysize(snippets); i++) { | 896 for (size_t i = 0; i < arraysize(snippets); i++) { |
899 Handle<BytecodeArray> bytecode_array = | 897 Handle<BytecodeArray> bytecode_array = |
900 helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName); | 898 helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName); |
901 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 899 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
902 } | 900 } |
903 } | 901 } |
904 | 902 |
905 | 903 |
904 TEST(BasicLoops) { | |
905 InitializedHandleScope handle_scope; | |
906 BytecodeGeneratorHelper helper; | |
907 | |
908 Handle<Object> unused = helper.factory()->undefined_value(); | |
909 ExpectedSnippet<Handle<Object>> snippets[] = { | |
910 {"var x = 0;" | |
911 "var y = 1;" | |
912 "while (x < 10) {" | |
913 " y = y * 10;" | |
914 " x = x + 1;" | |
915 "}" | |
916 "return y;", | |
917 3 * kPointerSize, | |
918 1, | |
919 42, | |
920 { | |
921 B(LdaZero), // | |
922 B(Star), R(0), // | |
923 B(LdaSmi8), U8(1), // | |
924 B(Star), R(1), // | |
925 B(Jump), U8(22), // | |
926 B(Ldar), R(1), // | |
927 B(Star), R(2), // | |
928 B(LdaSmi8), U8(10), // | |
929 B(Mul), R(2), // | |
930 B(Star), R(1), // | |
931 B(Ldar), R(0), // | |
932 B(Star), R(2), // | |
933 B(LdaSmi8), U8(1), // | |
934 B(Add), R(2), // | |
935 B(Star), R(0), // | |
936 B(Ldar), R(0), // | |
937 B(Star), R(2), // | |
938 B(LdaSmi8), U8(10), // | |
939 B(TestLessThan), R(2), // | |
940 B(JumpIfTrue), U8(-28), // | |
941 B(Ldar), R(1), // | |
942 B(Return), // | |
943 }, | |
944 0, | |
945 {unused, unused, unused, unused}}, | |
rmcilroy
2015/10/01 09:18:56
Do you need the constant pool checks? Looks this i
oth
2015/10/01 11:43:02
The only reason unused exists is to explicitly ini
rmcilroy
2015/10/01 12:12:07
Right, but if none of the tests have any constants
oth
2015/10/01 13:13:56
Done.
| |
946 {"var i = 0;" | |
947 "while(true) {" | |
948 " if (i < 0) continue;" | |
949 " if (i == 3) break;" | |
950 " if (i == 4) break;" | |
951 " if (i == 10) continue;" | |
952 " if (i == 5) break;" | |
953 " i = i + 1;" | |
954 "}" | |
955 "return i;", | |
956 2 * kPointerSize, | |
957 1, | |
958 80, | |
959 { | |
960 B(LdaZero), // | |
961 B(Star), R(0), // | |
962 B(Jump), U8(71), // | |
963 B(Ldar), R(0), // | |
964 B(Star), R(1), // | |
965 B(LdaZero), // | |
966 B(TestLessThan), R(1), // | |
967 B(JumpIfFalse), U8(4), // | |
968 B(Jump), U8(60), // | |
969 B(Ldar), R(0), // | |
970 B(Star), R(1), // | |
971 B(LdaSmi8), U8(3), // | |
972 B(TestEqual), R(1), // | |
973 B(JumpIfFalse), U8(4), // | |
974 B(Jump), U8(51), // | |
975 B(Ldar), R(0), // | |
976 B(Star), R(1), // | |
977 B(LdaSmi8), U8(4), // | |
978 B(TestEqual), R(1), // | |
979 B(JumpIfFalse), U8(4), // | |
980 B(Jump), U8(39), // | |
981 B(Ldar), R(0), // | |
982 B(Star), R(1), // | |
983 B(LdaSmi8), U8(10), // | |
984 B(TestEqual), R(1), // | |
985 B(JumpIfFalse), U8(4), // | |
986 B(Jump), U8(24), // | |
987 B(Ldar), R(0), // | |
988 B(Star), R(1), // | |
989 B(LdaSmi8), U8(5), // | |
990 B(TestEqual), R(1), // | |
991 B(JumpIfFalse), U8(4), // | |
992 B(Jump), U8(15), // | |
993 B(Ldar), R(0), // | |
994 B(Star), R(1), // | |
995 B(LdaSmi8), U8(1), // | |
996 B(Add), R(1), // | |
997 B(Star), R(0), // | |
998 B(LdaTrue), // | |
999 B(JumpIfTrue), U8(-70), // | |
1000 B(Ldar), R(0), // | |
1001 B(Return) // | |
1002 }, | |
1003 0, | |
1004 {unused, unused, unused, unused}}, | |
1005 {"var x = 0; var y = 1;" | |
1006 "do {" | |
1007 " y = y * 10;" | |
1008 " if (x == 5) break;" | |
1009 " if (x == 6) continue;" | |
1010 " x = x + 1;" | |
1011 "} while (x < 10);" | |
1012 "return y;", | |
1013 3 * kPointerSize, | |
1014 1, | |
1015 64, | |
1016 { | |
1017 B(LdaZero), // | |
1018 B(Star), R(0), // | |
1019 B(LdaSmi8), U8(1), // | |
1020 B(Star), R(1), // | |
1021 B(Ldar), R(1), // | |
1022 B(Star), R(2), // | |
1023 B(LdaSmi8), U8(10), // | |
1024 B(Mul), R(2), // | |
1025 B(Star), R(1), // | |
1026 B(Ldar), R(0), // | |
1027 B(Star), R(2), // | |
1028 B(LdaSmi8), U8(5), // | |
1029 B(TestEqual), R(2), // | |
1030 B(JumpIfFalse), U8(4), // | |
1031 B(Jump), U8(34), // | |
1032 B(Ldar), R(0), // | |
1033 B(Star), R(2), // | |
1034 B(LdaSmi8), U8(6), // | |
1035 B(TestEqual), R(2), // | |
1036 B(JumpIfFalse), U8(4), // | |
1037 B(Jump), U8(12), // | |
1038 B(Ldar), R(0), // | |
1039 B(Star), R(2), // | |
1040 B(LdaSmi8), U8(1), // | |
1041 B(Add), R(2), // | |
1042 B(Star), R(0), // | |
1043 B(Ldar), R(0), // | |
1044 B(Star), R(2), // | |
1045 B(LdaSmi8), U8(10), // | |
1046 B(TestLessThan), R(2), // | |
1047 B(JumpIfTrue), U8(-52), // | |
1048 B(Ldar), R(1), // | |
1049 B(Return) // | |
1050 }, | |
1051 0, | |
1052 {unused, unused, unused, unused}}, | |
1053 {"var x = 0; " | |
1054 "for(;;) {" | |
1055 " if (x == 1) break;" | |
1056 " x = x + 1;" | |
1057 "}", | |
1058 2 * kPointerSize, | |
1059 1, | |
1060 29, | |
1061 { | |
1062 B(LdaZero), // | |
1063 B(Star), R(0), // | |
1064 B(Ldar), R(0), // | |
1065 B(Star), R(1), // | |
1066 B(LdaSmi8), // | |
1067 U8(1), // | |
1068 B(TestEqual), R(1), // | |
1069 B(JumpIfFalse), U8(4), // | |
1070 B(Jump), U8(14), // | |
1071 B(Ldar), R(0), // | |
1072 B(Star), R(1), // | |
1073 B(LdaSmi8), U8(1), // | |
1074 B(Add), R(1), // | |
1075 B(Star), R(0), // | |
1076 B(Jump), U8(-22), // | |
1077 B(LdaUndefined), // | |
1078 B(Return), // | |
1079 }, | |
1080 0, | |
1081 {unused, unused, unused, unused}}, | |
1082 {"var u = 0;" | |
1083 "for(var i = 0; i < 100; i = i + 1) {" | |
1084 " u = u + 1;" | |
1085 " continue;" | |
1086 "}", | |
1087 3 * kPointerSize, | |
1088 1, | |
1089 42, | |
1090 { | |
1091 B(LdaZero), // | |
1092 B(Star), R(0), // | |
1093 B(LdaZero), // | |
1094 B(Star), R(1), // | |
1095 B(Jump), U8(24), // | |
1096 B(Ldar), R(0), // | |
1097 B(Star), R(2), // | |
1098 B(LdaSmi8), U8(1), // | |
1099 B(Add), R(2), // | |
1100 B(Star), R(0), // | |
1101 B(Jump), U8(2), // | |
1102 B(Ldar), R(1), // | |
1103 B(Star), R(2), // | |
1104 B(LdaSmi8), U8(1), // | |
1105 B(Add), R(2), // | |
1106 B(Star), R(1), // | |
1107 B(Ldar), R(1), // | |
1108 B(Star), R(2), // | |
1109 B(LdaSmi8), U8(100), // | |
1110 B(TestLessThan), R(2), // | |
1111 B(JumpIfTrue), U8(-30), // | |
1112 B(LdaUndefined), // | |
1113 B(Return), // | |
1114 }, | |
1115 0, | |
1116 {unused, unused, unused, unused}}, | |
1117 {"var i = 0;" | |
1118 "while(true) {" | |
1119 " while (i < 3) {" | |
1120 " if (i == 2) break;" | |
1121 " i = i + 1;" | |
1122 " }" | |
1123 " i = i + 1;" | |
1124 " break;" | |
1125 "}" | |
1126 "return i;", | |
1127 2 * kPointerSize, | |
1128 1, | |
1129 57, | |
1130 { | |
1131 B(LdaZero), // | |
1132 B(Star), R(0), // | |
1133 B(Jump), U8(48), // | |
1134 B(Jump), U8(24), // | |
1135 B(Ldar), R(0), // | |
1136 B(Star), R(1), // | |
1137 B(LdaSmi8), U8(2), // | |
1138 B(TestEqual), R(1), // | |
1139 B(JumpIfFalse), U8(4), // | |
1140 B(Jump), U8(22), // | |
1141 B(Ldar), R(0), // | |
1142 B(Star), R(1), // | |
1143 B(LdaSmi8), U8(1), // | |
1144 B(Add), R(1), // | |
1145 B(Star), R(0), // | |
1146 B(Ldar), R(0), // | |
1147 B(Star), R(1), // | |
1148 B(LdaSmi8), U8(3), // | |
1149 B(TestLessThan), R(1), // | |
1150 B(JumpIfTrue), U8(-30), // | |
1151 B(Ldar), R(0), // | |
1152 B(Star), R(1), // | |
1153 B(LdaSmi8), U8(1), // | |
1154 B(Add), R(1), // | |
1155 B(Star), R(0), // | |
1156 B(Jump), U8(5), // | |
1157 B(LdaTrue), // | |
1158 B(JumpIfTrue), U8(-47), // | |
1159 B(Ldar), R(0), // | |
1160 B(Return), // | |
1161 }, | |
1162 0, | |
1163 {unused, unused, unused, unused}}, | |
1164 }; | |
1165 | |
1166 for (size_t i = 0; i < arraysize(snippets); i++) { | |
1167 Handle<BytecodeArray> bytecode_array = | |
1168 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | |
1169 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | |
1170 } | |
1171 } | |
1172 | |
906 } // namespace interpreter | 1173 } // namespace interpreter |
907 } // namespace internal | 1174 } // namespace internal |
908 } // namespance v8 | 1175 } // namespance v8 |
OLD | NEW |