Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(153)

Side by Side Diff: test/cctest/interpreter/test-bytecode-generator.cc

Issue 1524803003: [Interpreter] Add support for Load / Store to Lookup slots. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@init_eval_impl
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/compiler.h" 7 #include "src/compiler.h"
8 #include "src/interpreter/bytecode-array-iterator.h" 8 #include "src/interpreter/bytecode-array-iterator.h"
9 #include "src/interpreter/bytecode-generator.h" 9 #include "src/interpreter/bytecode-generator.h"
10 #include "src/interpreter/interpreter.h" 10 #include "src/interpreter/interpreter.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 CompileRun(script); 48 CompileRun(script);
49 v8::Local<v8::Context> context = 49 v8::Local<v8::Context> context =
50 v8::Isolate::GetCurrent()->GetCurrentContext(); 50 v8::Isolate::GetCurrent()->GetCurrentContext();
51 Local<Function> function = Local<Function>::Cast( 51 Local<Function> function = Local<Function>::Cast(
52 CcTest::global()->Get(context, v8_str(function_name)).ToLocalChecked()); 52 CcTest::global()->Get(context, v8_str(function_name)).ToLocalChecked());
53 i::Handle<i::JSFunction> js_function = 53 i::Handle<i::JSFunction> js_function =
54 i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*function)); 54 i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*function));
55 return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate()); 55 return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate());
56 } 56 }
57 57
58 Handle<BytecodeArray> MakeBytecode(const char* script, const char* filter,
59 const char* function_name) {
60 const char* old_ignition_filter = i::FLAG_ignition_filter;
61 i::FLAG_ignition_filter = filter;
62 CompileRun(script);
63 i::FLAG_ignition_filter = old_ignition_filter;
64 v8::Local<v8::Context> context =
65 v8::Isolate::GetCurrent()->GetCurrentContext();
66 Local<Function> function = Local<Function>::Cast(
67 CcTest::global()->Get(context, v8_str(function_name)).ToLocalChecked());
68 i::Handle<i::JSFunction> js_function =
69 i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*function));
70 return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate());
71 }
72
58 Handle<BytecodeArray> MakeBytecodeForFunctionBody(const char* body) { 73 Handle<BytecodeArray> MakeBytecodeForFunctionBody(const char* body) {
59 ScopedVector<char> program(3072); 74 ScopedVector<char> program(3072);
60 SNPrintF(program, "function %s() { %s }\n%s();", kFunctionName, body, 75 SNPrintF(program, "function %s() { %s }\n%s();", kFunctionName, body,
61 kFunctionName); 76 kFunctionName);
62 return MakeBytecode(program.start(), kFunctionName); 77 return MakeBytecode(program.start(), kFunctionName);
63 } 78 }
64 79
65 Handle<BytecodeArray> MakeBytecodeForFunction(const char* function) { 80 Handle<BytecodeArray> MakeBytecodeForFunction(const char* function) {
66 ScopedVector<char> program(3072); 81 ScopedVector<char> program(3072);
67 SNPrintF(program, "%s\n%s();", function, kFunctionName); 82 SNPrintF(program, "%s\n%s();", function, kFunctionName);
(...skipping 5490 matching lines...) Expand 10 before | Expand all | Expand 10 after
5558 B(Mov), R(1), R(4), // 5573 B(Mov), R(1), R(4), //
5559 B(Mov), R(3), R(5), // 5574 B(Mov), R(3), R(5), //
5560 B(Mov), R(closure), R(6), // 5575 B(Mov), R(closure), R(6), //
5561 B(LdaZero), // 5576 B(LdaZero), //
5562 B(Star), R(7), // 5577 B(Star), R(7), //
5563 B(LdaSmi8), U8(10), // 5578 B(LdaSmi8), U8(10), //
5564 B(Star), R(8), // 5579 B(Star), R(8), //
5565 B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), // 5580 B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), //
5566 U8(5), // 5581 U8(5), //
5567 B(Star), R(1), // 5582 B(Star), R(1), //
5568 B(Call), R(1), R(2), U8(1), U8(2), // 5583 B(Call), R(1), R(2), U8(1), U8(0), //
5569 B(Return), // 5584 B(Return), //
5570 }, 5585 },
5571 2, 5586 2,
5572 {"eval", "1;"}}, 5587 {"eval", "1;"}},
5573 }; 5588 };
5574 5589
5575 for (size_t i = 0; i < arraysize(snippets); i++) { 5590 for (size_t i = 0; i < arraysize(snippets); i++) {
5576 Handle<BytecodeArray> bytecode_array = 5591 Handle<BytecodeArray> bytecode_array =
5577 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); 5592 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
5578 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 5593 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
5579 } 5594 }
5580 } 5595 }
5581 5596
5597
5598 TEST(StoreLookupSlotSloppy) {
5599 InitializedHandleScope handle_scope;
5600 BytecodeGeneratorHelper helper;
5601
5602 int closure = Register::function_closure().index();
5603 int first_context_slot = Context::MIN_CONTEXT_SLOTS;
5604 int context = Register::function_context().index();
5605 int new_target = Register::new_target().index();
5606
5607 ExpectedSnippet<const char*> snippets[] = {
5608 {"x = 20; return eval('');",
5609 9 * kPointerSize,
5610 1,
5611 80,
5612 {
5613 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), //
5614 U8(1), //
5615 B(PushContext), R(0), //
5616 B(Ldar), THIS(1), //
5617 B(StaContextSlot), R(0), U8(first_context_slot), //
5618 B(CreateMappedArguments), //
5619 B(StaContextSlot), R(0), U8(first_context_slot + 1), //
5620 B(Ldar), R(new_target), //
5621 B(StaContextSlot), R(0), U8(first_context_slot + 2), //
5622 B(LdaSmi8), U8(20), //
5623 B(StaLookupSlotSloppy), U8(0), R(0), //
5624 B(Mov), R(context), R(3), //
5625 B(LdaConstant), U8(1), //
5626 B(Star), R(4), //
5627 B(CallRuntime), U16(Runtime::kInterpreterLoadLookupSlotCallee), //
5628 R(3), U8(2), //
5629 B(Star), R(1), //
5630 B(CallRuntime), U16(Runtime::kInterpreterLoadLookupSlotReceiver), //
5631 R(3), U8(2), //
5632 B(Star), R(2), //
5633 B(LdaConstant), U8(2), //
5634 B(Star), R(3), //
5635 B(Mov), R(1), R(4), //
5636 B(Mov), R(3), R(5), //
5637 B(Mov), R(closure), R(6), //
5638 B(LdaZero), //
5639 B(Star), R(7), //
5640 B(LdaSmi8), U8(10), //
5641 B(Star), R(8), //
5642 B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), //
5643 U8(5), //
5644 B(Star), R(1), //
5645 B(Call), R(1), R(2), U8(1), U8(0), //
5646 B(Return), //
5647 },
5648 3,
5649 {"x", "eval", ""}},
5650 };
5651
5652 for (size_t i = 0; i < arraysize(snippets); i++) {
5653 Handle<BytecodeArray> bytecode_array =
5654 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
5655 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
5656 }
5657 }
5658
5659
5660 TEST(LdaLookupSlot) {
5661 InitializedHandleScope handle_scope;
5662 BytecodeGeneratorHelper helper;
5663
5664 int closure = Register::function_closure().index();
5665 int first_context_slot = Context::MIN_CONTEXT_SLOTS;
5666 int context = Register::function_context().index();
5667 int new_target = Register::new_target().index();
5668
5669 ExpectedSnippet<const char*> snippets[] = {
5670 {"eval('var x = 10;'); return x;",
5671 9 * kPointerSize,
5672 1,
5673 78,
5674 {
5675 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), //
5676 U8(1), //
5677 B(PushContext), R(0), //
5678 B(Ldar), THIS(1), //
5679 B(StaContextSlot), R(0), U8(first_context_slot), //
5680 B(CreateMappedArguments), //
5681 B(StaContextSlot), R(0), U8(first_context_slot + 1), //
5682 B(Ldar), R(new_target), //
5683 B(StaContextSlot), R(0), U8(first_context_slot + 2), //
5684 B(Mov), R(context), R(3), //
5685 B(LdaConstant), U8(0), //
5686 B(Star), R(4), //
5687 B(CallRuntime), U16(Runtime::kInterpreterLoadLookupSlotCallee), //
5688 R(3), U8(2), //
5689 B(Star), R(1), //
5690 B(CallRuntime), U16(Runtime::kInterpreterLoadLookupSlotReceiver), //
5691 R(3), U8(2), //
5692 B(Star), R(2), //
5693 B(LdaConstant), U8(1), //
5694 B(Star), R(3), //
5695 B(Mov), R(1), R(4), //
5696 B(Mov), R(3), R(5), //
5697 B(Mov), R(closure), R(6), //
5698 B(LdaZero), //
5699 B(Star), R(7), //
5700 B(LdaSmi8), U8(10), //
5701 B(Star), R(8), //
5702 B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), //
5703 U8(5), //
5704 B(Star), R(1), //
5705 B(Call), R(1), R(2), U8(1), U8(0), //
5706 B(LdaLookupSlot), U8(2), R(0), //
5707 B(Return), //
5708 },
5709 3,
5710 {"eval", "var x = 10;", "x"}},
5711 };
5712
5713 for (size_t i = 0; i < arraysize(snippets); i++) {
5714 Handle<BytecodeArray> bytecode_array =
5715 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
5716 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
5717 }
5718 }
5719
5720
5721 TEST(LdaLookupSlotInsideTypeOf) {
5722 InitializedHandleScope handle_scope;
5723 BytecodeGeneratorHelper helper;
5724
5725 int closure = Register::function_closure().index();
5726 int first_context_slot = Context::MIN_CONTEXT_SLOTS;
5727 int context = Register::function_context().index();
5728 int new_target = Register::new_target().index();
5729
5730 ExpectedSnippet<const char*> snippets[] = {
5731 {"eval('var x = 10;'); return typeof x;",
5732 9 * kPointerSize,
5733 1,
5734 79,
5735 {
5736 B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), //
5737 U8(1), //
5738 B(PushContext), R(0), //
5739 B(Ldar), THIS(1), //
5740 B(StaContextSlot), R(0), U8(first_context_slot), //
5741 B(CreateMappedArguments), //
5742 B(StaContextSlot), R(0), U8(first_context_slot + 1), //
5743 B(Ldar), R(new_target), //
5744 B(StaContextSlot), R(0), U8(first_context_slot + 2), //
5745 B(Mov), R(context), R(3), //
5746 B(LdaConstant), U8(0), //
5747 B(Star), R(4), //
5748 B(CallRuntime), U16(Runtime::kInterpreterLoadLookupSlotCallee), //
5749 R(3), U8(2), //
5750 B(Star), R(1), //
5751 B(CallRuntime), U16(Runtime::kInterpreterLoadLookupSlotReceiver), //
5752 R(3), U8(2), //
5753 B(Star), R(2), //
5754 B(LdaConstant), U8(1), //
5755 B(Star), R(3), //
5756 B(Mov), R(1), R(4), //
5757 B(Mov), R(3), R(5), //
5758 B(Mov), R(closure), R(6), //
5759 B(LdaZero), //
5760 B(Star), R(7), //
5761 B(LdaSmi8), U8(10), //
5762 B(Star), R(8), //
5763 B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), //
5764 U8(5), //
5765 B(Star), R(1), //
5766 B(Call), R(1), R(2), U8(1), U8(0), //
5767 B(LdaLookupSlotInsideTypeof), U8(2), R(0), //
5768 B(TypeOf), //
5769 B(Return), //
5770 },
5771 3,
5772 {"eval", "var x = 10;", "x"}},
5773 };
5774
5775 for (size_t i = 0; i < arraysize(snippets); i++) {
5776 Handle<BytecodeArray> bytecode_array =
5777 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
5778 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
5779 }
5780 }
5781
5782
5783 TEST(LookupSlotInEval) {
5784 InitializedHandleScope handle_scope;
5785 BytecodeGeneratorHelper helper;
5786
5787 int context = Register::function_context().index();
5788
5789 const char* function_prologue = "var f;"
5790 "var x = 1;"
5791 "function f1() {"
5792 " eval(\"function t() {";
5793 const char* function_epilogue = " }; f = t; f();\");"
5794 "}"
5795 "f1();";
5796
5797 ExpectedSnippet<const char*> snippets[] = {
5798 {"return x;",
5799 0 * kPointerSize,
5800 1,
5801 4,
5802 {
5803 B(LdaLookupSlot), U8(0), R(context), //
5804 B(Return) //
5805 },
5806 1,
5807 {"x"}},
5808 {"x = 10;",
5809 0 * kPointerSize,
5810 1,
5811 7,
5812 {
5813 B(LdaSmi8), U8(10), //
5814 B(StaLookupSlotSloppy), U8(0), R(context), //
5815 B(LdaUndefined), //
5816 B(Return), //
5817 },
5818 1,
5819 {"x"}},
5820 {"'use strict'; x = 10;",
5821 0 * kPointerSize,
5822 1,
5823 7,
5824 {
5825 B(LdaSmi8), U8(10), //
5826 B(StaLookupSlotStrict), U8(0), R(context), //
5827 B(LdaUndefined), //
5828 B(Return), //
5829 },
5830 1,
5831 {"x"}},
5832 {"return typeof x;",
5833 0 * kPointerSize,
5834 1,
5835 5,
5836 {
5837 B(LdaLookupSlotInsideTypeof), U8(0), R(context), //
5838 B(TypeOf), //
5839 B(Return), //
5840 },
5841 1,
5842 {"x"}},
5843 };
5844
5845 for (size_t i = 0; i < arraysize(snippets); i++) {
5846 std::string script = std::string(function_prologue) +
5847 std::string(snippets[i].code_snippet) +
5848 std::string(function_epilogue);
5849 // TODO(mythria): use * as filter when function declarations are supported
5850 // inside eval.
5851 Handle<BytecodeArray> bytecode_array =
5852 helper.MakeBytecode(script.c_str(), "t", "f");
5853 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
5854 }
5855 }
5856
5582 } // namespace interpreter 5857 } // namespace interpreter
5583 } // namespace internal 5858 } // namespace internal
5584 } // namespace v8 5859 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698