Changeset 210146 in webkit


Ignore:
Timestamp:
Dec 24, 2016 1:26:22 PM (7 years ago)
Author:
commit-queue@webkit.org
Message:

[test262] Fixing mapped arguments object property test case
https://bugs.webkit.org/show_bug.cgi?id=159398

Patch by Caio Lima <Caio Lima> on 2016-12-24
Reviewed by Saam Barati.

JSTests:

  • stress/arguments-bizarre-behaviour-disable-enumerability.js:
  • stress/arguments-define-property.js: Added.

(assert):
(testProperties):

  • stress/arguments-non-configurable.js: Added.

(assert):
(tryChangeNonConfigurableDescriptor):
(set tryChangeNonConfigurableDescriptor):
(tryChangeWritableOfNonConfigurableDescriptor):

  • test262.yaml:

Source/JavaScriptCore:

This patch changes GenericArguments' override mechanism to
implement corret behavior on ECMAScript test262 suite test cases of
mapped arguments object with non-configurable and non-writable
property. Also it is ensuring that arguments[i]
cannot be deleted when argument "i" is {configurable: false}.

The previous implementation is against to the specification for 2 reasons:

  1. Every argument in arguments object are {writable: true} by default (http://www.ecma-international.org/ecma-262/7.0/index.html#sec-createunmappedargumentsobject). It means that we have to stop mapping a defined property index if the new property descriptor contains writable (i.e writable is present) and its value is false (also check https://tc39.github.io/ecma262/#sec-arguments-exotic-objects-defineownproperty-p-desc). Previous implementation considers {writable: false} if writable is not present.
  1. When a property is overriden, "delete" operation is always returning true. However delete operations should follow the specification.

We created an auxilary boolean array named m_modifiedArgumentsDescriptor
to store which arguments[i] descriptor was changed from its default
property descriptor. This modification was necessary because m_overrides
was responsible to keep this information at the same time
of keeping information about arguments mapping. The problem of this apporach was
that we needed to call overridesArgument(i) as soon as the ith argument's property
descriptor was changed and it stops the argument's mapping as sideffect, producing
wrong behavior.
To keep tracking arguments mapping status, we renamed DirectArguments::m_overrides to
DirectArguments::m_mappedArguments and now we it is responsible to manage if an
argument[i] is mapped or not.
With these 2 structures, now it is possible to an argument[i] have its property
descriptor modified and don't stop the mapping as soon as it happens. One example
of that wrong behavior can be found on arguments-bizarre-behaviour-disable-enumerability
test case, that now is fixed by this new mechanism.

  • bytecode/PolymorphicAccess.cpp:

(JSC::AccessCase::generateWithGuard):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileGetByValOnDirectArguments):
(JSC::DFG::SpeculativeJIT::compileGetArrayLength):
(JSC::DFG::SpeculativeJIT::compileCreateDirectArguments):

  • ftl/FTLAbstractHeapRepository.h:
  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileGetArrayLength):
(JSC::FTL::DFG::LowerDFGToB3::compileGetByVal):
(JSC::FTL::DFG::LowerDFGToB3::compileCreateDirectArguments):

  • jit/JITOperations.cpp:

(JSC::canAccessArgumentIndexQuickly):

  • jit/JITPropertyAccess.cpp:

(JSC::JIT::emitDirectArgumentsGetByVal):

  • runtime/DirectArguments.cpp:

(JSC::DirectArguments::estimatedSize):
(JSC::DirectArguments::visitChildren):
(JSC::DirectArguments::overrideThings):
(JSC::DirectArguments::overrideThingsIfNecessary):
(JSC::DirectArguments::unmapArgument):
(JSC::DirectArguments::copyToArguments):
(JSC::DirectArguments::overridesSize):
(JSC::DirectArguments::overrideArgument): Deleted.

  • runtime/DirectArguments.h:

(JSC::DirectArguments::length):
(JSC::DirectArguments::isMappedArgument):
(JSC::DirectArguments::isMappedArgumentInDFG):
(JSC::DirectArguments::getIndexQuickly):
(JSC::DirectArguments::setIndexQuickly):
(JSC::DirectArguments::overrodeThings):
(JSC::DirectArguments::initModifiedArgumentsDescriptorIfNecessary):
(JSC::DirectArguments::setModifiedArgumentDescriptor):
(JSC::DirectArguments::isModifiedArgumentDescriptor):
(JSC::DirectArguments::offsetOfMappedArguments):
(JSC::DirectArguments::offsetOfModifiedArgumentsDescriptor):
(JSC::DirectArguments::canAccessIndexQuickly): Deleted.
(JSC::DirectArguments::canAccessArgumentIndexQuicklyInDFG): Deleted.
(JSC::DirectArguments::offsetOfOverrides): Deleted.

  • runtime/GenericArguments.h:
  • runtime/GenericArgumentsInlines.h:

(JSC::GenericArguments<Type>::visitChildren):
(JSC::GenericArguments<Type>::getOwnPropertySlot):
(JSC::GenericArguments<Type>::getOwnPropertySlotByIndex):
(JSC::GenericArguments<Type>::getOwnPropertyNames):
(JSC::GenericArguments<Type>::put):
(JSC::GenericArguments<Type>::putByIndex):
(JSC::GenericArguments<Type>::deleteProperty):
(JSC::GenericArguments<Type>::deletePropertyByIndex):
(JSC::GenericArguments<Type>::defineOwnProperty):
(JSC::GenericArguments<Type>::initModifiedArgumentsDescriptor):
(JSC::GenericArguments<Type>::initModifiedArgumentsDescriptorIfNecessary):
(JSC::GenericArguments<Type>::setModifiedArgumentDescriptor):
(JSC::GenericArguments<Type>::isModifiedArgumentDescriptor):
(JSC::GenericArguments<Type>::copyToArguments):

  • runtime/ScopedArguments.cpp:

