| 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 <utility> | 5 #include <utility> | 
| 6 | 6 | 
| 7 #include "src/compiler/pipeline.h" | 7 #include "src/compiler/pipeline.h" | 
| 8 #include "src/execution.h" | 8 #include "src/execution.h" | 
| 9 #include "src/handles.h" | 9 #include "src/handles.h" | 
| 10 #include "src/interpreter/bytecode-array-builder.h" | 10 #include "src/interpreter/bytecode-array-builder.h" | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 63 | 63 | 
| 64 | 64 | 
| 65 class BytecodeGraphTester { | 65 class BytecodeGraphTester { | 
| 66  public: | 66  public: | 
| 67   BytecodeGraphTester(Isolate* isolate, Zone* zone, const char* script, | 67   BytecodeGraphTester(Isolate* isolate, Zone* zone, const char* script, | 
| 68                       const char* filter = kFunctionName) | 68                       const char* filter = kFunctionName) | 
| 69       : isolate_(isolate), zone_(zone), script_(script) { | 69       : isolate_(isolate), zone_(zone), script_(script) { | 
| 70     i::FLAG_ignition = true; | 70     i::FLAG_ignition = true; | 
| 71     i::FLAG_always_opt = false; | 71     i::FLAG_always_opt = false; | 
| 72     i::FLAG_allow_natives_syntax = true; | 72     i::FLAG_allow_natives_syntax = true; | 
|  | 73     i::FLAG_ignition_fallback_on_eval_and_catch = false; | 
| 73     // Set ignition filter flag via SetFlagsFromString to avoid double-free | 74     // Set ignition filter flag via SetFlagsFromString to avoid double-free | 
| 74     // (or potential leak with StrDup() based on ownership confusion). | 75     // (or potential leak with StrDup() based on ownership confusion). | 
| 75     ScopedVector<char> ignition_filter(64); | 76     ScopedVector<char> ignition_filter(64); | 
| 76     SNPrintF(ignition_filter, "--ignition-filter=%s", filter); | 77     SNPrintF(ignition_filter, "--ignition-filter=%s", filter); | 
| 77     FlagList::SetFlagsFromString(ignition_filter.start(), | 78     FlagList::SetFlagsFromString(ignition_filter.start(), | 
| 78                                  ignition_filter.length()); | 79                                  ignition_filter.length()); | 
| 79     // Ensure handler table is generated. | 80     // Ensure handler table is generated. | 
| 80     isolate->interpreter()->Initialize(); | 81     isolate->interpreter()->Initialize(); | 
| 81   } | 82   } | 
| 82   virtual ~BytecodeGraphTester() {} | 83   virtual ~BytecodeGraphTester() {} | 
| (...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1095              function_epilogue); | 1096              function_epilogue); | 
| 1096 | 1097 | 
| 1097     BytecodeGraphTester tester(isolate, zone, script.start(), "t"); | 1098     BytecodeGraphTester tester(isolate, zone, script.start(), "t"); | 
| 1098     auto callable = tester.GetCallable<>(); | 1099     auto callable = tester.GetCallable<>(); | 
| 1099     Handle<Object> return_value = callable().ToHandleChecked(); | 1100     Handle<Object> return_value = callable().ToHandleChecked(); | 
| 1100     CHECK(return_value->SameValue(*snippets[i].return_value())); | 1101     CHECK(return_value->SameValue(*snippets[i].return_value())); | 
| 1101   } | 1102   } | 
| 1102 } | 1103 } | 
| 1103 | 1104 | 
| 1104 | 1105 | 
|  | 1106 TEST(BytecodeGraphBuilderEval) { | 
|  | 1107   HandleAndZoneScope scope; | 
|  | 1108   Isolate* isolate = scope.main_isolate(); | 
|  | 1109   Zone* zone = scope.main_zone(); | 
|  | 1110   Factory* factory = isolate->factory(); | 
|  | 1111 | 
|  | 1112   ExpectedSnippet<0> snippets[] = { | 
|  | 1113       {"return eval('1;');", {handle(Smi::FromInt(1), isolate)}}, | 
|  | 1114       {"return eval('100 * 20;');", {handle(Smi::FromInt(2000), isolate)}}, | 
|  | 1115       {"var x = 10; return eval('x + 20;');", | 
|  | 1116        {handle(Smi::FromInt(30), isolate)}}, | 
|  | 1117       {"var x = 10; eval('x = 33;'); return x;", | 
|  | 1118        {handle(Smi::FromInt(33), isolate)}}, | 
|  | 1119       {"'use strict'; var x = 20; var z = 0;\n" | 
|  | 1120        "eval('var x = 33; z = x;'); return x + z;", | 
|  | 1121        {handle(Smi::FromInt(53), isolate)}}, | 
|  | 1122       {"eval('var x = 33;'); eval('var y = x + 20'); return x + y;", | 
|  | 1123        {handle(Smi::FromInt(86), isolate)}}, | 
|  | 1124       {"var x = 1; eval('for(i = 0; i < 10; i++) x = x + 1;'); return x", | 
|  | 1125        {handle(Smi::FromInt(11), isolate)}}, | 
|  | 1126       {"var x = 10; eval('var x = 20;'); return x;", | 
|  | 1127        {handle(Smi::FromInt(20), isolate)}}, | 
|  | 1128       {"var x = 1; eval('\"use strict\"; var x = 2;'); return x;", | 
|  | 1129        {handle(Smi::FromInt(1), isolate)}}, | 
|  | 1130       {"'use strict'; var x = 1; eval('var x = 2;'); return x;", | 
|  | 1131        {handle(Smi::FromInt(1), isolate)}}, | 
|  | 1132       {"var x = 10; eval('x + 20;'); return typeof x;", | 
|  | 1133        {factory->NewStringFromStaticChars("number")}}, | 
|  | 1134       {"eval('var y = 10;'); return typeof unallocated;", | 
|  | 1135        {factory->NewStringFromStaticChars("undefined")}}, | 
|  | 1136       {"'use strict'; eval('var y = 10;'); return typeof unallocated;", | 
|  | 1137        {factory->NewStringFromStaticChars("undefined")}}, | 
|  | 1138       {"eval('var x = 10;'); return typeof x;", | 
|  | 1139        {factory->NewStringFromStaticChars("number")}}, | 
|  | 1140       {"var x = {}; eval('var x = 10;'); return typeof x;", | 
|  | 1141        {factory->NewStringFromStaticChars("number")}}, | 
|  | 1142       {"'use strict'; var x = {}; eval('var x = 10;'); return typeof x;", | 
|  | 1143        {factory->NewStringFromStaticChars("object")}}, | 
|  | 1144   }; | 
|  | 1145 | 
|  | 1146   size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); | 
|  | 1147   for (size_t i = 0; i < num_snippets; i++) { | 
|  | 1148     ScopedVector<char> script(1024); | 
|  | 1149     SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, | 
|  | 1150              snippets[i].code_snippet, kFunctionName); | 
|  | 1151     BytecodeGraphTester tester(isolate, zone, script.start()); | 
|  | 1152     auto callable = tester.GetCallable<>(); | 
|  | 1153     Handle<Object> return_value = callable().ToHandleChecked(); | 
|  | 1154     CHECK(return_value->SameValue(*snippets[i].return_value())); | 
|  | 1155   } | 
|  | 1156 } | 
|  | 1157 | 
|  | 1158 | 
|  | 1159 TEST(BytecodeGraphBuilderEvalParams) { | 
|  | 1160   HandleAndZoneScope scope; | 
|  | 1161   Isolate* isolate = scope.main_isolate(); | 
|  | 1162   Zone* zone = scope.main_zone(); | 
|  | 1163 | 
|  | 1164   ExpectedSnippet<1> snippets[] = { | 
|  | 1165       {"var x = 10; return eval('x + p1;');", | 
|  | 1166        {handle(Smi::FromInt(30), isolate), handle(Smi::FromInt(20), isolate)}}, | 
|  | 1167       {"var x = 10; eval('p1 = x;'); return p1;", | 
|  | 1168        {handle(Smi::FromInt(10), isolate), handle(Smi::FromInt(20), isolate)}}, | 
|  | 1169       {"var a = 10;" | 
|  | 1170        "function inner() { return eval('a + p1;');}" | 
|  | 1171        "return inner();", | 
|  | 1172        {handle(Smi::FromInt(30), isolate), handle(Smi::FromInt(20), isolate)}}, | 
|  | 1173   }; | 
|  | 1174 | 
|  | 1175   size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); | 
|  | 1176   for (size_t i = 0; i < num_snippets; i++) { | 
|  | 1177     ScopedVector<char> script(1024); | 
|  | 1178     SNPrintF(script, "function %s(p1) { %s }\n%s(0);", kFunctionName, | 
|  | 1179              snippets[i].code_snippet, kFunctionName); | 
|  | 1180     BytecodeGraphTester tester(isolate, zone, script.start()); | 
|  | 1181     auto callable = tester.GetCallable<Handle<Object>>(); | 
|  | 1182     Handle<Object> return_value = | 
|  | 1183         callable(snippets[i].parameter(0)).ToHandleChecked(); | 
|  | 1184     CHECK(return_value->SameValue(*snippets[i].return_value())); | 
|  | 1185   } | 
|  | 1186 } | 
|  | 1187 | 
|  | 1188 | 
|  | 1189 TEST(BytecodeGraphBuilderEvalGlobal) { | 
|  | 1190   HandleAndZoneScope scope; | 
|  | 1191   Isolate* isolate = scope.main_isolate(); | 
|  | 1192   Zone* zone = scope.main_zone(); | 
|  | 1193   Factory* factory = isolate->factory(); | 
|  | 1194 | 
|  | 1195   ExpectedSnippet<0> snippets[] = { | 
|  | 1196       {"function add_global() { eval('function f() { z = 33; }; f()'); };" | 
|  | 1197        "function f() { add_global(); return z; }; f();", | 
|  | 1198        {handle(Smi::FromInt(33), isolate)}}, | 
|  | 1199       {"function add_global() {\n" | 
|  | 1200        " eval('\"use strict\"; function f() { y = 33; };" | 
|  | 1201        "      try { f() } catch(e) {}');\n" | 
|  | 1202        "}\n" | 
|  | 1203        "function f() { add_global(); return typeof y; } f();", | 
|  | 1204        {factory->NewStringFromStaticChars("undefined")}}, | 
|  | 1205   }; | 
|  | 1206 | 
|  | 1207   size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); | 
|  | 1208   for (size_t i = 0; i < num_snippets; i++) { | 
|  | 1209     BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet); | 
|  | 1210     auto callable = tester.GetCallable<>(); | 
|  | 1211     Handle<Object> return_value = callable().ToHandleChecked(); | 
|  | 1212     CHECK(return_value->SameValue(*snippets[i].return_value())); | 
|  | 1213   } | 
|  | 1214 } | 
|  | 1215 | 
|  | 1216 | 
| 1105 bool get_compare_result(Token::Value opcode, Handle<Object> lhs_value, | 1217 bool get_compare_result(Token::Value opcode, Handle<Object> lhs_value, | 
| 1106                         Handle<Object> rhs_value) { | 1218                         Handle<Object> rhs_value) { | 
| 1107   switch (opcode) { | 1219   switch (opcode) { | 
| 1108     case Token::Value::EQ: | 1220     case Token::Value::EQ: | 
| 1109       return Object::Equals(lhs_value, rhs_value).FromJust(); | 1221       return Object::Equals(lhs_value, rhs_value).FromJust(); | 
| 1110     case Token::Value::NE: | 1222     case Token::Value::NE: | 
| 1111       return !Object::Equals(lhs_value, rhs_value).FromJust(); | 1223       return !Object::Equals(lhs_value, rhs_value).FromJust(); | 
| 1112     case Token::Value::EQ_STRICT: | 1224     case Token::Value::EQ_STRICT: | 
| 1113       return lhs_value->StrictEquals(*rhs_value); | 1225       return lhs_value->StrictEquals(*rhs_value); | 
| 1114     case Token::Value::NE_STRICT: | 1226     case Token::Value::NE_STRICT: | 
| (...skipping 1073 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2188           callable(factory->NewNumberFromInt(a)).ToHandleChecked(); | 2300           callable(factory->NewNumberFromInt(a)).ToHandleChecked(); | 
| 2189       static const int results[] = {11, 12, 2}; | 2301       static const int results[] = {11, 12, 2}; | 
| 2190       CHECK_EQ(Handle<Smi>::cast(return_val)->value(), results[a]); | 2302       CHECK_EQ(Handle<Smi>::cast(return_val)->value(), results[a]); | 
| 2191     } | 2303     } | 
| 2192   } | 2304   } | 
| 2193 } | 2305 } | 
| 2194 | 2306 | 
| 2195 }  // namespace compiler | 2307 }  // namespace compiler | 
| 2196 }  // namespace internal | 2308 }  // namespace internal | 
| 2197 }  // namespace v8 | 2309 }  // namespace v8 | 
| OLD | NEW | 
|---|