Chromium Code Reviews| 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 <stdlib.h> | 5 #include <stdlib.h> |
| 6 #include <map> | |
| 6 | 7 |
| 7 #include "src/v8.h" | 8 #include "src/v8.h" |
| 8 | 9 |
| 9 #include "src/ast/ast.h" | 10 #include "src/ast/ast.h" |
| 10 #include "src/ast/ast-expression-visitor.h" | 11 #include "src/ast/ast-expression-visitor.h" |
| 11 #include "src/ast/scopes.h" | 12 #include "src/ast/scopes.h" |
| 12 #include "src/parsing/parser.h" | 13 #include "src/parsing/parser.h" |
| 13 #include "src/parsing/rewriter.h" | 14 #include "src/parsing/rewriter.h" |
| 14 #include "test/cctest/cctest.h" | 15 #include "test/cctest/cctest.h" |
| 15 #include "test/cctest/expression-type-collector.h" | 16 #include "test/cctest/expression-type-collector.h" |
| 16 #include "test/cctest/expression-type-collector-macros.h" | 17 #include "test/cctest/expression-type-collector-macros.h" |
| 17 | 18 |
| 18 using namespace v8::internal; | 19 using namespace v8::internal; |
| 19 | 20 |
| 20 namespace { | 21 namespace { |
| 21 | 22 |
| 22 static void CollectTypes(HandleAndZoneScope* handles, const char* source, | 23 class NodeTypeCounter : public AstExpressionVisitor { |
| 23 ZoneVector<ExpressionTypeEntry>* dst) { | 24 public: |
| 24 i::Isolate* isolate = CcTest::i_isolate(); | 25 typedef std::map<AstNode::NodeType, int> Counters; |
| 25 i::Factory* factory = isolate->factory(); | |
| 26 | 26 |
| 27 i::Handle<i::String> source_code = | 27 NodeTypeCounter(Isolate* isolate, Expression* expr, Counters* counts) |
| 28 factory->NewStringFromUtf8(i::CStrVector(source)).ToHandleChecked(); | 28 : AstExpressionVisitor(isolate, expr), counts_(counts) {} |
| 29 | 29 |
| 30 i::Handle<i::Script> script = factory->NewScript(source_code); | 30 protected: |
| 31 void VisitExpression(Expression* expr) override { | |
| 32 (*counts_)[expr->node_type()]++; | |
| 33 } | |
| 31 | 34 |
| 32 i::ParseInfo info(handles->main_zone(), script); | 35 private: |
| 33 i::Parser parser(&info); | 36 Counters* counts_; |
| 34 info.set_global(); | 37 }; |
| 35 info.set_lazy(false); | |
| 36 info.set_allow_lazy_parsing(false); | |
| 37 info.set_toplevel(true); | |
| 38 | |
| 39 CHECK(i::Compiler::ParseAndAnalyze(&info)); | |
| 40 | |
| 41 ExpressionTypeCollector( | |
| 42 isolate, | |
| 43 info.scope()->declarations()->at(0)->AsFunctionDeclaration()->fun(), dst) | |
| 44 .Run(); | |
| 45 } | |
| 46 | 38 |
| 47 } // namespace | 39 } // namespace |
| 48 | 40 |
| 49 | 41 TEST(VisitExpression) { |
| 50 TEST(VisitExpressions) { | |
| 51 v8::V8::Initialize(); | |
| 52 HandleAndZoneScope handles; | |
| 53 ZoneVector<ExpressionTypeEntry> types(handles.main_zone()); | |
| 54 const char test_function[] = | 42 const char test_function[] = |
| 55 "function GeometricMean(stdlib, foreign, buffer) {\n" | 43 "function GeometricMean(stdlib, foreign, buffer) {\n" |
| 56 " \"use asm\";\n" | 44 " \"use asm\";\n" |
| 57 "\n" | 45 "\n" |
| 58 " var exp = stdlib.Math.exp;\n" | 46 " var exp = stdlib.Math.exp;\n" |
| 59 " var log = stdlib.Math.log;\n" | 47 " var log = stdlib.Math.log;\n" |
| 60 " var values = new stdlib.Float64Array(buffer);\n" | 48 " var values = new stdlib.Float64Array(buffer);\n" |
| 61 "\n" | 49 "\n" |
| 62 " function logSum(start, end) {\n" | 50 " function logSum(start, end) {\n" |
| 63 " start = start|0;\n" | 51 " start = start|0;\n" |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 77 " function geometricMean(start, end) {\n" | 65 " function geometricMean(start, end) {\n" |
| 78 " start = start|0;\n" | 66 " start = start|0;\n" |
| 79 " end = end|0;\n" | 67 " end = end|0;\n" |
| 80 "\n" | 68 "\n" |
| 81 " return +exp(+logSum(start, end) / +((end - start)|0));\n" | 69 " return +exp(+logSum(start, end) / +((end - start)|0));\n" |
| 82 " }\n" | 70 " }\n" |
| 83 "\n" | 71 "\n" |
| 84 " return { geometricMean: geometricMean };\n" | 72 " return { geometricMean: geometricMean };\n" |
| 85 "}\n"; | 73 "}\n"; |
| 86 | 74 |
| 87 CollectTypes(&handles, test_function, &types); | 75 // Parse + compile test_function, and extract the AST node for it. |
| 88 CHECK_TYPES_BEGIN { | |
| 89 // function logSum | |
| 90 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) { | |
| 91 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) { | |
| 92 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | |
| 93 CHECK_VAR(start, Bounds::Unbounded()); | |
| 94 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 95 CHECK_VAR(start, Bounds::Unbounded()); | |
| 96 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 97 } | |
| 98 } | |
| 99 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | |
| 100 CHECK_VAR(end, Bounds::Unbounded()); | |
| 101 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 102 CHECK_VAR(end, Bounds::Unbounded()); | |
| 103 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 104 } | |
| 105 } | |
| 106 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | |
| 107 CHECK_VAR(sum, Bounds::Unbounded()); | |
| 108 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 109 } | |
| 110 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | |
| 111 CHECK_VAR(p, Bounds::Unbounded()); | |
| 112 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 113 } | |
| 114 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | |
| 115 CHECK_VAR(q, Bounds::Unbounded()); | |
| 116 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 117 } | |
| 118 // for (p = start << 3, q = end << 3; | |
| 119 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 120 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | |
| 121 CHECK_VAR(p, Bounds::Unbounded()); | |
| 122 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 123 CHECK_VAR(start, Bounds::Unbounded()); | |
| 124 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 125 } | |
| 126 } | |
| 127 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | |
| 128 CHECK_VAR(q, Bounds::Unbounded()); | |
| 129 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 130 CHECK_VAR(end, Bounds::Unbounded()); | |
| 131 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 132 } | |
| 133 } | |
| 134 } | |
| 135 // (p|0) < (q|0); | |
| 136 CHECK_EXPR(CompareOperation, Bounds::Unbounded()) { | |
| 137 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 138 CHECK_VAR(p, Bounds::Unbounded()); | |
| 139 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 140 } | |
| 141 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 142 CHECK_VAR(q, Bounds::Unbounded()); | |
| 143 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 144 } | |
| 145 } | |
| 146 // p = (p + 8)|0) {\n" | |
| 147 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | |
| 148 CHECK_VAR(p, Bounds::Unbounded()); | |
| 149 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 150 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 151 CHECK_VAR(p, Bounds::Unbounded()); | |
| 152 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 153 } | |
| 154 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 155 } | |
| 156 } | |
| 157 // sum = sum + +log(values[p>>3]); | |
| 158 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | |
| 159 CHECK_VAR(sum, Bounds::Unbounded()); | |
| 160 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 161 CHECK_VAR(sum, Bounds::Unbounded()); | |
| 162 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 163 CHECK_EXPR(Call, Bounds::Unbounded()) { | |
| 164 CHECK_VAR(log, Bounds::Unbounded()); | |
| 165 CHECK_EXPR(Property, Bounds::Unbounded()) { | |
| 166 CHECK_VAR(values, Bounds::Unbounded()); | |
| 167 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 168 CHECK_VAR(p, Bounds::Unbounded()); | |
| 169 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 170 } | |
| 171 } | |
| 172 } | |
| 173 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 174 } | |
| 175 } | |
| 176 } | |
| 177 // return +sum; | |
| 178 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 179 CHECK_VAR(sum, Bounds::Unbounded()); | |
| 180 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 181 } | |
| 182 } | |
| 183 // function geometricMean | |
| 184 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) { | |
| 185 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | |
| 186 CHECK_VAR(start, Bounds::Unbounded()); | |
| 187 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 188 CHECK_VAR(start, Bounds::Unbounded()); | |
| 189 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 190 } | |
| 191 } | |
| 192 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | |
| 193 CHECK_VAR(end, Bounds::Unbounded()); | |
| 194 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 195 CHECK_VAR(end, Bounds::Unbounded()); | |
| 196 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 197 } | |
| 198 } | |
| 199 // return +exp(+logSum(start, end) / +((end - start)|0)); | |
| 200 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 201 CHECK_EXPR(Call, Bounds::Unbounded()) { | |
| 202 CHECK_VAR(exp, Bounds::Unbounded()); | |
| 203 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 204 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 205 CHECK_EXPR(Call, Bounds::Unbounded()) { | |
| 206 CHECK_VAR(logSum, Bounds::Unbounded()); | |
| 207 CHECK_VAR(start, Bounds::Unbounded()); | |
| 208 CHECK_VAR(end, Bounds::Unbounded()); | |
| 209 } | |
| 210 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 211 } | |
| 212 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 213 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 214 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 215 CHECK_VAR(end, Bounds::Unbounded()); | |
| 216 CHECK_VAR(start, Bounds::Unbounded()); | |
| 217 } | |
| 218 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 219 } | |
| 220 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 221 } | |
| 222 } | |
| 223 } | |
| 224 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 225 } | |
| 226 } | |
| 227 // "use asm"; | |
| 228 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 229 // var exp = stdlib.Math.exp; | |
| 230 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | |
| 231 CHECK_VAR(exp, Bounds::Unbounded()); | |
| 232 CHECK_EXPR(Property, Bounds::Unbounded()) { | |
| 233 CHECK_EXPR(Property, Bounds::Unbounded()) { | |
| 234 CHECK_VAR(stdlib, Bounds::Unbounded()); | |
| 235 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 236 } | |
| 237 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 238 } | |
| 239 } | |
| 240 // var log = stdlib.Math.log; | |
| 241 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | |
| 242 CHECK_VAR(log, Bounds::Unbounded()); | |
| 243 CHECK_EXPR(Property, Bounds::Unbounded()) { | |
| 244 CHECK_EXPR(Property, Bounds::Unbounded()) { | |
| 245 CHECK_VAR(stdlib, Bounds::Unbounded()); | |
| 246 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 247 } | |
| 248 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 249 } | |
| 250 } | |
| 251 // var values = new stdlib.Float64Array(buffer); | |
| 252 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | |
| 253 CHECK_VAR(values, Bounds::Unbounded()); | |
| 254 CHECK_EXPR(CallNew, Bounds::Unbounded()) { | |
| 255 CHECK_EXPR(Property, Bounds::Unbounded()) { | |
| 256 CHECK_VAR(stdlib, Bounds::Unbounded()); | |
| 257 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 258 } | |
| 259 CHECK_VAR(buffer, Bounds::Unbounded()); | |
| 260 } | |
| 261 } | |
| 262 // return { geometricMean: geometricMean }; | |
| 263 CHECK_EXPR(ObjectLiteral, Bounds::Unbounded()) { | |
| 264 CHECK_VAR(geometricMean, Bounds::Unbounded()); | |
| 265 } | |
| 266 } | |
| 267 } | |
| 268 CHECK_TYPES_END | |
| 269 } | |
| 270 | |
| 271 | |
| 272 TEST(VisitConditional) { | |
| 273 v8::V8::Initialize(); | 76 v8::V8::Initialize(); |
| 274 HandleAndZoneScope handles; | 77 HandleAndZoneScope handles; |
| 275 ZoneVector<ExpressionTypeEntry> types(handles.main_zone()); | 78 i::Isolate* isolate = CcTest::i_isolate(); |
| 276 // Check that traversing the ternary operator works. | 79 i::Handle<i::String> source_code = |
| 277 const char test_function[] = | 80 isolate->factory() |
| 278 "function foo() {\n" | 81 ->NewStringFromUtf8(i::CStrVector(test_function)) |
| 279 " var a, b, c;\n" | 82 .ToHandleChecked(); |
| 280 " var x = a ? b : c;\n" | 83 i::Handle<i::Script> script = isolate->factory()->NewScript(source_code); |
| 281 "}\n"; | 84 i::ParseInfo info(handles.main_zone(), script); |
| 282 CollectTypes(&handles, test_function, &types); | 85 i::Parser parser(&info); |
| 283 CHECK_TYPES_BEGIN { | 86 info.set_global(); |
| 284 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) { | 87 info.set_lazy(false); |
| 285 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | 88 info.set_allow_lazy_parsing(false); |
| 286 CHECK_VAR(x, Bounds::Unbounded()); | 89 info.set_toplevel(true); |
| 287 CHECK_EXPR(Conditional, Bounds::Unbounded()) { | 90 CHECK(i::Compiler::ParseAndAnalyze(&info)); |
| 288 CHECK_VAR(a, Bounds::Unbounded()); | 91 Expression* test_function_expr = |
| 289 CHECK_VAR(b, Bounds::Unbounded()); | 92 info.scope()->declarations()->at(0)->AsFunctionDeclaration()->fun(); |
| 290 CHECK_VAR(c, Bounds::Unbounded()); | 93 |
| 291 } | 94 // Run NodeTypeCounter and sanity check counts for 3 expression types, |
| 292 } | 95 // and for overall # of types found. |
|
bradnelson
2016/05/12 15:43:45
Yeah that's better, this was overkill at the time.
| |
| 293 } | 96 NodeTypeCounter::Counters counts; |
| 294 } | 97 NodeTypeCounter(isolate, test_function_expr, &counts).Run(); |
| 295 CHECK_TYPES_END | 98 CHECK_EQ(21, counts[AstNode::kBinaryOperation]); |
| 99 CHECK_EQ(26, counts[AstNode::kLiteral]); | |
| 100 CHECK_EQ(3, counts[AstNode::kFunctionLiteral]); | |
| 101 CHECK_EQ(10, counts.size()); | |
| 296 } | 102 } |
| 297 | |
| 298 | |
| 299 TEST(VisitEmptyForStatment) { | |
| 300 v8::V8::Initialize(); | |
| 301 HandleAndZoneScope handles; | |
| 302 ZoneVector<ExpressionTypeEntry> types(handles.main_zone()); | |
| 303 // Check that traversing an empty for statement works. | |
| 304 const char test_function[] = | |
| 305 "function foo() {\n" | |
| 306 " for (;;) {}\n" | |
| 307 "}\n"; | |
| 308 CollectTypes(&handles, test_function, &types); | |
| 309 CHECK_TYPES_BEGIN { | |
| 310 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) {} | |
| 311 } | |
| 312 CHECK_TYPES_END | |
| 313 } | |
| 314 | |
| 315 | |
| 316 TEST(VisitSwitchStatment) { | |
| 317 v8::V8::Initialize(); | |
| 318 HandleAndZoneScope handles; | |
| 319 ZoneVector<ExpressionTypeEntry> types(handles.main_zone()); | |
| 320 // Check that traversing a switch with a default works. | |
| 321 const char test_function[] = | |
| 322 "function foo() {\n" | |
| 323 " switch (0) { case 1: break; default: break; }\n" | |
| 324 "}\n"; | |
| 325 CollectTypes(&handles, test_function, &types); | |
| 326 CHECK_TYPES_BEGIN { | |
| 327 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) { | |
| 328 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | |
| 329 CHECK_VAR(.switch_tag, Bounds::Unbounded()); | |
| 330 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 331 } | |
| 332 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 333 CHECK_VAR(.switch_tag, Bounds::Unbounded()); | |
| 334 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 335 } | |
| 336 } | |
| 337 CHECK_TYPES_END | |
| 338 } | |
| 339 | |
| 340 | |
| 341 TEST(VisitThrow) { | |
| 342 v8::V8::Initialize(); | |
| 343 HandleAndZoneScope handles; | |
| 344 ZoneVector<ExpressionTypeEntry> types(handles.main_zone()); | |
| 345 const char test_function[] = | |
| 346 "function foo() {\n" | |
| 347 " throw 123;\n" | |
| 348 "}\n"; | |
| 349 CollectTypes(&handles, test_function, &types); | |
| 350 CHECK_TYPES_BEGIN { | |
| 351 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) { | |
| 352 CHECK_EXPR(Throw, Bounds::Unbounded()) { | |
| 353 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 354 } | |
| 355 } | |
| 356 } | |
| 357 CHECK_TYPES_END | |
| 358 } | |
| 359 | |
| 360 | |
| 361 TEST(VisitYield) { | |
| 362 v8::V8::Initialize(); | |
| 363 HandleAndZoneScope handles; | |
| 364 ZoneVector<ExpressionTypeEntry> types(handles.main_zone()); | |
| 365 const char test_function[] = | |
| 366 "function* foo() {\n" | |
| 367 " yield 123;\n" | |
| 368 "}\n"; | |
| 369 CollectTypes(&handles, test_function, &types); | |
| 370 CHECK_TYPES_BEGIN { | |
| 371 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) { | |
| 372 // Implicit initial yield | |
| 373 CHECK_EXPR(Yield, Bounds::Unbounded()) { | |
| 374 CHECK_VAR(.generator_object, Bounds::Unbounded()); | |
| 375 CHECK_EXPR(Assignment, Bounds::Unbounded()) { | |
| 376 CHECK_VAR(.generator_object, Bounds::Unbounded()); | |
| 377 CHECK_EXPR(CallRuntime, Bounds::Unbounded()) { | |
| 378 CHECK_EXPR(ThisFunction, Bounds::Unbounded()); | |
| 379 CHECK_EXPR(VariableProxy, Bounds::Unbounded()); | |
| 380 } | |
| 381 } | |
| 382 } | |
| 383 // Explicit yield (argument wrapped with CreateIterResultObject) | |
| 384 CHECK_EXPR(Yield, Bounds::Unbounded()) { | |
| 385 CHECK_VAR(.generator_object, Bounds::Unbounded()); | |
| 386 CHECK_EXPR(CallRuntime, Bounds::Unbounded()) { | |
| 387 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 388 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 389 } | |
| 390 } | |
| 391 // Argument to implicit final return | |
| 392 CHECK_EXPR(CallRuntime, Bounds::Unbounded()) { // CreateIterResultObject | |
| 393 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 394 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 395 } | |
| 396 // Implicit finally clause | |
| 397 CHECK_EXPR(CallRuntime, Bounds::Unbounded()) { | |
| 398 CHECK_VAR(.generator_object, Bounds::Unbounded()); | |
| 399 } | |
| 400 } | |
| 401 } | |
| 402 CHECK_TYPES_END | |
| 403 } | |
| 404 | |
| 405 | |
| 406 TEST(VisitSkipping) { | |
| 407 v8::V8::Initialize(); | |
| 408 HandleAndZoneScope handles; | |
| 409 ZoneVector<ExpressionTypeEntry> types(handles.main_zone()); | |
| 410 const char test_function[] = | |
| 411 "function foo(x) {\n" | |
| 412 " return (x + x) + 1;\n" | |
| 413 "}\n"; | |
| 414 CollectTypes(&handles, test_function, &types); | |
| 415 CHECK_TYPES_BEGIN { | |
| 416 CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) { | |
| 417 CHECK_EXPR(BinaryOperation, Bounds::Unbounded()) { | |
| 418 // Skip x + x | |
| 419 CHECK_SKIP(); | |
| 420 CHECK_EXPR(Literal, Bounds::Unbounded()); | |
| 421 } | |
| 422 } | |
| 423 } | |
| 424 CHECK_TYPES_END | |
| 425 } | |
| OLD | NEW |