| Index: src/api.cc
|
| diff --git a/src/api.cc b/src/api.cc
|
| index 7098859de3cfa9fa85d786b29cf8eef56846f086..95d4e252a64127065230203b5896c85b80e8191c 100644
|
| --- a/src/api.cc
|
| +++ b/src/api.cc
|
| @@ -13,6 +13,7 @@
|
| #include "include/v8-profiler.h"
|
| #include "include/v8-testing.h"
|
| #include "src/assert-scope.h"
|
| +#include "src/background-parser-thread.h"
|
| #include "src/base/platform/platform.h"
|
| #include "src/base/platform/time.h"
|
| #include "src/base/utils/random-number-generator.h"
|
| @@ -1575,6 +1576,13 @@ ScriptCompiler::CachedData::~CachedData() {
|
| }
|
|
|
|
|
| +ScriptCompiler::StreamedSource::~StreamedSource() {
|
| + delete source_stream;
|
| + delete cached_data;
|
| + delete info;
|
| +}
|
| +
|
| +
|
| Local<Script> UnboundScript::BindToCurrentContext() {
|
| i::Handle<i::HeapObject> obj =
|
| i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
|
| @@ -1775,6 +1783,91 @@ Local<UnboundScript> ScriptCompiler::CompileUnbound(
|
| }
|
|
|
|
|
| +bool ScriptCompiler::StartStreamingScript(Isolate* v8_isolate,
|
| + StreamedSource* source,
|
| + StreamingCompleteCallback callback,
|
| + void* callback_data,
|
| + CompileOptions options) {
|
| + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
|
| + if (!isolate->global_context().is_null() &&
|
| + !isolate->global_context()->IsNativeContext()) {
|
| + // The context chain is non-trivial, and constructing the corresponding
|
| + // non-trivial Scope chain outside the V8 heap is not implemented. Don't
|
| + // stream the script. This will only occur if Harmony scoping is enabled and
|
| + // a previous script has introduced "let" or "const" variables. TODO(marja):
|
| + // Implement externalizing ScopeInfos and constructing non-trivial Scope
|
| + // chains independent of the V8 heap so that we can stream also in this
|
| + // case.
|
| + return false;
|
| + }
|
| + // At the moment, it's only possible to stream one script per
|
| + // time. TODO(marja): get rid of this restriction. Since we need one
|
| + // background thread per a script to be streamed, we need to find a trade-off
|
| + // between launching new threads and streaming more scripts.
|
| + if (isolate->background_parser_thread()->HasTask()) return false;
|
| +
|
| + source->info = new i::CompilationInfoWithZone(source->source_stream, isolate);
|
| + source->info->MarkAsGlobal();
|
| + DCHECK(options == kProduceParserCache || options == kProduceCodeCache ||
|
| + options == kNoCompileOptions);
|
| + bool allow_lazy = !i::Compiler::DebuggerWantsEagerCompilation(source->info);
|
| + i::BackgroundParsingTask* task = new i::BackgroundParsingTask(
|
| + source, callback, callback_data, allow_lazy, isolate);
|
| + if (options == kProduceParserCache || options == kProduceCodeCache) {
|
| + source->info->SetCachedData(&(task->script_data_), options);
|
| + }
|
| + // We don't set the context to the CompilationInfo yet, because the background
|
| + // thread cannot do anything with it anyway. We set it just before compilation
|
| + // on the foreground thread.
|
| + isolate->background_parser_thread()->SetTask(task);
|
| + return true;
|
| +}
|
| +
|
| +
|
| +Local<Script> ScriptCompiler::Compile(Isolate* v8_isolate,
|
| + StreamedSource* source,
|
| + Handle<String> full_source_string,
|
| + const ScriptOrigin& origin) {
|
| + if (source->info->function() == NULL) {
|
| + // Parsing has failed.
|
| + return Local<Script>();
|
| + }
|
| + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
|
| + source->info->ast_value_factory()->Internalize(isolate);
|
| +
|
| + i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
|
| + i::Handle<i::Script> script = isolate->factory()->NewScript(str);
|
| + if (!origin.ResourceName().IsEmpty()) {
|
| + script->set_name(*Utils::OpenHandle(*(origin.ResourceName())));
|
| + }
|
| + if (!origin.ResourceLineOffset().IsEmpty()) {
|
| + script->set_line_offset(i::Smi::FromInt(
|
| + static_cast<int>(origin.ResourceLineOffset()->Value())));
|
| + }
|
| + if (!origin.ResourceColumnOffset().IsEmpty()) {
|
| + script->set_column_offset(i::Smi::FromInt(
|
| + static_cast<int>(origin.ResourceColumnOffset()->Value())));
|
| + }
|
| + if (!origin.ResourceIsSharedCrossOrigin().IsEmpty()) {
|
| + script->set_is_shared_cross_origin(origin.ResourceIsSharedCrossOrigin() ==
|
| + v8::True(v8_isolate));
|
| + }
|
| + source->info->set_script(script);
|
| + source->info->SetContext(isolate->global_context());
|
| +
|
| + ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()", return Local<Script>());
|
| + LOG_API(isolate, "ScriptCompiler::Compile()");
|
| + ENTER_V8(isolate);
|
| + EXCEPTION_PREAMBLE(isolate);
|
| + i::Handle<i::SharedFunctionInfo> result =
|
| + i::Compiler::CompileStreamedScript(source->info, str->length());
|
| + EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
|
| + Local<UnboundScript> generic = ToApiHandle<UnboundScript>(result);
|
| + if (generic.IsEmpty()) return Local<Script>();
|
| + return generic->BindToCurrentContext();
|
| +}
|
| +
|
| +
|
| Local<Script> ScriptCompiler::Compile(
|
| Isolate* v8_isolate,
|
| Source* source,
|
|
|