Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(659)

Side by Side Diff: test/cctest/interpreter/test-interpreter.cc

Issue 1369123002: [Interpreter] Add interpreter support for compare ops and ToBoolean. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Incorporate review feedback from mstarzinger and rmcilroy. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 144
145 DISALLOW_COPY_AND_ASSIGN(InterpreterTester); 145 DISALLOW_COPY_AND_ASSIGN(InterpreterTester);
146 }; 146 };
147 147
148 } // namespace interpreter 148 } // namespace interpreter
149 } // namespace internal 149 } // namespace internal
150 } // namespace v8 150 } // namespace v8
151 151
152 using v8::internal::BytecodeArray; 152 using v8::internal::BytecodeArray;
153 using v8::internal::Handle; 153 using v8::internal::Handle;
154 using v8::internal::LanguageMode;
154 using v8::internal::Object; 155 using v8::internal::Object;
155 using v8::internal::Runtime; 156 using v8::internal::Runtime;
156 using v8::internal::Smi; 157 using v8::internal::Smi;
157 using v8::internal::Token; 158 using v8::internal::Token;
158 using namespace v8::internal::interpreter; 159 using namespace v8::internal::interpreter;
159 160
160 TEST(InterpreterReturn) { 161 TEST(InterpreterReturn) {
161 HandleAndZoneScope handles; 162 HandleAndZoneScope handles;
162 Handle<Object> undefined_value = 163 Handle<Object> undefined_value =
163 handles.main_isolate()->factory()->undefined_value(); 164 handles.main_isolate()->factory()->undefined_value();
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 .Bind(&done) 970 .Bind(&done)
970 .Bind(&done1) 971 .Bind(&done1)
971 .Return(); 972 .Return();
972 973
973 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); 974 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
974 InterpreterTester tester(handles.main_isolate(), bytecode_array); 975 InterpreterTester tester(handles.main_isolate(), bytecode_array);
975 auto callable = tester.GetCallable<>(); 976 auto callable = tester.GetCallable<>();
976 Handle<Object> return_value = callable().ToHandleChecked(); 977 Handle<Object> return_value = callable().ToHandleChecked();
977 CHECK_EQ(Smi::cast(*return_value)->value(), 7); 978 CHECK_EQ(Smi::cast(*return_value)->value(), 7);
978 } 979 }
980
981
982 static const Token::Value kComparisonTypes[] = {
983 Token::Value::EQ, Token::Value::NE, Token::Value::EQ_STRICT,
984 Token::Value::NE_STRICT, Token::Value::LTE, Token::Value::LTE,
985 Token::Value::GT, Token::Value::GTE};
986
987
988 template <typename T>
989 bool CompareC(Token::Value op, T lhs, T rhs, bool types_differed = false) {
990 switch (op) {
991 case Token::Value::EQ:
992 return lhs == rhs;
993 case Token::Value::NE:
994 return lhs != rhs;
995 case Token::Value::EQ_STRICT:
996 return (lhs == rhs) && !types_differed;
997 case Token::Value::NE_STRICT:
998 return (lhs != rhs) || types_differed;
999 case Token::Value::LT:
1000 return lhs < rhs;
1001 case Token::Value::LTE:
1002 return lhs <= rhs;
1003 case Token::Value::GT:
1004 return lhs > rhs;
1005 case Token::Value::GTE:
1006 return lhs >= rhs;
1007 default:
1008 UNREACHABLE();
1009 return false;
1010 }
1011 }
1012
1013
1014 TEST(InterpreterSmiComparisons) {
1015 // NB Constants cover 31-bit space.
1016 int inputs[] = {v8::internal::kMinInt / 2,
1017 v8::internal::kMinInt / 4,
1018 -108733832,
1019 -999,
1020 -42,
1021 -2,
1022 -1,
1023 0,
1024 +1,
1025 +2,
1026 42,
1027 12345678,
1028 v8::internal::kMaxInt / 4,
1029 v8::internal::kMaxInt / 2};
1030
1031 for (size_t c = 0; c < arraysize(kComparisonTypes); c++) {
1032 Token::Value comparison = kComparisonTypes[c];
1033 for (size_t i = 0; i < arraysize(inputs); i++) {
1034 for (size_t j = 0; j < arraysize(inputs); j++) {
1035 HandleAndZoneScope handles;
1036 BytecodeArrayBuilder builder(handles.main_isolate(),
1037 handles.main_zone());
1038 Register r0(0);
1039 builder.set_locals_count(1);
1040 builder.set_parameter_count(0);
1041 builder.LoadLiteral(Smi::FromInt(inputs[i]))
1042 .StoreAccumulatorInRegister(r0)
1043 .LoadLiteral(Smi::FromInt(inputs[j]))
1044 .CompareOperation(comparison, r0, LanguageMode::SLOPPY)
1045 .Return();
1046
1047 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
1048 InterpreterTester tester(handles.main_isolate(), bytecode_array);
1049 auto callable = tester.GetCallable<>();
1050 Handle<Object> return_value = callable().ToHandleChecked();
1051 CHECK(return_value->IsBoolean());
1052 CHECK_EQ(return_value->BooleanValue(),
1053 CompareC(comparison, inputs[i], inputs[j]));
1054 }
1055 }
1056 }
1057 }
1058
1059
1060 TEST(InterpreterHeapNumberComparisons) {
1061 double inputs[] = {std::numeric_limits<double>::min(),
1062 std::numeric_limits<double>::max(),
1063 -0.001,
1064 0.01,
1065 0.1000001,
1066 1e99,
1067 -1e-99};
1068 for (size_t c = 0; c < arraysize(kComparisonTypes); c++) {
1069 Token::Value comparison = kComparisonTypes[c];
1070 for (size_t i = 0; i < arraysize(inputs); i++) {
1071 for (size_t j = 0; j < arraysize(inputs); j++) {
1072 HandleAndZoneScope handles;
1073 i::Factory* factory = handles.main_isolate()->factory();
1074 BytecodeArrayBuilder builder(handles.main_isolate(),
1075 handles.main_zone());
1076 Register r0(0);
1077 builder.set_locals_count(1);
1078 builder.set_parameter_count(0);
1079 builder.LoadLiteral(factory->NewHeapNumber(inputs[i]))
1080 .StoreAccumulatorInRegister(r0)
1081 .LoadLiteral(factory->NewHeapNumber(inputs[j]))
1082 .CompareOperation(comparison, r0, LanguageMode::SLOPPY)
1083 .Return();
1084
1085 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
1086 InterpreterTester tester(handles.main_isolate(), bytecode_array);
1087 auto callable = tester.GetCallable<>();
1088 Handle<Object> return_value = callable().ToHandleChecked();
1089 CHECK(return_value->IsBoolean());
1090 CHECK_EQ(return_value->BooleanValue(),
1091 CompareC(comparison, inputs[i], inputs[j]));
1092 }
1093 }
1094 }
1095 }
1096
1097
1098 TEST(InterpreterStringComparisons) {
1099 std::string inputs[] = {"A", "abc", "z", "", "Foo!", "Foo"};
1100
1101 for (size_t c = 0; c < arraysize(kComparisonTypes); c++) {
1102 Token::Value comparison = kComparisonTypes[c];
1103 for (size_t i = 0; i < arraysize(inputs); i++) {
1104 for (size_t j = 0; j < arraysize(inputs); j++) {
1105 const char* lhs = inputs[i].c_str();
1106 const char* rhs = inputs[j].c_str();
1107 HandleAndZoneScope handles;
1108 i::Factory* factory = handles.main_isolate()->factory();
1109 BytecodeArrayBuilder builder(handles.main_isolate(),
1110 handles.main_zone());
1111 Register r0(0);
1112 builder.set_locals_count(1);
1113 builder.set_parameter_count(0);
1114 builder.LoadLiteral(factory->NewStringFromAsciiChecked(lhs))
1115 .StoreAccumulatorInRegister(r0)
1116 .LoadLiteral(factory->NewStringFromAsciiChecked(rhs))
1117 .CompareOperation(comparison, r0, LanguageMode::SLOPPY)
1118 .Return();
1119
1120 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
1121 InterpreterTester tester(handles.main_isolate(), bytecode_array);
1122 auto callable = tester.GetCallable<>();
1123 Handle<Object> return_value = callable().ToHandleChecked();
1124 CHECK(return_value->IsBoolean());
1125 CHECK_EQ(return_value->BooleanValue(),
1126 CompareC(comparison, inputs[i], inputs[j]));
1127 }
1128 }
1129 }
1130 }
1131
1132
1133 TEST(InterpreterMixedComparisons) {
1134 // This test compares a HeapNumber with a String. The latter is
1135 // convertible to a HeapNumber so comparison will be between numeric
1136 // values except for the strict comparisons where no conversion is
1137 // performed.
1138 const char* inputs[] = {"-1.77", "-40.333", "0.01", "55.77e5", "2.01"};
1139
1140 i::UnicodeCache unicode_cache;
1141
1142 for (size_t c = 0; c < arraysize(kComparisonTypes); c++) {
1143 Token::Value comparison = kComparisonTypes[c];
1144 for (size_t i = 0; i < arraysize(inputs); i++) {
1145 for (size_t j = 0; j < arraysize(inputs); j++) {
1146 for (int pass = 0; pass < 2; pass++) {
1147 const char* lhs_cstr = inputs[i];
1148 const char* rhs_cstr = inputs[j];
1149 double lhs = StringToDouble(&unicode_cache, lhs_cstr,
1150 i::ConversionFlags::NO_FLAGS);
1151 double rhs = StringToDouble(&unicode_cache, rhs_cstr,
1152 i::ConversionFlags::NO_FLAGS);
1153 HandleAndZoneScope handles;
1154 i::Factory* factory = handles.main_isolate()->factory();
1155 BytecodeArrayBuilder builder(handles.main_isolate(),
1156 handles.main_zone());
1157 Register r0(0);
1158 builder.set_locals_count(1);
1159 builder.set_parameter_count(0);
1160 if (pass == 0) {
1161 // Comparison with HeapNumber on the lhs and String on the rhs
1162 builder.LoadLiteral(factory->NewNumber(lhs))
1163 .StoreAccumulatorInRegister(r0)
1164 .LoadLiteral(factory->NewStringFromAsciiChecked(rhs_cstr))
1165 .CompareOperation(comparison, r0, LanguageMode::SLOPPY)
1166 .Return();
1167 } else {
1168 // Comparison with HeapNumber on the rhs and String on the lhs
1169 builder.LoadLiteral(factory->NewStringFromAsciiChecked(lhs_cstr))
1170 .StoreAccumulatorInRegister(r0)
1171 .LoadLiteral(factory->NewNumber(rhs))
1172 .CompareOperation(comparison, r0, LanguageMode::SLOPPY)
1173 .Return();
1174 }
1175
1176 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
1177 InterpreterTester tester(handles.main_isolate(), bytecode_array);
1178 auto callable = tester.GetCallable<>();
1179 Handle<Object> return_value = callable().ToHandleChecked();
1180 CHECK(return_value->IsBoolean());
1181 CHECK_EQ(return_value->BooleanValue(),
1182 CompareC(comparison, lhs, rhs, true));
1183 }
1184 }
1185 }
1186 }
1187 }
1188
1189
1190 TEST(InterpreterInstanceOf) {
1191 HandleAndZoneScope handles;
1192 i::Factory* factory = handles.main_isolate()->factory();
1193 Handle<i::String> name = factory->NewStringFromAsciiChecked("cons");
1194 Handle<i::JSFunction> func = factory->NewFunction(name);
1195 Handle<i::JSObject> instance = factory->NewJSObject(func);
1196 Handle<i::Object> other = factory->NewNumber(3.3333);
1197 Handle<i::Object> cases[] = {Handle<i::Object>::cast(instance), other};
1198 for (size_t i = 0; i < arraysize(cases); i++) {
1199 bool expected_value = (i == 0);
1200 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone());
1201 Register r0(0);
1202 builder.set_locals_count(1);
1203 builder.set_parameter_count(0);
1204 builder.LoadLiteral(cases[i]);
1205 builder.StoreAccumulatorInRegister(r0)
1206 .LoadLiteral(func)
1207 .CompareOperation(Token::Value::INSTANCEOF, r0, LanguageMode::SLOPPY)
1208 .Return();
1209
1210 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
1211 InterpreterTester tester(handles.main_isolate(), bytecode_array);
1212 auto callable = tester.GetCallable<>();
1213 Handle<Object> return_value = callable().ToHandleChecked();
1214 CHECK(return_value->IsBoolean());
1215 CHECK_EQ(return_value->BooleanValue(), expected_value);
1216 }
1217 }
1218
1219
1220 TEST(InterpreterTestIn) {
1221 HandleAndZoneScope handles;
1222 i::Factory* factory = handles.main_isolate()->factory();
1223 // Allocate an array
1224 Handle<i::JSArray> array =
1225 factory->NewJSArray(i::ElementsKind::FAST_SMI_ELEMENTS);
1226 // Check for these properties on the array object
1227 const char* properties[] = {"length", "fuzzle", "x", "0"};
1228 for (size_t i = 0; i < arraysize(properties); i++) {
1229 bool expected_value = (i == 0);
1230 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone());
1231 Register r0(0);
1232 builder.set_locals_count(1);
1233 builder.set_parameter_count(0);
1234 builder.LoadLiteral(factory->NewStringFromAsciiChecked(properties[i]))
1235 .StoreAccumulatorInRegister(r0)
1236 .LoadLiteral(Handle<Object>::cast(array))
1237 .CompareOperation(Token::Value::IN, r0, LanguageMode::SLOPPY)
1238 .Return();
1239
1240 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
1241 InterpreterTester tester(handles.main_isolate(), bytecode_array);
1242 auto callable = tester.GetCallable<>();
1243 Handle<Object> return_value = callable().ToHandleChecked();
1244 CHECK(return_value->IsBoolean());
1245 CHECK_EQ(return_value->BooleanValue(), expected_value);
1246 }
1247 }
OLDNEW
« no previous file with comments | « test/cctest/interpreter/test-bytecode-generator.cc ('k') | test/unittests/interpreter/bytecodes-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698