Changeset 197815 in webkit


Ignore:
Timestamp:
Mar 8, 2016, 4:01:09 PM (9 years ago)
Author:
mark.lam@apple.com
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.
Location:
trunk
Files:
3 added
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r197811 r197815  
     12016-03-08  Mark Lam  <mark.lam@apple.com>
     2
     3        Implement Function.name support for getters/setters and inferring name of function properties.
     4        https://bugs.webkit.org/show_bug.cgi?id=154865
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        * js/function-toString-vs-name-expected.txt: Added.
     9        * js/function-toString-vs-name.html: Added.
     10        * js/script-tests/function-toString-vs-name.js: Added.
     11
    1122016-03-08  Myles C. Maxfield  <mmaxfield@apple.com>
    213
  • trunk/LayoutTests/inspector/model/remote-object-get-properties-expected.txt

    r196648 r197815  
    221221EXPRESSION: window.boundFunction
    222222type: function
    223 description: function () {
     223description: function unboundFunction() {
    224224    [native code]
    225225}
  • trunk/LayoutTests/platform/mac/http/tests/media/media-source/SourceBuffer-abort-readyState-expected.txt

    r196033 r197815  
    55step@http://127.0.0.1:8000/w3c/resources/testharness.js:1160:30
    66isTypeSupported@http://127.0.0.1:8000/media/media-source/SourceBuffer-abort-readyState.html:19:18
    7 bound isTypeSupported@[native code]
     7isTypeSupported@[native code]
    88http://127.0.0.1:8000/media/media-source/SourceBuffer-abort-readyState.html:42:36
    99step@http://127.0.0.1:8000/w3c/resources/testharness.js:1160:30
  • trunk/LayoutTests/platform/mac/http/tests/media/media-source/SourceBuffer-abort-removed-expected.txt

    r196033 r197815  
    55step@http://127.0.0.1:8000/w3c/resources/testharness.js:1160:30
    66isTypeSupported@http://127.0.0.1:8000/media/media-source/SourceBuffer-abort-removed.html:18:18
    7 bound isTypeSupported@[native code]
     7isTypeSupported@[native code]
    88http://127.0.0.1:8000/media/media-source/SourceBuffer-abort-removed.html:28:36
    99step@http://127.0.0.1:8000/w3c/resources/testharness.js:1160:30
  • trunk/LayoutTests/platform/mac/http/tests/media/media-source/SourceBuffer-abort-updating-expected.txt

    r196033 r197815  
    55step@http://127.0.0.1:8000/w3c/resources/testharness.js:1160:30
    66isTypeSupported@http://127.0.0.1:8000/media/media-source/SourceBuffer-abort-updating.html:32:18
    7 bound isTypeSupported@[native code]
     7isTypeSupported@[native code]
    88http://127.0.0.1:8000/media/media-source/SourceBuffer-abort-updating.html:42:36
    99step@http://127.0.0.1:8000/w3c/resources/testharness.js:1160:30
  • trunk/LayoutTests/platform/mac/http/tests/media/media-source/mediasource-sourcebuffer-mode-expected.txt

    r196033 r197815  
    99http://127.0.0.1:8000/media/media-source/mediasource-sourcebuffer-mode.html:114:32
    1010handleWaitCallback_@http://127.0.0.1:8000/media/media-source/mediasource-util.js:97:17
    11 bound @[native code]
     11handleWaitCallback_@[native code]
    1212step@http://127.0.0.1:8000/w3c/resources/testharness.js:1160:30
    1313http://127.0.0.1:8000/w3c/resources/testharness.js:1189:33)
  • trunk/Source/JavaScriptCore/ChangeLog

    r197803 r197815  
     12016-03-08  Mark Lam  <mark.lam@apple.com>
     2
     3        Implement Function.name support for getters/setters and inferring name of function properties.
     4        https://bugs.webkit.org/show_bug.cgi?id=154865
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        1. toString() no longer uses the value of Function.name as the name of the
     9           function in the returned string, because ...
     10
     11            i. Function.name is supposed to be configurable.  Hence, it can be made
     12               writable and can be set to any JSValue, or deleted.
     13           ii. Function.prototype.toString() is supposed to produce a string that can be
     14               eval'ed.  Hence, for JS functions, the function name in the produced
     15               string must be a legal function name (and not some arbitrary value set in
     16               Function.name).  For example, while a number is a legal value for
     17               Function.name, it is not legal as the function name in the toString()
     18               string.
     19
     20           Instead, we'll always use the original name from the JS source that the
     21           function was parsed from.
     22
     23        2. JSFunction::name() now always return the original name, not the value of
     24           the Function.name property.  As a result, it also no longer needs an
     25           ExecState* arg.
     26
     27           If the original name is an empty string, JSFunction::name() will use the
     28           inferred name.
     29
     30        3. For JS functions, the original name can be attained from their
     31           FunctionExecutable object.
     32
     33           For host/native functions (which do not have a FunctionExecutable), we get the
     34           "original" name from its NativeExecutable.
     35
     36        4. The m_hostFunctionStubMap now keys its NativeExecutable pointers using the
     37           original name, in addition to the native function and constructor pointers.
     38
     39           This is needed because we want a different NativeExecutable for functions with
     40           a different name (to satisfy (3) above).
     41
     42        5. Changed JSBoundFunction to store the name of its bound function in its
     43           NativeExecutable.  This will later be used to generate the toString() string.
     44           It's Function.name value is eagerly initialized at construction time.
     45
     46        6. Function.name for getters/setters are now prefixed with "get"/"set".
     47           This was done both for the JSBoundSlotBaseFunctions and JS definable get/set
     48           functions.
     49
     50        7. Added InternalFunction::m_originalName so that we can use it to generate the
     51           toString() string.  We're storing it as a JSString instead of a WTF::String
     52           only because we want InternalFunction to be continue to be trivially
     53           destructible.
     54
     55        * inspector/JSInjectedScriptHost.cpp:
     56        (Inspector::JSInjectedScriptHost::functionDetails):
     57        * jit/JITThunks.cpp:
     58        (JSC::JITThunks::finalize):
     59        (JSC::JITThunks::hostFunctionStub):
     60        * jit/JITThunks.h:
     61        * runtime/Executable.h:
     62        * runtime/FunctionPrototype.cpp:
     63        (JSC::functionProtoFuncToString):
     64        * runtime/InternalFunction.cpp:
     65        (JSC::InternalFunction::finishCreation):
     66        (JSC::InternalFunction::visitChildren):
     67        (JSC::InternalFunction::name):
     68        (JSC::InternalFunction::displayName):
     69        * runtime/InternalFunction.h:
     70        * runtime/JSBoundFunction.cpp:
     71        (JSC::JSBoundFunction::create):
     72        (JSC::JSBoundFunction::visitChildren):
     73        (JSC::JSBoundFunction::toStringName): Deleted.
     74        * runtime/JSBoundFunction.h:
     75        (JSC::JSBoundFunction::boundThis):
     76        (JSC::JSBoundFunction::boundArgs):
     77        (JSC::JSBoundFunction::createStructure):
     78        * runtime/JSBoundSlotBaseFunction.cpp:
     79        (JSC::boundSlotBaseFunctionCall):
     80        (JSC::JSBoundSlotBaseFunction::create):
     81        * runtime/JSFunction.cpp:
     82        (JSC::JSFunction::initializeRareData):
     83        (JSC::JSFunction::name):
     84        (JSC::JSFunction::displayName):
     85        (JSC::JSFunction::calculatedDisplayName):
     86        (JSC::JSFunction::reifyName):
     87        * runtime/JSFunction.h:
     88        * tests/es6.yaml:
     89
    1902016-03-08  Commit Queue  <commit-queue@webkit.org>
    291
  • trunk/Source/JavaScriptCore/inspector/JSInjectedScriptHost.cpp

    r197539 r197815  
    204204    result->putDirect(exec->vm(), Identifier::fromString(exec, "location"), location);
    205205
    206     String name = function->name(exec);
     206    String name = function->name();
    207207    if (!name.isEmpty())
    208208        result->putDirect(exec->vm(), Identifier::fromString(exec, "name"), jsString(exec, name));
  • 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}
  • trunk/Source/JavaScriptCore/jit/JITThunks.h

    r195000 r197815  
    3737#include "WeakHandleOwner.h"
    3838#include "WeakInlines.h"
     39#include <tuple>
    3940#include <wtf/HashMap.h>
    4041#include <wtf/RefPtr.h>
     
    6869    typedef HashMap<ThunkGenerator, MacroAssemblerCodeRef> CTIStubMap;
    6970    CTIStubMap m_ctiStubMap;
    70     typedef HashMap<std::pair<NativeFunction, NativeFunction>, Weak<NativeExecutable>> HostFunctionStubMap;
     71
     72    typedef std::tuple<NativeFunction, NativeFunction, String> HostFunctionKey;
     73
     74    struct HostFunctionHash {
     75        static unsigned hash(const HostFunctionKey& key)
     76        {
     77            unsigned hash = WTF::pairIntHash(hashPointer(std::get<0>(key)), hashPointer(std::get<1>(key)));
     78            if (!std::get<2>(key).isNull())
     79                hash = WTF::pairIntHash(hash, DefaultHash<String>::Hash::hash(std::get<2>(key)));
     80            return hash;
     81        }
     82        static bool equal(const HostFunctionKey& a, const HostFunctionKey& b)
     83        {
     84            return (std::get<0>(a) == std::get<0>(b)) && (std::get<1>(a) == std::get<1>(b)) && (std::get<2>(a) == std::get<2>(b));
     85        }
     86        static const bool safeToCompareToEmptyOrDeleted = true;
     87
     88    private:
     89        static inline unsigned hashPointer(NativeFunction p)
     90        {
     91            return DefaultHash<NativeFunction>::Hash::hash(p);
     92        }
     93    };
     94
     95    struct HostFunctionHashTrait : WTF::GenericHashTraits<HostFunctionKey> {
     96        static const bool emptyValueIsZero = true;
     97        static EmptyValueType emptyValue() { return std::make_tuple(nullptr, nullptr, String()); }
     98
     99        static void constructDeletedValue(HostFunctionKey& slot) { std::get<0>(slot) = reinterpret_cast<NativeFunction>(-1); }
     100        static bool isDeletedValue(const HostFunctionKey& value) { return std::get<0>(value) == reinterpret_cast<NativeFunction>(-1); }
     101    };
     102   
     103    typedef HashMap<HostFunctionKey, Weak<NativeExecutable>, HostFunctionHash, HostFunctionHashTrait> HostFunctionStubMap;
    71104    std::unique_ptr<HostFunctionStubMap> m_hostFunctionStubMap;
    72105    Lock m_lock;
  • 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(); }
  • trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp

    r197648 r197815  
    8686    if (thisValue.inherits(JSFunction::info())) {
    8787        JSFunction* function = jsCast<JSFunction*>(thisValue);
    88         if (function->isHostOrBuiltinFunction()) {
    89             String name;
    90             if (JSBoundFunction* boundFunction = jsDynamicCast<JSBoundFunction*>(function))
    91                 name = boundFunction->toStringName(exec);
    92             else
    93                 name = function->name(exec);
    94             return JSValue::encode(jsMakeNontrivialString(exec, "function ", name, "() {\n    [native code]\n}"));
    95         }
     88        if (function->isHostOrBuiltinFunction())
     89            return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(), "() {\n    [native code]\n}"));
    9690
    9791        FunctionExecutable* executable = function->jsExecutable();
     
    10296            executable->parametersStartOffset(),
    10397            executable->parametersStartOffset() + executable->source().length());
    104         return JSValue::encode(jsMakeNontrivialString(exec, functionHeader, function->name(exec), source));
     98        return JSValue::encode(jsMakeNontrivialString(exec, functionHeader, function->name(), source));
    10599    }
    106100
     
    168162    }
    169163
    170     JSString* name = target.get(exec, exec->propertyNames().name).toString(exec);
     164    JSValue nameProp = target.get(exec, exec->propertyNames().name);
     165    JSString* name = nameProp.isString() ? nameProp.toString(exec) : jsEmptyString(exec);
    171166    return JSValue::encode(JSBoundFunction::create(vm, exec, globalObject, targetObject, exec->argument(0), boundArgs, length, name->value(exec)));
    172167}
  • trunk/Source/JavaScriptCore/runtime/InternalFunction.cpp

    r197614 r197815  
    4545    ASSERT(inherits(info()));
    4646    ASSERT(methodTable()->getCallData != InternalFunction::info()->methodTable.getCallData);
    47     putDirect(vm, vm.propertyNames->name, jsString(&vm, name), DontDelete | ReadOnly | DontEnum);
     47    JSString* nameString = jsString(&vm, name);
     48    m_originalName.set(vm, this, nameString);
     49    putDirect(vm, vm.propertyNames->name, nameString, ReadOnly | DontEnum);
    4850}
    4951
    50 const String& InternalFunction::name(ExecState* exec)
     52void InternalFunction::visitChildren(JSCell* cell, SlotVisitor& visitor)
    5153{
    52     return asString(getDirect(exec->vm(), exec->vm().propertyNames->name))->tryGetValue();
     54    InternalFunction* thisObject = jsCast<InternalFunction*>(cell);
     55    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     56    Base::visitChildren(thisObject, visitor);
     57   
     58    visitor.append(&thisObject->m_originalName);
     59}
     60
     61const String& InternalFunction::name(ExecState*)
     62{
     63    const String& name = m_originalName->tryGetValue();
     64    ASSERT(name); // m_originalName was built from a String, and hence, there is no rope to resolve.
     65    return name;
    5366}
    5467
  • trunk/Source/JavaScriptCore/runtime/InternalFunction.h

    r194869 r197815  
    3939    DECLARE_EXPORT_INFO;
    4040
     41    JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
     42
    4143    JS_EXPORT_PRIVATE const String& name(ExecState*);
    4244    const String displayName(ExecState*);
     
    5658
    5759    static CallType getCallData(JSCell*, CallData&);
     60    WriteBarrier<JSString> m_originalName;
    5861};
    5962
  • trunk/Source/JavaScriptCore/runtime/JSBoundFunction.cpp

    r197648 r197815  
    125125    ConstructType constructType = JSC::getConstructData(targetFunction, constructData);
    126126    bool canConstruct = constructType != ConstructType::None;
    127     NativeExecutable* executable = vm.getHostFunction(boundFunctionCall, canConstruct ? boundFunctionConstruct : callHostFunctionAsConstructor, ASCIILiteral("Function.prototype.bind result"));
     127    NativeExecutable* executable = vm.getHostFunction(boundFunctionCall, canConstruct ? boundFunctionConstruct : callHostFunctionAsConstructor, name);
    128128    Structure* structure = getBoundFunctionStructure(vm, exec, globalObject, targetFunction);
    129129    if (UNLIKELY(vm.exception()))
     
    168168}
    169169
    170 String JSBoundFunction::toStringName(ExecState* exec)
    171 {
    172     return m_targetFunction->get(exec, exec->vm().propertyNames->name).toWTFString(exec);
    173 }
    174 
    175170} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSBoundFunction.h

    r197648 r197815  
    4141    const static unsigned StructureFlags = ~ImplementsDefaultHasInstance & Base::StructureFlags;
    4242
    43     static JSBoundFunction* create(VM&, ExecState*, JSGlobalObject*, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs, int, const String&);
     43    static JSBoundFunction* create(VM&, ExecState*, JSGlobalObject*, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs, int, const String& name);
    4444   
    4545    static bool customHasInstance(JSObject*, ExecState*, JSValue);
     
    4949    JSValue boundArgs() { return m_boundArgs.get(); }
    5050
    51     String toStringName(ExecState*);
    52 
    53     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     51    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    5452    {
    5553        ASSERT(globalObject);
     
    6563    JSBoundFunction(VM&, JSGlobalObject*, Structure*, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs);
    6664   
    67     void finishCreation(VM&, NativeExecutable*, int, const String&);
     65    void finishCreation(VM&, NativeExecutable*, int length, const String& name);
    6866
    6967    WriteBarrier<JSObject> m_targetFunction;
  • trunk/Source/JavaScriptCore/runtime/JSBoundSlotBaseFunction.cpp

    r196331 r197815  
    5151        return JSValue::encode(jsUndefined());
    5252
    53     const String& name = boundSlotBaseFunction->name(exec);
     53    const String& name = boundSlotBaseFunction->name();
    5454    return getter(exec, JSValue::encode(exec->thisValue()), PropertyName(Identifier::fromString(exec, name)));
    5555}
     
    6868
    6969    // Can't do this during initialization because getHostFunction might do a GC allocation.
    70     function->finishCreation(vm, executable, boundSlotBase, getterSetter, name);
     70    String prefix = (type == Type::Getter) ? "get " : "set ";
     71    function->finishCreation(vm, executable, boundSlotBase, getterSetter, makeString(prefix, name));
    7172    return function;
    7273}
  • trunk/Source/JavaScriptCore/runtime/JSCJSValue.cpp

    r197794 r197815  
    208208        return;
    209209   
     210    if (shouldThrow && !exec->hadException())
    210211    if (shouldThrow)
    211212        throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
  • trunk/Source/JavaScriptCore/runtime/JSFunction.cpp

    r197794 r197815  
    178178}
    179179
    180 String JSFunction::name(ExecState* exec)
    181 {
    182     return get(exec, exec->vm().propertyNames->name).toWTFString(exec);
     180String JSFunction::name()
     181{
     182    if (isHostFunction()) {
     183        NativeExecutable* executable = jsCast<NativeExecutable*>(this->executable());
     184        return executable->name();
     185    }
     186    return jsExecutable()->name().string();
    183187}
    184188
     
    200204        return explicitName;
    201205   
    202     const String actualName = name(exec);
     206    const String actualName = name();
    203207    if (!actualName.isEmpty() || isHostOrBuiltinFunction())
    204208        return actualName;
     
    590594    ASSERT(!isHostFunction());
    591595    unsigned initialAttributes = DontEnum | ReadOnly;
    592     const Identifier& identifier = exec->propertyNames().name;
    593     putDirect(vm, identifier, jsString(exec, jsExecutable()->name().string()), initialAttributes);
    594 
     596    const Identifier& propID = exec->propertyNames().name;
     597
     598    const Identifier& nameID = jsExecutable()->name();
     599    String name = nameID.string();
     600    if (name.isEmpty())
     601        name = jsExecutable()->ecmaName().string();
     602
     603    if (jsExecutable()->isGetter())
     604        name = makeString("get ", name);
     605    else if (jsExecutable()->isSetter())
     606        name = makeString("set ", name);
     607
     608    putDirect(vm, propID, jsString(exec, name), initialAttributes);
    595609    rareData->setHasReifiedName();
    596610}
  • trunk/Source/JavaScriptCore/runtime/JSFunction.h

    r197205 r197815  
    8282    static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*, const String& name);
    8383
    84     JS_EXPORT_PRIVATE String name(ExecState*);
     84    JS_EXPORT_PRIVATE String name();
    8585    JS_EXPORT_PRIVATE String displayName(ExecState*);
    8686    const String calculatedDisplayName(ExecState*);
  • trunk/Source/JavaScriptCore/tests/es6.yaml

    r197732 r197815  
    792792  cmd: runES6 :normal
    793793- path: es6/function_name_property_accessor_properties.js
    794   cmd: runES6 :fail
     794  cmd: runES6 :normal
    795795- path: es6/function_name_property_bound_functions.js
    796796  cmd: runES6 :normal
     
    812812  cmd: runES6 :fail
    813813- path: es6/function_name_property_variables_function.js
    814   cmd: runES6 :fail
     814  cmd: runES6 :normal
    815815- path: es6/generators_%GeneratorPrototype%.constructor.js
    816816  cmd: runES6 :normal
Note: See TracChangeset for help on using the changeset viewer.