Ignore:
Timestamp:
Feb 26, 2016, 2:29:59 PM (9 years ago)
Author:
[email protected]
Message:

Function.name and Function.length should be configurable.
https://bugs.webkit.org/show_bug.cgi?id=154604

Reviewed by Saam Barati.

Source/JavaScriptCore:

According to https://tc39.github.io/ecma262/#sec-ecmascript-language-functions-and-classes,
"Unless otherwise specified, the name property of a built-in Function object,
if it exists, has the attributes { Writable: false, Enumerable: false,
Configurable: true }."

Similarly, "the length property of a built-in Function object has the attributes
{ Writable: false, Enumerable: false, Configurable: true }."

This patch makes Function.name and Function.length configurable.

We do this by lazily reifying the JSFunction name and length properties on first
access. We track whether each of these properties have been reified using flags
in the FunctionRareData. On first access, if not already reified, we will put
the property into the object with its default value and attributes and set the
reified flag. Thereafter, we rely on the base JSObject to handle access to the
property.

Also, lots of test results have to be re-baselined because the old Function.length
has attribute DontDelete, which is in conflict with the ES6 requirement that it
is configurable.

  • runtime/FunctionRareData.h:

(JSC::FunctionRareData::hasReifiedLength):
(JSC::FunctionRareData::setHasReifiedLength):
(JSC::FunctionRareData::hasReifiedName):
(JSC::FunctionRareData::setHasReifiedName):

  • Flags for tracking whether each property has been reified.
  • runtime/JSFunction.cpp:

(JSC::JSFunction::finishCreation):
(JSC::JSFunction::createBuiltinFunction):

  • Host and builtin functions currently always reify their name and length properties. Currently, for builtins, the default names that are used may differ from the executable name. For now, we'll stay with keeping this alternate approach to getting the name and length properties for host and builtin functions. However, we need their default attribute to be configurable as well.

(JSC::JSFunction::getOwnPropertySlot):
(JSC::JSFunction::getOwnNonIndexPropertyNames):
(JSC::JSFunction::put):
(JSC::JSFunction::deleteProperty):
(JSC::JSFunction::defineOwnProperty):
(JSC::JSFunction::reifyLength):
(JSC::JSFunction::reifyName):
(JSC::JSFunction::reifyLazyPropertyIfNeeded):
(JSC::JSFunction::lengthGetter): Deleted.
(JSC::JSFunction::nameGetter): Deleted.

  • runtime/JSFunction.h:
  • runtime/JSFunctionInlines.h:

(JSC::JSFunction::hasReifiedLength):
(JSC::JSFunction::hasReifiedName):

  • tests/es6.yaml:
  • 4 new passing tests.
  • tests/mozilla/ecma/Array/15.4.4.3-1.js:
  • tests/mozilla/ecma/Array/15.4.4.4-1.js:
  • tests/mozilla/ecma/Array/15.4.4.4-2.js:
  • tests/mozilla/ecma/GlobalObject/15.1.2.1-1.js:
  • tests/mozilla/ecma/GlobalObject/15.1.2.2-1.js:
  • tests/mozilla/ecma/GlobalObject/15.1.2.3-1.js:
  • tests/mozilla/ecma/GlobalObject/15.1.2.4.js:
  • tests/mozilla/ecma/GlobalObject/15.1.2.5-1.js:
  • tests/mozilla/ecma/GlobalObject/15.1.2.6.js:
  • tests/mozilla/ecma/GlobalObject/15.1.2.7.js:
  • tests/mozilla/ecma/String/15.5.4.10-1.js:
  • tests/mozilla/ecma/String/15.5.4.11-1.js:
  • tests/mozilla/ecma/String/15.5.4.11-5.js:
  • tests/mozilla/ecma/String/15.5.4.12-1.js:
  • tests/mozilla/ecma/String/15.5.4.6-2.js:
  • tests/mozilla/ecma/String/15.5.4.7-2.js:
  • tests/mozilla/ecma/String/15.5.4.8-1.js:
  • tests/mozilla/ecma/String/15.5.4.9-1.js:
  • Rebase expected test results.
  • tests/stress/function-configurable-properties.js: Added.

LayoutTests:

  • ietestcenter/Javascript/TestCases/15.2.3.3-4-187.js:

(ES5Harness.registerTest.test):

  • ietestcenter/Javascript/TestCases/15.3.4.5-15-2.js:

