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/jit/JITThunks.cpp

    r195000 r197815  
    8080{
    8181    auto* nativeExecutable = jsCast<NativeExecutable*>(handle.get().asCell());
    82     weakRemove(*m_hostFunctionStubMap, std::make_pair(nativeExecutable->function(), nativeExecutable->constructor()), nativeExecutable);
     82    weakRemove(*m_hostFunctionStubMap, std::make_tuple(nativeExecutable->function(), nativeExecutable->constructor(), nativeExecutable->name()), nativeExecutable);
    8383}
    8484
     
    8787    ASSERT(!isCompilationThread());
    8888
    89     if (NativeExecutable* nativeExecutable = m_hostFunctionStubMap->get(std::make_pair(function, constructor)))
     89    if (NativeExecutable* nativeExecutable = m_hostFunctionStubMap->get(std::make_tuple(function, constructor, name)))
    9090        return nativeExecutable;
    9191
     
    9696        adoptRef(new NativeJITCode(MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct(vm)), JITCode::HostCallThunk)),
    9797        constructor, NoIntrinsic, name);
    98     weakAdd(*m_hostFunctionStubMap, std::make_pair(function, constructor), Weak<NativeExecutable>(nativeExecutable, this));
     98    weakAdd(*m_hostFunctionStubMap, std::make_tuple(function, constructor, name), Weak<NativeExecutable>(nativeExecutable, this));
    9999    return nativeExecutable;
    100100}
     
    105105    ASSERT(vm->canUseJIT());
    106106
    107     if (NativeExecutable* nativeExecutable = m_hostFunctionStubMap->get(std::make_pair(function, &callHostFunctionAsConstructor)))
     107    if (NativeExecutable* nativeExecutable = m_hostFunctionStubMap->get(std::make_tuple(function, &callHostFunctionAsConstructor, name)))
    108108        return nativeExecutable;
    109109
     
    118118   
    119119    NativeExecutable* nativeExecutable = NativeExecutable::create(*vm, forCall, function, forConstruct, callHostFunctionAsConstructor, intrinsic, name);
    120     weakAdd(*m_hostFunctionStubMap, std::make_pair(function, &callHostFunctionAsConstructor), Weak<NativeExecutable>(nativeExecutable, this));
     120    weakAdd(*m_hostFunctionStubMap, std::make_tuple(function, &callHostFunctionAsConstructor, name), Weak<NativeExecutable>(nativeExecutable, this));
    121121    return nativeExecutable;
    122122}
Note: See TracChangeset for help on using the changeset viewer.