Changeset 95751 in webkit


Ignore:
Timestamp:
Sep 22, 2011 2:22:17 PM (13 years ago)
Author:
barraclough@apple.com
Message:

Implement Function.prototype.bind
https://bugs.webkit.org/show_bug.cgi?id=26382

Reviewed by Sam Weinig.

Source/JavaScriptCore:

This patch provides a basic functional implementation
for Function.bind. It should (hopefully!) be fully
functionally correct, and the bound functions can be
called to quickly (since they are a subclass of
JSFunction, not InternalFunction), but we'll probably
want to follow up with some optimization work to keep
bound calls in JIT code.

(JSC::JITThunks::hostFunctionStub):

  • jit/JITStubs.h:
  • jsc.cpp:

(GlobalObject::addFunction):

  • runtime/CommonIdentifiers.h:
  • runtime/ConstructData.h:
  • runtime/Executable.h:

(JSC::NativeExecutable::NativeExecutable):

  • runtime/FunctionPrototype.cpp:

(JSC::FunctionPrototype::addFunctionProperties):
(JSC::functionProtoFuncBind):

  • runtime/FunctionPrototype.h:
  • runtime/JSBoundFunction.cpp: Added.

(JSC::boundFunctionCall):
(JSC::boundFunctionConstruct):
(JSC::JSBoundFunction::create):
(JSC::JSBoundFunction::hasInstance):
(JSC::JSBoundFunction::getOwnPropertySlot):
(JSC::JSBoundFunction::getOwnPropertyDescriptor):
(JSC::JSBoundFunction::JSBoundFunction):
(JSC::JSBoundFunction::finishCreation):

  • runtime/JSBoundFunction.h: Added.

(JSC::JSBoundFunction::targetFunction):
(JSC::JSBoundFunction::boundThis):
(JSC::JSBoundFunction::boundArgs):
(JSC::JSBoundFunction::createStructure):

  • runtime/JSFunction.cpp:

(JSC::JSFunction::create):
(JSC::JSFunction::finishCreation):
(JSC::createDescriptorForThrowingProperty):
(JSC::JSFunction::getOwnPropertySlot):

  • runtime/JSFunction.h:
  • runtime/JSGlobalData.cpp:

(JSC::JSGlobalData::getHostFunction):

  • runtime/JSGlobalData.h:
  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::reset):
(JSC::JSGlobalObject::visitChildren):

  • runtime/JSGlobalObject.h:

(JSC::JSGlobalObject::boundFunctionStructure):

  • runtime/Lookup.cpp:

(JSC::setUpStaticFunctionSlot):

Source/WebCore:

Test: fast/js/function-bind.html

  • bindings/js/JSDOMBinding.cpp:

(WebCore::objectToStringFunctionGetter):

  • bindings/js/JSDOMWindowCustom.cpp:

(WebCore::nonCachingStaticFunctionGetter):

  • bindings/js/JSHistoryCustom.cpp:

(WebCore::nonCachingStaticBackFunctionGetter):
(WebCore::nonCachingStaticForwardFunctionGetter):
(WebCore::nonCachingStaticGoFunctionGetter):

  • bindings/js/JSLocationCustom.cpp:

(WebCore::nonCachingStaticReplaceFunctionGetter):
(WebCore::nonCachingStaticReloadFunctionGetter):
(WebCore::nonCachingStaticAssignFunctionGetter):

  • Function::create no longer requires functionStructure() to be passed.

LayoutTests:

We now pass Function.bind tests.

  • fast/js/Object-getOwnPropertyNames-expected.txt:
  • fast/js/basic-strict-mode-expected.txt:
  • fast/js/function-bind-expected.txt: Added.
  • fast/js/function-bind.html: Added.
  • fast/js/mozilla/strict/15.3.4.5-expected.txt:
  • fast/js/script-tests/function-bind.js: Added.
  • ietestcenter/Javascript/15.2.3.3-4-38-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-0-1-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-0-2-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-13.b-1-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-13.b-2-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-13.b-3-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-13.b-4-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-13.b-5-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-15-1-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-15-2-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-16-1-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-2-1-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-2-2-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-2-3-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-2-4-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-2-5-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-2-6-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-2-7-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-2-8-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-2-9-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-8-1-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-8-2-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-9-1-expected.txt:
  • ietestcenter/Javascript/15.3.4.5-9-2-expected.txt:
