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

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

Powered by Google App Engine
This is Rietveld 408576698