NativeExecutable cache needs to use both call and construct functions for key
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 11 Jul 2013 18:35:35 +0000 (18:35 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 11 Jul 2013 18:35:35 +0000 (18:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=118545

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

Make the native executable cache make use a key pair so we don't decide to
treat all subsequent functions as not being constructors.

* jit/JITThunks.cpp:
(JSC::JITThunks::hostFunctionStub):
* jit/JITThunks.h:
* runtime/JSBoundFunction.cpp:
(JSC::JSBoundFunction::create):
* runtime/JSCell.cpp:
(JSC::JSCell::getCallData):
(JSC::JSCell::getConstructData):

LayoutTests:

Make sure we don't decide that all bound functions aren't constructors.

* fast/js/function-bind-expected.txt:
* fast/js/script-tests/function-bind.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@152573 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/js/function-bind-expected.txt
LayoutTests/fast/js/script-tests/function-bind.js
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/jit/JITThunks.cpp
Source/JavaScriptCore/jit/JITThunks.h
Source/JavaScriptCore/runtime/JSBoundFunction.cpp
Source/JavaScriptCore/runtime/JSCell.cpp

index dcfd71d..bb54e26 100644 (file)
@@ -1,3 +1,15 @@
+2013-07-10  Oliver Hunt  <oliver@apple.com>
+
+        NativeExecutable cache needs to use both call and construct functions for key
+        https://bugs.webkit.org/show_bug.cgi?id=118545
+
+        Reviewed by Geoffrey Garen.
+
+        Make sure we don't decide that all bound functions aren't constructors.
+
+        * fast/js/function-bind-expected.txt:
+        * fast/js/script-tests/function-bind.js:
+
 2013-07-11  Andrei Bucur  <abucur@adobe.com>
 
         [CSS Regions] In a region chain with auto-height regions, lines get their length based only on the first region
index d2de454..5f4017a 100644 (file)
@@ -3,6 +3,10 @@ Tests Function.bind.
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
+PASS new (decodeURI.bind())() threw exception TypeError: 'function decodeURI() {
+    [native code]
+}' is not a constructor (evaluating 'new (decodeURI.bind())()').
+PASS (new (String.bind())('foo')).toString() is 'foo'
 PASS result is "[object Window] -> x:1, y:2"
 PASS result is "'a' -> x:'b', y:1"
 PASS result is "'a' -> x:'b', y:'c'"
index 583ccf6..18e6335 100644 (file)
@@ -1,5 +1,8 @@
 description("Tests Function.bind.");
 
+shouldThrow("new (decodeURI.bind())()");
+shouldBe("(new (String.bind())('foo')).toString()", "'foo'");
+
 var result;
 
 function F(x, y)
index 59f6669..39200f2 100644 (file)
@@ -1,3 +1,22 @@
+2013-07-10  Oliver Hunt  <oliver@apple.com>
+
+        NativeExecutable cache needs to use both call and construct functions for key
+        https://bugs.webkit.org/show_bug.cgi?id=118545
+
+        Reviewed by Geoffrey Garen.
+
+        Make the native executable cache make use a key pair so we don't decide to
+        treat all subsequent functions as not being constructors.
+
+        * jit/JITThunks.cpp:
+        (JSC::JITThunks::hostFunctionStub):
+        * jit/JITThunks.h:
+        * runtime/JSBoundFunction.cpp:
+        (JSC::JSBoundFunction::create):
+        * runtime/JSCell.cpp:
+        (JSC::JSCell::getCallData):
+        (JSC::JSCell::getConstructData):
+
 2013-07-09  Mark Lam  <mark.lam@apple.com>
 
         Gardening to unbreak builds on the Windows bot.
index 680a126..0a6ebcf 100644 (file)
@@ -71,17 +71,17 @@ MacroAssemblerCodeRef JITThunks::ctiStub(VM* vm, ThunkGenerator generator)
 
 NativeExecutable* JITThunks::hostFunctionStub(VM* vm, NativeFunction function, NativeFunction constructor)
 {
-    if (NativeExecutable* nativeExecutable = m_hostFunctionStubMap->get(function))
+    if (NativeExecutable* nativeExecutable = m_hostFunctionStubMap->get(std::make_pair(function, constructor)))
         return nativeExecutable;
 
     NativeExecutable* nativeExecutable = NativeExecutable::create(*vm, JIT::compileCTINativeCall(vm, function), function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct(vm)), constructor, NoIntrinsic);
-    weakAdd(*m_hostFunctionStubMap, function, PassWeak<NativeExecutable>(nativeExecutable));
+    weakAdd(*m_hostFunctionStubMap, std::make_pair(function, constructor), PassWeak<NativeExecutable>(nativeExecutable));
     return nativeExecutable;
 }
 
 NativeExecutable* JITThunks::hostFunctionStub(VM* vm, NativeFunction function, ThunkGenerator generator, Intrinsic intrinsic)
 {
-    if (NativeExecutable* nativeExecutable = m_hostFunctionStubMap->get(function))
+    if (NativeExecutable* nativeExecutable = m_hostFunctionStubMap->get(std::make_pair(function, callHostFunctionAsConstructor)))
         return nativeExecutable;
 
     MacroAssemblerCodeRef code;
@@ -94,7 +94,7 @@ NativeExecutable* JITThunks::hostFunctionStub(VM* vm, NativeFunction function, T
         code = JIT::compileCTINativeCall(vm, function);
 
     NativeExecutable* nativeExecutable = NativeExecutable::create(*vm, code, function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct(vm)), callHostFunctionAsConstructor, intrinsic);
-    weakAdd(*m_hostFunctionStubMap, function, PassWeak<NativeExecutable>(nativeExecutable));
+    weakAdd(*m_hostFunctionStubMap, std::make_pair(function, callHostFunctionAsConstructor), PassWeak<NativeExecutable>(nativeExecutable));
     return nativeExecutable;
 }
 