(ES5Harness.registerTest.test):

  • js/dom/function-name-expected.txt:
  • js/dom/getOwnPropertyDescriptor-expected.txt:
  • js/dom/script-tests/function-name.js:
  • js/mozilla/strict/15.3.5.1-expected.txt:
  • js/mozilla/strict/function-name-arity-expected.txt:
  • js/mozilla/strict/script-tests/15.3.5.1.js:
  • js/mozilla/strict/script-tests/function-name-arity.js:
  • js/resources/getOwnPropertyDescriptor.js:
  • sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.6/15.10.6.2_RegExp.prototype.exec/S15.10.6.2_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.6/15.10.6.3_RegExp.prototype.test/S15.10.6.3_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.6/15.10.6.4_RegExp.prototype.toString/S15.10.6.4_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/15.1.2/15.1.2.1_eval/S15.1.2.1_A4.2.html:
  • sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/15.1.2/15.1.2.2_parseInt/S15.1.2.2_A9.2.html:
  • sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/15.1.2/15.1.2.3_parseFloat/S15.1.2.3_A7.2.html:
  • sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/15.1.2/15.1.2.4_isNaN/S15.1.2.4_A2.2.html:
  • sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/15.1.2/15.1.2.5_isFinite/S15.1.2.5_A2.2.html:
  • sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/15.1.3/15.1.3.1_decodeURI/S15.1.3.1_A5.2.html:
  • sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/15.1.3/15.1.3.2_decodeURIComponent/S15.1.3.2_A5.2.html:
  • sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/15.1.3/15.1.3.3_encodeURI/S15.1.3.3_A5.2.html:
  • sputnik/Conformance/15_Native_Objects/15.1_The_Global_Object/15.1.3/15.1.3.4_encodeURIComponent/S15.1.3.4_A5.2.html:
  • sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/15.2.4.2_Object.prototype.toString/S15.2.4.2_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/15.2.4.3_Object.prototype.toLocaleString/S15.2.4.3_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/15.2.4.4_Object.prototype.valueOf/S15.2.4.4_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/15.2.4.5_Object.prototype.hasOwnProperty/S15.2.4.5_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/15.2.4.6_Object.prototype.isPrototypeOf/S15.2.4.6_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.2_Object/15.2.4/15.2.4.7_Object.prototype.propertyIsEnumerable/S15.2.4.7_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.3_Function/15.3.4/15.3.4.2_Function.prototype.toString/S15.3.4.2_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.3_Function/15.3.4/15.3.4.3_Function.prototype.apply/S15.3.4.3_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.3_Function/15.3.4/15.3.4.4_Function.prototype.call/S15.3.4.4_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.3_Function/15.3.5/S15.3.5.1_A2_T1.html:
  • sputnik/Conformance/15_Native_Objects/15.3_Function/15.3.5/S15.3.5.1_A2_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.3_Function/15.3.5/S15.3.5.1_A2_T3.html:
  • sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.10_Array_prototype_slice/S15.4.4.10_A5.2.html:
  • sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.11_Array_prototype_sort/S15.4.4.11_A7.2.html:
  • sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.12_Array_prototype_splice/S15.4.4.12_A5.2.html:
  • sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.13_Array_prototype_unshift/S15.4.4.13_A5.2.html:
  • sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.2_Array_prototype_toString/S15.4.4.2_A4.2.html:
  • sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.3_Array_prototype_toLocaleString/S15.4.4.3_A4.2.html:
  • sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.4_Array_prototype_concat/S15.4.4.4_A4.2.html:
  • sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.5_Array_prototype_join/S15.4.4.5_A6.2.html:
  • sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.6_Array_prototype_pop/S15.4.4.6_A5.2.html:
  • sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.7_Array_prototype_push/S15.4.4.7_A6.2.html:
  • sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.8_Array_prototype_reverse/S15.4.4.8_A5.2.html:
  • sputnik/Conformance/15_Native_Objects/15.4_Array/15.4.4/15.4.4.9_Array_prototype_shift/S15.4.4.9_A5.2.html:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.10_String.prototype.match/S15.5.4.10_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.11_String.prototype.replace/S15.5.4.11_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.12_String.prototype.search/S15.5.4.12_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.13_String.prototype.slice/S15.5.4.13_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.14_String.prototype.split/S15.5.4.14_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.15_String.prototype.substring/S15.5.4.15_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.16_String.prototype.toLowerCase/S15.5.4.16_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.17_String.prototype.toLocaleLowerCase/S15.5.4.17_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.18_String.prototype.toUpperCase/S15.5.4.18_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.19_String.prototype.toLocaleUpperCase/S15.5.4.19_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.4_String.prototype.charAt/S15.5.4.4_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.5_String.prototype.charCodeAt/S15.5.4.5_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.6_String.prototype.concat/S15.5.4.6_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.7_String.prototype.indexOf/S15.5.4.7_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.8_String.prototype.lastIndexOf/S15.5.4.8_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.5_String/15.5.4/15.5.4.9_String.prototype.localeCompare/S15.5.4.9_A9.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.4/15.9.4.2_Date.parse/S15.9.4.2_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.4/15.9.4.3_Date.UTC/S15.9.4.3_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.10_Date.prototype.getFullYear/S15.9.5.10_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.11_Date.prototype.getUTCFullYear/S15.9.5.11_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.12_Date.prototype.getMonth/S15.9.5.12_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.13_Date.prototype.getUTCMonth/S15.9.5.13_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.14_Date.prototype.getDate/S15.9.5.14_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.15_Date.prototype.getUTCDate/S15.9.5.15_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.16_Date.prototype.getDay/S15.9.5.16_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.17_Date.prototype.getUTCDay/S15.9.5.17_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.18_Date.prototype.getHours/S15.9.5.18_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.19_Date.prototype.getUTCHours/S15.9.5.19_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.20_Date.prototype.getMinutes/S15.9.5.20_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.21_Date.prototype.getUTCMinutes/S15.9.5.21_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.22_Date.prototype.getSeconds/S15.9.5.22_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.23_Date.prototype.getUTCSeconds/S15.9.5.23_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.24_Date.prototype.getMilliseconds/S15.9.5.24_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.25_Date.prototype.getUTCMilliseconds/S15.9.5.25_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.26_Date.prototype.getTimezoneOffset/S15.9.5.26_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.27_Date.prototype.setTime/S15.9.5.27_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.28_Date.prototype.setMilliseconds/S15.9.5.28_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.29_Date.prototype.setUTCMilliseconds/S15.9.5.29_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.2_Date.prototype.toString/S15.9.5.2_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.30_Date.prototype.setSeconds/S15.9.5.30_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.31_Date.prototype.setUTCSeconds/S15.9.5.31_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.32_Date.prototype.setMinutes/S15.9.5.32_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.33_Date.prototype.setUTCMinutes/S15.9.5.33_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.34_Date.prototype.setHours/S15.9.5.34_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.35_Date.prototype.setUTCHours/S15.9.5.35_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.36_Date.prototype.setDate/S15.9.5.36_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.37_Date.prototype.setUTCDate/S15.9.5.37_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.38_Date.prototype.setMonth/S15.9.5.38_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.39_Date.prototype.setUTCMonth/S15.9.5.39_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.3_Date.prototype.toDateString/S15.9.5.3_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.40_Date.prototype.setFullYear/S15.9.5.40_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.41_Date.prototype.setUTCFullYear/S15.9.5.41_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.42_Date.prototype.toUTCString/S15.9.5.42_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.4_Date.prototype.toTimeString/S15.9.5.4_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.5_Date.prototype.toLocaleString/S15.9.5.5_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.6_Date.prototype.toLocaleDateString/S15.9.5.6_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.7_Date.prototype.toLocaleTimeString/S15.9.5.7_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.8_Date.prototype.valueOf/S15.9.5.8_A3_T2.html:
  • sputnik/Conformance/15_Native_Objects/15.9_Date/15.9.5/15.9.5.9_Date.prototype.getTime/S15.9.5.9_A3_T2.html:
