| 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 |