index 30d475e..73a8bed 100644 (file)
@@ -64,7 +64,7 @@ public:
 private:
     typedef HashMap<ThunkGenerator, MacroAssemblerCodeRef> CTIStubMap;
     CTIStubMap m_ctiStubMap;
-    typedef HashMap<NativeFunction, Weak<NativeExecutable> > HostFunctionStubMap;
+    typedef HashMap<pair<NativeFunction, NativeFunction>, Weak<NativeExecutable> > HostFunctionStubMap;
     OwnPtr<HostFunctionStubMap> m_hostFunctionStubMap;
 };
 
index 5c63da4..fb255d9 100644 (file)
@@ -79,7 +79,6 @@ JSBoundFunction* JSBoundFunction::create(ExecState* exec, JSGlobalObject* global
     ConstructData constructData;
     ConstructType constructType = JSC::getConstructData(targetFunction, constructData);
     bool canConstruct = constructType != ConstructTypeNone;
-
     NativeExecutable* executable = exec->vm().getHostFunction(boundFunctionCall, canConstruct ? boundFunctionConstruct : callHostFunctionAsConstructor);
     JSBoundFunction* function = new (NotNull, allocateCell<JSBoundFunction>(*exec->heap())) JSBoundFunction(exec, globalObject, globalObject->boundFunctionStructure(), targetFunction, boundThis, boundArgs);
 
index da142e4..07b3331 100644 (file)
@@ -66,13 +66,19 @@ const JSObject* JSCell::getObject() const
     return isObject() ? static_cast<const JSObject*>(this) : 0;
 }
 
-CallType JSCell::getCallData(JSCell*, CallData&)
+CallType JSCell::getCallData(JSCell*, CallData& callData)
 {
+    callData.js.functionExecutable = 0;
+    callData.js.scope = 0;
+    callData.native.function = 0;
     return CallTypeNone;
 }
 
-ConstructType JSCell::getConstructData(JSCell*, ConstructData&)
+ConstructType JSCell::getConstructData(JSCell*, ConstructData& constructData)
 {
+    constructData.js.functionExecutable = 0;
+    constructData.js.scope = 0;
+    constructData.native.function = 0;
     return ConstructTypeNone;
 }