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/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 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1172 .Bind(&done1) | 1172 .Bind(&done1) |
1173 .Return(); | 1173 .Return(); |
1174 | 1174 |
1175 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 1175 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
1176 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 1176 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
1177 auto callable = tester.GetCallable<>(); | 1177 auto callable = tester.GetCallable<>(); |
1178 Handle<Object> return_value = callable().ToHandleChecked(); | 1178 Handle<Object> return_value = callable().ToHandleChecked(); |
1179 CHECK_EQ(Smi::cast(*return_value)->value(), 7); | 1179 CHECK_EQ(Smi::cast(*return_value)->value(), 7); |
1180 } | 1180 } |
1181 | 1181 |
1182 | |
1183 static const Token::Value kComparisonTypes[] = { | 1182 static const Token::Value kComparisonTypes[] = { |
1184 Token::Value::EQ, Token::Value::NE, Token::Value::EQ_STRICT, | 1183 Token::Value::EQ, Token::Value::NE, Token::Value::EQ_STRICT, |
1185 Token::Value::NE_STRICT, Token::Value::LT, Token::Value::LTE, | 1184 Token::Value::LT, Token::Value::LTE, Token::Value::GT, |
1186 Token::Value::GT, Token::Value::GTE}; | 1185 Token::Value::GTE}; |
1187 | |
1188 | 1186 |
1189 template <typename T> | 1187 template <typename T> |
1190 bool CompareC(Token::Value op, T lhs, T rhs, bool types_differed = false) { | 1188 bool CompareC(Token::Value op, T lhs, T rhs, bool types_differed = false) { |
1191 switch (op) { | 1189 switch (op) { |
1192 case Token::Value::EQ: | 1190 case Token::Value::EQ: |
1193 return lhs == rhs; | 1191 return lhs == rhs; |
1194 case Token::Value::NE: | 1192 case Token::Value::NE: |
1195 return lhs != rhs; | 1193 return lhs != rhs; |
1196 case Token::Value::EQ_STRICT: | 1194 case Token::Value::EQ_STRICT: |
1197 return (lhs == rhs) && !types_differed; | 1195 return (lhs == rhs) && !types_differed; |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1372 Handle<Object> return_value = callable().ToHandleChecked(); | 1370 Handle<Object> return_value = callable().ToHandleChecked(); |
1373 CHECK(return_value->IsBoolean()); | 1371 CHECK(return_value->IsBoolean()); |
1374 CHECK_EQ(return_value->BooleanValue(), | 1372 CHECK_EQ(return_value->BooleanValue(), |
1375 CompareC(comparison, lhs, rhs, true)); | 1373 CompareC(comparison, lhs, rhs, true)); |
1376 } | 1374 } |
1377 } | 1375 } |
1378 } | 1376 } |
1379 } | 1377 } |
1380 } | 1378 } |
1381 | 1379 |
| 1380 TEST(InterpreterStrictNotEqual) { |
| 1381 HandleAndZoneScope handles; |
| 1382 i::Factory* factory = handles.main_isolate()->factory(); |
| 1383 const char* code_snippet = |
| 1384 "function f(lhs, rhs) {\n" |
| 1385 " return lhs !== rhs;\n" |
| 1386 "}\n" |
| 1387 "f(0, 0);\n"; |
| 1388 InterpreterTester tester(handles.main_isolate(), code_snippet); |
| 1389 auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>(); |
| 1390 |
| 1391 // Test passing different types. |
| 1392 const char* inputs[] = {"-1.77", "-40.333", "0.01", "55.77e5", "2.01"}; |
| 1393 i::UnicodeCache unicode_cache; |
| 1394 for (size_t i = 0; i < arraysize(inputs); i++) { |
| 1395 for (size_t j = 0; j < arraysize(inputs); j++) { |
| 1396 double lhs = StringToDouble(&unicode_cache, inputs[i], |
| 1397 i::ConversionFlags::NO_FLAGS); |
| 1398 double rhs = StringToDouble(&unicode_cache, inputs[j], |
| 1399 i::ConversionFlags::NO_FLAGS); |
| 1400 Handle<Object> lhs_obj = factory->NewNumber(lhs); |
| 1401 Handle<Object> rhs_obj = factory->NewStringFromAsciiChecked(inputs[j]); |
| 1402 |
| 1403 Handle<Object> return_value = |
| 1404 callable(lhs_obj, rhs_obj).ToHandleChecked(); |
| 1405 CHECK(return_value->IsBoolean()); |
| 1406 CHECK_EQ(return_value->BooleanValue(), |
| 1407 CompareC(Token::Value::NE_STRICT, lhs, rhs, true)); |
| 1408 } |
| 1409 } |
| 1410 |
| 1411 // Test passing string types. |
| 1412 const char* inputs_str[] = {"A", "abc", "z", "", "Foo!", "Foo"}; |
| 1413 for (size_t i = 0; i < arraysize(inputs_str); i++) { |
| 1414 for (size_t j = 0; j < arraysize(inputs_str); j++) { |
| 1415 Handle<Object> lhs_obj = |
| 1416 factory->NewStringFromAsciiChecked(inputs_str[i]); |
| 1417 Handle<Object> rhs_obj = |
| 1418 factory->NewStringFromAsciiChecked(inputs_str[j]); |
| 1419 |
| 1420 Handle<Object> return_value = |
| 1421 callable(lhs_obj, rhs_obj).ToHandleChecked(); |
| 1422 CHECK(return_value->IsBoolean()); |
| 1423 CHECK_EQ(return_value->BooleanValue(), |
| 1424 CompareC(Token::Value::NE_STRICT, inputs_str[i], inputs_str[j])); |
| 1425 } |
| 1426 } |
| 1427 |
| 1428 // Test passing doubles. |
| 1429 double inputs_number[] = {std::numeric_limits<double>::min(), |
| 1430 std::numeric_limits<double>::max(), |
| 1431 -0.001, |
| 1432 0.01, |
| 1433 0.1000001, |
| 1434 1e99, |
| 1435 -1e-99}; |
| 1436 for (size_t i = 0; i < arraysize(inputs_number); i++) { |
| 1437 for (size_t j = 0; j < arraysize(inputs_number); j++) { |
| 1438 Handle<Object> lhs_obj = factory->NewNumber(inputs_number[i]); |
| 1439 Handle<Object> rhs_obj = factory->NewNumber(inputs_number[j]); |
| 1440 |
| 1441 Handle<Object> return_value = |
| 1442 callable(lhs_obj, rhs_obj).ToHandleChecked(); |
| 1443 CHECK(return_value->IsBoolean()); |
| 1444 CHECK_EQ(return_value->BooleanValue(), |
| 1445 CompareC(Token::Value::NE_STRICT, inputs_number[i], |
| 1446 inputs_number[j])); |
| 1447 } |
| 1448 } |
| 1449 } |
1382 | 1450 |
1383 TEST(InterpreterInstanceOf) { | 1451 TEST(InterpreterInstanceOf) { |
1384 HandleAndZoneScope handles; | 1452 HandleAndZoneScope handles; |
1385 i::Factory* factory = handles.main_isolate()->factory(); | 1453 i::Factory* factory = handles.main_isolate()->factory(); |
1386 Handle<i::String> name = factory->NewStringFromAsciiChecked("cons"); | 1454 Handle<i::String> name = factory->NewStringFromAsciiChecked("cons"); |
1387 Handle<i::JSFunction> func = factory->NewFunction(name); | 1455 Handle<i::JSFunction> func = factory->NewFunction(name); |
1388 Handle<i::JSObject> instance = factory->NewJSObject(func); | 1456 Handle<i::JSObject> instance = factory->NewJSObject(func); |
1389 Handle<i::Object> other = factory->NewNumber(3.3333); | 1457 Handle<i::Object> other = factory->NewNumber(3.3333); |
1390 Handle<i::Object> cases[] = {Handle<i::Object>::cast(instance), other}; | 1458 Handle<i::Object> cases[] = {Handle<i::Object>::cast(instance), other}; |
1391 for (size_t i = 0; i < arraysize(cases); i++) { | 1459 for (size_t i = 0; i < arraysize(cases); i++) { |
(...skipping 2766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4158 Handle<i::Object> return_value = callable().ToHandleChecked(); | 4226 Handle<i::Object> return_value = callable().ToHandleChecked(); |
4159 CHECK(return_value->SameValue(*const_decl[i].second)); | 4227 CHECK(return_value->SameValue(*const_decl[i].second)); |
4160 } | 4228 } |
4161 | 4229 |
4162 FLAG_legacy_const = old_flag_legacy_const; | 4230 FLAG_legacy_const = old_flag_legacy_const; |
4163 } | 4231 } |
4164 | 4232 |
4165 } // namespace interpreter | 4233 } // namespace interpreter |
4166 } // namespace internal | 4234 } // namespace internal |
4167 } // namespace v8 | 4235 } // namespace v8 |
OLD | NEW |