Index: Source/bindings/core/v8/ScriptStreamer.h |
diff --git a/Source/bindings/core/v8/ScriptStreamer.h b/Source/bindings/core/v8/ScriptStreamer.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..34a48f8d57410024033842b3dd861a48deb80047 |
--- /dev/null |
+++ b/Source/bindings/core/v8/ScriptStreamer.h |
@@ -0,0 +1,112 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef ScriptStreamer_h |
+#define ScriptStreamer_h |
+ |
+#include "wtf/RefCounted.h" |
+ |
+#include <v8.h> |
+ |
+namespace blink { |
+ |
+class PendingScript; |
+class Resource; |
+class ScriptResource; |
+class ScriptResourceClient; |
+class ScriptState; |
+class Settings; |
+class SourceStream; |
+ |
+// ScriptStreamer streams incomplete script data to V8 so that it can be parsed |
+// while it's loaded. PendingScript holds a reference to ScriptStreamer. At the |
+// moment, ScriptStreamer is only used for parser blocking scripts; this means |
+// that the Document stays stable and no other scripts are executing while we're |
+// streaming. It is possible, though, that Document and the PendingScript are |
+// destroyed while the streaming is in progress, and ScriptStreamer handles it |
+// gracefully. |
+class ScriptStreamer : public RefCounted<ScriptStreamer> { |
+ WTF_MAKE_NONCOPYABLE(ScriptStreamer); |
+public: |
+ // Launches a task (on a background thread) which will stream the given |
+ // PendingScript into V8 as it loads. It's also possible that V8 cannot |
+ // stream the given script; in that case this function returns |
+ // false. Internally, this constructs a ScriptStreamer and attaches it to |
+ // the PendingScript. Use ScriptStreamer::addClient to get notified when the |
+ // streaming finishes. |
+ static bool startStreaming(PendingScript&, Settings*, ScriptState*); |
+ |
+ bool streamingInProgress() const { return !m_loadingFinished || !m_parsingFinished; } |
+ |
+ v8::ScriptCompiler::StreamedSource* source() { return &m_source; } |
+ ScriptResource* resource() const { return m_resource; } |
+ |
+ // Called when the script is not needed any more (e.g., loading was |
+ // cancelled). After calling cancel, PendingScript can drop its reference to |
+ // ScriptStreamer, and ScriptStreamer takes care of eventually deleting |
+ // itself (after the V8 side has finished too). |
+ void cancel(); |
+ |
+ // When the streaming is suppressed, the data is not given to V8, but |
+ // ScriptStreamer still watches the resource load and notifies the upper |
+ // layers when loading is finished. It is used in situations when we have |
+ // started streaming but then we detect we don't want to stream (e.g., when |
+ // we have the code cache for the script) and we still want to parse and |
+ // execute it when it has finished loading. |
+ void suppressStreaming() { m_streamingSuppressed = true; } |
+ bool streamingSuppressed() const { return m_streamingSuppressed; } |
+ |
+ unsigned cachedDataType() const { return m_cachedDataType; } |
+ |
+ void addClient(ScriptResourceClient* client) |
+ { |
+ ASSERT(!m_client); |
+ m_client = client; |
+ } |
+ |
+ void removeClient(ScriptResourceClient* client) |
+ { |
+ ASSERT(m_client == client); |
+ m_client = 0; |
+ } |
+ |
+ // Called by PendingScript when data arrives from the network. |
+ void notifyAppendData(ScriptResource*); |
+ void notifyFinished(Resource*); |
+ |
+ // Called by ScriptStreamingTask when it has streamed all data to V8 and V8 |
+ // has processed it. |
+ void streamingComplete(); |
+ |
+private: |
+ ScriptStreamer(ScriptResource*, v8::ScriptCompiler::StreamedSource::Encoding); |
+ |
+ void notifyFinishedToClient(); |
+ |
+ // This pointer is weak. If PendingScript and its Resource are deleted |
+ // before ScriptStreamer, PendingScript will notify ScriptStreamer of its |
+ // deletion by calling cancel(). |
+ ScriptResource* m_resource; |
+ // Whether ScriptStreamer is detached from the Resource. In those cases, the |
+ // script data is not needed any more, and the client won't get notified |
+ // when the loading and streaming are done. |
+ bool m_detached; |
+ |
+ SourceStream* m_stream; |
+ v8::ScriptCompiler::StreamedSource m_source; |
+ ScriptResourceClient* m_client; |
+ bool m_loadingFinished; // Whether loading from the network is done. |
+ bool m_parsingFinished; // Whether the V8 side processing is done. |
+ |
+ // Whether the script source code should be retrieved from the Resource |
+ // instead of the ScriptStreamer. |
+ bool m_streamingSuppressed; |
+ |
+ // What kind of cached data V8 produces during streaming. |
+ unsigned m_cachedDataType; |
+}; |
+ |
+} // namespace blink |
+ |
+#endif // ScriptStreamer_h |