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/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 Loading... |
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 Handle<BytecodeArray> return_val = MakeBytecode(script, function_name); |
| 63 i::FLAG_ignition_filter = old_ignition_filter; |
| 64 return return_val; |
| 65 } |
| 66 |
58 Handle<BytecodeArray> MakeBytecodeForFunctionBody(const char* body) { | 67 Handle<BytecodeArray> MakeBytecodeForFunctionBody(const char* body) { |
59 ScopedVector<char> program(3072); | 68 ScopedVector<char> program(3072); |
60 SNPrintF(program, "function %s() { %s }\n%s();", kFunctionName, body, | 69 SNPrintF(program, "function %s() { %s }\n%s();", kFunctionName, body, |
61 kFunctionName); | 70 kFunctionName); |
62 return MakeBytecode(program.start(), kFunctionName); | 71 return MakeBytecode(program.start(), kFunctionName); |
63 } | 72 } |
64 | 73 |
65 Handle<BytecodeArray> MakeBytecodeForFunction(const char* function) { | 74 Handle<BytecodeArray> MakeBytecodeForFunction(const char* function) { |
66 ScopedVector<char> program(3072); | 75 ScopedVector<char> program(3072); |
67 SNPrintF(program, "%s\n%s();", function, kFunctionName); | 76 SNPrintF(program, "%s\n%s();", function, kFunctionName); |
68 return MakeBytecode(program.start(), kFunctionName); | 77 return MakeBytecode(program.start(), kFunctionName); |
69 } | 78 } |
70 | 79 |
71 Handle<BytecodeArray> MakeBytecodeForFunctionNoFilter(const char* function) { | 80 Handle<BytecodeArray> MakeBytecodeForFunctionNoFilter(const char* function) { |
72 const char* old_ignition_filter = i::FLAG_ignition_filter; | |
73 i::FLAG_ignition_filter = "*"; | |
74 ScopedVector<char> program(3072); | 81 ScopedVector<char> program(3072); |
75 SNPrintF(program, "%s\n%s();", function, kFunctionName); | 82 SNPrintF(program, "%s\n%s();", function, kFunctionName); |
76 Handle<BytecodeArray> return_val = | 83 return MakeBytecode(program.start(), "*", kFunctionName); |
77 MakeBytecode(program.start(), kFunctionName); | |
78 i::FLAG_ignition_filter = old_ignition_filter; | |
79 return return_val; | |
80 } | 84 } |
81 }; | 85 }; |
82 | 86 |
83 | 87 |
84 // Helper macros for handcrafting bytecode sequences. | 88 // Helper macros for handcrafting bytecode sequences. |
85 #define B(x) static_cast<uint8_t>(Bytecode::k##x) | 89 #define B(x) static_cast<uint8_t>(Bytecode::k##x) |
86 #define U8(x) static_cast<uint8_t>((x) & 0xff) | 90 #define U8(x) static_cast<uint8_t>((x) & 0xff) |
87 #define R(x) static_cast<uint8_t>(-(x) & 0xff) | 91 #define R(x) static_cast<uint8_t>(-(x) & 0xff) |
88 #define A(x, n) R(helper.kLastParamIndex - (n) + 1 + (x)) | 92 #define A(x, n) R(helper.kLastParamIndex - (n) + 1 + (x)) |
89 #define THIS(n) A(0, n) | 93 #define THIS(n) A(0, n) |
(...skipping 5421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5511 }, | 5515 }, |
5512 0}}; | 5516 0}}; |
5513 | 5517 |
5514 for (size_t i = 0; i < arraysize(snippets); i++) { | 5518 for (size_t i = 0; i < arraysize(snippets); i++) { |
5515 Handle<BytecodeArray> bytecode_array = | 5519 Handle<BytecodeArray> bytecode_array = |
5516 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); | 5520 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); |
5517 CheckBytecodeArrayEqual(snippets[i], bytecode_array); | 5521 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
5518 } | 5522 } |
5519 } | 5523 } |
5520 | 5524 |
| 5525 |
| 5526 TEST(LookupSlotInEval) { |
| 5527 InitializedHandleScope handle_scope; |
| 5528 BytecodeGeneratorHelper helper; |
| 5529 |
| 5530 const char* function_prologue = "var f;" |
| 5531 "var x = 1;" |
| 5532 "function f1() {" |
| 5533 " eval(\"function t() {"; |
| 5534 const char* function_epilogue = " }; f = t; f();\");" |
| 5535 "}" |
| 5536 "f1();"; |
| 5537 |
| 5538 ExpectedSnippet<const char*> snippets[] = { |
| 5539 {"return x;", |
| 5540 0 * kPointerSize, |
| 5541 1, |
| 5542 3, |
| 5543 { |
| 5544 B(LdaLookupSlot), U8(0), // |
| 5545 B(Return) // |
| 5546 }, |
| 5547 1, |
| 5548 {"x"}}, |
| 5549 {"x = 10;", |
| 5550 0 * kPointerSize, |
| 5551 1, |
| 5552 6, |
| 5553 { |
| 5554 B(LdaSmi8), U8(10), // |
| 5555 B(StaLookupSlotSloppy), U8(0), // |
| 5556 B(LdaUndefined), // |
| 5557 B(Return), // |
| 5558 }, |
| 5559 1, |
| 5560 {"x"}}, |
| 5561 {"'use strict'; x = 10;", |
| 5562 0 * kPointerSize, |
| 5563 1, |
| 5564 6, |
| 5565 { |
| 5566 B(LdaSmi8), U8(10), // |
| 5567 B(StaLookupSlotStrict), U8(0), // |
| 5568 B(LdaUndefined), // |
| 5569 B(Return), // |
| 5570 }, |
| 5571 1, |
| 5572 {"x"}}, |
| 5573 {"return typeof x;", |
| 5574 0 * kPointerSize, |
| 5575 1, |
| 5576 4, |
| 5577 { |
| 5578 B(LdaLookupSlotInsideTypeof), U8(0), // |
| 5579 B(TypeOf), // |
| 5580 B(Return), // |
| 5581 }, |
| 5582 1, |
| 5583 {"x"}}, |
| 5584 }; |
| 5585 |
| 5586 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 5587 std::string script = std::string(function_prologue) + |
| 5588 std::string(snippets[i].code_snippet) + |
| 5589 std::string(function_epilogue); |
| 5590 // TODO(mythria): use * as filter when function declarations are supported |
| 5591 // inside eval. |
| 5592 Handle<BytecodeArray> bytecode_array = |
| 5593 helper.MakeBytecode(script.c_str(), "t", "f"); |
| 5594 CheckBytecodeArrayEqual(snippets[i], bytecode_array); |
| 5595 } |
| 5596 } |
| 5597 |
5521 } // namespace interpreter | 5598 } // namespace interpreter |
5522 } // namespace internal | 5599 } // namespace internal |
5523 } // namespace v8 | 5600 } // namespace v8 |
OLD | NEW |