Location:
trunk/Source/JavaScriptCore/runtime
Files:
4 edited

Legend:

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

    r196956 r197205  
    9494    void setBoundFunctionStructure(VM& vm, Structure* structure) { m_boundFunctionStructure.set(vm, this, structure); }
    9595
     96    bool hasReifiedLength() const { return m_hasReifiedLength; }
     97    void setHasReifiedLength() { m_hasReifiedLength = true; }
     98    bool hasReifiedName() const { return m_hasReifiedName; }
     99    void setHasReifiedName() { m_hasReifiedName = true; }
     100
    96101protected:
    97102    FunctionRareData(VM&);
     
    119124    InternalFunctionAllocationProfile m_internalFunctionAllocationProfile;
    120125    WriteBarrier<Structure> m_boundFunctionStructure;
     126    bool m_hasReifiedLength { false };
     127    bool m_hasReifiedName { false };
    121128};
    122129
  • trunk/Source/JavaScriptCore/runtime/JSFunction.cpp

    r196722 r197205  
    117117    ASSERT(inherits(info()));
    118118    m_executable.set(vm, this, executable);
    119     putDirect(vm, vm.propertyNames->name, jsString(&vm, name), DontDelete | ReadOnly | DontEnum);
    120     putDirect(vm, vm.propertyNames->length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
     119    putDirect(vm, vm.propertyNames->name, jsString(&vm, name), ReadOnly | DontEnum);
     120    putDirect(vm, vm.propertyNames->length, jsNumber(length), ReadOnly | DontEnum);
    121121}
    122122
     
    124124{
    125125    JSFunction* function = create(vm, executable, globalObject);
    126     function->putDirect(vm, vm.propertyNames->name, jsString(&vm, executable->name().string()), DontDelete | ReadOnly | DontEnum);
    127     function->putDirect(vm, vm.propertyNames->length, jsNumber(executable->parameterCount()), DontDelete | ReadOnly | DontEnum);
     126    function->putDirect(vm, vm.propertyNames->name, jsString(&vm, executable->name().string()), ReadOnly | DontEnum);
     127    function->putDirect(vm, vm.propertyNames->length, jsNumber(executable->parameterCount()), ReadOnly | DontEnum);
    128128    return function;
    129129}
     
    132132{
    133133    JSFunction* function = create(vm, executable, globalObject);
    134     function->putDirect(vm, vm.propertyNames->name, jsString(&vm, name), DontDelete | ReadOnly | DontEnum);
    135     function->putDirect(vm, vm.propertyNames->length, jsNumber(executable->parameterCount()), DontDelete | ReadOnly | DontEnum);
     134    function->putDirect(vm, vm.propertyNames->name, jsString(&vm, name), ReadOnly | DontEnum);
     135    function->putDirect(vm, vm.propertyNames->length, jsNumber(executable->parameterCount()), ReadOnly | DontEnum);
    136136    return function;
    137137}
     
    342342        return JSValue::encode(caller);
    343343    return JSValue::encode(throwTypeError(exec, ASCIILiteral("Function.caller used to retrieve strict caller")));
    344 }
    345 
    346 EncodedJSValue JSFunction::lengthGetter(ExecState*, EncodedJSValue thisValue, PropertyName)
    347 {
    348     JSFunction* thisObj = jsCast<JSFunction*>(JSValue::decode(thisValue));
    349     ASSERT(!thisObj->isHostFunction());
    350     return JSValue::encode(jsNumber(thisObj->jsExecutable()->parameterCount()));
    351 }
    352 
    353 EncodedJSValue JSFunction::nameGetter(ExecState*, EncodedJSValue thisValue, PropertyName)
    354 {
    355     JSFunction* thisObj = jsCast<JSFunction*>(JSValue::decode(thisValue));
    356     ASSERT(!thisObj->isHostFunction());
    357     return JSValue::encode(thisObj->jsExecutable()->nameValue());
    358344}
    359345
     
    398384    }
    399385
    400     if (propertyName == exec->propertyNames().length) {
    401         slot.setCacheableCustom(thisObject, ReadOnly | DontEnum | DontDelete, lengthGetter);
    402         return true;
    403     }
    404 
    405     if (propertyName == exec->propertyNames().name) {
    406         slot.setCacheableCustom(thisObject, ReadOnly | DontEnum | DontDelete, nameGetter);
    407         return true;
    408     }
    409 
    410386    if (propertyName == exec->propertyNames().caller) {
    411387        if (thisObject->jsExecutable()->isStrictMode()) {
     
    422398    }
    423399
     400    thisObject->reifyLazyPropertyIfNeeded(exec, propertyName);
     401
    424402    return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
    425403}
     
    436414        propertyNames.add(vm.propertyNames->arguments);
    437415        propertyNames.add(vm.propertyNames->caller);
    438         propertyNames.add(vm.propertyNames->length);
    439         propertyNames.add(vm.propertyNames->name);
     416        if (!thisObject->hasReifiedLength())
     417            propertyNames.add(vm.propertyNames->length);
     418        if (!thisObject->hasReifiedName())
     419            propertyNames.add(vm.propertyNames->name);
    440420    }
    441421    Base::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode);
     
    468448        return;
    469449    }
    470     if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length || propertyName == exec->propertyNames().name || propertyName == exec->propertyNames().caller) {
     450    if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().caller) {
    471451        if (slot.isStrictMode())
    472452            throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
    473453        return;
    474454    }
     455    thisObject->reifyLazyPropertyIfNeeded(exec, propertyName);
    475456    Base::put(thisObject, exec, propertyName, value, slot);
    476457}
     
    483464        FunctionExecutable* executable = thisObject->jsExecutable();
    484465        if (propertyName == exec->propertyNames().arguments
    485             || propertyName == exec->propertyNames().length
    486             || propertyName == exec->propertyNames().name
    487466            || (propertyName == exec->propertyNames().prototype && !executable->isArrowFunction())
    488467            || propertyName == exec->propertyNames().caller)
    489         return false;
     468            return false;
     469
     470        thisObject->reifyLazyPropertyIfNeeded(exec, propertyName);
    490471    }
    491472   
     
    526507        }
    527508        valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), retrieveCallerFunction(exec, thisObject));
    528     } else if (propertyName == exec->propertyNames().length)
    529         valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), jsNumber(thisObject->jsExecutable()->parameterCount()));
    530     else if (propertyName == exec->propertyNames().name)
    531         valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), thisObject->jsExecutable()->nameValue());
    532     else
     509    } else {
     510        thisObject->reifyLazyPropertyIfNeeded(exec, propertyName);
    533511        return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
     512    }
    534513     
    535514    if (descriptor.configurablePresent() && descriptor.configurable()) {
     
    589568}
    590569
     570void JSFunction::reifyLength(ExecState* exec)
     571{
     572    VM& vm = exec->vm();
     573    FunctionRareData* rareData = this->rareData(vm);
     574
     575    ASSERT(!hasReifiedLength());
     576    ASSERT(!isHostFunction());
     577    JSValue initialValue = jsNumber(jsExecutable()->parameterCount());
     578    unsigned initialAttributes = DontEnum | ReadOnly;
     579    const Identifier& identifier = exec->propertyNames().length;
     580    putDirect(vm, identifier, initialValue, initialAttributes);
     581
     582    rareData->setHasReifiedLength();
     583}
     584
     585void JSFunction::reifyName(ExecState* exec)
     586{
     587    VM& vm = exec->vm();
     588    FunctionRareData* rareData = this->rareData(vm);
     589
     590    ASSERT(!hasReifiedName());
     591    ASSERT(!isHostFunction());
     592    JSValue initialValue = jsExecutable()->nameValue();
     593    unsigned initialAttributes = DontEnum | ReadOnly;
     594    const Identifier& identifier = exec->propertyNames().name;
     595    putDirect(vm, identifier, initialValue, initialAttributes);
     596
     597    rareData->setHasReifiedName();
     598}
     599
     600void JSFunction::reifyLazyPropertyIfNeeded(ExecState* exec, PropertyName propertyName)
     601{
     602    if (propertyName == exec->propertyNames().length) {
     603        if (!hasReifiedLength())
     604            reifyLength(exec);
     605    } else if (propertyName == exec->propertyNames().name) {
     606        if (!hasReifiedName())
     607            reifyName(exec);
     608    }
     609}
     610
    591611} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSFunction.h

    r196331 r197205  
    187187        return function;
    188188    }
    189    
     189
     190    bool hasReifiedLength() const;
     191    bool hasReifiedName() const;
     192    void reifyLength(ExecState*);
     193    void reifyName(ExecState*);
     194    void reifyLazyPropertyIfNeeded(ExecState*, PropertyName propertyName);
     195
    190196    friend class LLIntOffsetsExtractor;
    191197
  • trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h

    r195070 r197205  
    11/*
    2  * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    111111}
    112112
     113inline bool JSFunction::hasReifiedLength() const
     114{
     115    return m_rareData ? m_rareData->hasReifiedLength() : false;
     116}
     117
     118inline bool JSFunction::hasReifiedName() const
     119{
     120    return m_rareData ? m_rareData->hasReifiedName() : false;
     121}
     122
    113123} // namespace JSC
    114124
Note: See TracChangeset for help on using the changeset viewer.