Index: test/unittests/compiler-dispatcher/compiler-dispatcher-job-unittest.cc |
diff --git a/test/unittests/compiler-dispatcher/compiler-dispatcher-job-unittest.cc b/test/unittests/compiler-dispatcher/compiler-dispatcher-job-unittest.cc |
index 480c3abe68181bbc67f647aa55d62706ee6ca8e0..97c44242602ac57a49f40e1ce0c9ea0f1abcf66e 100644 |
--- a/test/unittests/compiler-dispatcher/compiler-dispatcher-job-unittest.cc |
+++ b/test/unittests/compiler-dispatcher/compiler-dispatcher-job-unittest.cc |
@@ -4,9 +4,12 @@ |
#include <memory> |
+#include "src/ast/scopes.h" |
#include "src/compiler-dispatcher/compiler-dispatcher-job.h" |
+#include "src/compiler.h" |
#include "src/flags.h" |
#include "src/isolate-inl.h" |
+#include "src/parsing/parser.h" |
#include "test/unittests/test-utils.h" |
#include "testing/gtest/include/gtest/gtest.h" |
@@ -17,6 +20,8 @@ typedef TestWithContext CompilerDispatcherJobTest; |
namespace { |
+const char test_script[] = "x*x"; |
+ |
class ScriptResource : public v8::String::ExternalOneByteStringResource { |
public: |
ScriptResource(const char* data, size_t length) |
@@ -42,20 +47,32 @@ Handle<JSFunction> CreateFunction( |
->NewExternalStringFromOneByte(maybe_resource) |
.ToHandleChecked(); |
} else { |
- source = isolate->factory()->NewStringFromStaticChars("source"); |
+ source = isolate->factory()->NewStringFromAsciiChecked(test_script); |
} |
Handle<Script> script = isolate->factory()->NewScript(source); |
Handle<SharedFunctionInfo> shared = isolate->factory()->NewSharedFunctionInfo( |
- isolate->factory()->NewStringFromStaticChars("f"), MaybeHandle<Code>(), |
+ isolate->factory()->NewStringFromAsciiChecked("f"), MaybeHandle<Code>(), |
false); |
SharedFunctionInfo::SetScript(shared, script); |
- shared->set_end_position(source->length() - 1); |
+ shared->set_end_position(source->length()); |
Handle<JSFunction> function = |
isolate->factory()->NewFunctionFromSharedFunctionInfo( |
shared, handle(isolate->context(), isolate)); |
return scope.CloseAndEscape(function); |
} |
+// A CatchContext is the easiest way to get a context with a variable in a |
+// slot. |
+Handle<Context> GetContextWithVariable(Isolate* isolate, const char* var) { |
+ HandleScope handle_scope(isolate); |
+ Handle<JSFunction> closure(isolate->native_context()->closure()); |
+ Handle<Context> context = isolate->factory()->NewCatchContext( |
+ closure, handle(isolate->context()), |
+ isolate->factory()->NewStringFromAsciiChecked(var), |
+ isolate->factory()->undefined_value()); |
+ return handle_scope.CloseAndEscape(context); |
+} |
+ |
} // namespace |
TEST_F(CompilerDispatcherJobTest, Construct) { |
@@ -70,7 +87,7 @@ TEST_F(CompilerDispatcherJobTest, CanParseOnBackgroundThread) { |
ASSERT_FALSE(job->can_parse_on_background_thread()); |
} |
{ |
- ScriptResource script("script", strlen("script")); |
+ ScriptResource script(test_script, strlen(test_script)); |
std::unique_ptr<CompilerDispatcherJob> job(new CompilerDispatcherJob( |
i_isolate(), CreateFunction(i_isolate(), &script), FLAG_stack_size)); |
ASSERT_TRUE(job->can_parse_on_background_thread()); |
@@ -108,5 +125,31 @@ TEST_F(CompilerDispatcherJobTest, SyntaxError) { |
ASSERT_TRUE(i_isolate()->has_pending_exception()); |
} |
+TEST_F(CompilerDispatcherJobTest, ScopeChain) { |
+ Handle<Context> outer_scope = GetContextWithVariable(i_isolate(), "g"); |
+ const char source[] = "g = 1;"; |
+ ScriptResource script(source, strlen(source)); |
+ Handle<JSFunction> fun = CreateFunction(i_isolate(), &script); |
+ fun->set_context(*outer_scope); |
+ |
+ std::unique_ptr<CompilerDispatcherJob> job( |
+ new CompilerDispatcherJob(i_isolate(), fun, FLAG_stack_size)); |
+ job->PrepareToParseOnMainThread(); |
+ job->Parse(); |
+ job->FinalizeParsingOnMainThread(); |
+ ASSERT_TRUE(job->status() == CompileJobStatus::kReadyToCompile); |
+ |
+ Scope* scope = job->parse_info_->literal()->scope(); |
+ Scope* inner_scope = scope->inner_scope(); |
+ const AstRawString* var_name = |
+ job->parse_info_->ast_value_factory()->GetOneByteString("g"); |
+ Variable* var = inner_scope->Lookup(var_name); |
+ ASSERT_TRUE(var); |
+ // If the parser didn't use our outer_scope, "g" would be a global variable. |
+ ASSERT_TRUE(var->IsContextSlot()); |
+ |
+ job->ResetOnMainThread(); |
+} |
+ |
} // namespace internal |
} // namespace v8 |