Ignore:
Timestamp:
Mar 8, 2016, 4:01:09 PM (9 years ago)
Author:
[email protected]
Message:

Implement Function.name support for getters/setters and inferring name of function properties.
https://bugs.webkit.org/show_bug.cgi?id=154865

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

  1. toString() no longer uses the value of Function.name as the name of the function in the returned string, because ...
  1. Function.name is supposed to be configurable. Hence, it can be made writable and can be set to any JSValue, or deleted.
  1. Function.prototype.toString() is supposed to produce a string that can be

eval'ed. Hence, for JS functions, the function name in the produced
string must be a legal function name (and not some arbitrary value set in
Function.name). For example, while a number is a legal value for
Function.name, it is not legal as the function name in the toString()
string.

Instead, we'll always use the original name from the JS source that the
function was parsed from.

  1. JSFunction::name() now always return the original name, not the value of the Function.name property. As a result, it also no longer needs an ExecState* arg.

If the original name is an empty string, JSFunction::name() will use the
inferred name.

  1. For JS functions, the original name can be attained from their FunctionExecutable object.

For host/native functions (which do not have a FunctionExecutable), we get the
"original" name from its NativeExecutable.

  1. The m_hostFunctionStubMap now keys its NativeExecutable pointers using the original name, in addition to the native function and constructor pointers.

This is needed because we want a different NativeExecutable for functions with
a different name (to satisfy (3) above).

  1. Changed JSBoundFunction to store the name of its bound function in its NativeExecutable. This will later be used to generate the toString() string. It's Function.name value is eagerly initialized at construction time.
  1. Function.name for getters/setters are now prefixed with "get"/"set". This was done both for the JSBoundSlotBaseFunctions and JS definable get/set functions.
  1. Added InternalFunction::m_originalName so that we can use it to generate the toString() string. We're storing it as a JSString instead of a WTF::String only because we want InternalFunction to be continue to be trivially destructible.
  • inspector/JSInjectedScriptHost.cpp:

(Inspector::JSInjectedScriptHost::functionDetails):

  • jit/JITThunks.cpp:

(JSC::JITThunks::finalize):
(JSC::JITThunks::hostFunctionStub):

  • jit/JITThunks.h:
  • runtime/Executable.h:
  • runtime/FunctionPrototype.cpp:

(JSC::functionProtoFuncToString):

  • runtime/InternalFunction.cpp:

(JSC::InternalFunction::finishCreation):
(JSC::InternalFunction::visitChildren):
(JSC::InternalFunction::name):
(JSC::InternalFunction::displayName):

  • runtime/InternalFunction.h:
  • runtime/JSBoundFunction.cpp:

(JSC::JSBoundFunction::create):
(JSC::JSBoundFunction::visitChildren):
(JSC::JSBoundFunction::toStringName): Deleted.

  • runtime/JSBoundFunction.h:

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

  • runtime/JSBoundSlotBaseFunction.cpp:

(JSC::boundSlotBaseFunctionCall):
(JSC::JSBoundSlotBaseFunction::create):

  • runtime/JSFunction.cpp:

(JSC::JSFunction::initializeRareData):
(JSC::JSFunction::name):
(JSC::JSFunction::displayName):
(JSC::JSFunction::calculatedDisplayName):
(JSC::JSFunction::reifyName):

  • runtime/JSFunction.h:
  • tests/es6.yaml:

LayoutTests:

  • js/function-toString-vs-name-expected.txt: Added.
  • js/function-toString-vs-name.html: Added.
  • js/script-tests/function-toString-vs-name.js: Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r197308 r197815  
    664664    ConstructAbility constructAbility() const { return m_unlinkedExecutable->constructAbility(); }
    665665    bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; }
     666    bool isGetter() const { return parseMode() == SourceParseMode::GetterMode; }
     667    bool isSetter() const { return parseMode() == SourceParseMode::SetterMode; }
    666668    DerivedContextType derivedContextType() const { return m_unlinkedExecutable->derivedContextType(); }
    667669    bool isClassConstructorFunction() const { return m_unlinkedExecutable->isClassConstructorFunction(); }
    668670    const Identifier& name() { return m_unlinkedExecutable->name(); }
    669671    const Identifier& inferredName() { return m_unlinkedExecutable->inferredName(); }
     672    // FIXME: ecmaName() needs to be reimplement to be based on ES6 rules of determining the inferred
     673    // Function.name from non-computed names. https://bugs.webkit.org/show_bug.cgi?id=155203
     674    const Identifier& ecmaName() { return inferredName(); }
    670675    size_t parameterCount() const { return m_unlinkedExecutable->parameterCount(); } // Excluding 'this'!
    671676    SourceParseMode parseMode() const { return m_unlinkedExecutable->parseMode(); }
Note: See TracChangeset for help on using the changeset viewer.