summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjianli@chromium.org <jianli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-21 23:48:34 +0000
committerjianli@chromium.org <jianli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-21 23:48:34 +0000
commit9257d0132435d1248ca586e878ee67b1b8dcdb56 (patch)
tree5a6f4164d9f25dc7f0f6b0e83b81c37491141b39
parenta1a61172ee9e1c59f257c4c8c49d4b9eb4c046e9 (diff)
downloadchromium_src-9257d0132435d1248ca586e878ee67b1b8dcdb56.zip
chromium_src-9257d0132435d1248ca586e878ee67b1b8dcdb56.tar.gz
chromium_src-9257d0132435d1248ca586e878ee67b1b8dcdb56.tar.bz2
Add V8 bindings for Worker.
Review URL: http://codereview.chromium.org/17246 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8414 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/scoped_handle_win.h4
-rw-r--r--base/thread.h5
-rw-r--r--webkit/build/JavaScriptCore/SConscript1
-rw-r--r--webkit/build/JavaScriptCore/WTF.vcproj6
-rw-r--r--webkit/build/V8Bindings/SConscript5
-rw-r--r--webkit/build/V8Bindings/V8Bindings.vcproj32
-rw-r--r--webkit/build/WebCore/SConscript6
-rw-r--r--webkit/build/WebCore/WebCore.vcproj48
-rw-r--r--webkit/build/port/SConscript2
-rw-r--r--webkit/port/DerivedSources.make2
-rw-r--r--webkit/port/bindings/scripts/CodeGeneratorV8.pm17
-rw-r--r--webkit/port/bindings/v8/Threading.cpp96
-rw-r--r--webkit/port/bindings/v8/V8WorkerCustom.cpp276
-rw-r--r--webkit/port/bindings/v8/WorkerScriptController.cpp124
-rw-r--r--webkit/port/bindings/v8/WorkerScriptController.h64
-rw-r--r--webkit/port/bindings/v8/v8_custom.h16
-rw-r--r--webkit/port/bindings/v8/v8_index.cpp5
-rw-r--r--webkit/port/bindings/v8/v8_index.h12
-rw-r--r--webkit/port/bindings/v8/v8_proxy.cpp17
19 files changed, 731 insertions, 7 deletions
diff --git a/base/scoped_handle_win.h b/base/scoped_handle_win.h
index ead32ac..e9b2532 100644
--- a/base/scoped_handle_win.h
+++ b/base/scoped_handle_win.h
@@ -130,8 +130,12 @@ class ScopedHDC {
private:
void Close() {
+#ifdef NOGDI
+ assert(false);
+#else
if (hdc_)
DeleteDC(hdc_);
+#endif // NOGDI
}
HDC hdc_;
diff --git a/base/thread.h b/base/thread.h
index 93ba037..fd7fea2 100644
--- a/base/thread.h
+++ b/base/thread.h
@@ -101,6 +101,9 @@ class Thread : PlatformThread::Delegate {
// The native thread handle.
PlatformThreadHandle thread_handle() { return thread_; }
+ // The thread ID.
+ int thread_id() const { return thread_id_; }
+
protected:
// Called just prior to starting the message loop
virtual void Init() {}
@@ -130,7 +133,7 @@ class Thread : PlatformThread::Delegate {
// by the created thread.
MessageLoop* message_loop_;
- // Our thread's ID. Used for debugging purposes.
+ // Our thread's ID.
int thread_id_;
// The name of the thread. Used for debugging purposes.
diff --git a/webkit/build/JavaScriptCore/SConscript b/webkit/build/JavaScriptCore/SConscript
index 16b228d..f0db07a 100644
--- a/webkit/build/JavaScriptCore/SConscript
+++ b/webkit/build/JavaScriptCore/SConscript
@@ -156,7 +156,6 @@ wtf_inputs = [
'$WTF_DIR/RandomNumber.cpp',
'$WTF_DIR/RefCountedLeakCounter.cpp',
'$WTF_DIR/TCSystemAlloc.cpp',
- '$WTF_DIR/Threading.cpp',
'$WTF_DIR/unicode/UTF8.cpp',
'$WTF_DIR/unicode/icu/CollatorICU.cpp',
]
diff --git a/webkit/build/JavaScriptCore/WTF.vcproj b/webkit/build/JavaScriptCore/WTF.vcproj
index 7515ad7..5467e42 100644
--- a/webkit/build/JavaScriptCore/WTF.vcproj
+++ b/webkit/build/JavaScriptCore/WTF.vcproj
@@ -334,15 +334,15 @@
>
</File>
<File
- RelativePath="..\..\..\third_party\WebKit\JavaScriptCore\wtf\Threading.cpp"
+ RelativePath="..\..\..\third_party\WebKit\JavaScriptCore\wtf\Threading.h"
>
</File>
<File
- RelativePath="..\..\..\third_party\WebKit\JavaScriptCore\wtf\Threading.h"
+ RelativePath="..\..\..\third_party\WebKit\JavaScriptCore\wtf\ThreadingWin.cpp"
>
</File>
<File
- RelativePath="..\..\..\third_party\WebKit\JavaScriptCore\wtf\ThreadingWin.cpp"
+ RelativePath="..\..\..\third_party\WebKit\JavaScriptCore\wtf\ThreadSpecific.h"
>
</File>
<File
diff --git a/webkit/build/V8Bindings/SConscript b/webkit/build/V8Bindings/SConscript
index 11aa400..ceb335f 100644
--- a/webkit/build/V8Bindings/SConscript
+++ b/webkit/build/V8Bindings/SConscript
@@ -311,6 +311,8 @@ inputs = [
'$DERIVED_DIR/V8WebKitCSSTransformValue.cpp',
'$DERIVED_DIR/V8WebKitTransitionEvent.cpp',
'$DERIVED_DIR/V8WheelEvent.cpp',
+ '$DERIVED_DIR/V8Worker.cpp',
+ '$DERIVED_DIR/V8WorkerLocation.cpp',
'$DERIVED_DIR/V8XMLHttpRequest.cpp',
'$DERIVED_DIR/V8XMLHttpRequestException.cpp',
'$DERIVED_DIR/V8XMLHttpRequestProgressEvent.cpp',
@@ -333,6 +335,7 @@ inputs = [
'$PORT_DIR/bindings/v8/ScriptCallStack.cpp',
'$PORT_DIR/bindings/v8/ScriptInstance.cpp',
'$PORT_DIR/bindings/v8/ScriptValue.cpp',
+ '$PORT_DIR/bindings/v8/Threading.cpp',
'$PORT_DIR/bindings/v8/v8_custom.cpp',
'$PORT_DIR/bindings/v8/v8_events.cpp',
'$PORT_DIR/bindings/v8/v8_helpers.cpp',
@@ -344,7 +347,9 @@ inputs = [
'$PORT_DIR/bindings/v8/v8_vectornodelist.cpp',
'$PORT_DIR/bindings/v8/V8CanvasPixelArrayCustom.cpp',
'$PORT_DIR/bindings/v8/V8MessagePortCustom.cpp',
+ '$PORT_DIR/bindings/v8/V8WorkerCustom.cpp',
'$PORT_DIR/bindings/v8/V8XMLHttpRequestCustom.cpp',
+ '$PORT_DIR/bindings/v8/WorkerScriptController.cpp',
]
if env.Bit('windows'):
diff --git a/webkit/build/V8Bindings/V8Bindings.vcproj b/webkit/build/V8Bindings/V8Bindings.vcproj
index 4d038f2..d582d80 100644
--- a/webkit/build/V8Bindings/V8Bindings.vcproj
+++ b/webkit/build/V8Bindings/V8Bindings.vcproj
@@ -2280,6 +2280,22 @@
>
</File>
<File
+ RelativePath="$(IntDir)\DerivedSources\V8Worker.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\DerivedSources\V8Worker.h"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\DerivedSources\V8WorkerLocation.cpp"
+ >
+ </File>
+ <File
+ RelativePath="$(IntDir)\DerivedSources\V8WorkerLocation.h"
+ >
+ </File>
+ <File
RelativePath="$(IntDir)\DerivedSources\V8XMLHttpRequest.cpp"
>
</File>
@@ -2561,6 +2577,10 @@
>
</File>
<File
+ RelativePath="..\..\port\bindings\v8\Threading.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\port\bindings\v8\v8_binding.h"
>
</File>
@@ -2625,9 +2645,21 @@
>
</File>
<File
+ RelativePath="..\..\port\bindings\v8\V8WorkerCustom.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\port\bindings\v8\V8XMLHttpRequestCustom.cpp"
>
</File>
+ <File
+ RelativePath="..\..\port\bindings\v8\WorkerScriptController.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\port\bindings\v8\WorkerScriptController.h"
+ >
+ </File>
</Files>
<Globals>
</Globals>
diff --git a/webkit/build/WebCore/SConscript b/webkit/build/WebCore/SConscript
index 69b170d..78b59b4 100644
--- a/webkit/build/WebCore/SConscript
+++ b/webkit/build/WebCore/SConscript
@@ -174,6 +174,12 @@ input_files = [
'$WEBCORE_DIR/dom/WebKitAnimationEvent.cpp',
'$WEBCORE_DIR/dom/WebKitTransitionEvent.cpp',
'$WEBCORE_DIR/dom/WheelEvent.cpp',
+ '$WEBCORE_DIR/dom/Worker.cpp',
+ '$WEBCORE_DIR/dom/WorkerContext.cpp',
+ '$WEBCORE_DIR/dom/WorkerLocation.cpp',
+ '$WEBCORE_DIR/dom/WorkerMessagingProxy.cpp',
+ '$WEBCORE_DIR/dom/WorkerTask.cpp',
+ '$WEBCORE_DIR/dom/WorkerThread.cpp',
'$WEBCORE_DIR/dom/XMLTokenizer.cpp',
'$WEBCORE_DIR/dom/XMLTokenizerLibxml2.cpp',
diff --git a/webkit/build/WebCore/WebCore.vcproj b/webkit/build/WebCore/WebCore.vcproj
index 6b94985..a628a06 100644
--- a/webkit/build/WebCore/WebCore.vcproj
+++ b/webkit/build/WebCore/WebCore.vcproj
@@ -4811,6 +4811,54 @@
>
</File>
<File
+ RelativePath="..\..\..\third_party\WebKit\WebCore\dom\Worker.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\third_party\WebKit\WebCore\dom\Worker.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\third_party\WebKit\WebCore\dom\WorkerContext.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\third_party\WebKit\WebCore\dom\WorkerContext.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\third_party\WebKit\WebCore\dom\WorkerLocation.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\third_party\WebKit\WebCore\dom\WorkerLocation.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\third_party\WebKit\WebCore\dom\WorkerMessagingProxy.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\third_party\WebKit\WebCore\dom\WorkerMessagingProxy.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\third_party\WebKit\WebCore\dom\WorkerTask.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\third_party\WebKit\WebCore\dom\WorkerTask.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\third_party\WebKit\WebCore\dom\WorkerThread.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\third_party\WebKit\WebCore\dom\WorkerThread.h"
+ >
+ </File>
+ <File
RelativePath="..\..\..\third_party\WebKit\WebCore\dom\XMLTokenizer.cpp"
>
</File>
diff --git a/webkit/build/port/SConscript b/webkit/build/port/SConscript
index e380b3e..295bd60 100644
--- a/webkit/build/port/SConscript
+++ b/webkit/build/port/SConscript
@@ -223,6 +223,8 @@ idl_files = [
'dom/WebKitAnimationEvent.idl',
'dom/WebKitTransitionEvent.idl',
'dom/WheelEvent.idl',
+ 'dom/Worker.idl',
+ 'dom/WorkerLocation.idl',
'html/CanvasGradient.idl',
'html/CanvasPattern.idl',
diff --git a/webkit/port/DerivedSources.make b/webkit/port/DerivedSources.make
index 8e0effa..f1cf49d 100644
--- a/webkit/port/DerivedSources.make
+++ b/webkit/port/DerivedSources.make
@@ -899,6 +899,8 @@ all : \
V8WebKitCSSTransformValue.h \
V8WebKitTransitionEvent.h \
V8WheelEvent.h \
+ V8Worker.h \
+ V8WorkerLocation.h \
V8XMLHttpRequest.h \
V8XMLHttpRequestException.h \
V8XMLHttpRequestProgressEvent.h \
diff --git a/webkit/port/bindings/scripts/CodeGeneratorV8.pm b/webkit/port/bindings/scripts/CodeGeneratorV8.pm
index c63f314..ab6be33 100644
--- a/webkit/port/bindings/scripts/CodeGeneratorV8.pm
+++ b/webkit/port/bindings/scripts/CodeGeneratorV8.pm
@@ -262,6 +262,8 @@ sub GenerateHeader
push(@headerContent, "\n#if ENABLE(SVG)\n");
} elsif (IsVideoClassName($className)) {
push(@headerContent, "\n#if ENABLE(VIDEO)\n");
+ } elsif (IsWorkerClassName($className)) {
+ push(@headerContent, "\n#if ENABLE(WORKERS)\n");
}
push(@headerContent, "\n#ifndef $className" . "_H");
@@ -310,6 +312,8 @@ END
push(@headerContent, "\n#endif // ENABLE(SVG)\n");
} elsif (IsVideoClassName($className)) {
push(@headerContent, "\n#endif // ENABLE(VIDEO)\n");
+ } elsif (IsWorkerClassName($className)) {
+ push(@headerContent, "\n#endif // ENABLE(WORKERS)\n");
}
}
@@ -1000,6 +1004,8 @@ sub GenerateImplementation
push(@implFixedHeader, "#if ENABLE(SVG)\n\n");
} elsif (IsVideoClassName($className)) {
push(@implFixedHeader, "#if ENABLE(VIDEO)\n\n");
+ } elsif (IsWorkerClassName($className)) {
+ push(@implFixedHeader, "#if ENABLE(WORKERS)\n\n");
}
if ($className =~ /^V8SVGAnimated/) {
@@ -1323,6 +1329,8 @@ END
push(@implContent, "\n#endif // ENABLE(SVG)\n");
} elsif (IsVideoClassName($className)) {
push(@implContent, "\n#endif // ENABLE(VIDEO)\n");
+ } elsif (IsWorkerClassName($className)) {
+ push(@implContent, "\n#endif // ENABLE(WORKERS)\n");
}
}
@@ -1595,6 +1603,15 @@ sub IsVideoClassName
return 0;
}
+sub IsWorkerClassName
+{
+ my $class = shift;
+ return 1 if $class eq "V8Worker";
+ return 1 if $class eq "V8WorkerLocation";
+
+ return 0;
+}
+
sub GetNativeType
{
my $type = shift;
diff --git a/webkit/port/bindings/v8/Threading.cpp b/webkit/port/bindings/v8/Threading.cpp
new file mode 100644
index 0000000..f005c76
--- /dev/null
+++ b/webkit/port/bindings/v8/Threading.cpp
@@ -0,0 +1,96 @@
+// Copyright (c) 2009, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+
+#include "Threading.h"
+#undef LOG
+
+#include "base/message_loop.h"
+#include "base/task.h"
+
+namespace WTF {
+
+struct NewThreadContext {
+ NewThreadContext(ThreadFunction entryPoint, void* data, const char* name)
+ : entryPoint(entryPoint)
+ , data(data)
+ , name(name)
+ { }
+
+ ThreadFunction entryPoint;
+ void* data;
+ std::string name;
+
+ Mutex creationMutex;
+};
+
+static void* threadEntryPoint(void* contextData)
+{
+ NewThreadContext* context = reinterpret_cast<NewThreadContext*>(contextData);
+
+ // Block until our creating thread has completed any extra setup work
+ {
+ MutexLocker locker(context->creationMutex);
+ }
+
+ // Run via Chrome's message loop
+ MessageLoop message_loop;
+ message_loop.set_thread_name(context->name);
+ message_loop.PostTask(FROM_HERE,
+ NewRunnableFunction(context->entryPoint, context->data));
+ message_loop.Run();
+
+ delete context;
+
+ return NULL;
+}
+
+ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char* name)
+{
+ NewThreadContext* context = new NewThreadContext(entryPoint, data, name);
+
+ // Prevent the thread body from executing until we've established the thread identifier
+ MutexLocker locker(context->creationMutex);
+
+ return createThreadInternal(threadEntryPoint, context, name);
+}
+
+#if PLATFORM(MAC) || PLATFORM(WIN)
+
+// This function is deprecated but needs to be kept around for backward
+// compatibility. Use the 3-argument version of createThread above.
+
+ThreadIdentifier createThread(ThreadFunction entryPoint, void* data)
+{
+ return createThread(entryPoint, data, 0);
+}
+#endif
+
+} // namespace WTF
diff --git a/webkit/port/bindings/v8/V8WorkerCustom.cpp b/webkit/port/bindings/v8/V8WorkerCustom.cpp
new file mode 100644
index 0000000..0d44c5a
--- /dev/null
+++ b/webkit/port/bindings/v8/V8WorkerCustom.cpp
@@ -0,0 +1,276 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "v8_binding.h"
+#include "v8_custom.h"
+#include "v8_events.h"
+#include "v8_proxy.h"
+
+#include "V8Document.h"
+#include "V8HTMLDocument.h"
+
+#include "ExceptionCode.h"
+#include "MessagePort.h"
+#include "Worker.h"
+
+namespace WebCore {
+
+CALLBACK_FUNC_DECL(WorkerConstructor) {
+ INC_STATS(L"DOM.Worker.Constructor");
+
+ if (!args.IsConstructCall()) {
+ V8Proxy::ThrowError(V8Proxy::TYPE_ERROR,
+ "DOM object constructor cannot be called as a function.");
+ return v8::Undefined();
+ }
+
+ if (args.Length() == 0) {
+ V8Proxy::ThrowError(V8Proxy::SYNTAX_ERROR, "Not enough arguments");
+ return v8::Undefined();
+ }
+
+ v8::TryCatch try_catch;
+ v8::Handle<v8::String> script_url = args[0]->ToString();
+ if (try_catch.HasCaught()) {
+ v8::ThrowException(try_catch.Exception());
+ return v8::Undefined();
+ }
+ if (script_url.IsEmpty()) {
+ return v8::Undefined();
+ }
+
+ // Get the document.
+ Frame* frame = V8Proxy::retrieveFrame();
+ if (!frame)
+ return v8::Undefined();
+ Document* document = frame->document();
+
+ // Create the worker object.
+ // Note: it's OK to let this RefPtr go out of scope because we also call
+ // SetDOMWrapper(), which effectively holds a reference to obj.
+ ExceptionCode ec = 0;
+ RefPtr<Worker> obj = Worker::create(
+ ToWebCoreString(script_url), document, ec);
+
+ // Setup the standard wrapper object internal fields.
+ v8::Handle<v8::Object> wrapper_object = args.Holder();
+ V8Proxy::SetDOMWrapper(
+ wrapper_object, V8ClassIndex::WORKER, obj.get());
+
+ obj->ref();
+ V8Proxy::SetJSWrapperForDOMObject(
+ obj.get(), v8::Persistent<v8::Object>::New(wrapper_object));
+
+ return wrapper_object;
+}
+
+// TODO(mbelshe) - merge these with XHR's CreateHiddenXHRDependency
+
+// Use an array to hold dependents. It works like a ref-counted scheme.
+// A value can be added more than once to the xhr object.
+static void CreateHiddenDependency(v8::Local<v8::Object> object,
+ v8::Local<v8::Value> value) {
+ ASSERT(V8Proxy::GetDOMWrapperType(object) ==
+ V8ClassIndex::WORKER);
+ v8::Local<v8::Value> cache =
+ object->GetInternalField(V8Custom::kWorkerRequestCacheIndex);
+ if (cache->IsNull() || cache->IsUndefined()) {
+ cache = v8::Array::New();
+ object->SetInternalField(V8Custom::kWorkerRequestCacheIndex, cache);
+ }
+
+ v8::Local<v8::Array> cache_array = v8::Local<v8::Array>::Cast(cache);
+ cache_array->Set(v8::Integer::New(cache_array->Length()), value);
+}
+
+static void RemoveHiddenDependency(v8::Local<v8::Object> object,
+ v8::Local<v8::Value> value) {
+ ASSERT(V8Proxy::GetDOMWrapperType(object) == V8ClassIndex::WORKER);
+ v8::Local<v8::Value> cache =
+ object->GetInternalField(V8Custom::kWorkerRequestCacheIndex);
+ ASSERT(cache->IsArray());
+ v8::Local<v8::Array> cache_array = v8::Local<v8::Array>::Cast(cache);
+ for (int i = cache_array->Length() - 1; i >= 0; i--) {
+ v8::Local<v8::Value> cached = cache_array->Get(v8::Integer::New(i));
+ if (cached->StrictEquals(value)) {
+ cache_array->Delete(i);
+ return;
+ }
+ }
+
+ // We should only get here if we try to remove an event listener that was
+ // never added.
+}
+
+ACCESSOR_GETTER(WorkerOnmessage) {
+ INC_STATS(L"DOM.Worker.onmessage._get");
+ Worker* imp = V8Proxy::ToNativeObject<Worker>(
+ V8ClassIndex::WORKER, info.Holder());
+ if (imp->onmessage()) {
+ V8ObjectEventListener* listener =
+ static_cast<V8ObjectEventListener*>(imp->onmessage());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ return v8_listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(WorkerOnmessage) {
+ INC_STATS(L"DOM.Worker.onmessage._set");
+ Worker* imp = V8Proxy::ToNativeObject<Worker>(
+ V8ClassIndex::WORKER, info.Holder());
+ V8ObjectEventListener* old_listener =
+ static_cast<V8ObjectEventListener*>(imp->onmessage());
+ if (value->IsNull()) {
+ if (old_listener) {
+ v8::Local<v8::Object> old_v8_listener = old_listener->GetListenerObject();
+ RemoveHiddenDependency(info.Holder(), old_v8_listener);
+ }
+
+ // Clear the listener
+ imp->setOnmessage(0);
+
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(imp->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener =
+ proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ if (old_listener) {
+ v8::Local<v8::Object> old_v8_listener =
+ old_listener->GetListenerObject();
+ RemoveHiddenDependency(info.Holder(), old_v8_listener);
+ }
+
+ imp->setOnmessage(listener);
+ CreateHiddenDependency(info.Holder(), value);
+ }
+ }
+}
+
+ACCESSOR_GETTER(WorkerOnerror) {
+ INC_STATS(L"DOM.Worker.onerror._get");
+ Worker* imp = V8Proxy::ToNativeObject<Worker>(
+ V8ClassIndex::WORKER, info.Holder());
+ if (imp->onerror()) {
+ V8ObjectEventListener* listener =
+ static_cast<V8ObjectEventListener*>(imp->onerror());
+ v8::Local<v8::Object> v8_listener = listener->GetListenerObject();
+ return v8_listener;
+ }
+ return v8::Undefined();
+}
+
+ACCESSOR_SETTER(WorkerOnerror) {
+ INC_STATS(L"DOM.Worker.onerror._set");
+ Worker* imp = V8Proxy::ToNativeObject<Worker>(
+ V8ClassIndex::WORKER, info.Holder());
+ V8ObjectEventListener* old_listener =
+ static_cast<V8ObjectEventListener*>(imp->onerror());
+ if (value->IsNull()) {
+ if (old_listener) {
+ v8::Local<v8::Object> old_v8_listener =
+ old_listener->GetListenerObject();
+ RemoveHiddenDependency(info.Holder(), old_v8_listener);
+ }
+
+ // Clear the listener
+ imp->setOnerror(0);
+ } else {
+ V8Proxy* proxy = V8Proxy::retrieve(imp->scriptExecutionContext());
+ if (!proxy)
+ return;
+
+ RefPtr<EventListener> listener =
+ proxy->FindOrCreateObjectEventListener(value, false);
+ if (listener) {
+ if (old_listener) {
+ v8::Local<v8::Object> old_v8_listener = old_listener->GetListenerObject();
+ RemoveHiddenDependency(info.Holder(), old_v8_listener);
+ }
+
+ imp->setOnerror(listener);
+ CreateHiddenDependency(info.Holder(), value);
+ }
+ }
+}
+
+CALLBACK_FUNC_DECL(WorkerAddEventListener) {
+ INC_STATS(L"DOM.Worker.addEventListener()");
+ Worker* imp = V8Proxy::ToNativeObject<Worker>(
+ V8ClassIndex::WORKER, args.Holder());
+
+ V8Proxy* proxy = V8Proxy::retrieve(imp->scriptExecutionContext());
+ if (!proxy)
+ return v8::Undefined();
+
+ RefPtr<EventListener> listener =
+ proxy->FindOrCreateObjectEventListener(args[1], false);
+ if (listener) {
+ String type = ToWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ imp->addEventListener(type, listener, useCapture);
+
+ CreateHiddenDependency(args.Holder(), args[1]);
+ }
+ return v8::Undefined();
+}
+
+CALLBACK_FUNC_DECL(WorkerRemoveEventListener) {
+ INC_STATS(L"DOM.Worker.removeEventListener()");
+ Worker* imp = V8Proxy::ToNativeObject<Worker>(
+ V8ClassIndex::WORKER, args.Holder());
+
+ V8Proxy* proxy = V8Proxy::retrieve(imp->scriptExecutionContext());
+ if (!proxy)
+ return v8::Undefined(); // probably leaked
+
+ RefPtr<EventListener> listener =
+ proxy->FindObjectEventListener(args[1], false);
+
+ if (listener) {
+ String type = ToWebCoreString(args[0]);
+ bool useCapture = args[2]->BooleanValue();
+ imp->removeEventListener(type, listener.get(), useCapture);
+
+ RemoveHiddenDependency(args.Holder(), args[1]);
+ }
+
+ return v8::Undefined();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/webkit/port/bindings/v8/WorkerScriptController.cpp b/webkit/port/bindings/v8/WorkerScriptController.cpp
new file mode 100644
index 0000000..9e38c04
--- /dev/null
+++ b/webkit/port/bindings/v8/WorkerScriptController.cpp
@@ -0,0 +1,124 @@
+// Copyright (c) 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "WorkerScriptController.h"
+
+#include "ScriptSourceCode.h"
+#include "ScriptValue.h"
+#include "v8_proxy.h"
+#include "WorkerContext.h"
+#include "WorkerMessagingProxy.h"
+#include "WorkerThread.h"
+
+namespace WebCore {
+
+WorkerScriptController::WorkerScriptController(WorkerContext* workerContext)
+ : m_workerContext(workerContext)
+ , m_executionForbidden(false)
+{
+}
+
+WorkerScriptController::~WorkerScriptController()
+{
+ Dispose();
+}
+
+void WorkerScriptController::Dispose()
+{
+ if (!m_context.IsEmpty()) {
+ m_context.Dispose();
+ m_context.Clear();
+ }
+}
+
+void WorkerScriptController::InitContextIfNeeded()
+{
+ // Bail out if the context has already been initialized.
+ if (!m_context.IsEmpty())
+ return;
+
+ // Create a new environment
+ v8::Persistent<v8::ObjectTemplate> global_template;
+ m_context = v8::Context::New(NULL, global_template);
+
+ // TODO (jianli): to initialize the context.
+}
+
+ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode)
+{
+ {
+ MutexLocker lock(m_sharedDataMutex);
+ if (m_executionForbidden)
+ return ScriptValue();
+ }
+
+ v8::Local<v8::Value> result;
+ {
+ v8::Locker locker;
+ v8::HandleScope hs;
+
+ InitContextIfNeeded();
+ v8::Context::Scope scope(m_context);
+
+ v8::Local<v8::String> code = v8ExternalString(sourceCode.source());
+ v8::Handle<v8::Script> script =
+ V8Proxy::CompileScript(code,
+ sourceCode.url().string(),
+ sourceCode.startLine() - 1);
+
+ // TODO (jianli): handle infinite recursion.
+
+ result = script->Run();
+
+ if (V8Proxy::HandleOutOfMemory())
+ return ScriptValue();
+ }
+
+ m_workerContext->thread()->messagingProxy()->
+ reportWorkerThreadActivity(m_workerContext->hasPendingActivity());
+
+ return ScriptValue(result);
+}
+
+void WorkerScriptController::forbidExecution()
+{
+ // This function is called from another thread.
+ MutexLocker lock(m_sharedDataMutex);
+ m_executionForbidden = true;
+
+ Dispose();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
diff --git a/webkit/port/bindings/v8/WorkerScriptController.h b/webkit/port/bindings/v8/WorkerScriptController.h
new file mode 100644
index 0000000..a66e080
--- /dev/null
+++ b/webkit/port/bindings/v8/WorkerScriptController.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef WorkerScriptController_h
+#define WorkerScriptController_h
+
+#if ENABLE(WORKERS)
+
+#include "v8.h"
+
+namespace WebCore {
+
+ class ScriptSourceCode;
+ class ScriptValue;
+ class WorkerContext;
+
+ class WorkerScriptController {
+ public:
+ WorkerScriptController(WorkerContext*);
+ ~WorkerScriptController();
+
+ ScriptValue evaluate(const ScriptSourceCode&);
+
+ void forbidExecution();
+
+ private:
+ void InitContextIfNeeded();
+ void Dispose();
+
+ WorkerContext* m_workerContext;
+ v8::Persistent<v8::Context> m_context;
+
+ Mutex m_sharedDataMutex;
+ bool m_executionForbidden;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(WORKERS)
+
+#endif // WorkerScriptController_h
diff --git a/webkit/port/bindings/v8/v8_custom.h b/webkit/port/bindings/v8/v8_custom.h
index 1dd2858..3d23b26 100644
--- a/webkit/port/bindings/v8/v8_custom.h
+++ b/webkit/port/bindings/v8/v8_custom.h
@@ -83,6 +83,13 @@ class V8Custom {
static const int kMessagePortInternalFieldCount =
kDefaultWrapperInternalFieldCount + 2;
+#if ENABLE(WORKERS)
+ static const int kWorkerRequestCacheIndex =
+ kDefaultWrapperInternalFieldCount + 0;
+ static const int kWorkerInternalFieldCount =
+ kDefaultWrapperInternalFieldCount + 1;
+#endif
+
static const int kDOMWindowLocationIndex =
kDefaultWrapperInternalFieldCount + 0;
static const int kDOMWindowNavigatorIndex =
@@ -406,6 +413,15 @@ DECLARE_CALLBACK(SVGElementInstanceAddEventListener)
DECLARE_CALLBACK(SVGElementInstanceRemoveEventListener)
#endif
+// Worker
+#if ENABLE(WORKERS)
+DECLARE_PROPERTY_ACCESSOR(WorkerOnmessage)
+DECLARE_PROPERTY_ACCESSOR(WorkerOnerror)
+DECLARE_CALLBACK(WorkerConstructor)
+DECLARE_CALLBACK(WorkerAddEventListener)
+DECLARE_CALLBACK(WorkerRemoveEventListener)
+#endif
+
#undef DECLARE_INDEXED_ACCESS_CHECK
#undef DECLARE_NAMED_ACCESS_CHECK
diff --git a/webkit/port/bindings/v8/v8_index.cpp b/webkit/port/bindings/v8/v8_index.cpp
index 6f93171..5eb1f81 100644
--- a/webkit/port/bindings/v8/v8_index.cpp
+++ b/webkit/port/bindings/v8/v8_index.cpp
@@ -354,6 +354,11 @@
#include "V8TimeRanges.h"
#endif
+#if ENABLE(WORKERS)
+#include "V8Worker.h"
+#include "V8WorkerLocation.h"
+#endif
+
namespace WebCore {
FunctionTemplateFactory V8ClassIndex::GetFactory(V8WrapperType type) {
diff --git a/webkit/port/bindings/v8/v8_index.h b/webkit/port/bindings/v8/v8_index.h
index 171f690..0f6fc1f 100644
--- a/webkit/port/bindings/v8/v8_index.h
+++ b/webkit/port/bindings/v8/v8_index.h
@@ -26,6 +26,14 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
#define VIDEO_NONNODE_TYPES(V)
#endif
+#if ENABLE(WORKERS)
+#define WORKER_NONNODE_WRAPPER_TYPES(V) \
+ V(WORKER, Worker) \
+ V(WORKERLOCATION, WorkerLocation)
+#else
+#define WORKER_NONNODE_WRAPPER_TYPES(V)
+#endif
+
#define DOM_NODE_TYPES(V) \
V(ATTR, Attr) \
V(CHARACTERDATA, CharacterData) \
@@ -319,8 +327,8 @@ typedef v8::Persistent<v8::FunctionTemplate> (*FunctionTemplateFactory)();
V(XPATHRESULT, XPathResult) \
V(XSLTPROCESSOR, XSLTProcessor) \
ACTIVE_DOM_OBJECT_TYPES(V) \
- VIDEO_NONNODE_TYPES(V)
-
+ VIDEO_NONNODE_TYPES(V) \
+ WORKER_NONNODE_WRAPPER_TYPES(V)
#define DOM_OBJECT_TYPES(V) \
DOM_OBJECT_TYPES_1(V) \
diff --git a/webkit/port/bindings/v8/v8_proxy.cpp b/webkit/port/bindings/v8/v8_proxy.cpp
index b100ae6..913bad2 100644
--- a/webkit/port/bindings/v8/v8_proxy.cpp
+++ b/webkit/port/bindings/v8/v8_proxy.cpp
@@ -192,6 +192,11 @@
#include "V8SVGPODTypeWrapper.h"
#endif // SVG
+#if ENABLE(WORKERS)
+#include "Worker.h"
+#include "WorkerLocation.h"
+#endif // WORKERS
+
#if ENABLE(XPATH)
#include "XPathEvaluator.h"
#endif
@@ -1772,6 +1777,18 @@ v8::Persistent<v8::FunctionTemplate> V8Proxy::GetTemplate(
break;
}
+#if ENABLE(WORKERS)
+ case V8ClassIndex::WORKER: {
+ // Reserve one more internal field for keeping event listeners.
+ v8::Local<v8::ObjectTemplate> instance_template =
+ desc->InstanceTemplate();
+ instance_template->SetInternalFieldCount(
+ V8Custom::kWorkerInternalFieldCount);
+ desc->SetCallHandler(USE_CALLBACK(WorkerConstructor));
+ break;
+ }
+#endif // WORKERS
+
// The following objects are created from JavaScript.
case V8ClassIndex::DOMPARSER:
desc->SetCallHandler(USE_CALLBACK(DOMParserConstructor));