Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 <memory> | 5 #include <memory> |
| 6 | 6 |
| 7 #include "src/ast/scopes.h" | |
| 7 #include "src/compiler-dispatcher/compiler-dispatcher-job.h" | 8 #include "src/compiler-dispatcher/compiler-dispatcher-job.h" |
| 9 #include "src/compiler.h" | |
| 8 #include "src/flags.h" | 10 #include "src/flags.h" |
| 9 #include "src/isolate-inl.h" | 11 #include "src/isolate-inl.h" |
| 12 #include "src/parsing/parser.h" | |
| 10 #include "test/unittests/test-utils.h" | 13 #include "test/unittests/test-utils.h" |
| 11 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
| 12 | 15 |
| 13 namespace v8 { | 16 namespace v8 { |
| 14 namespace internal { | 17 namespace internal { |
| 15 | 18 |
| 16 typedef TestWithContext CompilerDispatcherJobTest; | 19 typedef TestWithContext CompilerDispatcherJobTest; |
| 17 | 20 |
| 18 namespace { | 21 namespace { |
| 19 | 22 |
| 23 const char test_script[] = "x*x"; | |
| 24 | |
| 20 class ScriptResource : public v8::String::ExternalOneByteStringResource { | 25 class ScriptResource : public v8::String::ExternalOneByteStringResource { |
| 21 public: | 26 public: |
| 22 ScriptResource(const char* data, size_t length) | 27 ScriptResource(const char* data, size_t length) |
| 23 : data_(data), length_(length) {} | 28 : data_(data), length_(length) {} |
| 24 ~ScriptResource() override = default; | 29 ~ScriptResource() override = default; |
| 25 | 30 |
| 26 const char* data() const override { return data_; } | 31 const char* data() const override { return data_; } |
| 27 size_t length() const override { return length_; } | 32 size_t length() const override { return length_; } |
| 28 | 33 |
| 29 private: | 34 private: |
| 30 const char* data_; | 35 const char* data_; |
| 31 size_t length_; | 36 size_t length_; |
| 32 | 37 |
| 33 DISALLOW_COPY_AND_ASSIGN(ScriptResource); | 38 DISALLOW_COPY_AND_ASSIGN(ScriptResource); |
| 34 }; | 39 }; |
| 35 | 40 |
| 36 Handle<JSFunction> CreateFunction( | 41 Handle<JSFunction> CreateFunction( |
| 37 Isolate* isolate, ExternalOneByteString::Resource* maybe_resource) { | 42 Isolate* isolate, ExternalOneByteString::Resource* maybe_resource) { |
| 38 HandleScope scope(isolate); | 43 HandleScope scope(isolate); |
| 39 Handle<String> source; | 44 Handle<String> source; |
| 40 if (maybe_resource) { | 45 if (maybe_resource) { |
| 41 source = isolate->factory() | 46 source = isolate->factory() |
| 42 ->NewExternalStringFromOneByte(maybe_resource) | 47 ->NewExternalStringFromOneByte(maybe_resource) |
| 43 .ToHandleChecked(); | 48 .ToHandleChecked(); |
| 44 } else { | 49 } else { |
| 45 source = isolate->factory()->NewStringFromStaticChars("source"); | 50 source = isolate->factory()->NewStringFromAsciiChecked(test_script); |
| 46 } | 51 } |
| 47 Handle<Script> script = isolate->factory()->NewScript(source); | 52 Handle<Script> script = isolate->factory()->NewScript(source); |
| 48 Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo( | 53 Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo( |
| 49 isolate->factory()->NewStringFromStaticChars("f"), MaybeHandle<Code>(), | 54 isolate->factory()->NewStringFromAsciiChecked("f"), MaybeHandle<Code>(), |
| 50 false); | 55 false); |
| 51 SharedFunctionInfo::SetScript(shared, script); | 56 SharedFunctionInfo::SetScript(shared, script); |
| 52 shared->set_end_position(source->length() - 1); | 57 shared->set_end_position(source->length()); |
| 53 Handle<JSFunction> function = | 58 Handle<JSFunction> function = |
| 54 isolate->factory()->NewFunctionFromSharedFunctionInfo( | 59 isolate->factory()->NewFunctionFromSharedFunctionInfo( |
| 55 shared, handle(isolate->context(), isolate)); | 60 shared, handle(isolate->context(), isolate)); |
| 56 return scope.CloseAndEscape(function); | 61 return scope.CloseAndEscape(function); |
| 57 } | 62 } |
| 58 | 63 |
| 64 Handle<Context> GetScopeWithVariable(Isolate* isolate, const char* var) { | |
|
marja
2016/08/03 08:07:48
This function name is surprising given that it doe
jochen (gone - plz use gerrit)
2016/08/03 09:14:49
done
| |
| 65 HandleScope handle_scope(isolate); | |
| 66 Handle<JSFunction> closure(isolate->native_context()->closure()); | |
| 67 Handle<Context> context = isolate->factory()->NewCatchContext( | |
| 68 closure, handle(isolate->context()), | |
| 69 isolate->factory()->NewStringFromAsciiChecked(var), | |
| 70 isolate->factory()->undefined_value()); | |
| 71 return handle_scope.CloseAndEscape(context); | |
| 72 } | |
| 73 | |
| 59 } // namespace | 74 } // namespace |
| 60 | 75 |
| 61 TEST_F(CompilerDispatcherJobTest, Construct) { | 76 TEST_F(CompilerDispatcherJobTest, Construct) { |
| 62 std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob( | 77 std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob( |
| 63 i_isolate(), CreateFunction(i_isolate(), nullptr), FLAG_stack_size)); | 78 i_isolate(), CreateFunction(i_isolate(), nullptr), FLAG_stack_size)); |
| 64 } | 79 } |
| 65 | 80 |
| 66 TEST_F(CompilerDispatcherJobTest, CanParseOnBackgroundThread) { | 81 TEST_F(CompilerDispatcherJobTest, CanParseOnBackgroundThread) { |
| 67 { | 82 { |
| 68 std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob( | 83 std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob( |
| 69 i_isolate(), CreateFunction(i_isolate(), nullptr), FLAG_stack_size)); | 84 i_isolate(), CreateFunction(i_isolate(), nullptr), FLAG_stack_size)); |
| 70 ASSERT_FALSE(job->can_parse_on_background_thread()); | 85 ASSERT_FALSE(job->can_parse_on_background_thread()); |
| 71 } | 86 } |
| 72 { | 87 { |
| 73 ScriptResource script("script", strlen("script")); | 88 ScriptResource script(test_script, strlen(test_script)); |
| 74 std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob( | 89 std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob( |
| 75 i_isolate(), CreateFunction(i_isolate(), &script), FLAG_stack_size)); | 90 i_isolate(), CreateFunction(i_isolate(), &script), FLAG_stack_size)); |
| 76 ASSERT_TRUE(job->can_parse_on_background_thread()); | 91 ASSERT_TRUE(job->can_parse_on_background_thread()); |
| 77 } | 92 } |
| 78 } | 93 } |
| 79 | 94 |
| 80 TEST_F(CompilerDispatcherJobTest, StateTransitions) { | 95 TEST_F(CompilerDispatcherJobTest, StateTransitions) { |
| 81 std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob( | 96 std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob( |
| 82 i_isolate(), CreateFunction(i_isolate(), nullptr), FLAG_stack_size)); | 97 i_isolate(), CreateFunction(i_isolate(), nullptr), FLAG_stack_size)); |
| 83 | 98 |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 101 job->Parse(); | 116 job->Parse(); |
| 102 job->FinalizeParsingOnMainThread(); | 117 job->FinalizeParsingOnMainThread(); |
| 103 | 118 |
| 104 ASSERT_TRUE(job->status() == CompileJobStatus::kFailed); | 119 ASSERT_TRUE(job->status() == CompileJobStatus::kFailed); |
| 105 ASSERT_FALSE(i_isolate()->has_pending_exception()); | 120 ASSERT_FALSE(i_isolate()->has_pending_exception()); |
| 106 job->ReportErrorsOnMainThread(); | 121 job->ReportErrorsOnMainThread(); |
| 107 ASSERT_TRUE(job->status() == CompileJobStatus::kDone); | 122 ASSERT_TRUE(job->status() == CompileJobStatus::kDone); |
| 108 ASSERT_TRUE(i_isolate()->has_pending_exception()); | 123 ASSERT_TRUE(i_isolate()->has_pending_exception()); |
| 109 } | 124 } |
| 110 | 125 |
| 126 TEST_F(CompilerDispatcherJobTest, ScopeChain) { | |
| 127 Handle<Context> outter_scope = GetScopeWithVariable(i_isolate(), "g"); | |
|
marja
2016/08/03 08:07:48
Typo: outter
jochen (gone - plz use gerrit)
2016/08/03 09:14:49
done
| |
| 128 const char source[] = "g = 1;"; | |
| 129 ScriptResource script(source, strlen(source)); | |
| 130 Handle<JSFunction> fun = CreateFunction(i_isolate(), &script); | |
| 131 fun->set_context(*outter_scope); | |
| 132 | |
| 133 std::unique_ptr<CompilerDispatcherJob> job( | |
| 134 new CompilerDispatcherJob(i_isolate(), fun, FLAG_stack_size)); | |
| 135 job->PrepareToParseOnMainThread(); | |
| 136 job->Parse(); | |
| 137 job->FinalizeParsingOnMainThread(); | |
| 138 ASSERT_TRUE(job->status() == CompileJobStatus::kReadyToCompile); | |
| 139 | |
| 140 Scope* scope = job->parse_info_->literal()->scope(); | |
| 141 Scope* inner_scope = scope->inner_scope(); | |
| 142 const AstRawString* var_name = | |
| 143 job->parse_info_->ast_value_factory()->GetOneByteString("g"); | |
| 144 Variable* var = inner_scope->Lookup(var_name); | |
| 145 ASSERT_TRUE(var); | |
| 146 ASSERT_TRUE(var->IsContextSlot()); | |
|
marja
2016/08/03 08:07:48
Hmm, this test is not clear to me... Is g a functi
jochen (gone - plz use gerrit)
2016/08/03 09:14:49
well, without the parsing step, there is no litera
| |
| 147 | |
| 148 job->ResetOnMainThread(); | |
| 149 } | |
| 150 | |
| 111 } // namespace internal | 151 } // namespace internal |
| 112 } // namespace v8 | 152 } // namespace v8 |
| OLD | NEW |