(JSC::ScopedArguments::visitChildren):
(JSC::ScopedArguments::unmapArgument):
(JSC::ScopedArguments::overrideArgument): Deleted.

  • runtime/ScopedArguments.h:

(JSC::ScopedArguments::isMappedArgument):
(JSC::ScopedArguments::isMappedArgumentInDFG):
(JSC::ScopedArguments::getIndexQuickly):
(JSC::ScopedArguments::setIndexQuickly):
(JSC::ScopedArguments::initModifiedArgumentsDescriptorIfNecessary):
(JSC::ScopedArguments::setModifiedArgumentDescriptor):
(JSC::ScopedArguments::isModifiedArgumentDescriptor):
(JSC::ScopedArguments::canAccessIndexQuickly): Deleted.
(JSC::ScopedArguments::canAccessArgumentIndexQuicklyInDFG): Deleted.

Location:
trunk
Files:
2 added
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r210137 r210146  
     12016-12-24  Caio Lima  <ticaiolima@gmail.com>
     2
     3        [test262] Fixing mapped arguments object property test case
     4        https://bugs.webkit.org/show_bug.cgi?id=159398
     5
     6        Reviewed by Saam Barati.
     7
     8        * stress/arguments-bizarre-behaviour-disable-enumerability.js:
     9        * stress/arguments-define-property.js: Added.
     10        (assert):
     11        (testProperties):
     12        * stress/arguments-non-configurable.js: Added.
     13        (assert):
     14        (tryChangeNonConfigurableDescriptor):
     15        (set tryChangeNonConfigurableDescriptor):
     16        (tryChangeWritableOfNonConfigurableDescriptor):
     17        * test262.yaml:
     18
     19016-12-20  Caio Lima  <ticaiolima@gmail.com>
     20
     21        [test262] Fixing mapped arguments object property test case
     22        https://bugs.webkit.org/show_bug.cgi?id=159398
     23
     24        Reviewed by .
     25
     26        * stress/arguments-bizarre-behaviour-disable-enumerability.js:
     27        * stress/arguments-define-property.js: Added.
     28        (assert):
     29        (testProperties):
     30        * stress/arguments-non-configurable.js: Added.
     31        (assert):
     32        (tryChangeNonConfigurableDescriptor):
     33        (set tryChangeNonConfigurableDescriptor):
     34        (tryChangeWritableOfNonConfigurableDescriptor):
     35        * test262.yaml:
     36
    1372016-12-23  Keith Miller  <keith_miller@apple.com>
    238
  • trunk/JSTests/stress/arguments-bizarre-behaviour-disable-enumerability.js

    r180564 r210146  
    2525    throw new Error();
    2626
    27 // FIXME: This is totally weird!
    28 // https://bugs.webkit.org/show_bug.cgi?id=141952
    29 if (Object.getOwnPropertyDescriptor(result[2], 0).enumerable !== true)
     27if (Object.getOwnPropertyDescriptor(result[2], 0).enumerable === true)
    3028    throw new Error();
  • trunk/JSTests/test262.yaml

    r208843 r210146  
    5136551365  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
    5136651366- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-2.js
    51367   cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
     51367  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
    5136851368- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-3.js
    51369   cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
     51369  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
    5137051370- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-4.js
    51371   cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
     51371  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
    5137251372- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-1.js
    5137351373  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
    5137451374- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-2.js
    51375   cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
     51375  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
    5137651376- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-3.js
    51377   cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
     51377  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
    5137851378- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-4.js
    51379   cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
     51379  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
    5138051380- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-1.js
    5138151381  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
     
    5138351383  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
    5138451384- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-3.js
    51385   cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
     51385  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
    5138651386- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-4.js
    51387   cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
     51387  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
    5138851388- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-5.js
    51389   cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
     51389  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
    5139051390- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-1.js
    5139151391  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
    5139251392- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-2.js
    51393   cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
     51393  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
    5139451394- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-3.js
    51395   cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
     51395  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
    5139651396- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-4.js
    51397   cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
     51397  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
    5139851398- path: test262/test/language/arguments-object/mapped/mapped-arguments-nonwritable-nonconfigurable-1.js
    5139951399  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], []
  • trunk/Source/JavaScriptCore/ChangeLog

    r210139 r210146  
     12016-12-24  Caio Lima  <ticaiolima@gmail.com>
     2
     3        [test262] Fixing mapped arguments object property test case
     4        https://bugs.webkit.org/show_bug.cgi?id=159398
     5
     6        Reviewed by Saam Barati.
     7
     8        This patch changes GenericArguments' override mechanism to
     9        implement corret behavior on ECMAScript test262 suite test cases of
     10        mapped arguments object with non-configurable and non-writable
     11        property. Also it is ensuring that arguments[i]
     12        cannot be deleted when argument "i" is {configurable: false}.
     13       
     14        The previous implementation is against to the specification for 2 reasons:
     15
     16        1. Every argument in arguments object are {writable: true} by default
     17           (http://www.ecma-international.org/ecma-262/7.0/index.html#sec-createunmappedargumentsobject).
     18           It means that we have to stop mapping a defined property index
     19           if the new property descriptor contains writable (i.e writable is
     20           present) and its value is false (also check
     21           https://tc39.github.io/ecma262/#sec-arguments-exotic-objects-defineownproperty-p-desc).
     22           Previous implementation considers {writable: false} if writable is
     23           not present.
     24
     25        2. When a property is overriden, "delete" operation is always returning true. However
     26           delete operations should follow the specification.
     27
     28        We created an auxilary boolean array named m_modifiedArgumentsDescriptor
     29        to store which arguments[i] descriptor was changed from its default
     30        property descriptor. This modification was necessary because m_overrides
     31        was responsible to keep this information at the same time
     32        of keeping information about arguments mapping. The problem of this apporach was
     33        that we needed to call overridesArgument(i) as soon as the ith argument's property
     34        descriptor was changed and it stops the argument's mapping as sideffect, producing
     35        wrong behavior.
     36        To keep tracking arguments mapping status, we renamed DirectArguments::m_overrides to
     37        DirectArguments::m_mappedArguments and now we it is responsible to manage if an
     38        argument[i] is mapped or not.
     39        With these 2 structures, now it is possible to an argument[i] have its property
     40        descriptor modified and don't stop the mapping as soon as it happens. One example
     41        of that wrong behavior can be found on arguments-bizarre-behaviour-disable-enumerability
     42        test case, that now is fixed by this new mechanism.
     43
     44        * bytecode/PolymorphicAccess.cpp:
     45        (JSC::AccessCase::generateWithGuard):
     46        * dfg/DFGSpeculativeJIT.cpp:
     47        (JSC::DFG::SpeculativeJIT::compileGetByValOnDirectArguments):
     48        (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
     49        (JSC::DFG::SpeculativeJIT::compileCreateDirectArguments):
     50        * ftl/FTLAbstractHeapRepository.h:
     51        * ftl/FTLLowerDFGToB3.cpp:
     52        (JSC::FTL::DFG::LowerDFGToB3::compileGetArrayLength):
     53        (JSC::FTL::DFG::LowerDFGToB3::compileGetByVal):
     54        (JSC::FTL::DFG::LowerDFGToB3::compileCreateDirectArguments):
     55        * jit/JITOperations.cpp:
     56        (JSC::canAccessArgumentIndexQuickly):
     57        * jit/JITPropertyAccess.cpp:
     58        (JSC::JIT::emitDirectArgumentsGetByVal):
     59        * runtime/DirectArguments.cpp:
     60        (JSC::DirectArguments::estimatedSize):
     61        (JSC::DirectArguments::visitChildren):
     62        (JSC::DirectArguments::overrideThings):
     63        (JSC::DirectArguments::overrideThingsIfNecessary):
     64        (JSC::DirectArguments::unmapArgument):
     65        (JSC::DirectArguments::copyToArguments):
     66        (JSC::DirectArguments::overridesSize):
     67        (JSC::DirectArguments::overrideArgument): Deleted.
     68        * runtime/DirectArguments.h:
     69        (JSC::DirectArguments::length):
     70        (JSC::DirectArguments::isMappedArgument):
     71        (JSC::DirectArguments::isMappedArgumentInDFG):
     72        (JSC::DirectArguments::getIndexQuickly):
     73        (JSC::DirectArguments::setIndexQuickly):
     74        (JSC::DirectArguments::overrodeThings):
     75        (JSC::DirectArguments::initModifiedArgumentsDescriptorIfNecessary):
     76        (JSC::DirectArguments::setModifiedArgumentDescriptor):
     77        (JSC::DirectArguments::isModifiedArgumentDescriptor):
     78        (JSC::DirectArguments::offsetOfMappedArguments):
     79        (JSC::DirectArguments::offsetOfModifiedArgumentsDescriptor):
     80        (JSC::DirectArguments::canAccessIndexQuickly): Deleted.
     81        (JSC::DirectArguments::canAccessArgumentIndexQuicklyInDFG): Deleted.
     82        (JSC::DirectArguments::offsetOfOverrides): Deleted.
     83        * runtime/GenericArguments.h:
     84        * runtime/GenericArgumentsInlines.h:
     85        (JSC::GenericArguments<Type>::visitChildren):
     86        (JSC::GenericArguments<Type>::getOwnPropertySlot):
     87        (JSC::GenericArguments<Type>::getOwnPropertySlotByIndex):
     88        (JSC::GenericArguments<Type>::getOwnPropertyNames):
     89        (JSC::GenericArguments<Type>::put):
     90        (JSC::GenericArguments<Type>::putByIndex):
     91        (JSC::GenericArguments<Type>::deleteProperty):
     92        (JSC::GenericArguments<Type>::deletePropertyByIndex):
     93        (JSC::GenericArguments<Type>::defineOwnProperty):
     94        (JSC::GenericArguments<Type>::initModifiedArgumentsDescriptor):
     95        (JSC::GenericArguments<Type>::initModifiedArgumentsDescriptorIfNecessary):
     96        (JSC::GenericArguments<Type>::setModifiedArgumentDescriptor):
     97        (JSC::GenericArguments<Type>::isModifiedArgumentDescriptor):
     98        (JSC::GenericArguments<Type>::copyToArguments):
     99        * runtime/ScopedArguments.cpp:
     100        (JSC::ScopedArguments::visitChildren):
     101        (JSC::ScopedArguments::unmapArgument):
     102        (JSC::ScopedArguments::overrideArgument): Deleted.
     103        * runtime/ScopedArguments.h:
     104        (JSC::ScopedArguments::isMappedArgument):
     105        (JSC::ScopedArguments::isMappedArgumentInDFG):
     106        (JSC::ScopedArguments::getIndexQuickly):
     107        (JSC::ScopedArguments::setIndexQuickly):
     108        (JSC::ScopedArguments::initModifiedArgumentsDescriptorIfNecessary):
     109        (JSC::ScopedArguments::setModifiedArgumentDescriptor):
     110        (JSC::ScopedArguments::isModifiedArgumentDescriptor):
     111        (JSC::ScopedArguments::canAccessIndexQuickly): Deleted.
     112        (JSC::ScopedArguments::canAccessArgumentIndexQuicklyInDFG): Deleted.
     113
    11142016-12-23  Mark Lam  <mark.lam@apple.com>
    2115
  • trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp

    r209897 r210146  
    639639            jit.branchTestPtr(
    640640                CCallHelpers::NonZero,
    641                 CCallHelpers::Address(baseGPR, DirectArguments::offsetOfOverrides())));
     641                CCallHelpers::Address(baseGPR, DirectArguments::offsetOfMappedArguments())));
    642642        jit.load32(
    643643            CCallHelpers::Address(baseGPR, DirectArguments::offsetOfLength()),
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r210023 r210146  
    61196119        m_jit.branchTestPtr(
    61206120            MacroAssembler::NonZero,
    6121             MacroAssembler::Address(baseReg, DirectArguments::offsetOfOverrides())));
     6121            MacroAssembler::Address(baseReg, DirectArguments::offsetOfMappedArguments())));
    61226122    speculationCheck(
    61236123        ExoticObjectMode, JSValueSource(), 0,
     
    62936293            m_jit.branchTestPtr(
    62946294                MacroAssembler::NonZero,
    6295                 MacroAssembler::Address(baseReg, DirectArguments::offsetOfOverrides())));
     6295                MacroAssembler::Address(baseReg, DirectArguments::offsetOfMappedArguments())));
    62966296       
    62976297        m_jit.load32(
     
    66596659       
    66606660    m_jit.storePtr(
    6661         TrustedImmPtr(0), JITCompiler::Address(resultGPR, DirectArguments::offsetOfOverrides()));
     6661        TrustedImmPtr(0), JITCompiler::Address(resultGPR, DirectArguments::offsetOfMappedArguments()));
     6662
     6663    m_jit.storePtr(
     6664        TrustedImmPtr(0), JITCompiler::Address(resultGPR, DirectArguments::offsetOfModifiedArgumentsDescriptor()));
    66626665   
    66636666    if (lengthIsKnown) {
  • trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h

    r209146 r210146  
    5252    macro(DirectArguments_length, DirectArguments::offsetOfLength()) \
    5353    macro(DirectArguments_minCapacity, DirectArguments::offsetOfMinCapacity()) \
    54     macro(DirectArguments_overrides, DirectArguments::offsetOfOverrides()) \
     54    macro(DirectArguments_mappedArguments, DirectArguments::offsetOfMappedArguments()) \
     55    macro(DirectArguments_modifiedArgumentsDescriptor, DirectArguments::offsetOfModifiedArgumentsDescriptor()) \
    5556    macro(GetterSetter_getter, GetterSetter::offsetOfGetter()) \
    5657    macro(GetterSetter_setter, GetterSetter::offsetOfSetter()) \
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r209846 r210146  
    31413141            speculate(
    31423142                ExoticObjectMode, noValue(), nullptr,
    3143                 m_out.notNull(m_out.loadPtr(arguments, m_heaps.DirectArguments_overrides)));
     3143                m_out.notNull(m_out.loadPtr(arguments, m_heaps.DirectArguments_mappedArguments)));
    31443144            setInt32(m_out.load32NonNegative(arguments, m_heaps.DirectArguments_length));
    31453145            return;
     
    32933293            speculate(
    32943294                ExoticObjectMode, noValue(), nullptr,
    3295                 m_out.notNull(m_out.loadPtr(base, m_heaps.DirectArguments_overrides)));
     3295                m_out.notNull(m_out.loadPtr(base, m_heaps.DirectArguments_mappedArguments)));
    32963296            speculate(
    32973297                ExoticObjectMode, noValue(), nullptr,
     
    40894089        m_out.store32(length.value, fastObject, m_heaps.DirectArguments_length);
    40904090        m_out.store32(m_out.constInt32(minCapacity), fastObject, m_heaps.DirectArguments_minCapacity);
    4091         m_out.storePtr(m_out.intPtrZero, fastObject, m_heaps.DirectArguments_overrides);
     4091        m_out.storePtr(m_out.intPtrZero, fastObject, m_heaps.DirectArguments_mappedArguments);
     4092        m_out.storePtr(m_out.intPtrZero, fastObject, m_heaps.DirectArguments_modifiedArgumentsDescriptor);
    40924093       
    40934094        ValueFromBlock fastResult = m_out.anchor(fastObject);
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r209764 r210146  
    16211621    case DirectArgumentsType: {
    16221622        DirectArguments* directArguments = jsCast<DirectArguments*>(&object);
    1623         if (directArguments->canAccessArgumentIndexQuicklyInDFG(index))
     1623        if (directArguments->isMappedArgumentInDFG(index))
    16241624            return true;
    16251625        break;
     
    16271627    case ScopedArgumentsType: {
    16281628        ScopedArguments* scopedArguments = jsCast<ScopedArguments*>(&object);
    1629         if (scopedArguments->canAccessArgumentIndexQuicklyInDFG(index))
     1629        if (scopedArguments->isMappedArgumentInDFG(index))
    16301630            return true;
    16311631        break;
  • trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp

    r208761 r210146  
    14591459   
    14601460    slowCases.append(branch32(AboveOrEqual, property, Address(base, DirectArguments::offsetOfLength())));
    1461     slowCases.append(branchTestPtr(NonZero, Address(base, DirectArguments::offsetOfOverrides())));
     1461    slowCases.append(branchTestPtr(NonZero, Address(base, DirectArguments::offsetOfMappedArguments())));
    14621462   
    14631463    zeroExtend32ToPtr(property, scratch);
  • trunk/Source/JavaScriptCore/runtime/DirectArguments.cpp

    r209897 r210146  
    8787{
    8888    DirectArguments* thisObject = jsCast<DirectArguments*>(cell);
    89     size_t overridesSize = thisObject->m_overrides ? thisObject->overridesSize() : 0;
    90     return Base::estimatedSize(cell) + overridesSize;
     89    size_t mappedArgumentsSize = thisObject->m_mappedArguments ? thisObject->mappedArgumentsSize() * sizeof(bool) : 0;
     90    size_t modifiedArgumentsSize = thisObject->m_modifiedArgumentsDescriptor ? thisObject->m_length * sizeof(bool) : 0;
     91    return Base::estimatedSize(cell) + mappedArgumentsSize + modifiedArgumentsSize;
    9192}
    9293
     
    9697    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    9798    Base::visitChildren(thisObject, visitor);
    98    
     99
    99100    visitor.appendValues(thisObject->storage(), std::max(thisObject->m_length, thisObject->m_minCapacity));
    100101    visitor.append(thisObject->m_callee);
    101102
    102     if (bool* override = thisObject->m_overrides.get())
    103         visitor.markAuxiliary(override);
     103    if (thisObject->m_mappedArguments)
     104        visitor.markAuxiliary(thisObject->m_mappedArguments.get());
     105    GenericArguments<DirectArguments>::visitChildren(thisCell, visitor);
    104106}
    105107
     
    111113void DirectArguments::overrideThings(VM& vm)
    112114{
    113     RELEASE_ASSERT(!m_overrides);
     115    RELEASE_ASSERT(!m_mappedArguments);
    114116   
    115117    putDirect(vm, vm.propertyNames->length, jsNumber(m_length), DontEnum);
     
    117119    putDirect(vm, vm.propertyNames->iteratorSymbol, globalObject()->arrayProtoValuesFunction(), DontEnum);
    118120   
    119     void* backingStore = vm.heap.tryAllocateAuxiliary(this, overridesSize());
     121    void* backingStore = vm.heap.tryAllocateAuxiliary(this, mappedArgumentsSize());
    120122    RELEASE_ASSERT(backingStore);
    121123    bool* overrides = static_cast<bool*>(backingStore);
    122     m_overrides.set(vm, this, overrides);
     124    m_mappedArguments.set(vm, this, overrides);
    123125    for (unsigned i = m_length; i--;)
    124126        overrides[i] = false;
     
    127129void DirectArguments::overrideThingsIfNecessary(VM& vm)
    128130{
    129     if (!m_overrides)
     131    if (!m_mappedArguments)
    130132        overrideThings(vm);
    131133}
    132134
    133 void DirectArguments::overrideArgument(VM& vm, unsigned index)
     135void DirectArguments::unmapArgument(VM& vm, unsigned index)
    134136{
    135137    overrideThingsIfNecessary(vm);
    136     m_overrides.get()[index] = true;
     138    m_mappedArguments.get()[index] = true;
    137139}
    138140
    139141void DirectArguments::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length)
    140142{
    141     if (!m_overrides) {
     143    if (!m_mappedArguments) {
    142144        unsigned limit = std::min(length + offset, m_length);
    143145        unsigned i;
     
    153155}
    154156
    155 unsigned DirectArguments::overridesSize()
     157unsigned DirectArguments::mappedArgumentsSize()
    156158{
    157159    // We always allocate something; in the relatively uncommon case of overriding an empty argument we
    158     // still allocate so that m_overrides is non-null. We use that to indicate that the other properties
     160    // still allocate so that m_mappedArguments is non-null. We use that to indicate that the other properties
    159161    // (length, etc) are overridden.
    160162    return WTF::roundUpToMultipleOf<8>(m_length ? m_length : 1);
  • trunk/Source/JavaScriptCore/runtime/DirectArguments.h

    r206525 r210146  
    6767    uint32_t length(ExecState* exec) const
    6868    {
    69         if (UNLIKELY(m_overrides))
     69        if (UNLIKELY(m_mappedArguments))
    7070            return get(exec, exec->propertyNames().length).toUInt32(exec);
    7171        return m_length;
    7272    }
    7373   
    74     bool canAccessIndexQuickly(uint32_t i) const
     74    bool isMappedArgument(uint32_t i) const
    7575    {
    76         return i < m_length && (!m_overrides || !m_overrides.get()[i]);
     76        return i < m_length && (!m_mappedArguments || !m_mappedArguments.get()[i]);
    7777    }
    7878
    79     bool canAccessArgumentIndexQuicklyInDFG(uint32_t i) const
     79    bool isMappedArgumentInDFG(uint32_t i) const
    8080    {
    8181        return i < m_length && !overrodeThings();
     
    8484    JSValue getIndexQuickly(uint32_t i) const
    8585    {
    86         ASSERT_WITH_SECURITY_IMPLICATION(canAccessIndexQuickly(i));
     86        ASSERT_WITH_SECURITY_IMPLICATION(isMappedArgument(i));
    8787        return const_cast<DirectArguments*>(this)->storage()[i].get();
    8888    }
     
    9090    void setIndexQuickly(VM& vm, uint32_t i, JSValue value)
    9191    {
    92         ASSERT_WITH_SECURITY_IMPLICATION(canAccessIndexQuickly(i));
     92        ASSERT_WITH_SECURITY_IMPLICATION(isMappedArgument(i));
    9393        storage()[i].set(vm, this, value);
    9494    }
     
    107107   
    108108    // Methods intended for use by the GenericArguments mixin.
    109     bool overrodeThings() const { return !!m_overrides; }
     109    bool overrodeThings() const { return !!m_mappedArguments; }
    110110    void overrideThings(VM&);
    111111    void overrideThingsIfNecessary(VM&);
    112     void overrideArgument(VM&, unsigned index);
    113    
     112    void unmapArgument(VM&, unsigned index);
     113
     114    void initModifiedArgumentsDescriptorIfNecessary(VM& vm)
     115    {
     116        GenericArguments<DirectArguments>::initModifiedArgumentsDescriptorIfNecessary(vm, m_length);
     117    }
     118
     119    void setModifiedArgumentDescriptor(VM& vm, unsigned index)
     120    {
     121        GenericArguments<DirectArguments>::setModifiedArgumentDescriptor(vm, index, m_length);
     122    }
     123
     124    bool isModifiedArgumentDescriptor(unsigned index)
     125    {
     126        return GenericArguments<DirectArguments>::isModifiedArgumentDescriptor(index, m_length);
     127    }
     128
    114129    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
    115130
     
    121136    static ptrdiff_t offsetOfLength() { return OBJECT_OFFSETOF(DirectArguments, m_length); }
    122137    static ptrdiff_t offsetOfMinCapacity() { return OBJECT_OFFSETOF(DirectArguments, m_minCapacity); }
    123     static ptrdiff_t offsetOfOverrides() { return OBJECT_OFFSETOF(DirectArguments, m_overrides); }
     138    static ptrdiff_t offsetOfMappedArguments() { return OBJECT_OFFSETOF(DirectArguments, m_mappedArguments); }
     139    static ptrdiff_t offsetOfModifiedArgumentsDescriptor() { return OBJECT_OFFSETOF(DirectArguments, m_modifiedArgumentsDescriptor); }
    124140   
    125141    static size_t storageOffset()
     
    144160    }
    145161   
    146     unsigned overridesSize();
     162    unsigned mappedArgumentsSize();
    147163   
    148164    WriteBarrier<JSFunction> m_callee;
    149165    uint32_t m_length; // Always the actual length of captured arguments and never what was stored into the length property.
    150166    uint32_t m_minCapacity; // The max of this and length determines the capacity of this object. It may be the actual capacity, or maybe something smaller. We arrange it this way to be kind to the JITs.
    151     AuxiliaryBarrier<bool*> m_overrides; // If non-null, it means that length, callee, and caller are fully materialized properties.
     167    AuxiliaryBarrier<bool*> m_mappedArguments; // If non-null, it means that length, callee, and caller are fully materialized properties.
    152168};
    153169
  • trunk/Source/JavaScriptCore/runtime/GenericArguments.h

    r206525 r210146  
    4444    }
    4545
     46    static void visitChildren(JSCell*, SlotVisitor&);
    4647    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    4748    static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
     
    5354    static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
    5455   
     56    void initModifiedArgumentsDescriptor(VM&, unsigned length);
     57    void initModifiedArgumentsDescriptorIfNecessary(VM&, unsigned length);
     58    void setModifiedArgumentDescriptor(VM&, unsigned index, unsigned length);
     59    bool isModifiedArgumentDescriptor(unsigned index, unsigned length);
     60
    5561    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
     62   
     63    AuxiliaryBarrier<bool*> m_modifiedArgumentsDescriptor;
    5664};
    5765
  • trunk/Source/JavaScriptCore/runtime/GenericArgumentsInlines.h

    r208985 r210146  
    3232
    3333template<typename Type>
     34void GenericArguments<Type>::visitChildren(JSCell* thisCell, SlotVisitor& visitor)
     35{
     36    Type* thisObject = static_cast<Type*>(thisCell);
     37    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     38   
     39    if (thisObject->m_modifiedArgumentsDescriptor)
     40        visitor.markAuxiliary(thisObject->m_modifiedArgumentsDescriptor.get());
     41}
     42
     43template<typename Type>
    3444bool GenericArguments<Type>::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName ident, PropertySlot& slot)
    3545{
     
    5363   
    5464    std::optional<uint32_t> index = parseIndex(ident);
    55     if (index && thisObject->canAccessIndexQuickly(index.value())) {
     65    if (index && !thisObject->isModifiedArgumentDescriptor(index.value()) && thisObject->isMappedArgument(index.value())) {
    5666        slot.setValue(thisObject, None, thisObject->getIndexQuickly(index.value()));
    5767        return true;
    5868    }
    5969   
    60     return Base::getOwnPropertySlot(thisObject, exec, ident, slot);
     70    bool result = Base::getOwnPropertySlot(thisObject, exec, ident, slot);
     71   
     72    if (index && thisObject->isMappedArgument(index.value()))
     73        slot.setValue(thisObject, slot.attributes(), thisObject->getIndexQuickly(index.value()));
     74   
     75    return result;
    6176}
    6277
     
    6681    Type* thisObject = jsCast<Type*>(object);
    6782   
    68     if (thisObject->canAccessIndexQuickly(index)) {
    69         JSValue result = thisObject->getIndexQuickly(index);
    70         slot.setValue(thisObject, None, result);
     83    if (!thisObject->isModifiedArgumentDescriptor(index) && thisObject->isMappedArgument(index)) {
     84        slot.setValue(thisObject, None, thisObject->getIndexQuickly(index));
    7185        return true;
    7286    }
    7387   
    7488    bool result = Base::getOwnPropertySlotByIndex(object, exec, index, slot);
     89   
     90    if (thisObject->isMappedArgument(index))
     91        slot.setValue(thisObject, slot.attributes(), thisObject->getIndexQuickly(index));
     92   
    7593    return result;
    7694}
     
    83101    if (array.includeStringProperties()) {
    84102        for (unsigned i = 0; i < thisObject->internalLength(); ++i) {
    85             if (!thisObject->canAccessIndexQuickly(i))
     103            if (!thisObject->isMappedArgument(i))
    86104                continue;
    87105            array.add(Identifier::from(exec, i));
     
    119137   
    120138    std::optional<uint32_t> index = parseIndex(ident);
    121     if (index && thisObject->canAccessIndexQuickly(index.value())) {
     139    if (index && thisObject->isMappedArgument(index.value())) {
    122140        thisObject->setIndexQuickly(vm, index.value(), value);
    123141        return true;
     
    132150    Type* thisObject = jsCast<Type*>(cell);
    133151    VM& vm = exec->vm();
    134    
    135     if (thisObject->canAccessIndexQuickly(index)) {
     152
     153    if (thisObject->isMappedArgument(index)) {
    136154        thisObject->setIndexQuickly(vm, index, value);
    137155        return true;
     
    154172   
    155173    std::optional<uint32_t> index = parseIndex(ident);
    156     if (index && thisObject->canAccessIndexQuickly(index.value())) {
    157         thisObject->overrideArgument(vm, index.value());
     174    if (index && !thisObject->isModifiedArgumentDescriptor(index.value()) && thisObject->isMappedArgument(index.value())) {
     175        thisObject->unmapArgument(vm, index.value());
     176        thisObject->setModifiedArgumentDescriptor(vm, index.value());
    158177        return true;
    159178    }
     
    167186    Type* thisObject = jsCast<Type*>(cell);
    168187    VM& vm = exec->vm();
    169    
    170     if (thisObject->canAccessIndexQuickly(index)) {
    171         thisObject->overrideArgument(vm, index);
    172         return true;
    173     }
    174    
     188
     189    if (!thisObject->isModifiedArgumentDescriptor(index) && thisObject->isMappedArgument(index)) {
     190        thisObject->unmapArgument(vm, index);
     191        thisObject->setModifiedArgumentDescriptor(vm, index);
     192        return true;
     193    }
     194
    175195    return Base::deletePropertyByIndex(cell, exec, index);
    176196}
     
    188208    else {
    189209        std::optional<uint32_t> optionalIndex = parseIndex(ident);
    190         if (optionalIndex && thisObject->canAccessIndexQuickly(optionalIndex.value())) {
     210        if (optionalIndex) {
    191211            uint32_t index = optionalIndex.value();
    192             if (!descriptor.isAccessorDescriptor()) {
     212            if (!descriptor.isAccessorDescriptor() && thisObject->isMappedArgument(optionalIndex.value())) {
    193213                // If the property is not deleted and we are using a non-accessor descriptor, then
    194214                // make sure that the aliased argument sees the value.
     
    196216                    thisObject->setIndexQuickly(vm, index, descriptor.value());
    197217           
    198                 // If the property is not deleted and we are using a non-accessor, writable
    199                 // descriptor, then we are done. The argument continues to be aliased. Note that we
    200                 // ignore the request to change enumerability. We appear to have always done so, in
    201                 // cases where the argument was still aliased.
    202                 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=141952
    203                 if (descriptor.writable())
     218                // If the property is not deleted and we are using a non-accessor, writable,
     219                // configurable and enumerable descriptor and isn't modified, then we are done.
     220                // The argument continues to be aliased.
     221                if (descriptor.writable() && descriptor.configurable() && descriptor.enumerable() && !thisObject->isModifiedArgumentDescriptor(index))
    204222                    return true;
     223               
     224                if (!thisObject->isModifiedArgumentDescriptor(index)) {
     225                    // If it is a new entry, we need to put direct to initialize argument[i] descriptor properly
     226                    JSValue value = thisObject->getIndexQuickly(index);
     227                    ASSERT(value);
     228                    object->putDirectMayBeIndex(exec, ident, value);
     229                   
     230                    thisObject->setModifiedArgumentDescriptor(vm, index);
     231                }
    205232            }
    206        
    207             // If the property is a non-deleted argument, then move it into the base object and
    208             // then delete it.
    209             JSValue value = thisObject->getIndexQuickly(index);
    210             ASSERT(value);
    211             object->putDirectMayBeIndex(exec, ident, value);
    212             thisObject->overrideArgument(vm, index);
    213         }
    214     }
    215    
     233           
     234            if (thisObject->isMappedArgument(index)) {
     235                // Just unmap arguments if its descriptor contains {writable: false}.
     236                // Check https://tc39.github.io/ecma262/#sec-createunmappedargumentsobject
     237                // and https://tc39.github.io/ecma262/#sec-createmappedargumentsobject to verify that all data
     238                // property from arguments object are {writable: true, configurable: true, enumerable: true} by default
     239                if ((descriptor.writablePresent() && !descriptor.writable()) || descriptor.isAccessorDescriptor()) {
     240                    if (!descriptor.isAccessorDescriptor()) {
     241                        JSValue value = thisObject->getIndexQuickly(index);
     242                        ASSERT(value);
     243                        object->putDirectMayBeIndex(exec, ident, value);
     244                    }
     245                    thisObject->unmapArgument(vm, index);
     246                    thisObject->setModifiedArgumentDescriptor(vm, index);
     247                }
     248            }
     249        }
     250    }
     251
    216252    // Now just let the normal object machinery do its thing.
    217253    return Base::defineOwnProperty(object, exec, ident, descriptor, shouldThrow);
     
    219255
    220256template<typename Type>
     257void GenericArguments<Type>::initModifiedArgumentsDescriptor(VM& vm, unsigned argsLength)
     258{
     259    RELEASE_ASSERT(!m_modifiedArgumentsDescriptor);
     260
     261    if (argsLength) {
     262        void* backingStore = vm.heap.tryAllocateAuxiliary(this, WTF::roundUpToMultipleOf<8>(argsLength));
     263        RELEASE_ASSERT(backingStore);
     264        bool* modifiedArguments = static_cast<bool*>(backingStore);
     265        m_modifiedArgumentsDescriptor.set(vm, this, modifiedArguments);
     266        for (unsigned i = argsLength; i--;)
     267            modifiedArguments[i] = false;
     268    }
     269}
     270
     271template<typename Type>
     272void GenericArguments<Type>::initModifiedArgumentsDescriptorIfNecessary(VM& vm, unsigned argsLength)
     273{
     274    if (!m_modifiedArgumentsDescriptor)
     275        initModifiedArgumentsDescriptor(vm, argsLength);
     276}
     277
     278template<typename Type>
     279void GenericArguments<Type>::setModifiedArgumentDescriptor(VM& vm, unsigned index, unsigned length)
     280{
     281    initModifiedArgumentsDescriptorIfNecessary(vm, length);
     282    if (index < length)
     283        m_modifiedArgumentsDescriptor.get()[index] = true;
     284}
     285
     286template<typename Type>
     287bool GenericArguments<Type>::isModifiedArgumentDescriptor(unsigned index, unsigned length)
     288{
     289    if (!m_modifiedArgumentsDescriptor)
     290        return false;
     291    if (index < length)
     292        return m_modifiedArgumentsDescriptor.get()[index];
     293    return false;
     294}
     295
     296template<typename Type>
    221297void GenericArguments<Type>::copyToArguments(ExecState* exec, VirtualRegister firstElementDest, unsigned offset, unsigned length)
    222298{
     
    226302    Type* thisObject = static_cast<Type*>(this);
    227303    for (unsigned i = 0; i < length; ++i) {
    228         if (thisObject->canAccessIndexQuickly(i + offset))
     304        if (thisObject->isMappedArgument(i + offset))
    229305            exec->r(firstElementDest + i) = thisObject->getIndexQuickly(i + offset);
    230306        else {
  • trunk/Source/JavaScriptCore/runtime/ScopedArguments.cpp

    r209897 r210146  
    112112            thisObject->overflowStorage(), thisObject->m_totalLength - thisObject->m_table->length());
    113113    }
     114
     115    GenericArguments<ScopedArguments>::visitChildren(cell, visitor);
    114116}
    115117
     
    136138}
    137139
    138 void ScopedArguments::overrideArgument(VM& vm, uint32_t i)
     140void ScopedArguments::unmapArgument(VM& vm, uint32_t i)
    139141{
    140142    ASSERT_WITH_SECURITY_IMPLICATION(i < m_totalLength);
  • trunk/Source/JavaScriptCore/runtime/ScopedArguments.h

    r206525 r210146  
    7171    }
    7272   
    73     bool canAccessIndexQuickly(uint32_t i) const
     73    bool isMappedArgument(uint32_t i) const
    7474    {
    7575        if (i >= m_totalLength)
     
    8181    }
    8282
    83     bool canAccessArgumentIndexQuicklyInDFG(uint32_t i) const
     83    bool isMappedArgumentInDFG(uint32_t i) const
    8484    {
    85         return canAccessIndexQuickly(i);
     85        return isMappedArgument(i);
    8686    }
    8787   
    8888    JSValue getIndexQuickly(uint32_t i) const
    8989    {
    90         ASSERT_WITH_SECURITY_IMPLICATION(canAccessIndexQuickly(i));
     90        ASSERT_WITH_SECURITY_IMPLICATION(isMappedArgument(i));
    9191        unsigned namedLength = m_table->length();
    9292        if (i < namedLength)
     
    9797    void setIndexQuickly(VM& vm, uint32_t i, JSValue value)
    9898    {
    99         ASSERT_WITH_SECURITY_IMPLICATION(canAccessIndexQuickly(i));
     99        ASSERT_WITH_SECURITY_IMPLICATION(isMappedArgument(i));
    100100        unsigned namedLength = m_table->length();
    101101        if (i < namedLength)
     
    109109        return m_callee;
    110110    }
    111    
     111
    112112    bool overrodeThings() const { return m_overrodeThings; }
    113113    void overrideThings(VM&);
    114114    void overrideThingsIfNecessary(VM&);
    115     void overrideArgument(VM&, uint32_t index);
     115    void unmapArgument(VM&, uint32_t index);
    116116   
     117    void initModifiedArgumentsDescriptorIfNecessary(VM& vm)
     118    {
     119        GenericArguments<ScopedArguments>::initModifiedArgumentsDescriptorIfNecessary(vm, m_table->length());
     120    }
     121
     122    void setModifiedArgumentDescriptor(VM& vm, unsigned index)
     123    {
     124        GenericArguments<ScopedArguments>::setModifiedArgumentDescriptor(vm, index, m_table->length());
     125    }
     126
     127    bool isModifiedArgumentDescriptor(unsigned index)
     128    {
     129        return GenericArguments<ScopedArguments>::isModifiedArgumentDescriptor(index, m_table->length());
     130    }
     131
    117132    void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
    118133
Note: See TracChangeset for help on using the changeset viewer.