| 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 // TODO(jochen): Remove this after the setting is turned on globally. | 5 // TODO(jochen): Remove this after the setting is turned on globally. | 
| 6 #define V8_IMMINENT_DEPRECATION_WARNINGS | 6 #define V8_IMMINENT_DEPRECATION_WARNINGS | 
| 7 | 7 | 
| 8 #include <utility> | 8 #include <utility> | 
| 9 | 9 | 
| 10 #include "src/compiler/pipeline.h" | 10 #include "src/compiler/pipeline.h" | 
| 11 #include "src/execution.h" | 11 #include "src/execution.h" | 
| 12 #include "src/handles.h" | 12 #include "src/handles.h" | 
| 13 #include "src/interpreter/bytecode-array-builder.h" | 13 #include "src/interpreter/bytecode-array-builder.h" | 
| 14 #include "src/interpreter/interpreter.h" | 14 #include "src/interpreter/interpreter.h" | 
| 15 #include "src/parser.h" | 15 #include "src/parser.h" | 
| 16 #include "test/cctest/cctest.h" | 16 #include "test/cctest/cctest.h" | 
| 17 | 17 | 
| 18 namespace v8 { | 18 namespace v8 { | 
| 19 namespace internal { | 19 namespace internal { | 
| 20 namespace compiler { | 20 namespace compiler { | 
| 21 | 21 | 
| 22 | 22 | 
| 23 static const char kFunctionName[] = "f"; | 23 static const char kFunctionName[] = "f"; | 
| 24 | 24 | 
|  | 25 static const Token::Value kCompareOperators[] = { | 
|  | 26     Token::Value::EQ,        Token::Value::NE, Token::Value::EQ_STRICT, | 
|  | 27     Token::Value::NE_STRICT, Token::Value::LT, Token::Value::LTE, | 
|  | 28     Token::Value::GT,        Token::Value::GTE}; | 
|  | 29 | 
|  | 30 static const int SMI_MAX = (1 << 30) - 1; | 
|  | 31 static const int SMI_MIN = -(1 << 30); | 
| 25 | 32 | 
| 26 static MaybeHandle<Object> CallFunction(Isolate* isolate, | 33 static MaybeHandle<Object> CallFunction(Isolate* isolate, | 
| 27                                         Handle<JSFunction> function) { | 34                                         Handle<JSFunction> function) { | 
| 28   return Execution::Call(isolate, function, | 35   return Execution::Call(isolate, function, | 
| 29                          isolate->factory()->undefined_value(), 0, nullptr); | 36                          isolate->factory()->undefined_value(), 0, nullptr); | 
| 30 } | 37 } | 
| 31 | 38 | 
| 32 | 39 | 
| 33 template <class... A> | 40 template <class... A> | 
| 34 static MaybeHandle<Object> CallFunction(Isolate* isolate, | 41 static MaybeHandle<Object> CallFunction(Isolate* isolate, | 
| (...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 755              snippets[i].code_snippet, kFunctionName); | 762              snippets[i].code_snippet, kFunctionName); | 
| 756 | 763 | 
| 757     BytecodeGraphTester tester(isolate, zone, script.start()); | 764     BytecodeGraphTester tester(isolate, zone, script.start()); | 
| 758     auto callable = tester.GetCallable<Handle<Object>>(); | 765     auto callable = tester.GetCallable<Handle<Object>>(); | 
| 759     Handle<Object> return_value = | 766     Handle<Object> return_value = | 
| 760         callable(snippets[i].parameter(0)).ToHandleChecked(); | 767         callable(snippets[i].parameter(0)).ToHandleChecked(); | 
| 761     CHECK(return_value->SameValue(*snippets[i].return_value())); | 768     CHECK(return_value->SameValue(*snippets[i].return_value())); | 
| 762   } | 769   } | 
| 763 } | 770 } | 
| 764 | 771 | 
|  | 772 | 
|  | 773 bool get_compare_result(Token::Value opcode, Handle<Object> lhs_value, | 
|  | 774                         Handle<Object> rhs_value) { | 
|  | 775   switch (opcode) { | 
|  | 776     case Token::Value::EQ: | 
|  | 777       return Object::Equals(lhs_value, rhs_value).FromJust(); | 
|  | 778     case Token::Value::NE: | 
|  | 779       return !Object::Equals(lhs_value, rhs_value).FromJust(); | 
|  | 780     case Token::Value::EQ_STRICT: | 
|  | 781       return lhs_value->StrictEquals(*rhs_value); | 
|  | 782     case Token::Value::NE_STRICT: | 
|  | 783       return !lhs_value->StrictEquals(*rhs_value); | 
|  | 784     case Token::Value::LT: | 
|  | 785       return Object::LessThan(lhs_value, rhs_value).FromJust(); | 
|  | 786     case Token::Value::LTE: | 
|  | 787       return Object::LessThanOrEqual(lhs_value, rhs_value).FromJust(); | 
|  | 788     case Token::Value::GT: | 
|  | 789       return Object::GreaterThan(lhs_value, rhs_value).FromJust(); | 
|  | 790     case Token::Value::GTE: | 
|  | 791       return Object::GreaterThanOrEqual(lhs_value, rhs_value).FromJust(); | 
|  | 792     default: | 
|  | 793       UNREACHABLE(); | 
|  | 794       return false; | 
|  | 795   } | 
|  | 796 } | 
|  | 797 | 
|  | 798 | 
|  | 799 const char* get_code_snippet(Token::Value opcode) { | 
|  | 800   switch (opcode) { | 
|  | 801     case Token::Value::EQ: | 
|  | 802       return "return p1 == p2;"; | 
|  | 803     case Token::Value::NE: | 
|  | 804       return "return p1 != p2;"; | 
|  | 805     case Token::Value::EQ_STRICT: | 
|  | 806       return "return p1 === p2;"; | 
|  | 807     case Token::Value::NE_STRICT: | 
|  | 808       return "return p1 !== p2;"; | 
|  | 809     case Token::Value::LT: | 
|  | 810       return "return p1 < p2;"; | 
|  | 811     case Token::Value::LTE: | 
|  | 812       return "return p1 <= p2;"; | 
|  | 813     case Token::Value::GT: | 
|  | 814       return "return p1 > p2;"; | 
|  | 815     case Token::Value::GTE: | 
|  | 816       return "return p1 >= p2;"; | 
|  | 817     default: | 
|  | 818       UNREACHABLE(); | 
|  | 819       return ""; | 
|  | 820   } | 
|  | 821 } | 
|  | 822 | 
|  | 823 | 
|  | 824 TEST(BytecodeGraphBuilderCompare) { | 
|  | 825   HandleAndZoneScope scope; | 
|  | 826   Isolate* isolate = scope.main_isolate(); | 
|  | 827   Zone* zone = scope.main_zone(); | 
|  | 828   Factory* factory = isolate->factory(); | 
|  | 829   Handle<Object> lhs_values[] = { | 
|  | 830       factory->NewNumberFromInt(10), factory->NewHeapNumber(3.45), | 
|  | 831       factory->NewStringFromStaticChars("abc"), | 
|  | 832       factory->NewNumberFromInt(SMI_MAX), factory->NewNumberFromInt(SMI_MIN)}; | 
|  | 833   Handle<Object> rhs_values[] = {factory->NewNumberFromInt(10), | 
|  | 834                                  factory->NewStringFromStaticChars("10"), | 
|  | 835                                  factory->NewNumberFromInt(20), | 
|  | 836                                  factory->NewStringFromStaticChars("abc"), | 
|  | 837                                  factory->NewHeapNumber(3.45), | 
|  | 838                                  factory->NewNumberFromInt(SMI_MAX), | 
|  | 839                                  factory->NewNumberFromInt(SMI_MIN)}; | 
|  | 840 | 
|  | 841   for (size_t i = 0; i < arraysize(kCompareOperators); i++) { | 
|  | 842     ScopedVector<char> script(1024); | 
|  | 843     SNPrintF(script, "function %s(p1, p2) { %s }\n%s({}, {});", kFunctionName, | 
|  | 844              get_code_snippet(kCompareOperators[i]), kFunctionName); | 
|  | 845 | 
|  | 846     BytecodeGraphTester tester(isolate, zone, script.start()); | 
|  | 847     auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>(); | 
|  | 848     for (size_t j = 0; j < arraysize(lhs_values); j++) { | 
|  | 849       for (size_t k = 0; k < arraysize(rhs_values); k++) { | 
|  | 850         Handle<Object> return_value = | 
|  | 851             callable(lhs_values[j], rhs_values[k]).ToHandleChecked(); | 
|  | 852         bool result = get_compare_result(kCompareOperators[i], lhs_values[j], | 
|  | 853                                          rhs_values[k]); | 
|  | 854         CHECK(return_value->SameValue(*factory->ToBoolean(result))); | 
|  | 855       } | 
|  | 856     } | 
|  | 857   } | 
|  | 858 } | 
|  | 859 | 
|  | 860 | 
|  | 861 TEST(BytecodeGraphBuilderTestIn) { | 
|  | 862   HandleAndZoneScope scope; | 
|  | 863   Isolate* isolate = scope.main_isolate(); | 
|  | 864   Zone* zone = scope.main_zone(); | 
|  | 865   Factory* factory = isolate->factory(); | 
|  | 866 | 
|  | 867   ExpectedSnippet<2> snippets[] = { | 
|  | 868       {"return p2 in p1;", | 
|  | 869        {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})"), | 
|  | 870         factory->NewStringFromStaticChars("val")}}, | 
|  | 871       {"return p2 in p1;", | 
|  | 872        {factory->true_value(), BytecodeGraphTester::NewObject("[]"), | 
|  | 873         factory->NewStringFromStaticChars("length")}}, | 
|  | 874       {"return p2 in p1;", | 
|  | 875        {factory->true_value(), BytecodeGraphTester::NewObject("[]"), | 
|  | 876         factory->NewStringFromStaticChars("toString")}}, | 
|  | 877       {"return p2 in p1;", | 
|  | 878        {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})"), | 
|  | 879         factory->NewStringFromStaticChars("toString")}}, | 
|  | 880       {"return p2 in p1;", | 
|  | 881        {factory->false_value(), BytecodeGraphTester::NewObject("({val : 10})"), | 
|  | 882         factory->NewStringFromStaticChars("abc")}}, | 
|  | 883       {"return p2 in p1;", | 
|  | 884        {factory->false_value(), BytecodeGraphTester::NewObject("({val : 10})"), | 
|  | 885         factory->NewNumberFromInt(10)}}, | 
|  | 886       {"return p2 in p1;", | 
|  | 887        {factory->true_value(), BytecodeGraphTester::NewObject("({10 : 'val'})"), | 
|  | 888         factory->NewNumberFromInt(10)}}, | 
|  | 889       {"return p2 in p1;", | 
|  | 890        {factory->false_value(), | 
|  | 891         BytecodeGraphTester::NewObject("({10 : 'val'})"), | 
|  | 892         factory->NewNumberFromInt(1)}}, | 
|  | 893   }; | 
|  | 894 | 
|  | 895   size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); | 
|  | 896   for (size_t i = 0; i < num_snippets; i++) { | 
|  | 897     ScopedVector<char> script(1024); | 
|  | 898     SNPrintF(script, "function %s(p1, p2) { %s }\n%s({}, {});", kFunctionName, | 
|  | 899              snippets[i].code_snippet, kFunctionName); | 
|  | 900 | 
|  | 901     BytecodeGraphTester tester(isolate, zone, script.start()); | 
|  | 902     auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>(); | 
|  | 903     Handle<Object> return_value = | 
|  | 904         callable(snippets[i].parameter(0), snippets[i].parameter(1)) | 
|  | 905             .ToHandleChecked(); | 
|  | 906     CHECK(return_value->SameValue(*snippets[i].return_value())); | 
|  | 907   } | 
|  | 908 } | 
|  | 909 | 
|  | 910 | 
|  | 911 TEST(BytecodeGraphBuilderTestInstanceOf) { | 
|  | 912   // TODO(mythria): Add tests when CreateLiterals/CreateClousre are supported. | 
|  | 913 } | 
|  | 914 | 
| 765 }  // namespace compiler | 915 }  // namespace compiler | 
| 766 }  // namespace internal | 916 }  // namespace internal | 
| 767 }  // namespace v8 | 917 }  // namespace v8 | 
| OLD | NEW | 
|---|