Diff
Modified: trunk/LayoutTests/ChangeLog (201807 => 201808)
--- trunk/LayoutTests/ChangeLog 2016-06-08 17:21:52 UTC (rev 201807)
+++ trunk/LayoutTests/ChangeLog 2016-06-08 17:31:12 UTC (rev 201808)
@@ -1,3 +1,19 @@
+2016-06-08 Chris Dumez <cdu...@apple.com>
+
+ self.hasOwnProperty() does not work inside Web workers
+ https://bugs.webkit.org/show_bug.cgi?id=158446
+ <rdar://problem/26638397>
+
+ Reviewed by Geoffrey Garen.
+
+ Add tests to make sure that self.toString() and self.hasOwnProperty()
+ now work in workers.
+
+ * fast/workers/self-hasOwnProperty-expected.txt: Added.
+ * fast/workers/self-hasOwnProperty.html: Added.
+ * fast/workers/self-toString-expected.txt: Added.
+ * fast/workers/self-toString.html: Added.
+
2016-06-06 Antti Koivisto <an...@apple.com>
WebKit memory cache doesn't respect Vary header
Added: trunk/LayoutTests/fast/workers/self-hasOwnProperty-expected.txt (0 => 201808)
--- trunk/LayoutTests/fast/workers/self-hasOwnProperty-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/workers/self-hasOwnProperty-expected.txt 2016-06-08 17:31:12 UTC (rev 201808)
@@ -0,0 +1,12 @@
+Tests that self.hasOwnProperty() works in workers
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+self.hasOwnProperty('DedicatedWorkerGlobalScope'): true
+self.hasOwnProperty('WorkerGlobalScope'): true
+self.hasOwnProperty('navigator'): true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/workers/self-hasOwnProperty.html (0 => 201808)
--- trunk/LayoutTests/fast/workers/self-hasOwnProperty.html (rev 0)
+++ trunk/LayoutTests/fast/workers/self-hasOwnProperty.html 2016-06-08 17:31:12 UTC (rev 201808)
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<script src=""
+<script src=""
+<script>
+
+var jsTestIsAsync = true;
+
+description('Tests that self.hasOwnProperty() works in workers');
+
+var worker = createWorker();
+worker.postMessage("eval self.hasOwnProperty('DedicatedWorkerGlobalScope')");
+worker.postMessage("eval self.hasOwnProperty('WorkerGlobalScope')");
+worker.postMessage("eval self.hasOwnProperty('navigator')");
+worker.postMessage("eval DONE");
+
+worker._onmessage_ = function(evt) {
+ if (!/DONE/.test(evt.data))
+ debug(evt.data.replace(new RegExp("/.*LayoutTests"), "<...>"));
+ else
+ finishJSTest();
+};
+
+</script>
+<script src=""
Added: trunk/LayoutTests/fast/workers/self-toString-expected.txt (0 => 201808)
--- trunk/LayoutTests/fast/workers/self-toString-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/workers/self-toString-expected.txt 2016-06-08 17:31:12 UTC (rev 201808)
@@ -0,0 +1,11 @@
+Tests that self.toString() works in workers
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+self.toString(): [object DedicatedWorkerGlobalScope]
+'self: ' + self: self: [object DedicatedWorkerGlobalScope]
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/workers/self-toString.html (0 => 201808)
--- trunk/LayoutTests/fast/workers/self-toString.html (rev 0)
+++ trunk/LayoutTests/fast/workers/self-toString.html 2016-06-08 17:31:12 UTC (rev 201808)
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<script src=""
+<script src=""
+<script>
+
+var jsTestIsAsync = true;
+
+description('Tests that self.toString() works in workers');
+
+var worker = createWorker();
+worker.postMessage("eval self.toString()");
+worker.postMessage("eval 'self: ' + self");
+worker.postMessage("eval DONE");
+
+worker._onmessage_ = function(evt) {
+ if (!/DONE/.test(evt.data))
+ debug(evt.data.replace(new RegExp("/.*LayoutTests"), "<...>"));
+ else
+ finishJSTest();
+};
+
+</script>
+<script src=""
Modified: trunk/Source/_javascript_Core/ChangeLog (201807 => 201808)
--- trunk/Source/_javascript_Core/ChangeLog 2016-06-08 17:21:52 UTC (rev 201807)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-06-08 17:31:12 UTC (rev 201808)
@@ -1,3 +1,20 @@
+2016-06-08 Chris Dumez <cdu...@apple.com>
+
+ self.hasOwnProperty() does not work inside Web workers
+ https://bugs.webkit.org/show_bug.cgi?id=158446
+ <rdar://problem/26638397>
+
+ Reviewed by Geoffrey Garen.
+
+ Add a factory function to JSProxy to create a JSProxy without a target.
+ Also make the setTarget() method public so that the target can now be
+ set after creation. This is needed so that we can create a proxy for
+ JSWorkerGlobalScope, then create the JSWorkerGlobalScope object,
+ passing it the proxy and finally set the target on the proxy.
+
+ * runtime/JSProxy.h:
+ (JSC::JSProxy::create):
+
2016-06-07 Filip Pizlo <fpi...@apple.com>
Add result validation to JSAir
Modified: trunk/Source/_javascript_Core/runtime/JSProxy.h (201807 => 201808)
--- trunk/Source/_javascript_Core/runtime/JSProxy.h 2016-06-08 17:21:52 UTC (rev 201807)
+++ trunk/Source/_javascript_Core/runtime/JSProxy.h 2016-06-08 17:31:12 UTC (rev 201808)
@@ -42,6 +42,13 @@
return proxy;
}
+ static JSProxy* create(VM& vm, Structure* structure)
+ {
+ JSProxy* proxy = new (NotNull, allocateCell<JSProxy>(vm.heap)) JSProxy(vm, structure);
+ proxy->finishCreation(vm);
+ return proxy;
+ }
+
static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, JSType proxyType)
{
ASSERT(proxyType == ImpureProxyType || proxyType == PureForwardingProxyType);
@@ -53,6 +60,8 @@
JSObject* target() const { return m_target.get(); }
static ptrdiff_t targetOffset() { return OBJECT_OFFSETOF(JSProxy, m_target); }
+ JS_EXPORT_PRIVATE void setTarget(VM&, JSGlobalObject*);
+
protected:
JSProxy(VM& vm, Structure* structure)
: JSDestructibleObject(vm, structure)
@@ -72,8 +81,6 @@
JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
- JS_EXPORT_PRIVATE void setTarget(VM&, JSGlobalObject*);
-
JS_EXPORT_PRIVATE static String className(const JSObject*);
JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
JS_EXPORT_PRIVATE static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned, PropertySlot&);
Modified: trunk/Source/WebCore/ChangeLog (201807 => 201808)
--- trunk/Source/WebCore/ChangeLog 2016-06-08 17:21:52 UTC (rev 201807)
+++ trunk/Source/WebCore/ChangeLog 2016-06-08 17:31:12 UTC (rev 201808)
@@ -1,3 +1,45 @@
+2016-06-08 Chris Dumez <cdu...@apple.com>
+
+ self.hasOwnProperty() does not work inside Web workers
+ https://bugs.webkit.org/show_bug.cgi?id=158446
+ <rdar://problem/26638397>
+
+ Reviewed by Geoffrey Garen.
+
+ W3C tests for workers were severely broken on WebKit because
+ self.hasOwnProperty() did not work inside workers. The reason is that
+ hasOwnProperty() (and other methods like toString()) call toThis() in
+ StrictMode on thisValue. However, in the case of 'self' in workers,
+ self was a DedicatedWorkerGlobalScope, which is a JSGlobalObject.
+ JSGlobalObject::toThis() returns jsUndefined() when called in strict
+ mode. As a result, we would end up with exceptions such as "undefined
+ is not an object" when calling self.hasOwnProperty() in workers.
+
+ To address the problem, this patch introduces a JSProxy whose proxy
+ type is PureForwardingProxyType and whose target is the
+ WorkerGlobalScope. This JSProxy is what we expose to the _javascript_,
+ instead of the JSWorkerGlobalScope itself. As a result, toThis() now
+ behaves as expected and self.hasOwnProperty() works inside workers.
+
+ This patch greatly improves our pass rate on several W3C tests:
+ http://w3c-test.org/workers/interfaces.worker: 20 passes -> 50 passes (out of 128)
+ http://w3c-test.org/IndexedDB/interfaces.worker 0 passes -> 145 passes (out of 156)
+
+ Tests: fast/workers/self-hasOwnProperty.html
+ fast/workers/self-toString.html
+
+ * bindings/js/JSWorkerGlobalScopeBase.cpp:
+ (WebCore::JSWorkerGlobalScopeBase::finishCreation):
+ (WebCore::JSWorkerGlobalScopeBase::visitChildren):
+ (WebCore::toJS):
+ * bindings/js/JSWorkerGlobalScopeBase.h:
+ (WebCore::JSWorkerGlobalScopeBase::proxy):
+ * bindings/js/WorkerScriptController.cpp:
+ (WebCore::WorkerScriptController::initScript):
+ * bindings/scripts/CodeGeneratorJS.pm:
+ (GenerateHeader):
+ (GenerateImplementation):
+
2016-06-08 Antti Koivisto <an...@apple.com>
WebKit memory cache doesn't respect Vary header
Modified: trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeBase.cpp (201807 => 201808)
--- trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeBase.cpp 2016-06-08 17:21:52 UTC (rev 201807)
+++ trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeBase.cpp 2016-06-08 17:31:12 UTC (rev 201808)
@@ -35,6 +35,7 @@
#include "JSWorkerGlobalScope.h"
#include "Language.h"
#include "WorkerGlobalScope.h"
+#include <runtime/JSCInlines.h>
#include <runtime/JSCJSValueInlines.h>
#include <runtime/Microtask.h>
@@ -52,12 +53,22 @@
{
}
-void JSWorkerGlobalScopeBase::finishCreation(VM& vm)
+void JSWorkerGlobalScopeBase::finishCreation(VM& vm, JSProxy* proxy)
{
- Base::finishCreation(vm);
+ m_proxy.set(vm, this, proxy);
+
+ Base::finishCreation(vm, m_proxy.get());
ASSERT(inherits(info()));
}
+void JSWorkerGlobalScopeBase::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+ JSWorkerGlobalScopeBase* thisObject = jsCast<JSWorkerGlobalScopeBase*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ Base::visitChildren(thisObject, visitor);
+ visitor.append(&thisObject->m_proxy);
+}
+
void JSWorkerGlobalScopeBase::destroy(JSCell* cell)
{
static_cast<JSWorkerGlobalScopeBase*>(cell)->JSWorkerGlobalScopeBase::~JSWorkerGlobalScopeBase();
@@ -111,7 +122,7 @@
return jsNull();
JSWorkerGlobalScope* contextWrapper = script->workerGlobalScopeWrapper();
ASSERT(contextWrapper);
- return contextWrapper;
+ return contextWrapper->proxy();
}
JSDedicatedWorkerGlobalScope* toJSDedicatedWorkerGlobalScope(JSValue value)
Modified: trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeBase.h (201807 => 201808)
--- trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeBase.h 2016-06-08 17:21:52 UTC (rev 201807)
+++ trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeBase.h 2016-06-08 17:31:12 UTC (rev 201808)
@@ -43,6 +43,7 @@
DECLARE_INFO;
WorkerGlobalScope& wrapped() const { return *m_wrapped; }
+ JSC::JSProxy* proxy() const { ASSERT(m_proxy); return m_proxy.get(); }
ScriptExecutionContext* scriptExecutionContext() const;
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
@@ -61,10 +62,13 @@
protected:
JSWorkerGlobalScopeBase(JSC::VM&, JSC::Structure*, RefPtr<WorkerGlobalScope>&&);
- void finishCreation(JSC::VM&);
+ void finishCreation(JSC::VM&, JSC::JSProxy*);
+ static void visitChildren(JSC::JSCell*, JSC::SlotVisitor&);
+
private:
RefPtr<WorkerGlobalScope> m_wrapped;
+ JSC::WriteBarrier<JSC::JSProxy> m_proxy;
};
// Returns a JSWorkerGlobalScope or jsNull()
Modified: trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp (201807 => 201808)
--- trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp 2016-06-08 17:21:52 UTC (rev 201807)
+++ trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp 2016-06-08 17:31:12 UTC (rev 201808)
@@ -88,8 +88,10 @@
Structure* dedicatedContextPrototypeStructure = JSDedicatedWorkerGlobalScopePrototype::createStructure(*m_vm, 0, workerGlobalScopePrototype.get());
Strong<JSDedicatedWorkerGlobalScopePrototype> dedicatedContextPrototype(*m_vm, JSDedicatedWorkerGlobalScopePrototype::create(*m_vm, 0, dedicatedContextPrototypeStructure));
Structure* structure = JSDedicatedWorkerGlobalScope::createStructure(*m_vm, 0, dedicatedContextPrototype.get());
+ auto* proxyStructure = JSProxy::createStructure(*m_vm, nullptr, jsNull(), PureForwardingProxyType);
+ auto* proxy = JSProxy::create(*m_vm, proxyStructure);
- m_workerGlobalScopeWrapper.set(*m_vm, JSDedicatedWorkerGlobalScope::create(*m_vm, structure, static_cast<DedicatedWorkerGlobalScope&>(*m_workerGlobalScope)));
+ m_workerGlobalScopeWrapper.set(*m_vm, JSDedicatedWorkerGlobalScope::create(*m_vm, structure, static_cast<DedicatedWorkerGlobalScope&>(*m_workerGlobalScope), proxy));
workerGlobalScopePrototypeStructure->setGlobalObject(*m_vm, m_workerGlobalScopeWrapper.get());
dedicatedContextPrototypeStructure->setGlobalObject(*m_vm, m_workerGlobalScopeWrapper.get());
ASSERT(structure->globalObject() == m_workerGlobalScopeWrapper);
@@ -97,6 +99,9 @@
workerGlobalScopePrototype->structure()->setGlobalObject(*m_vm, m_workerGlobalScopeWrapper.get());
workerGlobalScopePrototype->structure()->setPrototypeWithoutTransition(*m_vm, JSEventTarget::prototype(*m_vm, m_workerGlobalScopeWrapper.get()));
dedicatedContextPrototype->structure()->setGlobalObject(*m_vm, m_workerGlobalScopeWrapper.get());
+
+ proxy->setTarget(*m_vm, m_workerGlobalScopeWrapper.get());
+ proxy->structure()->setGlobalObject(*m_vm, m_workerGlobalScopeWrapper.get());
}
ASSERT(m_workerGlobalScopeWrapper->globalObject() == m_workerGlobalScopeWrapper);
ASSERT(asObject(m_workerGlobalScopeWrapper->getPrototypeDirect())->globalObject() == m_workerGlobalScopeWrapper);
Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (201807 => 201808)
--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2016-06-08 17:21:52 UTC (rev 201807)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2016-06-08 17:31:12 UTC (rev 201808)
@@ -1101,10 +1101,10 @@
push(@headerContent, " return ptr;\n");
push(@headerContent, " }\n\n");
} elsif ($codeGenerator->InheritsInterface($interface, "WorkerGlobalScope")) {
- push(@headerContent, " static $className* create(JSC::VM& vm, JSC::Structure* structure, Ref<$implType>&& impl)\n");
+ push(@headerContent, " static $className* create(JSC::VM& vm, JSC::Structure* structure, Ref<$implType>&& impl, JSC::JSProxy* proxy)\n");
push(@headerContent, " {\n");
push(@headerContent, " $className* ptr = new (NotNull, JSC::allocateCell<$className>(vm.heap)) ${className}(vm, structure, WTFMove(impl));\n");
- push(@headerContent, " ptr->finishCreation(vm);\n");
+ push(@headerContent, " ptr->finishCreation(vm, proxy);\n");
push(@headerContent, " vm.heap.addFinalizer(ptr, destroy);\n");
push(@headerContent, " return ptr;\n");
push(@headerContent, " }\n\n");
@@ -1416,7 +1416,7 @@
if ($interfaceName eq "DOMWindow") {
push(@headerContent, " void finishCreation(JSC::VM&, JSDOMWindowShell*);\n");
} else {
- push(@headerContent, " void finishCreation(JSC::VM&);\n");
+ push(@headerContent, " void finishCreation(JSC::VM&, JSC::JSProxy*);\n");
}
}
@@ -2359,9 +2359,9 @@
push(@implContent, "{\n");
push(@implContent, " Base::finishCreation(vm, shell);\n\n");
} else {
- push(@implContent, "void ${className}::finishCreation(VM& vm)\n");
+ push(@implContent, "void ${className}::finishCreation(VM& vm, JSProxy* proxy)\n");
push(@implContent, "{\n");
- push(@implContent, " Base::finishCreation(vm);\n\n");
+ push(@implContent, " Base::finishCreation(vm, proxy);\n\n");
}
# Support for RuntimeEnabled attributes on global objects.
foreach my $attribute (@{$interface->attributes}) {