Ignore:
Timestamp:
Apr 9, 2014, 10:28:40 AM (11 years ago)
Author:
[email protected]
Message:

Rewrite Function.bind as a builtin
https://bugs.webkit.org/show_bug.cgi?id=131083

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

This change removes the existing function.bind implementation
entirely so JSBoundFunction is no more.

Instead we just return a regular JS closure with a few
private properties hanging off it that allow us to perform
the necessary bound function fakery. While most of this is
simple, a couple of key changes:

  • The parser and lexer now directly track whether they're parsing code for call or construct and convert the private name @IsConstructor into TRUETOK or FALSETOK as appropriate. This automatically gives us the ability to vary behaviour from within the builtin. It also leaves a lot of headroom for trivial future improvements.
  • The instanceof operator now uses the prototypeForHasInstance private name, and we have a helper function to ensure that all objects that need to can update their magical 'prototype' property pair correctly.
  • API/JSScriptRef.cpp:

(parseScript):

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • builtins/BuiltinExecutables.cpp:

(JSC::BuiltinExecutables::createBuiltinExecutable):

  • builtins/Function.prototype.js:

(bind.bindingFunction):
(bind.else.bindingFunction):
(bind):

  • bytecode/UnlinkedCodeBlock.cpp:

(JSC::generateFunctionCodeBlock):

  • bytecompiler/NodesCodegen.cpp:

(JSC::InstanceOfNode::emitBytecode):

  • interpreter/Interpreter.cpp:
  • parser/Lexer.cpp:

(JSC::Lexer<T>::Lexer):
(JSC::Lexer<LChar>::parseIdentifier):
(JSC::Lexer<UChar>::parseIdentifier):

  • parser/Lexer.h:
  • parser/Parser.cpp:

(JSC::Parser<LexerType>::Parser):
(JSC::Parser<LexerType>::parseInner):

  • parser/Parser.h:

(JSC::parse):

  • parser/ParserModes.h:
  • runtime/CodeCache.cpp:

(JSC::CodeCache::getGlobalCodeBlock):
(JSC::CodeCache::getFunctionExecutableFromGlobalCode):

  • runtime/CommonIdentifiers.h:
  • runtime/Completion.cpp:

(JSC::checkSyntax):

  • runtime/Executable.cpp:

(JSC::ProgramExecutable::checkSyntax):

  • runtime/FunctionPrototype.cpp:

(JSC::FunctionPrototype::addFunctionProperties):
(JSC::functionProtoFuncBind): Deleted.

  • runtime/JSBoundFunction.cpp: Removed.
  • runtime/JSBoundFunction.h: Removed.
  • runtime/JSFunction.cpp:

(JSC::RetrieveCallerFunctionFunctor::RetrieveCallerFunctionFunctor):
(JSC::RetrieveCallerFunctionFunctor::operator()):
(JSC::retrieveCallerFunction):
(JSC::JSFunction::getOwnPropertySlot):
(JSC::JSFunction::defineOwnProperty):

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::reset):

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::globalFuncSetTypeErrorAccessor):

  • runtime/JSGlobalObjectFunctions.h:
  • runtime/JSObject.h:

(JSC::JSObject::inlineGetOwnPropertySlot):

Source/WebCore:

Switch WebCore to use the helper functions when defining the
prototype properties on DOM constructors, and update bindings
tests accordingly.

  • bindings/js/JSImageConstructor.cpp:

(WebCore::JSImageConstructor::finishCreation):

  • bindings/scripts/CodeGeneratorJS.pm:

(GenerateConstructorHelperMethods):

  • bindings/scripts/test/JS/JSTestActiveDOMObject.cpp:

(WebCore::JSTestActiveDOMObjectConstructor::finishCreation):

  • bindings/scripts/test/JS/JSTestCustomNamedGetter.cpp:

(WebCore::JSTestCustomNamedGetterConstructor::finishCreation):

  • bindings/scripts/test/JS/JSTestEventConstructor.cpp:

(WebCore::JSTestEventConstructorConstructor::finishCreation):

  • bindings/scripts/test/JS/JSTestEventTarget.cpp:

(WebCore::JSTestEventTargetConstructor::finishCreation):

  • bindings/scripts/test/JS/JSTestException.cpp:

(WebCore::JSTestExceptionConstructor::finishCreation):

  • bindings/scripts/test/JS/JSTestGenerateIsReachable.cpp:

(WebCore::JSTestGenerateIsReachableConstructor::finishCreation):

  • bindings/scripts/test/JS/JSTestInterface.cpp:

(WebCore::JSTestInterfaceConstructor::finishCreation):

  • bindings/scripts/test/JS/JSTestMediaQueryListListener.cpp:

(WebCore::JSTestMediaQueryListListenerConstructor::finishCreation):

  • bindings/scripts/test/JS/JSTestNamedConstructor.cpp:

(WebCore::JSTestNamedConstructorConstructor::finishCreation):
(WebCore::JSTestNamedConstructorNamedConstructor::finishCreation):

  • bindings/scripts/test/JS/JSTestNode.cpp:

(WebCore::JSTestNodeConstructor::finishCreation):

  • bindings/scripts/test/JS/JSTestObj.cpp:

(WebCore::JSTestObjConstructor::finishCreation):

  • bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp:

(WebCore::JSTestOverloadedConstructorsConstructor::finishCreation):

  • bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp:

(WebCore::JSTestSerializedScriptValueInterfaceConstructor::finishCreation):

  • bindings/scripts/test/JS/JSTestTypedefs.cpp:

(WebCore::JSTestTypedefsConstructor::finishCreation):

  • bindings/scripts/test/JS/JSattribute.cpp:

(WebCore::JSattributeConstructor::finishCreation):

  • bindings/scripts/test/JS/JSreadonly.cpp:

(WebCore::JSreadonlyConstructor::finishCreation):

LayoutTests:

Testing.

  • js/dom/function-bind-expected.txt:
  • js/regress/function-bind-expected.txt: Added.
  • js/regress/function-bind.html: Added.
  • js/regress/script-tests/function-bind.js: Added.

(foo):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp

    r165703 r167020  
    2727
    2828#include "CallFrame.h"
     29#include "GetterSetter.h"
    2930#include "Interpreter.h"
    3031#include "JSFunction.h"
     
    806807    return JSValue::encode(jsUndefined());
    807808}
    808 
     809   
     810EncodedJSValue JSC_HOST_CALL globalFuncSetTypeErrorAccessor(ExecState* exec)
     811{
     812    JSObject* target = jsDynamicCast<JSObject*>(exec->argument(0));
     813    JSValue propertyName = exec->argument(1);
     814   
     815    // Setting __proto__ of a primitive should have no effect.
     816    if (!target || !propertyName.isString())
     817        return JSValue::encode(jsUndefined());
     818    VM& vm = exec->vm();
     819    Identifier property(exec, asString(propertyName)->getString(exec));
     820    target->putDirectNonIndexAccessor(vm, vm.propertyNames->arguments, target->globalObject()->throwTypeErrorGetterSetter(vm), DontDelete | DontEnum | Accessor);
     821    return JSValue::encode(jsUndefined());
     822}
     823   
    809824} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.