Location:
trunk
Files:
5 added
58 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r95750 r95751  
     12011-09-22  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Implement Function.prototype.bind
     4        https://bugs.webkit.org/show_bug.cgi?id=26382
     5
     6        Reviewed by Sam Weinig.
     7
     8        We now pass Function.bind tests.
     9
     10        * fast/js/Object-getOwnPropertyNames-expected.txt:
     11        * fast/js/basic-strict-mode-expected.txt:
     12        * fast/js/function-bind-expected.txt: Added.
     13        * fast/js/function-bind.html: Added.
     14        * fast/js/mozilla/strict/15.3.4.5-expected.txt:
     15        * fast/js/script-tests/function-bind.js: Added.
     16        * ietestcenter/Javascript/15.2.3.3-4-38-expected.txt:
     17        * ietestcenter/Javascript/15.3.4.5-0-1-expected.txt:
     18        * ietestcenter/Javascript/15.3.4.5-0-2-expected.txt:
     19        * ietestcenter/Javascript/15.3.4.5-13.b-1-expected.txt:
     20        * ietestcenter/Javascript/15.3.4.5-13.b-2-expected.txt:
     21        * ietestcenter/Javascript/15.3.4.5-13.b-3-expected.txt:
     22        * ietestcenter/Javascript/15.3.4.5-13.b-4-expected.txt:
     23        * ietestcenter/Javascript/15.3.4.5-13.b-5-expected.txt:
     24        * ietestcenter/Javascript/15.3.4.5-15-1-expected.txt:
     25        * ietestcenter/Javascript/15.3.4.5-15-2-expected.txt:
     26        * ietestcenter/Javascript/15.3.4.5-16-1-expected.txt:
     27        * ietestcenter/Javascript/15.3.4.5-2-1-expected.txt:
     28        * ietestcenter/Javascript/15.3.4.5-2-2-expected.txt:
     29        * ietestcenter/Javascript/15.3.4.5-2-3-expected.txt:
     30        * ietestcenter/Javascript/15.3.4.5-2-4-expected.txt:
     31        * ietestcenter/Javascript/15.3.4.5-2-5-expected.txt:
     32        * ietestcenter/Javascript/15.3.4.5-2-6-expected.txt:
     33        * ietestcenter/Javascript/15.3.4.5-2-7-expected.txt:
     34        * ietestcenter/Javascript/15.3.4.5-2-8-expected.txt:
     35        * ietestcenter/Javascript/15.3.4.5-2-9-expected.txt:
     36        * ietestcenter/Javascript/15.3.4.5-8-1-expected.txt:
     37        * ietestcenter/Javascript/15.3.4.5-8-2-expected.txt:
     38        * ietestcenter/Javascript/15.3.4.5-9-1-expected.txt:
     39        * ietestcenter/Javascript/15.3.4.5-9-2-expected.txt:
     40
    1412011-09-22  David Hyatt  <hyatt@apple.com>
    242
  • trunk/LayoutTests/fast/js/Object-getOwnPropertyNames-expected.txt

    r88315 r95751  
    4444PASS getSortedOwnPropertyNames(Object.prototype) is ['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']
    4545PASS getSortedOwnPropertyNames(Function) is ['length', 'name', 'prototype']
    46 PASS getSortedOwnPropertyNames(Function.prototype) is ['apply', 'call', 'constructor', 'length', 'name', 'toString']
     46FAIL getSortedOwnPropertyNames(Function.prototype) should be apply,call,constructor,length,name,toString. Was apply,bind,call,constructor,length,name,toString.
    4747PASS getSortedOwnPropertyNames(Array) is ['isArray', 'length', 'name', 'prototype']
    4848PASS getSortedOwnPropertyNames(Array.prototype) is ['concat', 'constructor', 'every', 'filter', 'forEach', 'indexOf', 'join', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift']
  • trunk/LayoutTests/fast/js/basic-strict-mode-expected.txt

    r90265 r95751  
    5757PASS (function (){'use strict'; arguments.callee; })() threw exception TypeError: Unable to access callee of strict mode function.
    5858PASS (function (){'use strict'; arguments.caller; })() threw exception TypeError: Unable to access caller of strict mode function.
    59 PASS (function f(){'use strict'; f.arguments; })() threw exception TypeError: Can't access arguments object of a strict mode function.
     59PASS (function f(){'use strict'; f.arguments; })() threw exception TypeError: Cannot access arguments property of a strict mode function.
    6060PASS (function f(){'use strict'; f.caller; })() threw exception TypeError: Cannot access caller property of a strict mode function.
    6161PASS (function f(){'use strict'; f.arguments=5; })() threw exception TypeError: Cannot access arguments property of a strict mode function.
     
    6363PASS (function (arg){'use strict'; arguments.callee; })() threw exception TypeError: Unable to access callee of strict mode function.
    6464PASS (function (arg){'use strict'; arguments.caller; })() threw exception TypeError: Unable to access caller of strict mode function.
    65 PASS (function f(arg){'use strict'; f.arguments; })() threw exception TypeError: Can't access arguments object of a strict mode function.
     65PASS (function f(arg){'use strict'; f.arguments; })() threw exception TypeError: Cannot access arguments property of a strict mode function.
    6666PASS (function f(arg){'use strict'; f.caller; })() threw exception TypeError: Cannot access caller property of a strict mode function.
    6767PASS (function f(arg){'use strict'; f.arguments=5; })() threw exception TypeError: Cannot access arguments property of a strict mode function.
  • trunk/LayoutTests/fast/js/mozilla/strict/15.3.4.5-expected.txt

    r78731 r95751  
    1 CONSOLE MESSAGE: line 12: TypeError: 'undefined' is not a function (evaluating 'strict.bind(true)')
    2 FAIL successfullyParsed should be true (of type boolean). Was undefined (of type undefined).
     1PASS true === true
     2PASS 42 === 42
     3PASS  ===
     4PASS null === null
     5PASS undefined === undefined
     6PASS [object Object] === [object Object]
     7PASS true === true
     8PASS true === true
     9PASS true === true
     10PASS [object DOMWindow] === [object DOMWindow]
     11PASS [object DOMWindow] === [object DOMWindow]
     12PASS [object Object] === [object Object]
     13 PASSED!
     14PASS successfullyParsed is true
    315
    416TEST COMPLETE
  • trunk/LayoutTests/ietestcenter/Javascript/15.2.3.3-4-38-expected.txt

    r62810 r95751  
    55
    66PASS ES5Harness.preconditionPassed is true
    7 FAIL ES5Harness.testPassed should be true. Was false.
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-0-1-expected.txt

    r62810 r95751  
    55
    66PASS ES5Harness.preconditionPassed is true
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-0-2-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
    77FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
    88PASS successfullyParsed is true
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-13.b-1-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-13.b-2-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-13.b-3-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-13.b-4-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-13.b-5-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-15-1-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-15-2-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-16-1-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-2-1-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-2-2-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-2-3-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-2-4-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-2-5-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-2-6-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-2-7-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-2-8-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-2-9-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-8-1-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-8-2-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-9-1-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/LayoutTests/ietestcenter/Javascript/15.3.4.5-9-2-expected.txt

    r62810 r95751  
    44
    55
    6 FAIL ES5Harness.preconditionPassed should be true (of type boolean). Was undefined (of type undefined).
    7 FAIL ES5Harness.testPassed should be true (of type boolean). Was undefined (of type undefined).
     6PASS ES5Harness.preconditionPassed is true
     7PASS ES5Harness.testPassed is true
    88PASS successfullyParsed is true
    99
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r95681 r95751  
    124124    runtime/JSCell.cpp
    125125    runtime/JSFunction.cpp
     126    runtime/JSBoundFunction.cpp
    126127    runtime/JSGlobalData.cpp
    127128    runtime/JSGlobalObject.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r95742 r95751  
     12011-09-22  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Implement Function.prototype.bind
     4        https://bugs.webkit.org/show_bug.cgi?id=26382
     5
     6        Reviewed by Sam Weinig.
     7
     8        This patch provides a basic functional implementation
     9        for Function.bind. It should (hopefully!) be fully
     10        functionally correct, and the bound functions can be
     11        called to quickly (since they are a subclass of
     12        JSFunction, not InternalFunction), but we'll probably
     13        want to follow up with some optimization work to keep
     14        bound calls in JIT code.
     15
     16        * JavaScriptCore.JSVALUE32_64only.exp:
     17        * JavaScriptCore.JSVALUE64only.exp:
     18        * JavaScriptCore.exp:
     19        * JavaScriptCore.xcodeproj/project.pbxproj:
     20        * jit/JITStubs.cpp:
     21        (JSC::JITThunks::hostFunctionStub):
     22        * jit/JITStubs.h:
     23        * jsc.cpp:
     24        (GlobalObject::addFunction):
     25        * runtime/CommonIdentifiers.h:
     26        * runtime/ConstructData.h:
     27        * runtime/Executable.h:
     28        (JSC::NativeExecutable::NativeExecutable):
     29        * runtime/FunctionPrototype.cpp:
     30        (JSC::FunctionPrototype::addFunctionProperties):
     31        (JSC::functionProtoFuncBind):
     32        * runtime/FunctionPrototype.h:
     33        * runtime/JSBoundFunction.cpp: Added.
     34        (JSC::boundFunctionCall):
     35        (JSC::boundFunctionConstruct):
     36        (JSC::JSBoundFunction::create):
     37        (JSC::JSBoundFunction::hasInstance):
     38        (JSC::JSBoundFunction::getOwnPropertySlot):
     39        (JSC::JSBoundFunction::getOwnPropertyDescriptor):
     40        (JSC::JSBoundFunction::JSBoundFunction):
     41        (JSC::JSBoundFunction::finishCreation):
     42        * runtime/JSBoundFunction.h: Added.
     43        (JSC::JSBoundFunction::targetFunction):
     44        (JSC::JSBoundFunction::boundThis):
     45        (JSC::JSBoundFunction::boundArgs):
     46        (JSC::JSBoundFunction::createStructure):
     47        * runtime/JSFunction.cpp:
     48        (JSC::JSFunction::create):
     49        (JSC::JSFunction::finishCreation):
     50        (JSC::createDescriptorForThrowingProperty):
     51        (JSC::JSFunction::getOwnPropertySlot):
     52        * runtime/JSFunction.h:
     53        * runtime/JSGlobalData.cpp:
     54        (JSC::JSGlobalData::getHostFunction):
     55        * runtime/JSGlobalData.h:
     56        * runtime/JSGlobalObject.cpp:
     57        (JSC::JSGlobalObject::reset):
     58        (JSC::JSGlobalObject::visitChildren):
     59        * runtime/JSGlobalObject.h:
     60        (JSC::JSGlobalObject::boundFunctionStructure):
     61        * runtime/Lookup.cpp:
     62        (JSC::setUpStaticFunctionSlot):
     63
    1642011-09-22  Oliver Hunt  <oliver@apple.com>
    265
  • trunk/Source/JavaScriptCore/GNUmakefile.list.am

    r95681 r95751  
    348348        Source/JavaScriptCore/runtime/JSFunction.cpp \
    349349        Source/JavaScriptCore/runtime/JSFunction.h \
     350        Source/JavaScriptCore/runtime/JSBoundFunction.cpp \
     351        Source/JavaScriptCore/runtime/JSBoundFunction.h \
    350352        Source/JavaScriptCore/runtime/JSGlobalData.cpp \
    351353        Source/JavaScriptCore/runtime/JSGlobalData.h \
  • trunk/Source/JavaScriptCore/JavaScriptCore.JSVALUE32_64only.exp

    r94376 r95751  
    1 __ZN3JSC12JSGlobalData15getHostFunctionEPFxPNS_9ExecStateEE
     1__ZN3JSC10JSFunction6createEPNS_9ExecStateEPNS_14JSGlobalObjectEiRKNS_10IdentifierEPFxS2_ES9_
  • trunk/Source/JavaScriptCore/JavaScriptCore.JSVALUE64only.exp

    r94376 r95751  
    1 __ZN3JSC12JSGlobalData15getHostFunctionEPFPvPNS_9ExecStateEE
     1__ZN3JSC10JSFunction6createEPNS_9ExecStateEPNS_14JSGlobalObjectEiRKNS_10IdentifierEPFPvS2_ESA_
  • trunk/Source/JavaScriptCore/JavaScriptCore.exp

    r95559 r95751  
    110110__ZN3JSC10Identifier4fromEPNS_9ExecStateEj
    111111__ZN3JSC10Identifier8toUInt32ERKNS_7UStringERb
    112 __ZN3JSC10JSFunction14finishCreationEPNS_9ExecStateEiRKNS_10IdentifierEPNS_14ExecutableBaseE
    113112__ZN3JSC10JSFunction4nameEPNS_9ExecStateE
    114113__ZN3JSC10JSFunction6s_infoE
     
    230229__ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE
    231230__ZN3JSC25evaluateInGlobalCallFrameERKNS_7UStringERNS_7JSValueEPNS_14JSGlobalObjectE
     231__ZN3JSC29callHostFunctionAsConstructorEPNS_9ExecStateE
    232232__ZN3JSC30isTerminatedExecutionExceptionENS_7JSValueE
    233233__ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
  • trunk/Source/JavaScriptCore/JavaScriptCore.gypi

    r95559 r95751  
    8484            'runtime/JSCell.h',
    8585            'runtime/JSFunction.h',
     86            'runtime/JSBoundFunction.h',
    8687            'runtime/JSGlobalData.h',
    8788            'runtime/JSGlobalObject.h',
     
    517518            'runtime/JSCell.cpp',
    518519            'runtime/JSFunction.cpp',
     520            'runtime/JSBoundFunction.cpp',
    519521            'runtime/JSGlobalData.cpp',
    520522            'runtime/JSGlobalObject.cpp',
  • trunk/Source/JavaScriptCore/JavaScriptCore.pro

    r95681 r95751  
    154154    runtime/JSCell.cpp \
    155155    runtime/JSFunction.cpp \
     156    runtime/JSBoundFunction.cpp \
    156157    runtime/JSGlobalData.cpp \
    157158    runtime/JSGlobalObject.cpp \
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj

    r95681 r95751  
    799799                        </File>
    800800                        <File
     801                                RelativePath="..\..\runtime\JSBoundFunction.cpp"
     802                                >
     803                        </File>
     804                        <File
     805                                RelativePath="..\..\runtime\JSBoundFunction.h"
     806                                >
     807                        </File>
     808                        <File
    801809                                RelativePath="..\..\runtime\JSGlobalData.cpp"
    802810                                >
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r95681 r95751  
    362362                86ECA3FA132DF25A002B2AD7 /* DFGScoreBoard.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ECA3F9132DF25A002B2AD7 /* DFGScoreBoard.h */; };
    363363                86F38859121130CA007A7CE3 /* AtomicStringHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F38858121130CA007A7CE3 /* AtomicStringHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
     364                86FA9E91142BBB2E001773B7 /* JSBoundFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86FA9E8F142BBB2D001773B7 /* JSBoundFunction.cpp */; };
     365                86FA9E92142BBB2E001773B7 /* JSBoundFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 86FA9E90142BBB2E001773B7 /* JSBoundFunction.h */; };
    364366                90213E3D123A40C200D422F3 /* MemoryStatistics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90213E3B123A40C200D422F3 /* MemoryStatistics.cpp */; };
    365367                90213E3E123A40C200D422F3 /* MemoryStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 90213E3C123A40C200D422F3 /* MemoryStatistics.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    11161118                86ECA3F9132DF25A002B2AD7 /* DFGScoreBoard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGScoreBoard.h; path = dfg/DFGScoreBoard.h; sourceTree = "<group>"; };
    11171119                86F38858121130CA007A7CE3 /* AtomicStringHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AtomicStringHash.h; path = text/AtomicStringHash.h; sourceTree = "<group>"; };
     1120                86FA9E8F142BBB2D001773B7 /* JSBoundFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSBoundFunction.cpp; sourceTree = "<group>"; };
     1121                86FA9E90142BBB2E001773B7 /* JSBoundFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBoundFunction.h; sourceTree = "<group>"; };
    11181122                90213E3B123A40C200D422F3 /* MemoryStatistics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryStatistics.cpp; sourceTree = "<group>"; };
    11191123                90213E3C123A40C200D422F3 /* MemoryStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryStatistics.h; sourceTree = "<group>"; };
     
    20672071                                93ADFCE60CCBD7AC00D30B08 /* JSArray.cpp */,
    20682072                                938772E5038BFE19008635CE /* JSArray.h */,
     2073                                86FA9E8F142BBB2D001773B7 /* JSBoundFunction.cpp */,
     2074                                86FA9E90142BBB2E001773B7 /* JSBoundFunction.h */,
    20692075                                A791EF270F11E07900AE1F68 /* JSByteArray.cpp */,
    20702076                                A791EF260F11E07900AE1F68 /* JSByteArray.h */,
     
    28122818                                1A08277A142168D70090CCAC /* BinarySemaphore.h in Headers */,
    28132819                                A70456B01427FB910037DA68 /* AllocationSpace.h in Headers */,
     2820                                86FA9E92142BBB2E001773B7 /* JSBoundFunction.h in Headers */,
    28142821                        );
    28152822                        runOnlyForDeploymentPostprocessing = 0;
     
    33353342                                1A082779142168D70090CCAC /* BinarySemaphore.cpp in Sources */,
    33363343                                A70456B11427FB950037DA68 /* AllocationSpace.cpp in Sources */,
     3344                                86FA9E91142BBB2E001773B7 /* JSBoundFunction.cpp in Sources */,
    33373345                        );
    33383346                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r95681 r95751  
    20872087    ASSERT(typeInfo.type() != UnspecifiedType);
    20882088
    2089     if (!typeInfo.overridesHasInstance()) {
    2090         if (!value.isObject())
    2091             return JSValue::encode(jsBoolean(false));
    2092 
    2093         if (!proto.isObject()) {
    2094             throwError(callFrame, createTypeError(callFrame, "instanceof called on an object with an invalid prototype property."));
    2095             VM_THROW_EXCEPTION();
    2096         }
    2097     }
     2089    if (!typeInfo.overridesHasInstance() && !value.isObject())
     2090        return JSValue::encode(jsBoolean(false));
    20982091
    20992092    JSValue result = jsBoolean(asObject(baseVal)->hasInstance(callFrame, value, proto));
     
    38273820}
    38283821
    3829 NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function)
     3822NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function, NativeFunction constructor)
    38303823{
    38313824    std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap->add(function, Weak<NativeExecutable>());
    38323825    if (!*entry.first->second)
    3833         entry.first->second.set(*globalData, NativeExecutable::create(*globalData, JIT::compileCTINativeCall(globalData, function), function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct()), callHostFunctionAsConstructor, DFG::NoIntrinsic));
     3826        entry.first->second.set(*globalData, NativeExecutable::create(*globalData, JIT::compileCTINativeCall(globalData, function), function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct()), constructor, DFG::NoIntrinsic));
    38343827    return entry.first->second.get();
    38353828}
  • trunk/Source/JavaScriptCore/jit/JITStubs.h

    r95388 r95751  
    298298        MacroAssemblerCodeRef ctiStub(JSGlobalData*, ThunkGenerator);
    299299
    300         NativeExecutable* hostFunctionStub(JSGlobalData*, NativeFunction);
     300        NativeExecutable* hostFunctionStub(JSGlobalData*, NativeFunction, NativeFunction constructor);
    301301        NativeExecutable* hostFunctionStub(JSGlobalData*, NativeFunction, ThunkGenerator, DFG::Intrinsic);
    302302
  • trunk/Source/JavaScriptCore/jsc.cpp

    r95318 r95751  
    191191    {
    192192        Identifier identifier(globalExec(), name);
    193         putDirect(globalData, identifier, JSFunction::create(globalExec(), this, functionStructure(), arguments, identifier, function));
     193        putDirect(globalData, identifier, JSFunction::create(globalExec(), this, arguments, identifier, function));
    194194    }
    195195};
  • trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h

    r89109 r95751  
    3434    macro(apply) \
    3535    macro(arguments) \
     36    macro(bind) \
    3637    macro(call) \
    3738    macro(callee) \
  • trunk/Source/JavaScriptCore/runtime/ConstructData.h

    r60708 r95751  
    3030#define ConstructData_h
    3131
     32#include "CallData.h"
    3233#include "JSValue.h"
    3334
     
    4647    };
    4748
    48     typedef EncodedJSValue (JSC_HOST_CALL *NativeConstructor)(ExecState*);
    49 
    5049    union ConstructData {
    5150        struct {
    52             NativeConstructor function;
     51            NativeFunction function;
    5352        } native;
    5453        struct {
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r95681 r95751  
    202202
    203203        NativeFunction function() { return m_function; }
     204        NativeFunction constructor() { return m_constructor; }
    204205
    205206        static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(LeafType, StructureFlags), &s_info); }
     
    229230 
    230231    private:
    231 #if ENABLE(JIT)
    232232        NativeExecutable(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
    233233            : ExecutableBase(globalData, globalData.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST)
     
    236236        {
    237237        }
    238 #else
    239         NativeExecutable(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor)
    240             : ExecutableBase(globalData, globalData.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST)
    241             , m_function(function)
    242             , m_constructor(constructor)
    243         {
    244         }
    245 #endif
    246238
    247239        NativeFunction m_function;
    248         // Probably should be a NativeConstructor, but this will currently require rewriting the JIT
    249         // trampoline. It may be easier to make NativeFunction be passed 'this' as a part of the ArgList.
    250240        NativeFunction m_constructor;
    251241       
     
    639629    }
    640630
     631    inline NativeFunction JSFunction::nativeConstructor()
     632    {
     633        ASSERT(isHostFunction());
     634        return static_cast<NativeExecutable*>(m_executable.get())->constructor();
     635    }
     636
    641637    inline bool isHostFunction(JSValue value, NativeFunction nativeFunction)
    642638    {
  • trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp

    r95318 r95751  
    2424#include "Arguments.h"
    2525#include "JSArray.h"
     26#include "JSBoundFunction.h"
    2627#include "JSFunction.h"
    2728#include "JSString.h"
     
    3738static EncodedJSValue JSC_HOST_CALL functionProtoFuncApply(ExecState*);
    3839static EncodedJSValue JSC_HOST_CALL functionProtoFuncCall(ExecState*);
     40static EncodedJSValue JSC_HOST_CALL functionProtoFuncBind(ExecState*);
    3941
    4042FunctionPrototype::FunctionPrototype(JSGlobalObject* globalObject, Structure* structure)
     
    4951}
    5052
    51 void FunctionPrototype::addFunctionProperties(ExecState* exec, JSGlobalObject* globalObject, Structure* functionStructure, JSFunction** callFunction, JSFunction** applyFunction)
    52 {
    53     JSFunction* toStringFunction = JSFunction::create(exec, globalObject, functionStructure, 0, exec->propertyNames().toString, functionProtoFuncToString);
     53void FunctionPrototype::addFunctionProperties(ExecState* exec, JSGlobalObject* globalObject, JSFunction** callFunction, JSFunction** applyFunction)
     54{
     55    JSFunction* toStringFunction = JSFunction::create(exec, globalObject, 0, exec->propertyNames().toString, functionProtoFuncToString);
    5456    putDirectWithoutTransition(exec->globalData(), exec->propertyNames().toString, toStringFunction, DontEnum);
    5557
    56     *applyFunction = JSFunction::create(exec, globalObject, functionStructure, 2, exec->propertyNames().apply, functionProtoFuncApply);
     58    *applyFunction = JSFunction::create(exec, globalObject, 2, exec->propertyNames().apply, functionProtoFuncApply);
    5759    putDirectWithoutTransition(exec->globalData(), exec->propertyNames().apply, *applyFunction, DontEnum);
    5860
    59     *callFunction = JSFunction::create(exec, globalObject, functionStructure, 1, exec->propertyNames().call, functionProtoFuncCall);
     61    *callFunction = JSFunction::create(exec, globalObject, 1, exec->propertyNames().call, functionProtoFuncCall);
    6062    putDirectWithoutTransition(exec->globalData(), exec->propertyNames().call, *callFunction, DontEnum);
     63
     64    JSFunction* bindFunction = JSFunction::create(exec, globalObject, 0, exec->propertyNames().bind, functionProtoFuncBind);
     65    putDirectWithoutTransition(exec->globalData(), exec->propertyNames().bind, bindFunction, DontEnum);
    6166}
    6267
     
    154159}
    155160
     161// 15.3.4.5 Function.prototype.bind (thisArg [, arg1 [, arg2, ...]])
     162EncodedJSValue JSC_HOST_CALL functionProtoFuncBind(ExecState* exec)
     163{
     164    JSGlobalObject* globalObject = exec->callee()->globalObject();
     165
     166    // Let Target be the this value.
     167    JSValue target = exec->hostThisValue();
     168
     169    // If IsCallable(Target) is false, throw a TypeError exception.
     170    CallData callData;
     171    CallType callType = getCallData(target, callData);
     172    if (callType == CallTypeNone)
     173        return throwVMTypeError(exec);
     174    // Primitive values are not callable.
     175    ASSERT(target.isObject());
     176    JSObject* targetObject = asObject(target);
     177
     178    // Let A be a new (possibly empty) internal list of all of the argument values provided after thisArg (arg1, arg2 etc), in order.
     179    size_t numBoundArgs = exec->argumentCount() > 1 ? exec->argumentCount() - 1 : 0;
     180    JSArray* boundArgs = JSArray::create(exec->globalData(), globalObject->arrayStructure(), numBoundArgs, CreateCompact);
     181    for (size_t i = 0; i < numBoundArgs; ++i)
     182        boundArgs->uncheckedSetIndex(exec->globalData(), i, exec->argument(i + 1));
     183    boundArgs->setLength(numBoundArgs);
     184
     185    // If the [[Class]] internal property of Target is "Function", then ...
     186    // Else set the length own property of F to 0.
     187    unsigned length = 0;
     188    if (targetObject->inherits(&JSFunction::s_info)) {
     189        ASSERT(target.get(exec, exec->propertyNames().length).isNumber());
     190        // a. Let L be the length property of Target minus the length of A.
     191        // b. Set the length own property of F to either 0 or L, whichever is larger.
     192        unsigned targetLength = (unsigned)target.get(exec, exec->propertyNames().length).uncheckedGetNumber();
     193        if (targetLength > numBoundArgs)
     194            length = targetLength - numBoundArgs;
     195    }
     196
     197    Identifier name(exec, target.get(exec, exec->propertyNames().name).toString(exec));
     198
     199    return JSValue::encode(JSBoundFunction::create(exec, globalObject, targetObject, exec->argument(0), boundArgs, length, name));
     200}
     201
    156202} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/FunctionPrototype.h

    r95108 r95751  
    3737        }
    3838       
    39         void addFunctionProperties(ExecState*, JSGlobalObject*, Structure* functionStructure, JSFunction** callFunction, JSFunction** applyFunction);
     39        void addFunctionProperties(ExecState*, JSGlobalObject*, JSFunction** callFunction, JSFunction** applyFunction);
    4040       
    4141        static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto)
  • trunk/Source/JavaScriptCore/runtime/JSFunction.cpp

    r95205 r95751  
    3131#include "ExceptionHelpers.h"
    3232#include "FunctionPrototype.h"
     33#include "JSArray.h"
    3334#include "JSGlobalObject.h"
    3435#include "JSNotAnObject.h"
     
    5758}
    5859
     60JSFunction* JSFunction::create(ExecState* exec, JSGlobalObject* globalObject, int length, const Identifier& name, NativeFunction nativeFunction, NativeFunction nativeConstructor)
     61{
     62    NativeExecutable* executable = exec->globalData().getHostFunction(nativeFunction, nativeConstructor);
     63    JSFunction* function = new (allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, globalObject, globalObject->functionStructure());
     64    // Can't do this during initialization because getHostFunction might do a GC allocation.
     65    function->finishCreation(exec, executable, length, name);
     66    return function;
     67}
     68
     69JSFunction* JSFunction::create(ExecState* exec, JSGlobalObject* globalObject, int length, const Identifier& name, NativeExecutable* nativeExecutable)
     70{
     71    JSFunction* function = new (allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, globalObject, globalObject->functionStructure());
     72    function->finishCreation(exec, nativeExecutable, length, name);
     73    return function;
     74}
     75
    5976JSFunction::JSFunction(VPtrStealingHackType)
    6077    : Base(VPtrStealingHack)
     
    7693}
    7794
    78 void JSFunction::finishCreation(ExecState* exec, int length, const Identifier& name, ExecutableBase* executable)
     95void JSFunction::finishCreation(ExecState* exec, NativeExecutable* executable, int length, const Identifier& name)
    7996{
    8097    Base::finishCreation(exec->globalData());
     
    89106    Base::finishCreation(exec->globalData());
    90107    ASSERT(inherits(&s_info));
     108
     109    // Switching the structure here is only safe if we currently have the function structure!
     110    ASSERT(structure() == scopeChainNode->globalObject->functionStructure());
    91111    setStructure(exec->globalData(), scopeChainNode->globalObject->namedFunctionStructure());
    92112    putDirectOffset(exec->globalData(), scopeChainNode->globalObject->functionNameOffset(), executable->nameValue());
     
    98118}
    99119
    100 static const char* StrictModeCallerAccessError = "Cannot access caller property of a strict mode function";
    101 static const char* StrictModeArgumentsAccessError = "Cannot access arguments property of a strict mode function";
    102 
    103 static void createDescriptorForThrowingProperty(ExecState* exec, PropertyDescriptor& descriptor, const char* message)
     120const char* StrictModeCallerAccessError = "Cannot access caller property of a strict mode function";
     121const char* StrictModeArgumentsAccessError = "Cannot access arguments property of a strict mode function";
     122
     123void createDescriptorForThrowingProperty(ExecState* exec, PropertyDescriptor& descriptor, const char* message)
    104124{
    105125    JSValue thrower = createTypeErrorFunction(exec, message);
     
    197217    if (propertyName == exec->propertyNames().arguments) {
    198218        if (jsExecutable()->isStrictMode()) {
    199             throwTypeError(exec, "Can't access arguments object of a strict mode function");
     219            throwTypeError(exec, StrictModeArgumentsAccessError);
    200220            slot.setValue(jsNull());
    201221            return true;
     
    312332ConstructType JSFunction::getConstructData(ConstructData& constructData)
    313333{
    314     if (isHostFunction())
    315         return ConstructTypeNone;
     334    if (isHostFunction()) {
     335        constructData.native.function = nativeConstructor();
     336        return ConstructTypeHost;
     337    }
    316338    constructData.js.functionExecutable = jsExecutable();
    317339    constructData.js.scopeChain = scope();
  • trunk/Source/JavaScriptCore/runtime/JSFunction.h

    r95666 r95751  
    4242    EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);
    4343
     44    extern const char* StrictModeCallerAccessError;
     45    extern const char* StrictModeArgumentsAccessError;
     46
     47    void createDescriptorForThrowingProperty(ExecState*, PropertyDescriptor&, const char* message);
     48
    4449    class JSFunction : public JSNonFinalObject {
    4550        friend class JIT;
     
    4752        friend class JSGlobalData;
    4853
    49         JSFunction(ExecState*, JSGlobalObject*, Structure*);
    50         JSFunction(ExecState*, FunctionExecutable*, ScopeChainNode*);
    51        
    5254    public:
    5355        typedef JSNonFinalObject Base;
    5456
    55         static JSFunction* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, int length, const Identifier& name, NativeFunction nativeFunction)
    56         {
    57             ASSERT(structure->globalObject());
    58             ASSERT(structure->globalObject() == globalObject);
    59            
    60             ExecutableBase* executable = (ExecutableBase*)exec->globalData().getHostFunction(nativeFunction);
    61             JSFunction* function = new (allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, globalObject, structure);
    62             // Can't do this during initialization because getHostFunction might do a GC allocation.
    63             function->finishCreation(exec, length, name, executable);
    64             return function;
    65         }
    66 
    67         static JSFunction* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, int length, const Identifier& name, NativeExecutable* nativeExecutable)
    68         {
    69             ASSERT(structure->globalObject());
    70             ASSERT(structure->globalObject() == globalObject);
    71 
    72             JSFunction* function = new (allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, globalObject, structure);
    73             function->finishCreation(exec, length, name, (ExecutableBase*)nativeExecutable);
    74             return function;
    75         }
     57        static JSFunction* create(ExecState*, JSGlobalObject*, int length, const Identifier& name, NativeFunction nativeFunction, NativeFunction nativeConstructor = callHostFunctionAsConstructor);
     58        static JSFunction* create(ExecState*, JSGlobalObject*, int length, const Identifier& name, NativeExecutable* nativeExecutable);
    7659
    7760        static JSFunction* create(ExecState* exec, FunctionExecutable* executable, ScopeChainNode* scopeChain)
     
    124107
    125108        NativeFunction nativeFunction();
     109        NativeFunction nativeConstructor();
    126110
    127111        virtual ConstructType getConstructData(ConstructData&);
     
    141125        const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
    142126
    143         void finishCreation(ExecState*, int length, const Identifier& name, ExecutableBase*);
     127        JSFunction(ExecState*, JSGlobalObject*, Structure*);
     128        JSFunction(ExecState*, FunctionExecutable*, ScopeChainNode*);
     129       
     130        void finishCreation(ExecState*, NativeExecutable*, int length, const Identifier& name);
    144131        void finishCreation(ExecState*, FunctionExecutable*, ScopeChainNode*);
     132
     133        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
     134        virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
     135        virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode = ExcludeDontEnumProperties);
     136
     137        virtual void visitChildren(SlotVisitor&);
    145138
    146139    private:
     
    149142        bool isHostFunctionNonInline() const;
    150143
    151         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    152         virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
    153         virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
    154144        virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
    155145        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
    156 
    157         virtual void visitChildren(SlotVisitor&);
    158146
    159147        static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.cpp

    r95559 r95751  
    396396
    397397#if ENABLE(JIT)
    398 NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function)
    399 {
    400     return jitStubs->hostFunctionStub(this, function);
     398NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function, NativeFunction constructor)
     399{
     400    return jitStubs->hostFunctionStub(this, function, constructor);
    401401}
    402402NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function, ThunkGenerator generator, DFG::Intrinsic intrinsic)
     
    405405}
    406406#else
    407 NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function)
    408 {
    409     return NativeExecutable::create(*this, function, callHostFunctionAsConstructor);
     407NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function, NativeFunction constructor)
     408{
     409    return NativeExecutable::create(*this, function, constructor);
    410410}
    411411#endif
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.h

    r95510 r95751  
    220220        NativeExecutable* getHostFunction(NativeFunction, ThunkGenerator, DFG::Intrinsic);
    221221#endif
    222         NativeExecutable* getHostFunction(NativeFunction);
     222        NativeExecutable* getHostFunction(NativeFunction, NativeFunction constructor);
    223223
    224224        TimeoutChecker timeoutChecker;
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r95318 r95751  
    4747#include "FunctionConstructor.h"
    4848#include "FunctionPrototype.h"
     49#include "JSBoundFunction.h"
    4950#include "JSFunction.h"
    5051#include "JSGlobalObjectFunctions.h"
     
    188189    m_functionPrototype.set(exec->globalData(), this, FunctionPrototype::create(exec, this, FunctionPrototype::createStructure(exec->globalData(), this, jsNull()))); // The real prototype will be set once ObjectPrototype is created.
    189190    m_functionStructure.set(exec->globalData(), this, JSFunction::createStructure(exec->globalData(), this, m_functionPrototype.get()));
     191    m_boundFunctionStructure.set(exec->globalData(), this, JSBoundFunction::createStructure(exec->globalData(), this, m_functionPrototype.get()));
    190192    m_namedFunctionStructure.set(exec->globalData(), this, Structure::addPropertyTransition(exec->globalData(), m_functionStructure.get(), exec->globalData().propertyNames->name, DontDelete | ReadOnly | DontEnum, 0, m_functionNameOffset));
    191193    m_internalFunctionStructure.set(exec->globalData(), this, InternalFunction::createStructure(exec->globalData(), this, m_functionPrototype.get()));
    192194    JSFunction* callFunction = 0;
    193195    JSFunction* applyFunction = 0;
    194     m_functionPrototype->addFunctionProperties(exec, this, m_functionStructure.get(), &callFunction, &applyFunction);
     196    m_functionPrototype->addFunctionProperties(exec, this, &callFunction, &applyFunction);
    195197    m_callFunction.set(exec->globalData(), this, callFunction);
    196198    m_applyFunction.set(exec->globalData(), this, applyFunction);
     
    281283    putDirectWithoutTransition(exec->globalData(), Identifier(exec, "URIError"), m_URIErrorConstructor.get(), DontEnum);
    282284
    283     m_evalFunction.set(exec->globalData(), this, JSFunction::create(exec, this, m_functionStructure.get(), 1, exec->propertyNames().eval, globalFuncEval));
     285    m_evalFunction.set(exec->globalData(), this, JSFunction::create(exec, this, 1, exec->propertyNames().eval, globalFuncEval));
    284286    putDirectWithoutTransition(exec->globalData(), exec->propertyNames().eval, m_evalFunction.get(), DontEnum);
    285287
     
    350352    visitIfNeeded(visitor, &m_errorStructure);
    351353    visitIfNeeded(visitor, &m_functionStructure);
     354    visitIfNeeded(visitor, &m_boundFunctionStructure);
    352355    visitIfNeeded(visitor, &m_namedFunctionStructure);
    353356    visitIfNeeded(visitor, &m_numberObjectStructure);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h

    r95326 r95751  
    117117        WriteBarrier<Structure> m_errorStructure;
    118118        WriteBarrier<Structure> m_functionStructure;
     119        WriteBarrier<Structure> m_boundFunctionStructure;
    119120        WriteBarrier<Structure> m_namedFunctionStructure;
    120121        size_t m_functionNameOffset;
     
    229230        Structure* errorStructure() const { return m_errorStructure.get(); }
    230231        Structure* functionStructure() const { return m_functionStructure.get(); }
     232        Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(); }
    231233        Structure* namedFunctionStructure() const { return m_namedFunctionStructure.get(); }
    232234        size_t functionNameOffset() const { return m_functionNameOffset; }
  • trunk/Source/JavaScriptCore/runtime/Lookup.cpp

    r95399 r95751  
    8383#if ENABLE(JIT)
    8484        if (entry->generator() || entry->intrinsic() != DFG::NoIntrinsic)
    85             function = JSFunction::create(exec, globalObject, globalObject->functionStructure(), entry->functionLength(), propertyName, exec->globalData().getHostFunction(entry->function(), entry->generator(), entry->intrinsic()));
     85            function = JSFunction::create(exec, globalObject, entry->functionLength(), propertyName, exec->globalData().getHostFunction(entry->function(), entry->generator(), entry->intrinsic()));
    8686        else
    8787#endif
    88             function = JSFunction::create(exec, globalObject, globalObject->functionStructure(), entry->functionLength(), propertyName, entry->function());
     88            function = JSFunction::create(exec, globalObject, entry->functionLength(), propertyName, entry->function());
    8989
    9090        thisObj->putDirect(exec->globalData(), propertyName, function, entry->attributes());
  • trunk/Source/WebCore/ChangeLog

    r95750 r95751  
     12011-09-22  Gavin Barraclough  <barraclough@apple.com>
     2
     3        Implement Function.prototype.bind
     4        https://bugs.webkit.org/show_bug.cgi?id=26382
     5
     6        Reviewed by Sam Weinig.
     7
     8        Test: fast/js/function-bind.html
     9
     10        * bindings/js/JSDOMBinding.cpp:
     11        (WebCore::objectToStringFunctionGetter):
     12        * bindings/js/JSDOMWindowCustom.cpp:
     13        (WebCore::nonCachingStaticFunctionGetter):
     14        * bindings/js/JSHistoryCustom.cpp:
     15        (WebCore::nonCachingStaticBackFunctionGetter):
     16        (WebCore::nonCachingStaticForwardFunctionGetter):
     17        (WebCore::nonCachingStaticGoFunctionGetter):
     18        * bindings/js/JSLocationCustom.cpp:
     19        (WebCore::nonCachingStaticReplaceFunctionGetter):
     20        (WebCore::nonCachingStaticReloadFunctionGetter):
     21        (WebCore::nonCachingStaticAssignFunctionGetter):
     22            - Function::create no longer requires functionStructure() to be passed.
    1232011-09-22  David Hyatt  <hyatt@apple.com>
    224
  • trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp

    r95271 r95751  
    309309JSValue objectToStringFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
    310310{
    311     return JSFunction::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->functionStructure(), 0, propertyName, objectProtoFuncToString);
     311    return JSFunction::create(exec, exec->lexicalGlobalObject(), 0, propertyName, objectProtoFuncToString);
    312312}
    313313
  • trunk/Source/WebCore/bindings/js/JSDOMWindowCustom.cpp

    r95678 r95751  
    9393JSValue nonCachingStaticFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
    9494{
    95     return JSFunction::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->functionStructure(), length, propertyName, nativeFunction);
     95    return JSFunction::create(exec, exec->lexicalGlobalObject(), length, propertyName, nativeFunction);
    9696}
    9797
  • trunk/Source/WebCore/bindings/js/JSHistoryCustom.cpp

    r91194 r95751  
    4141static JSValue nonCachingStaticBackFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
    4242{
    43     return JSFunction::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->functionStructure(), 0, propertyName, jsHistoryPrototypeFunctionBack);
     43    return JSFunction::create(exec, exec->lexicalGlobalObject(), 0, propertyName, jsHistoryPrototypeFunctionBack);
    4444}
    4545
    4646static JSValue nonCachingStaticForwardFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
    4747{
    48     return JSFunction::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->functionStructure(), 0, propertyName, jsHistoryPrototypeFunctionForward);
     48    return JSFunction::create(exec, exec->lexicalGlobalObject(), 0, propertyName, jsHistoryPrototypeFunctionForward);
    4949}
    5050
    5151static JSValue nonCachingStaticGoFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
    5252{
    53     return JSFunction::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->functionStructure(), 1, propertyName, jsHistoryPrototypeFunctionGo);
     53    return JSFunction::create(exec, exec->lexicalGlobalObject(), 1, propertyName, jsHistoryPrototypeFunctionGo);
    5454}
    5555
  • trunk/Source/WebCore/bindings/js/JSLocationCustom.cpp

    r91194 r95751  
    3333static JSValue nonCachingStaticReplaceFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
    3434{
    35     return JSFunction::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->functionStructure(), 1, propertyName, jsLocationPrototypeFunctionReplace);
     35    return JSFunction::create(exec, exec->lexicalGlobalObject(), 1, propertyName, jsLocationPrototypeFunctionReplace);
    3636}
    3737
    3838static JSValue nonCachingStaticReloadFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
    3939{
    40     return JSFunction::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->functionStructure(), 0, propertyName, jsLocationPrototypeFunctionReload);
     40    return JSFunction::create(exec, exec->lexicalGlobalObject(), 0, propertyName, jsLocationPrototypeFunctionReload);
    4141}
    4242
    4343static JSValue nonCachingStaticAssignFunctionGetter(ExecState* exec, JSValue, const Identifier& propertyName)
    4444{
    45     return JSFunction::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->functionStructure(), 1, propertyName, jsLocationPrototypeFunctionAssign);
     45    return JSFunction::create(exec, exec->lexicalGlobalObject(), 1, propertyName, jsLocationPrototypeFunctionAssign);
    4646}
    4747
Note: See TracChangeset for help on using the changeset viewer.