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 |