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 "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 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1207 .Return(); | 1207 .Return(); |
| 1208 | 1208 |
| 1209 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 1209 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 1210 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 1210 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 1211 auto callable = tester.GetCallable<>(); | 1211 auto callable = tester.GetCallable<>(); |
| 1212 Handle<Object> return_value = callable().ToHandleChecked(); | 1212 Handle<Object> return_value = callable().ToHandleChecked(); |
| 1213 CHECK_EQ(Smi::cast(*return_value)->value(), 7); | 1213 CHECK_EQ(Smi::cast(*return_value)->value(), 7); |
| 1214 } | 1214 } |
| 1215 | 1215 |
| 1216 | 1216 |
| 1217 TEST(InterpreterConditionalJumps2) { | |
| 1218 // TODO(oth): Add tests for all conditional jumps near and far. | |
| 1219 HandleAndZoneScope handles; | |
| 1220 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); | |
| 1221 builder.set_locals_count(2); | |
| 1222 builder.set_context_count(0); | |
| 1223 builder.set_parameter_count(0); | |
| 1224 Register reg(0), scratch(1); | |
| 1225 BytecodeLabel label[2]; | |
| 1226 BytecodeLabel done, done1; | |
| 1227 | |
| 1228 builder.LoadLiteral(Smi::FromInt(0)) | |
| 1229 .StoreAccumulatorInRegister(reg) | |
| 1230 .LoadFalse() | |
| 1231 .JumpIfFalse(&label[0]); | |
| 1232 IncrementRegister(builder, reg, 1024, scratch) | |
| 1233 .Bind(&label[0]) | |
| 1234 .LoadTrue() | |
| 1235 .JumpIfFalse(&done); | |
| 1236 IncrementRegister(builder, reg, 1, scratch).LoadTrue().JumpIfTrue(&label[1]); | |
| 1237 IncrementRegister(builder, reg, 2048, scratch).Bind(&label[1]); | |
| 1238 IncrementRegister(builder, reg, 2, scratch).LoadFalse().JumpIfTrue(&done1); | |
| 1239 IncrementRegister(builder, reg, 4, scratch) | |
| 1240 .LoadAccumulatorWithRegister(reg) | |
| 1241 .Bind(&done) | |
| 1242 .Bind(&done1) | |
| 1243 .Return(); | |
| 1244 | |
| 1245 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | |
| 1246 InterpreterTester tester(handles.main_isolate(), bytecode_array); | |
| 1247 auto callable = tester.GetCallable<>(); | |
| 1248 Handle<Object> return_value = callable().ToHandleChecked(); | |
| 1249 CHECK_EQ(Smi::cast(*return_value)->value(), 7); | |
| 1250 } | |
| 1251 | |
| 1252 | |
| 1217 static const Token::Value kComparisonTypes[] = { | 1253 static const Token::Value kComparisonTypes[] = { |
| 1218 Token::Value::EQ, Token::Value::NE, Token::Value::EQ_STRICT, | 1254 Token::Value::EQ, Token::Value::NE, Token::Value::EQ_STRICT, |
| 1219 Token::Value::NE_STRICT, Token::Value::LTE, Token::Value::LTE, | 1255 Token::Value::NE_STRICT, Token::Value::LTE, Token::Value::LTE, |
| 1220 Token::Value::GT, Token::Value::GTE}; | 1256 Token::Value::GT, Token::Value::GTE}; |
| 1221 | 1257 |
| 1222 | 1258 |
| 1223 template <typename T> | 1259 template <typename T> |
| 1224 bool CompareC(Token::Value op, T lhs, T rhs, bool types_differed = false) { | 1260 bool CompareC(Token::Value op, T lhs, T rhs, bool types_differed = false) { |
| 1225 switch (op) { | 1261 switch (op) { |
| 1226 case Token::Value::EQ: | 1262 case Token::Value::EQ: |
| (...skipping 1167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2394 | 2430 |
| 2395 | 2431 |
| 2396 TEST(InterpreterDeleteSloppyUnqualifiedIdentifier) { | 2432 TEST(InterpreterDeleteSloppyUnqualifiedIdentifier) { |
| 2397 HandleAndZoneScope handles; | 2433 HandleAndZoneScope handles; |
| 2398 i::Isolate* isolate = handles.main_isolate(); | 2434 i::Isolate* isolate = handles.main_isolate(); |
| 2399 i::Factory* factory = isolate->factory(); | 2435 i::Factory* factory = isolate->factory(); |
| 2400 | 2436 |
| 2401 // These tests generate a syntax error for strict mode. We don't | 2437 // These tests generate a syntax error for strict mode. We don't |
| 2402 // test for it here. | 2438 // test for it here. |
| 2403 std::pair<const char*, Handle<Object>> test_delete[] = { | 2439 std::pair<const char*, Handle<Object>> test_delete[] = { |
| 2404 std::make_pair("var a = { x:10, y:'abc'};\n" | 2440 std::make_pair("var sloppy_a = { x:10, y:'abc'};\n" |
| 2405 "var b = delete a;\n" | 2441 "var sloppy_b = delete sloppy_a;\n" |
| 2406 "if (delete a) {\n" | 2442 "if (delete sloppy_a) {\n" |
| 2407 " return undefined;\n" | 2443 " return undefined;\n" |
| 2408 "} else {\n" | 2444 "} else {\n" |
| 2409 " return a.x;\n" | 2445 " return sloppy_a.x;\n" |
| 2410 "}\n", | 2446 "}\n", |
| 2411 Handle<Object>(Smi::FromInt(10), isolate)), | 2447 Handle<Object>(Smi::FromInt(10), isolate)), |
| 2412 // TODO(mythria) When try-catch is implemented change the tests to check | 2448 // TODO(mythria) When try-catch is implemented change the tests to check |
| 2413 // if delete actually deletes | 2449 // if delete actually deletes |
| 2414 std::make_pair("a = { x:10, y:'abc'};\n" | 2450 std::make_pair("sloppy_a = { x:10, y:'abc'};\n" |
| 2415 "var b = delete a;\n" | 2451 "var sloppy_b = delete sloppy_a;\n" |
| 2416 // "try{return a.x;} catch(e) {return b;}\n" | 2452 // "try{return a.x;} catch(e) {return b;}\n" |
| 2417 "return b;", | 2453 "return sloppy_b;", |
| 2418 factory->ToBoolean(true)), | 2454 factory->ToBoolean(true)), |
| 2419 std::make_pair("a = { x:10, y:'abc'};\n" | 2455 std::make_pair("sloppy_a = { x:10, y:'abc'};\n" |
| 2420 "var b = delete c;\n" | 2456 "var sloppy_b = delete sloppy_c;\n" |
| 2421 "return b;", | 2457 "return sloppy_b;", |
|
rmcilroy
2015/10/29 10:53:45
Thanks for fixing this!
| |
| 2422 factory->ToBoolean(true))}; | 2458 factory->ToBoolean(true))}; |
| 2423 | 2459 |
| 2424 | |
| 2425 for (size_t i = 0; i < arraysize(test_delete); i++) { | 2460 for (size_t i = 0; i < arraysize(test_delete); i++) { |
| 2426 std::string source(InterpreterTester::SourceForBody(test_delete[i].first)); | 2461 std::string source(InterpreterTester::SourceForBody(test_delete[i].first)); |
| 2427 InterpreterTester tester(handles.main_isolate(), source.c_str()); | 2462 InterpreterTester tester(handles.main_isolate(), source.c_str()); |
| 2428 auto callable = tester.GetCallable<>(); | 2463 auto callable = tester.GetCallable<>(); |
| 2429 | 2464 |
| 2430 Handle<i::Object> return_value = callable().ToHandleChecked(); | 2465 Handle<i::Object> return_value = callable().ToHandleChecked(); |
| 2431 CHECK(return_value->SameValue(*test_delete[i].second)); | 2466 CHECK(return_value->SameValue(*test_delete[i].second)); |
| 2432 } | 2467 } |
| 2433 } | 2468 } |
| 2434 | 2469 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2491 | 2526 |
| 2492 for (size_t i = 0; i < arraysize(test_global_delete); i++) { | 2527 for (size_t i = 0; i < arraysize(test_global_delete); i++) { |
| 2493 InterpreterTester tester(handles.main_isolate(), | 2528 InterpreterTester tester(handles.main_isolate(), |
| 2494 test_global_delete[i].first); | 2529 test_global_delete[i].first); |
| 2495 auto callable = tester.GetCallable<>(); | 2530 auto callable = tester.GetCallable<>(); |
| 2496 | 2531 |
| 2497 Handle<i::Object> return_value = callable().ToHandleChecked(); | 2532 Handle<i::Object> return_value = callable().ToHandleChecked(); |
| 2498 CHECK(return_value->SameValue(*test_global_delete[i].second)); | 2533 CHECK(return_value->SameValue(*test_global_delete[i].second)); |
| 2499 } | 2534 } |
| 2500 } | 2535 } |
| 2536 | |
| 2537 | |
| 2538 TEST(InterpreterForIn) { | |
| 2539 HandleAndZoneScope handles; | |
| 2540 | |
| 2541 // TODO(oth): Add a test here for delete mid-loop when delete is ready. | |
| 2542 std::pair<const char*, int> for_in_samples[] = { | |
| 2543 {"function f() {\n" | |
| 2544 " var r = -1;\n" | |
| 2545 " for (var a in null) { r = a; }\n" | |
| 2546 " return r;\n" | |
| 2547 "}", | |
| 2548 -1}, | |
| 2549 {"function f() {\n" | |
| 2550 " var r = -1;\n" | |
| 2551 " for (var a in undefined) { r = a; }\n" | |
| 2552 " return r;\n" | |
| 2553 "}", | |
| 2554 -1}, | |
| 2555 {"function f() {\n" | |
| 2556 " var r = 0;\n" | |
| 2557 " for (var a in [0,6,7,9]) { r = r + (1 << a); }\n" | |
| 2558 " return r;\n" | |
| 2559 "}", | |
| 2560 0xf}, | |
| 2561 {"function f() {\n" | |
| 2562 " var r = 0;\n" | |
| 2563 " for (var a in [0,6,7,9]) { r = r + (1 << a); }\n" | |
| 2564 " var r = 0;\n" | |
| 2565 " for (var a in [0,6,7,9]) { r = r + (1 << a); }\n" | |
| 2566 " return r;\n" | |
| 2567 "}", | |
| 2568 0xf}, | |
| 2569 {"function f() {\n" | |
| 2570 " var r = 0;\n" | |
| 2571 " for (var a in 'foobar') { r = r + (1 << a); }\n" | |
| 2572 " return r;\n" | |
| 2573 "}", | |
| 2574 0x3f}, | |
| 2575 {"function f() {\n" | |
| 2576 " var r = 0;\n" | |
| 2577 " for (var a in {1:0, 10:1, 100:2, 1000:3}) {\n" | |
| 2578 " r = r + Number(a);\n" | |
| 2579 " }\n" | |
| 2580 " return r;\n" | |
| 2581 "}", | |
| 2582 1111}, | |
| 2583 {"function f() {\n" | |
| 2584 " var r = 0;\n" | |
| 2585 " var data = {1:0, 10:1, 100:2, 1000:3};\n" | |
| 2586 " for (var a in data) {\n" | |
| 2587 " if (a == 1) delete data[1];\n" | |
| 2588 " r = r + Number(a);\n" | |
| 2589 " }\n" | |
| 2590 " return r;\n" | |
| 2591 "}", | |
| 2592 1111}, | |
| 2593 {"function f() {\n" | |
| 2594 " var r = 0;\n" | |
| 2595 " var data = {1:0, 10:1, 100:2, 1000:3};\n" | |
| 2596 " for (var a in data) {\n" | |
| 2597 " if (a == 10) delete data[100];\n" | |
| 2598 " r = r + Number(a);\n" | |
| 2599 " }\n" | |
| 2600 " return r;\n" | |
| 2601 "}", | |
| 2602 1011}, | |
| 2603 {"function f() {\n" | |
| 2604 " var r = 0;\n" | |
| 2605 " var data = {1:0, 10:1, 100:2, 1000:3};\n" | |
| 2606 " for (var a in data) {\n" | |
| 2607 " if (a == 10) data[10000] = 4;\n" | |
| 2608 " r = r + Number(a);\n" | |
| 2609 " }\n" | |
| 2610 " return r;\n" | |
| 2611 "}", | |
| 2612 1111}, | |
| 2613 {"function f() {\n" | |
| 2614 " var r = 0;\n" | |
| 2615 " var input = 'foobar';\n" | |
| 2616 " for (var a in input) {\n" | |
| 2617 " if (input[a] == 'b') break;\n" | |
| 2618 " r = r + (1 << a);\n" | |
| 2619 " }\n" | |
| 2620 " return r;\n" | |
| 2621 "}", | |
| 2622 0x7}, | |
| 2623 {"function f() {\n" | |
| 2624 "var r = 0;\n" | |
| 2625 "var input = 'foobar';\n" | |
| 2626 "for (var a in input) {\n" | |
| 2627 " if (input[a] == 'b') continue;\n" | |
| 2628 " r = r + (1 << a);\n" | |
| 2629 "}\n" | |
| 2630 "return r;\n" | |
| 2631 "}", | |
| 2632 0x37}, | |
| 2633 {"function f() {\n" | |
| 2634 " var r = 0;\n" | |
| 2635 " var data = {1:0, 10:1, 100:2, 1000:3};\n" | |
| 2636 " for (var a in data) {\n" | |
| 2637 " if (a == 10) {\n" | |
| 2638 " data[10000] = 4;\n" | |
| 2639 " }\n" | |
| 2640 " r = r + Number(a);\n" | |
| 2641 " }\n" | |
| 2642 " return r;\n" | |
| 2643 "}", | |
| 2644 1111}, | |
| 2645 {"function f() {\n" | |
| 2646 " var r = [ 3 ];\n" | |
| 2647 " var data = {1:0, 10:1, 100:2, 1000:3};\n" | |
| 2648 " for (r[10] in data) {\n" | |
| 2649 " }\n" | |
| 2650 " return Number(r[10]);\n" | |
| 2651 "}", | |
| 2652 1000}, | |
| 2653 {"function f() {\n" | |
| 2654 " var r = [ 3 ];\n" | |
| 2655 " var data = {1:0, 10:1, 100:2, 1000:3};\n" | |
| 2656 " for (r['100'] in data) {\n" | |
| 2657 " }\n" | |
| 2658 " return Number(r['100']);\n" | |
| 2659 "}", | |
| 2660 1000}, | |
| 2661 {"function f() {\n" | |
| 2662 " var obj = {}\n" | |
| 2663 " var descObj = new Boolean(false);\n" | |
| 2664 " var accessed = 0;\n" | |
| 2665 " descObj.enumerable = true;\n" | |
| 2666 " Object.defineProperties(obj, { prop:descObj });\n" | |
| 2667 " for (var p in obj) {\n" | |
| 2668 " if (p === 'prop') { accessed = 1; }\n" | |
| 2669 " }\n" | |
| 2670 " return accessed;" | |
| 2671 "}", | |
| 2672 1}, | |
| 2673 {"function f() {\n" | |
| 2674 " var appointment = {};\n" | |
| 2675 " Object.defineProperty(appointment, 'startTime', {\n" | |
| 2676 " value: 1001,\n" | |
| 2677 " writable: false,\n" | |
| 2678 " enumerable: false,\n" | |
| 2679 " configurable: true\n" | |
| 2680 " });\n" | |
| 2681 " Object.defineProperty(appointment, 'name', {\n" | |
| 2682 " value: 'NAME',\n" | |
| 2683 " writable: false,\n" | |
| 2684 " enumerable: false,\n" | |
| 2685 " configurable: true\n" | |
| 2686 " });\n" | |
| 2687 " var meeting = Object.create(appointment);\n" | |
| 2688 " Object.defineProperty(meeting, 'conferenceCall', {\n" | |
| 2689 " value: 'In-person meeting',\n" | |
| 2690 " writable: false,\n" | |
| 2691 " enumerable: false,\n" | |
| 2692 " configurable: true\n" | |
| 2693 " });\n" | |
| 2694 "\n" | |
| 2695 " var teamMeeting = Object.create(meeting);\n" | |
| 2696 "\n" | |
| 2697 " var flags = 0;\n" | |
| 2698 " for (var p in teamMeeting) {\n" | |
| 2699 " if (p === 'startTime') {\n" | |
| 2700 " flags |= 1;\n" | |
| 2701 " }\n" | |
| 2702 " if (p === 'name') {\n" | |
| 2703 " flags |= 2;\n" | |
| 2704 " }\n" | |
| 2705 " if (p === 'conferenceCall') {\n" | |
| 2706 " flags |= 4;\n" | |
| 2707 " }\n" | |
| 2708 " }\n" | |
| 2709 "\n" | |
| 2710 " var hasOwnProperty = !teamMeeting.hasOwnProperty('name') &&\n" | |
| 2711 " !teamMeeting.hasOwnProperty('startTime') &&\n" | |
| 2712 " !teamMeeting.hasOwnProperty('conferenceCall');\n" | |
| 2713 " if (!hasOwnProperty) {\n" | |
| 2714 " flags |= 8;\n" | |
| 2715 " }\n" | |
| 2716 " return flags;\n" | |
| 2717 " }", | |
| 2718 0}}; | |
| 2719 | |
| 2720 for (size_t i = 0; i < arraysize(for_in_samples); i++) { | |
| 2721 InterpreterTester tester(handles.main_isolate(), for_in_samples[i].first); | |
| 2722 auto callable = tester.GetCallable<>(); | |
| 2723 Handle<Object> return_val = callable().ToHandleChecked(); | |
| 2724 CHECK_EQ(Handle<Smi>::cast(return_val)->value(), for_in_samples[i].second); | |
| 2725 } | |
| 2726 } | |
| OLD | NEW |