Changeset 109866 in webkit


Ignore:
Timestamp:
Mar 5, 2012 11:23:21 PM (12 years ago)
Author:
barraclough@apple.com
Message:

putByIndex should throw in strict mode
https://bugs.webkit.org/show_bug.cgi?id=80335

Reviewed by Filip Pizlo.

Make the MethodTable PutByIndex trap take a boolean 'shouldThrow' parameter.

Source/JavaScriptCore:

This is a largely mechanical change, simply adding an extra parameter to a number
of functions. Some call sites need perform additional exception checks, and
operationPutByValBeyondArrayBounds needs to know whether it is strict or not.

This patch doesn't fix a missing throw from some cases of shift/unshift (this is
an existing bug), I'll follow up with a third patch to handle that.

  • API/JSObjectRef.cpp:

(JSObjectSetPropertyAtIndex):

  • JSCTypedArrayStubs.h:

(JSC):

  • dfg/DFGOperations.cpp:

(JSC::DFG::putByVal):

  • dfg/DFGOperations.h:
  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::privateExecute):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • jsc.cpp:

(GlobalObject::finishCreation):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • runtime/Arguments.cpp:

(JSC::Arguments::putByIndex):

  • runtime/Arguments.h:

(Arguments):

  • runtime/ArrayPrototype.cpp:

(JSC::arrayProtoFuncPush):
(JSC::arrayProtoFuncReverse):
(JSC::arrayProtoFuncShift):
(JSC::arrayProtoFuncSort):
(JSC::arrayProtoFuncSplice):
(JSC::arrayProtoFuncUnShift):

  • runtime/ClassInfo.h:

(MethodTable):

  • runtime/JSArray.cpp:

(JSC::SparseArrayValueMap::put):
(JSC::JSArray::put):
(JSC::JSArray::putByIndex):
(JSC::JSArray::putByIndexBeyondVectorLength):
(JSC::JSArray::push):
(JSC::JSArray::shiftCount):
(JSC::JSArray::unshiftCount):

  • runtime/JSArray.h:

(SparseArrayValueMap):
(JSArray):

  • runtime/JSByteArray.cpp:

(JSC::JSByteArray::putByIndex):

  • runtime/JSByteArray.h:

(JSByteArray):

  • runtime/JSCell.cpp:

(JSC::JSCell::putByIndex):

  • runtime/JSCell.h:

(JSCell):

  • runtime/JSNotAnObject.cpp:

(JSC::JSNotAnObject::putByIndex):

  • runtime/JSNotAnObject.h:

(JSNotAnObject):

  • runtime/JSONObject.cpp:

(JSC::Walker::walk):

  • runtime/JSObject.cpp:

(JSC::JSObject::putByIndex):

  • runtime/JSObject.h:

(JSC::JSValue::putByIndex):

  • runtime/RegExpConstructor.cpp:

(JSC::RegExpMatchesArray::fillArrayInstance):

  • runtime/RegExpMatchesArray.h:

(JSC::RegExpMatchesArray::putByIndex):

  • runtime/StringPrototype.cpp:

(JSC::stringProtoFuncSplit):

Source/WebCore:

  • bindings/js/SerializedScriptValue.cpp:

(WebCore::CloneDeserializer::putProperty):

  • bindings/objc/WebScriptObject.mm:

(-[WebScriptObject setWebScriptValueAtIndex:value:]):

  • bindings/scripts/CodeGeneratorJS.pm:

(GenerateHeader):
(GenerateImplementation):

  • bridge/NP_jsobject.cpp:

(_NPN_SetProperty):

  • bridge/jni/jni_jsobject.mm:

(JavaJSObject::setSlot):

  • bridge/runtime_array.cpp:

(JSC::RuntimeArray::putByIndex):

  • bridge/runtime_array.h:

(RuntimeArray):

Source/WebKit/mac:

  • Plugins/Hosted/NetscapePluginInstanceProxy.mm:

(WebKit::NetscapePluginInstanceProxy::setProperty):

Source/WebKit2:

  • WebProcess/Plugins/Netscape/NPJSObject.cpp:

(WebKit::NPJSObject::setProperty):

LayoutTests:

  • fast/js/Object-defineProperty-expected.txt:
  • fast/js/mozilla/strict/15.4.4.12-expected.txt:
  • fast/js/mozilla/strict/15.4.4.13-expected.txt:
  • fast/js/mozilla/strict/15.4.4.8-expected.txt:
  • fast/js/mozilla/strict/15.4.4.9-expected.txt:
  • fast/js/mozilla/strict/15.5.5.2-expected.txt:
  • fast/js/mozilla/strict/8.12.5-expected.txt:
  • fast/js/preventExtensions-expected.txt:
  • fast/js/primitive-property-access-edge-cases-expected.txt:
    • Checking in passing test results.
  • fast/js/script-tests/Object-defineProperty.js:
    • Added test cases for putting to numeric properties where property is read-only, length is read-only, or property is accessor with missing set function.
  • fast/js/script-tests/preventExtensions.js:
    • Added test case, putting numeric property to non-extensible array.
  • fast/js/script-tests/primitive-property-access-edge-cases.js:
    • Enabled test cases for putting numeric properties to primitive strings.
Location:
trunk
Files:
56 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r109851 r109866  
     12012-03-05  Gavin Barraclough  <barraclough@apple.com>
     2
     3        putByIndex should throw in strict mode
     4        https://bugs.webkit.org/show_bug.cgi?id=80335
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Make the MethodTable PutByIndex trap take a boolean 'shouldThrow' parameter.
     9
     10        * fast/js/Object-defineProperty-expected.txt:
     11        * fast/js/mozilla/strict/15.4.4.12-expected.txt:
     12        * fast/js/mozilla/strict/15.4.4.13-expected.txt:
     13        * fast/js/mozilla/strict/15.4.4.8-expected.txt:
     14        * fast/js/mozilla/strict/15.4.4.9-expected.txt:
     15        * fast/js/mozilla/strict/15.5.5.2-expected.txt:
     16        * fast/js/mozilla/strict/8.12.5-expected.txt:
     17        * fast/js/preventExtensions-expected.txt:
     18        * fast/js/primitive-property-access-edge-cases-expected.txt:
     19            - Checking in passing test results.
     20        * fast/js/script-tests/Object-defineProperty.js:
     21            - Added test cases for putting to numeric properties where property is read-only,
     22              length is read-only, or property is accessor with missing set function.
     23        * fast/js/script-tests/preventExtensions.js:
     24            - Added test case, putting numeric property to non-extensible array.
     25        * fast/js/script-tests/primitive-property-access-edge-cases.js:
     26            - Enabled test cases for putting numeric properties to primitive strings.
     27
    1282012-03-05  Adrienne Walker  <enne@google.com>
    229
  • trunk/LayoutTests/fast/js/Object-defineProperty-expected.txt

    r109240 r109866  
    120120PASS Object.getOwnPropertyDescriptor(Object.defineProperty(Object.defineProperty({}, 'foo', {get: function() { return false; }, configurable: true}), 'foo', {value:false, writable: false}), 'foo').writable is false
    121121PASS Object.getOwnPropertyDescriptor(Object.defineProperty(Object.defineProperty({}, 'foo', {get: function() { return false; }, configurable: true}), 'foo', {value:false, writable: true}), 'foo').writable is true
     122PASS var a = Object.defineProperty([], 'length', {writable: false}); a[0] = 42; 0 in a; is false
     123PASS 'use strict'; var a = Object.defineProperty([], 'length', {writable: false}); a[0] = 42; 0 in a; threw exception TypeError: Attempted to assign to readonly property..
     124PASS var a = Object.defineProperty([42], '0', {writable: false}); a[0] = false; a[0]; is 42
     125PASS 'use strict'; var a = Object.defineProperty([42], '0', {writable: false}); a[0] = false; a[0]; threw exception TypeError: Attempted to assign to readonly property..
     126PASS var a = Object.defineProperty([], '0', {set: undefined}); a[0] = 42; a[0]; is undefined.
     127PASS 'use strict'; var a = Object.defineProperty([], '0', {set: undefined}); a[0] = 42; a[0]; threw exception TypeError: Attempted to assign to readonly property..
    122128PASS successfullyParsed is true
    123129
  • trunk/LayoutTests/fast/js/mozilla/strict/15.4.4.12-expected.txt

    r78731 r109866  
    22FAIL var a = arr(); [a.splice(0, 1), a] should throw an instance of TypeError
    33PASS true === true
    4 FAIL 'use strict'; var o = obj(); [Array.prototype.splice.call(o, 0, 1), o] should throw an instance of TypeError
    5 FAIL var o = obj(); [Array.prototype.splice.call(o, 0, 1), o] should throw an instance of TypeError
     4PASS 'use strict'; var o = obj(); [Array.prototype.splice.call(o, 0, 1), o] threw exception of type TypeError.
     5PASS var o = obj(); [Array.prototype.splice.call(o, 0, 1), o] threw exception of type TypeError.
    66PASS true === true
    77FAIL 'use strict'; var a = agap(); [a.splice(0, 1), a] should throw an instance of TypeError
  • trunk/LayoutTests/fast/js/mozilla/strict/15.4.4.13-expected.txt

    r78731 r109866  
    22FAIL var a = arr(); [a.unshift(40, 50), a] should throw an instance of TypeError
    33PASS true === true
    4 FAIL 'use strict'; var o = obj(); [Array.prototype.unshift.call(o, 40, 50), o] should throw an instance of TypeError
    5 FAIL var o = obj(); [Array.prototype.unshift.call(o, 40, 50), o] should throw an instance of TypeError
     4PASS 'use strict'; var o = obj(); [Array.prototype.unshift.call(o, 40, 50), o] threw exception of type TypeError.
     5PASS var o = obj(); [Array.prototype.unshift.call(o, 40, 50), o] threw exception of type TypeError.
    66PASS true === true
    77FAIL 'use strict'; var a = agap(); [a.unshift(9), a] should throw an instance of TypeError
  • trunk/LayoutTests/fast/js/mozilla/strict/15.4.4.8-expected.txt

    r78731 r109866  
    1 FAIL 'use strict'; var a = arr(); a.reverse() should throw an instance of TypeError
    2 FAIL var a = arr(); a.reverse() should throw an instance of TypeError
     1PASS 'use strict'; var a = arr(); a.reverse() threw exception of type TypeError.
     2PASS var a = arr(); a.reverse() threw exception of type TypeError.
    33PASS true === true
    4 FAIL 'use strict'; var o = obj(); Array.prototype.reverse.call(o) should throw an instance of TypeError
    5 FAIL var o = obj(); Array.prototype.reverse.call(o) should throw an instance of TypeError
     4PASS 'use strict'; var o = obj(); Array.prototype.reverse.call(o) threw exception of type TypeError.
     5PASS var o = obj(); Array.prototype.reverse.call(o) threw exception of type TypeError.
    66PASS true === true
    77FAIL 'use strict'; var a = agap(); a.reverse() should throw an instance of TypeError
  • trunk/LayoutTests/fast/js/mozilla/strict/15.4.4.9-expected.txt

    r78731 r109866  
    22FAIL var a = arr(); [a.shift(), a] should throw an instance of TypeError
    33PASS true === true
    4 FAIL 'use strict'; var o = obj(); [Array.prototype.shift.call(o), o] should throw an instance of TypeError
    5 FAIL var o = obj(); [Array.prototype.shift.call(o), o] should throw an instance of TypeError
     4PASS 'use strict'; var o = obj(); [Array.prototype.shift.call(o), o] threw exception of type TypeError.
     5PASS var o = obj(); [Array.prototype.shift.call(o), o] threw exception of type TypeError.
    66PASS true === true
    77FAIL 'use strict'; var a = agap(); [a.shift(), a] should throw an instance of TypeError
  • trunk/LayoutTests/fast/js/mozilla/strict/15.5.5.2-expected.txt

    r78731 r109866  
    1 FAIL 'use strict'; "foo"[0] = 1 should throw an instance of TypeError
     1PASS 'use strict'; "foo"[0] = 1 threw exception of type TypeError.
    22PASS "foo"[0] = 1 is 1
    33PASS true === true
  • trunk/LayoutTests/fast/js/mozilla/strict/8.12.5-expected.txt

    r104488 r109866  
    2626PASS var a = arr(); a[0] = 2; a[0] is 2
    2727PASS true === true
    28 FAIL 'use strict'; var a = arr(); a[1] = 2; a[1] should throw an instance of TypeError
     28PASS 'use strict'; var a = arr(); a[1] = 2; a[1] threw exception of type TypeError.
    2929PASS var a = arr(); a[1] = 2; a[1] is 1
    3030PASS true === true
     
    3232PASS var a = arr(); a[2] = 2; a[2] is 2
    3333PASS true === true
    34 FAIL 'use strict'; var a = arr(); a[3] = 2; a[3] should throw an instance of TypeError
     34PASS 'use strict'; var a = arr(); a[3] = 2; a[3] threw exception of type TypeError.
    3535PASS var a = arr(); a[3] = 2; a[3] is 1
    3636PASS true === true
    37 FAIL 'use strict'; arr()[1]++ should throw an instance of TypeError
     37PASS 'use strict'; arr()[1]++ threw exception of type TypeError.
    3838PASS arr()[1]++ is 1
    3939PASS true === true
    40 FAIL 'use strict'; ++arr()[1] should throw an instance of TypeError
     40PASS 'use strict'; ++arr()[1] threw exception of type TypeError.
    4141PASS ++arr()[1] is 2
    4242PASS true === true
    43 FAIL 'use strict'; arr()[1]-- should throw an instance of TypeError
     43PASS 'use strict'; arr()[1]-- threw exception of type TypeError.
    4444PASS arr()[1]-- is 1
    4545PASS true === true
    46 FAIL 'use strict'; --arr()[1] should throw an instance of TypeError
     46PASS 'use strict'; --arr()[1] threw exception of type TypeError.
    4747PASS --arr()[1] is 0
    4848PASS true === true
  • trunk/LayoutTests/fast/js/preventExtensions-expected.txt

    r108651 r109866  
    1717PASS var arr = Object.preventExtensions([]); arr[0] = 42; arr[0] is undefined.
    1818PASS var arr = Object.preventExtensions([]); arr[0] = 42; arr.length is 0
     19PASS "use strict"; var arr = Object.preventExtensions([]); arr[0] = 42; arr[0] threw exception TypeError: Attempted to assign to readonly property..
    1920PASS obj.foo is 1
    2021PASS array[0] is 0
  • trunk/LayoutTests/fast/js/primitive-property-access-edge-cases-expected.txt

    r109824 r109866  
    3838PASS checkNumericGetStrict(true, Boolean) is true
    3939PASS checkNumericSetStrict(1, Number) is true
     40PASS checkNumericSetStrict('hello', String) is true
    4041PASS checkNumericSetStrict(true, Boolean) is true
    4142PASS checkNumericRead(1, Number) is true
     
    4950PASS checkNumericReadStrict(true, Boolean) is true
    5051PASS checkNumericWriteStrict(1, Number) threw exception TypeError: Attempted to assign to readonly property..
     52PASS checkNumericWriteStrict('hello', String) threw exception TypeError: Attempted to assign to readonly property..
    5153PASS checkNumericWriteStrict(true, Boolean) threw exception TypeError: Attempted to assign to readonly property..
    5254PASS didNotCrash is true
  • trunk/LayoutTests/fast/js/script-tests/Object-defineProperty.js

    r109240 r109866  
    172172shouldBeFalse("Object.getOwnPropertyDescriptor(Object.defineProperty(Object.defineProperty({}, 'foo', {get: function() { return false; }, configurable: true}), 'foo', {value:false, writable: false}), 'foo').writable");
    173173shouldBeTrue("Object.getOwnPropertyDescriptor(Object.defineProperty(Object.defineProperty({}, 'foo', {get: function() { return false; }, configurable: true}), 'foo', {value:false, writable: true}), 'foo').writable");
     174
     175// If array length is read-only, [[Put]] should fail.
     176shouldBeFalse("var a = Object.defineProperty([], 'length', {writable: false}); a[0] = 42; 0 in a;");
     177shouldThrow("'use strict'; var a = Object.defineProperty([], 'length', {writable: false}); a[0] = 42; 0 in a;");
     178
     179// If array property is read-only, [[Put]] should fail.
     180shouldBe("var a = Object.defineProperty([42], '0', {writable: false}); a[0] = false; a[0];", '42');
     181shouldThrow("'use strict'; var a = Object.defineProperty([42], '0', {writable: false}); a[0] = false; a[0];");
     182
     183// If array property is an undefined setter, [[Put]] should fail.
     184shouldBeUndefined("var a = Object.defineProperty([], '0', {set: undefined}); a[0] = 42; a[0];");
     185shouldThrow("'use strict'; var a = Object.defineProperty([], '0', {set: undefined}); a[0] = 42; a[0];");
  • trunk/LayoutTests/fast/js/script-tests/preventExtensions.js

    r108651 r109866  
    7979shouldBeUndefined('var arr = Object.preventExtensions([]); arr[0] = 42; arr[0]');
    8080shouldBe('var arr = Object.preventExtensions([]); arr[0] = 42; arr.length', '0');
     81// In strict mode, this throws.
     82shouldThrow('"use strict"; var arr = Object.preventExtensions([]); arr[0] = 42; arr[0]');
    8183
    8284// A read-only property on the prototype should prevent a [[Put]] .
  • trunk/LayoutTests/fast/js/script-tests/primitive-property-access-edge-cases.js

    r109824 r109866  
    173173shouldBeTrue("checkNumericGetStrict(true, Boolean)");
    174174shouldBeTrue("checkNumericSetStrict(1, Number)");
    175 //shouldBeTrue("checkNumericSetStrict('hello', String)"); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=80335
     175shouldBeTrue("checkNumericSetStrict('hello', String)");
    176176shouldBeTrue("checkNumericSetStrict(true, Boolean)");
    177177
     
    210210shouldBeTrue("checkNumericReadStrict(true, Boolean)");
    211211shouldThrow("checkNumericWriteStrict(1, Number)");
    212 //shouldThrow("checkNumericWriteStrict('hello', String)"); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=80335
     212shouldThrow("checkNumericWriteStrict('hello', String)");
    213213shouldThrow("checkNumericWriteStrict(true, Boolean)");
    214214
  • trunk/Source/JavaScriptCore/API/JSObjectRef.cpp

    r104899 r109866  
    313313    JSValue jsValue = toJS(exec, value);
    314314   
    315     jsObject->methodTable()->putByIndex(jsObject, exec, propertyIndex, jsValue);
     315    jsObject->methodTable()->putByIndex(jsObject, exec, propertyIndex, jsValue, false);
    316316    if (exec->hadException()) {
    317317        if (exception)
  • trunk/Source/JavaScriptCore/ChangeLog

    r109865 r109866  
     12012-03-05  Gavin Barraclough  <barraclough@apple.com>
     2
     3        putByIndex should throw in strict mode
     4        https://bugs.webkit.org/show_bug.cgi?id=80335
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Make the MethodTable PutByIndex trap take a boolean 'shouldThrow' parameter.
     9
     10        This is a largely mechanical change, simply adding an extra parameter to a number
     11        of functions. Some call sites need perform additional exception checks, and
     12        operationPutByValBeyondArrayBounds needs to know whether it is strict or not.
     13
     14        This patch doesn't fix a missing throw from some cases of shift/unshift (this is
     15        an existing bug), I'll follow up with a third patch to handle that.
     16
     17        * API/JSObjectRef.cpp:
     18        (JSObjectSetPropertyAtIndex):
     19        * JSCTypedArrayStubs.h:
     20        (JSC):
     21        * dfg/DFGOperations.cpp:
     22        (JSC::DFG::putByVal):
     23        * dfg/DFGOperations.h:
     24        * dfg/DFGSpeculativeJIT32_64.cpp:
     25        (JSC::DFG::SpeculativeJIT::compile):
     26        * dfg/DFGSpeculativeJIT64.cpp:
     27        (JSC::DFG::SpeculativeJIT::compile):
     28        * interpreter/Interpreter.cpp:
     29        (JSC::Interpreter::privateExecute):
     30        * jit/JITStubs.cpp:
     31        (JSC::DEFINE_STUB_FUNCTION):
     32        * jsc.cpp:
     33        (GlobalObject::finishCreation):
     34        * llint/LLIntSlowPaths.cpp:
     35        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
     36        * runtime/Arguments.cpp:
     37        (JSC::Arguments::putByIndex):
     38        * runtime/Arguments.h:
     39        (Arguments):
     40        * runtime/ArrayPrototype.cpp:
     41        (JSC::arrayProtoFuncPush):
     42        (JSC::arrayProtoFuncReverse):
     43        (JSC::arrayProtoFuncShift):
     44        (JSC::arrayProtoFuncSort):
     45        (JSC::arrayProtoFuncSplice):
     46        (JSC::arrayProtoFuncUnShift):
     47        * runtime/ClassInfo.h:
     48        (MethodTable):
     49        * runtime/JSArray.cpp:
     50        (JSC::SparseArrayValueMap::put):
     51        (JSC::JSArray::put):
     52        (JSC::JSArray::putByIndex):
     53        (JSC::JSArray::putByIndexBeyondVectorLength):
     54        (JSC::JSArray::push):
     55        (JSC::JSArray::shiftCount):
     56        (JSC::JSArray::unshiftCount):
     57        * runtime/JSArray.h:
     58        (SparseArrayValueMap):
     59        (JSArray):
     60        * runtime/JSByteArray.cpp:
     61        (JSC::JSByteArray::putByIndex):
     62        * runtime/JSByteArray.h:
     63        (JSByteArray):
     64        * runtime/JSCell.cpp:
     65        (JSC::JSCell::putByIndex):
     66        * runtime/JSCell.h:
     67        (JSCell):
     68        * runtime/JSNotAnObject.cpp:
     69        (JSC::JSNotAnObject::putByIndex):
     70        * runtime/JSNotAnObject.h:
     71        (JSNotAnObject):
     72        * runtime/JSONObject.cpp:
     73        (JSC::Walker::walk):
     74        * runtime/JSObject.cpp:
     75        (JSC::JSObject::putByIndex):
     76        * runtime/JSObject.h:
     77        (JSC::JSValue::putByIndex):
     78        * runtime/RegExpConstructor.cpp:
     79        (JSC::RegExpMatchesArray::fillArrayInstance):
     80        * runtime/RegExpMatchesArray.h:
     81        (JSC::RegExpMatchesArray::putByIndex):
     82        * runtime/StringPrototype.cpp:
     83        (JSC::stringProtoFuncSplit):
     84
    1852012-03-05  Yuqiang Xian  <yuqiang.xian@intel.com>
    286
  • trunk/Source/JavaScriptCore/JSCTypedArrayStubs.h

    r108432 r109866  
    152152}\
    153153\
    154 void JS##name##Array::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value)\
     154void JS##name##Array::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool)\
    155155{\
    156156    JS##name##Array* thisObject = jsCast<JS##name##Array*>(cell);\
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r109837 r109866  
    159159        }
    160160
    161         JSArray::putByIndex(array, exec, index, value);
     161        JSArray::putByIndex(array, exec, index, value, strict);
    162162        return;
    163163    }
     
    475475}
    476476
    477 void DFG_OPERATION operationPutByValBeyondArrayBounds(ExecState* exec, JSArray* array, int32_t index, EncodedJSValue encodedValue)
     477void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSArray* array, int32_t index, EncodedJSValue encodedValue)
    478478{
    479479    JSGlobalData* globalData = &exec->globalData();
     
    482482    // We should only get here if index is outside the existing vector.
    483483    ASSERT(!array->canSetIndex(index));
    484     JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue));
     484    JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue), true);
     485}
     486
     487void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSArray* array, int32_t index, EncodedJSValue encodedValue)
     488{
     489    JSGlobalData* globalData = &exec->globalData();
     490    NativeCallFrameTracer tracer(globalData, exec);
     491   
     492    // We should only get here if index is outside the existing vector.
     493    ASSERT(!array->canSetIndex(index));
     494    JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue), false);
    485495}
    486496
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r108908 r109866  
    120120void DFG_OPERATION operationPutByValCellStrict(ExecState*, JSCell*, EncodedJSValue encodedProperty, EncodedJSValue encodedValue);
    121121void DFG_OPERATION operationPutByValCellNonStrict(ExecState*, JSCell*, EncodedJSValue encodedProperty, EncodedJSValue encodedValue);
    122 void DFG_OPERATION operationPutByValBeyondArrayBounds(ExecState*, JSArray*, int32_t index, EncodedJSValue encodedValue);
     122void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState*, JSArray*, int32_t index, EncodedJSValue encodedValue);
     123void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState*, JSArray*, int32_t index, EncodedJSValue encodedValue);
    123124EncodedJSValue DFG_OPERATION operationArrayPush(ExecState*, EncodedJSValue encodedValue, JSArray*);
    124125EncodedJSValue DFG_OPERATION operationArrayPop(ExecState*, JSArray*);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r109834 r109866  
    23802380        // Code to handle put beyond array bounds.
    23812381        silentSpillAllRegisters(scratchReg);
    2382         callOperation(operationPutByValBeyondArrayBounds, baseReg, propertyReg, valueTagReg, valuePayloadReg);
     2382        callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict, baseReg, propertyReg, valueTagReg, valuePayloadReg);
    23832383        silentFillAllRegisters(scratchReg);
    23842384        JITCompiler::Jump wasBeyondArrayBounds = m_jit.jump();
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r109834 r109866  
    24262426        // Code to handle put beyond array bounds.
    24272427        silentSpillAllRegisters(scratchReg);
    2428         callOperation(operationPutByValBeyondArrayBounds, baseReg, propertyReg, valueReg);
     2428        callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict, baseReg, propertyReg, valueReg);
    24292429        silentFillAllRegisters(scratchReg);
    24302430        JITCompiler::Jump wasBeyondArrayBounds = m_jit.jump();
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r109863 r109866  
    37783778                    jsArray->setIndex(*globalData, i, callFrame->r(value).jsValue());
    37793779                else
    3780                     jsArray->JSArray::putByIndex(jsArray, callFrame, i, callFrame->r(value).jsValue());
     3780                    jsArray->JSArray::putByIndex(jsArray, callFrame, i, callFrame->r(value).jsValue(), codeBlock->isStrictMode());
    37813781            } else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
    37823782                JSByteArray* jsByteArray = asByteArray(baseValue);
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r109837 r109866  
    25542554                jsArray->setIndex(*globalData, i, value);
    25552555            else
    2556                 JSArray::putByIndex(jsArray, callFrame, i, value);
     2556                JSArray::putByIndex(jsArray, callFrame, i, value, callFrame->codeBlock()->isStrictMode());
    25572557        } else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
    25582558            JSByteArray* jsByteArray = asByteArray(baseValue);
  • trunk/Source/JavaScriptCore/jsc.cpp

    r108420 r109866  
    207207#endif
    208208
    209         JSObject* array = constructEmptyArray(globalExec());
     209        JSArray* array = constructEmptyArray(globalExec());
    210210        for (size_t i = 0; i < arguments.size(); ++i)
    211             array->methodTable()->putByIndex(array, globalExec(), i, jsString(globalExec(), arguments[i]));
     211            array->putDirectIndex(globalExec(), i, jsString(globalExec(), arguments[i]), false);
    212212        putDirect(globalData, Identifier(globalExec(), "arguments"), array);
    213213    }
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r109863 r109866  
    10451045                jsArray->setIndex(globalData, i, value);
    10461046            else
    1047                 JSArray::putByIndex(jsArray, exec, i, value);
     1047                JSArray::putByIndex(jsArray, exec, i, value, exec->codeBlock()->isStrictMode());
    10481048            LLINT_END();
    10491049        }
  • trunk/Source/JavaScriptCore/runtime/Arguments.cpp

    r108651 r109866  
    197197}
    198198
    199 void Arguments::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue value)
     199void Arguments::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue value, bool shouldThrow)
    200200{
    201201    Arguments* thisObject = jsCast<Arguments*>(cell);
     
    205205    }
    206206
    207     PutPropertySlot slot;
     207    PutPropertySlot slot(shouldThrow);
    208208    JSObject::put(thisObject, exec, Identifier(exec, UString::number(i)), value, slot);
    209209}
  • trunk/Source/JavaScriptCore/runtime/Arguments.h

    r108582 r109866  
    115115        static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
    116116        static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
    117         static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
     117        static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
    118118        static bool deleteProperty(JSCell*, ExecState*, const Identifier& propertyName);
    119119        static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
  • trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp

    r109673 r109866  
    427427        // Check for integer overflow; where safe we can do a fast put by index.
    428428        if (length + n >= length)
    429             thisObj->methodTable()->putByIndex(thisObj, exec, length + n, exec->argument(n));
     429            thisObj->methodTable()->putByIndex(thisObj, exec, length + n, exec->argument(n), true);
    430430        else {
    431431            PutPropertySlot slot;
     
    433433            thisObj->methodTable()->put(thisObj, exec, propertyName, exec->argument(n), slot);
    434434        }
     435        if (exec->hadException())
     436            return JSValue::encode(jsUndefined());
    435437    }
    436438    JSValue newLength(static_cast<int64_t>(length) + static_cast<int64_t>(exec->argumentCount()));
     
    457459
    458460        if (obj2)
    459             thisObj->methodTable()->putByIndex(thisObj, exec, k, obj2);
     461            thisObj->methodTable()->putByIndex(thisObj, exec, k, obj2, true);
    460462        else
    461463            thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k);
     464        if (exec->hadException())
     465            return JSValue::encode(jsUndefined());
    462466
    463467        if (obj)
    464             thisObj->methodTable()->putByIndex(thisObj, exec, lk1, obj);
     468            thisObj->methodTable()->putByIndex(thisObj, exec, lk1, obj, true);
    465469        else
    466470            thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, lk1);
     471        if (exec->hadException())
     472            return JSValue::encode(jsUndefined());
    467473    }
    468474    return JSValue::encode(thisObj);
     
    490496                    return JSValue::encode(jsUndefined());
    491497                if (obj)
    492                     thisObj->methodTable()->putByIndex(thisObj, exec, k - 1, obj);
     498                    thisObj->methodTable()->putByIndex(thisObj, exec, k - 1, obj, true);
    493499                else
    494500                    thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k - 1);
     501                if (exec->hadException())
     502                    return JSValue::encode(jsUndefined());
    495503            }
    496504            thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, length - 1);
     
    581589        // Swap themin and i
    582590        if (themin > i) {
    583             thisObj->methodTable()->putByIndex(thisObj, exec, i, minObj);
    584             thisObj->methodTable()->putByIndex(thisObj, exec, themin, iObj);
     591            thisObj->methodTable()->putByIndex(thisObj, exec, i, minObj, true);
     592            if (exec->hadException())
     593                return JSValue::encode(jsUndefined());
     594            thisObj->methodTable()->putByIndex(thisObj, exec, themin, iObj, true);
     595            if (exec->hadException())
     596                return JSValue::encode(jsUndefined());
    585597        }
    586598    }
     
    638650                        return JSValue::encode(jsUndefined());
    639651                    if (v)
    640                         thisObj->methodTable()->putByIndex(thisObj, exec, k + additionalArgs, v);
     652                        thisObj->methodTable()->putByIndex(thisObj, exec, k + additionalArgs, v, true);
    641653                    else
    642654                        thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k + additionalArgs);
     655                    if (exec->hadException())
     656                        return JSValue::encode(jsUndefined());
    643657                }
    644658                for (unsigned k = length; k > length - deleteCount + additionalArgs; --k)
     
    654668                        return JSValue::encode(jsUndefined());
    655669                    if (obj)
    656                         thisObj->methodTable()->putByIndex(thisObj, exec, k + additionalArgs - 1, obj);
     670                        thisObj->methodTable()->putByIndex(thisObj, exec, k + additionalArgs - 1, obj, true);
    657671                    else
    658672                        thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k + additionalArgs - 1);
     673                    if (exec->hadException())
     674                        return JSValue::encode(jsUndefined());
    659675                }
    660676            }
    661677        }
    662678    }
    663     for (unsigned k = 0; k < additionalArgs; ++k)
    664         thisObj->methodTable()->putByIndex(thisObj, exec, k + begin, exec->argument(k + 2));
     679    for (unsigned k = 0; k < additionalArgs; ++k) {
     680        thisObj->methodTable()->putByIndex(thisObj, exec, k + begin, exec->argument(k + 2), true);
     681        if (exec->hadException())
     682            return JSValue::encode(jsUndefined());
     683    }
    665684
    666685    putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - deleteCount + additionalArgs));
     
    687706                    return JSValue::encode(jsUndefined());
    688707                if (v)
    689                     thisObj->methodTable()->putByIndex(thisObj, exec, k + nrArgs - 1, v);
     708                    thisObj->methodTable()->putByIndex(thisObj, exec, k + nrArgs - 1, v, true);
    690709                else
    691710                    thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k + nrArgs - 1);
     711                if (exec->hadException())
     712                    return JSValue::encode(jsUndefined());
    692713            }
    693714        }
    694715    }
    695     for (unsigned k = 0; k < nrArgs; ++k)
    696         thisObj->methodTable()->putByIndex(thisObj, exec, k, exec->argument(k));
     716    for (unsigned k = 0; k < nrArgs; ++k) {
     717        thisObj->methodTable()->putByIndex(thisObj, exec, k, exec->argument(k), true);
     718        if (exec->hadException())
     719            return JSValue::encode(jsUndefined());
     720    }
    697721    JSValue result = jsNumber(length + nrArgs);
    698722    putProperty(exec, thisObj, exec->propertyNames().length, result);
  • trunk/Source/JavaScriptCore/runtime/ClassInfo.h

    r107544 r109866  
    4949        PutFunctionPtr put;
    5050
    51         typedef void (*PutByIndexFunctionPtr)(JSCell*, ExecState*, unsigned propertyName, JSValue);
     51        typedef void (*PutByIndexFunctionPtr)(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
    5252        PutByIndexFunctionPtr putByIndex;
    5353
  • trunk/Source/JavaScriptCore/runtime/JSArray.cpp

    r109673 r109866  
    208208}
    209209
    210 inline void SparseArrayValueMap::put(ExecState* exec, JSArray* array, unsigned i, JSValue value)
     210inline void SparseArrayValueMap::put(ExecState* exec, JSArray* array, unsigned i, JSValue value, bool shouldThrow)
    211211{
    212212    std::pair<SparseArrayValueMap::iterator, bool> result = add(array, i);
     
    218218    if (result.second && !array->isExtensible()) {
    219219        remove(result.first);
    220         // FIXME: should throw in strict mode.
     220        if (shouldThrow)
     221            throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
    221222        return;
    222223    }
     
    224225    if (!(entry.attributes & Accessor)) {
    225226        if (entry.attributes & ReadOnly) {
    226             // FIXME: should throw if being called from strict mode.
    227             // throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
     227            if (shouldThrow)
     228                throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
    228229            return;
    229230        }
     
    238239   
    239240    if (!setter) {
    240         // FIXME: should throw if being called from strict mode.
    241         // throwTypeError(exec, "setting a property that has only a getter");
     241        if (shouldThrow)
     242            throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
    242243        return;
    243244    }
     
    726727    unsigned i = propertyName.toArrayIndex(isArrayIndex);
    727728    if (isArrayIndex) {
    728         putByIndex(thisObject, exec, i, value);
     729        putByIndex(thisObject, exec, i, value, slot.isStrictMode());
    729730        return;
    730731    }
     
    743744}
    744745
    745 void JSArray::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue value)
     746void JSArray::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue value, bool shouldThrow)
    746747{
    747748    JSArray* thisObject = jsCast<JSArray*>(cell);
     
    770771    // Handle 2^32-1 - this is not an array index (see ES5.1 15.4), and is treated as a regular property.
    771772    if (UNLIKELY(i > MAX_ARRAY_INDEX)) {
    772         PutPropertySlot slot;
     773        PutPropertySlot slot(shouldThrow);
    773774        thisObject->methodTable()->put(thisObject, exec, Identifier::from(exec, i), value, slot);
    774775        return;
     
    776777
    777778    // For all other cases, call putByIndexBeyondVectorLength.
    778     thisObject->putByIndexBeyondVectorLength(exec, i, value);
     779    thisObject->putByIndexBeyondVectorLength(exec, i, value, shouldThrow);
    779780    thisObject->checkConsistency();
    780781}
    781782
    782 void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue value)
     783void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue value, bool shouldThrow)
    783784{
    784785    JSGlobalData& globalData = exec->globalData();
     
    811812        allocateSparseMap(exec->globalData());
    812813        map = m_sparseValueMap;
    813         map->put(exec, this, i, value);
     814        map->put(exec, this, i, value, shouldThrow);
    814815        return;
    815816    }
     
    820821        // Prohibit growing the array if length is not writable.
    821822        if (map->lengthIsReadOnly() || !isExtensible()) {
    822             // FIXME: should throw in strict mode.
     823            if (shouldThrow)
     824                throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
    823825            return;
    824826        }
     
    831833    unsigned numValuesInArray = storage->m_numValuesInVector + map->size();
    832834    if (map->sparseMode() || !isDenseEnoughForVector(length, numValuesInArray) || !increaseVectorLength(exec->globalData(), length)) {
    833         map->put(exec, this, i, value);
     835        map->put(exec, this, i, value, shouldThrow);
    834836        return;
    835837    }
     
    12961298    // Pushing to an array of length 2^32-1 stores the property, but throws a range error.
    12971299    if (UNLIKELY(storage->m_length == 0xFFFFFFFFu)) {
    1298         methodTable()->putByIndex(this, exec, storage->m_length, value);
     1300        methodTable()->putByIndex(this, exec, storage->m_length, value, true);
    12991301        // Per ES5.1 15.4.4.7 step 6 & 15.4.5.1 step 3.d.
    1300         throwError(exec, createRangeError(exec, "Invalid array length"));
     1302        if (!exec->hadException())
     1303            throwError(exec, createRangeError(exec, "Invalid array length"));
    13011304        return;
    13021305    }
    13031306
    13041307    // Handled the same as putIndex.
    1305     putByIndexBeyondVectorLength(exec, storage->m_length, value);
     1308    putByIndexBeyondVectorLength(exec, storage->m_length, value, true);
    13061309    checkConsistency();
    13071310}
     
    13281331                JSValue p = prototype();
    13291332                if ((!p.isNull()) && (asObject(p)->getPropertySlot(exec, i, slot)))
    1330                     methodTable()->putByIndex(this, exec, i, slot.getValue(exec, i));
     1333                    methodTable()->putByIndex(this, exec, i, slot.getValue(exec, i), false); // FIXME https://bugs.webkit.org/show_bug.cgi?id=80335
    13311334            }
    13321335        }
     
    13731376                JSValue p = prototype();
    13741377                if ((!p.isNull()) && (asObject(p)->getPropertySlot(exec, i, slot)))
    1375                     methodTable()->putByIndex(this, exec, i, slot.getValue(exec, i));
     1378                    methodTable()->putByIndex(this, exec, i, slot.getValue(exec, i), false); // FIXME https://bugs.webkit.org/show_bug.cgi?id=80335
    13761379            }
    13771380        }
  • trunk/Source/JavaScriptCore/runtime/JSArray.h

    r109673 r109866  
    8686
    8787        // These methods may mutate the contents of the map
    88         void put(ExecState*, JSArray*, unsigned, JSValue);
     88        void put(ExecState*, JSArray*, unsigned, JSValue, bool shouldThrow);
    8989        bool putDirect(ExecState*, JSArray*, unsigned, JSValue, bool shouldThrow);
    9090        std::pair<iterator, bool> add(JSArray*, unsigned);
     
    161161        JS_EXPORT_PRIVATE static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&);
    162162        static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
    163         static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
     163        static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
    164164        // This is similar to the JSObject::putDirect* methods:
    165165        //  - the prototype chain is not consulted
     
    296296
    297297        bool getOwnPropertySlotSlowCase(ExecState*, unsigned propertyName, PropertySlot&);
    298         void putByIndexBeyondVectorLength(ExecState*, unsigned propertyName, JSValue);
    299         bool putDirectIndexBeyondVectorLength(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
     298        void putByIndexBeyondVectorLength(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
     299        JS_EXPORT_PRIVATE bool putDirectIndexBeyondVectorLength(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
    300300
    301301        unsigned getNewVectorLength(unsigned desiredLength);
  • trunk/Source/JavaScriptCore/runtime/JSByteArray.cpp

    r104324 r109866  
    103103}
    104104
    105 void JSByteArray::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value)
     105void JSByteArray::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool)
    106106{
    107107    jsCast<JSByteArray*>(cell)->setIndex(exec, propertyName, value);
  • trunk/Source/JavaScriptCore/runtime/JSByteArray.h

    r104900 r109866  
    9393        JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
    9494        JS_EXPORT_PRIVATE static void put(JSC::JSCell*, JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);
    95         JS_EXPORT_PRIVATE static void putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue);
     95        JS_EXPORT_PRIVATE static void putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue, bool shouldThrow);
    9696
    9797        JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSC::JSObject*, JSC::ExecState*, JSC::PropertyNameArray&, EnumerationMode);
  • trunk/Source/JavaScriptCore/runtime/JSCell.cpp

    r109177 r109866  
    106106}
    107107
    108 void JSCell::putByIndex(JSCell* cell, ExecState* exec, unsigned identifier, JSValue value)
    109 {
    110     JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject());
    111     thisObject->methodTable()->putByIndex(thisObject, exec, identifier, value);
     108void JSCell::putByIndex(JSCell* cell, ExecState* exec, unsigned identifier, JSValue value, bool shouldThrow)
     109{
     110    if (cell->isString()) {
     111        PutPropertySlot slot(shouldThrow);
     112        JSValue(cell).putToPrimitive(exec, Identifier::from(exec, identifier), value, slot);
     113        return;
     114    }
     115    JSObject* thisObject = cell->toObject(exec, exec->lexicalGlobalObject());
     116    thisObject->methodTable()->putByIndex(thisObject, exec, identifier, value, shouldThrow);
    112117}
    113118
  • trunk/Source/JavaScriptCore/runtime/JSCell.h

    r108444 r109866  
    108108        const MethodTable* methodTable() const;
    109109        static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
    110         static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
     110        static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
    111111       
    112112        static bool deleteProperty(JSCell*, ExecState*, const Identifier& propertyName);
  • trunk/Source/JavaScriptCore/runtime/JSNotAnObject.cpp

    r103083 r109866  
    7171}
    7272
    73 void JSNotAnObject::putByIndex(JSCell*, ExecState* exec, unsigned, JSValue)
     73void JSNotAnObject::putByIndex(JSCell*, ExecState* exec, unsigned, JSValue, bool)
    7474{
    7575    ASSERT_UNUSED(exec, exec->hadException());
  • trunk/Source/JavaScriptCore/runtime/JSNotAnObject.h

    r103243 r109866  
    7474
    7575        static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
    76         static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
     76        static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
    7777
    7878        static bool deleteProperty(JSCell*, ExecState*, const Identifier& propertyName);
  • trunk/Source/JavaScriptCore/runtime/JSONObject.cpp

    r105698 r109866  
    705705                if (filteredValue.isUndefined())
    706706                    array->methodTable()->deletePropertyByIndex(array, m_exec, indexStack.last());
    707                 else {
    708                     if (isJSArray(array) && array->canSetIndex(indexStack.last()))
    709                         array->setIndex(m_exec->globalData(), indexStack.last(), filteredValue);
    710                     else
    711                         array->methodTable()->putByIndex(array, m_exec, indexStack.last(), filteredValue);
    712                 }
     707                else
     708                    array->putDirectIndex(m_exec, indexStack.last(), filteredValue, false);
    713709                if (m_exec->hadException())
    714710                    return jsNull();
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r109240 r109866  
    186186}
    187187
    188 void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value)
    189 {
    190     PutPropertySlot slot;
     188void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
     189{
     190    PutPropertySlot slot(shouldThrow);
    191191    JSObject* thisObject = jsCast<JSObject*>(cell);
    192192    thisObject->methodTable()->put(thisObject, exec, Identifier::from(exec, propertyName), value, slot);
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r109824 r109866  
    110110
    111111        JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
    112         JS_EXPORT_PRIVATE static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
     112        JS_EXPORT_PRIVATE static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
    113113
    114114        // putDirect is effectively an unchecked vesion of 'defineOwnProperty':
     
    848848        return;
    849849    }
    850     asCell()->methodTable()->putByIndex(asCell(), exec, propertyName, value);
     850    asCell()->methodTable()->putByIndex(asCell(), exec, propertyName, value, shouldThrow);
    851851}
    852852
  • trunk/Source/JavaScriptCore/runtime/RegExpConstructor.cpp

    r105698 r109866  
    154154        int start = m_regExpResult.ovector[2 * i];
    155155        if (start >= 0)
    156             JSArray::putByIndex(this, exec, i, jsSubstring(exec, m_regExpResult.input, start, m_regExpResult.ovector[2 * i + 1] - start));
     156            putDirectIndex(exec, i, jsSubstring(exec, m_regExpResult.input, start, m_regExpResult.ovector[2 * i + 1] - start), false);
    157157        else
    158             JSArray::putByIndex(this, exec, i, jsUndefined());
     158            putDirectIndex(exec, i, jsUndefined(), false);
    159159    }
    160160
  • trunk/Source/JavaScriptCore/runtime/RegExpMatchesArray.h

    r106189 r109866  
    8383        }
    8484       
    85         static void putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue v)
     85        static void putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue v, bool shouldThrow)
    8686        {
    8787            RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
    8888            if (!thisObject->m_didFillArrayInstance)
    8989                thisObject->fillArrayInstance(exec);
    90             JSArray::putByIndex(thisObject, exec, propertyName, v);
     90            JSArray::putByIndex(thisObject, exec, propertyName, v, shouldThrow);
    9191        }
    9292
  • trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp

    r106417 r109866  
    949949            // a. Call the [[DefineOwnProperty]] internal method of A with arguments "0",
    950950            //    Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
    951             result->methodTable()->putByIndex(result, exec, 0, jsStringWithReuse(exec, thisValue, input));
     951            result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input), false);
    952952            // b. Return A.
    953953            return JSValue::encode(result);
     
    962962            // d. Return A.
    963963            if (reg->match(*globalData, input, 0) < 0)
    964                 result->methodTable()->putByIndex(result, exec, 0, jsStringWithReuse(exec, thisValue, input));
     964                result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input), false);
    965965            return JSValue::encode(result);
    966966        }
     
    993993            // 2. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA),
    994994            //    Property Descriptor {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
    995             result->methodTable()->putByIndex(result, exec, resultLength, jsSubstring(exec, input, position, matchPosition - position));
     995            result->putDirectIndex(exec, resultLength, jsSubstring(exec, input, position, matchPosition - position), false);
    996996            // 3. Increment lengthA by 1.
    997997            // 4. If lengthA == lim, return A.
     
    10121012                //   true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
    10131013                int sub = ovector[i * 2];
    1014                 result->methodTable()->putByIndex(result, exec, resultLength, sub < 0 ? jsUndefined() : jsSubstring(exec, input, sub, ovector[i * 2 + 1] - sub));
     1014                result->putDirectIndex(exec, resultLength, sub < 0 ? jsUndefined() : jsSubstring(exec, input, sub, ovector[i * 2 + 1] - sub), false);
    10151015                // c Increment lengthA by 1.
    10161016                // d If lengthA == lim, return A.
     
    10311031            // a.  Call the [[DefineOwnProperty]] internal method of A with arguments "0",
    10321032            //     Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
    1033             result->methodTable()->putByIndex(result, exec, 0, jsStringWithReuse(exec, thisValue, input));
     1033            result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input), false);
    10341034            // b.  Return A.
    10351035            return JSValue::encode(result);
     
    10441044            // d. Return A.
    10451045            if (!separator.isEmpty())
    1046                 result->methodTable()->putByIndex(result, exec, 0, jsStringWithReuse(exec, thisValue, input));
     1046                result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input), false);
    10471047            return JSValue::encode(result);
    10481048        }
     
    10551055
    10561056            do {
    1057                 result->methodTable()->putByIndex(result, exec, position, jsSingleCharacterSubstring(exec, input, position));
     1057                result->putDirectIndex(exec, position, jsSingleCharacterSubstring(exec, input, position), false);
    10581058            } while (++position < limit);
    10591059
     
    10721072            // 2. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA),
    10731073            //    Property Descriptor {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
    1074             result->methodTable()->putByIndex(result, exec, resultLength, jsSubstring(exec, input, position, matchPosition - position));
     1074            result->putDirectIndex(exec, resultLength, jsSubstring(exec, input, position, matchPosition - position), false);
    10751075            // 3. Increment lengthA by 1.
    10761076            // 4. If lengthA == lim, return A.
     
    10881088    // 15. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA), Property Descriptor
    10891089    //     {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
    1090     result->methodTable()->putByIndex(result, exec, resultLength++, jsSubstring(exec, input, position, input.length() - position));
     1090    result->putDirectIndex(exec, resultLength++, jsSubstring(exec, input, position, input.length() - position), false);
    10911091
    10921092    // 16. Return A.
  • trunk/Source/WebCore/ChangeLog

    r109864 r109866  
     12012-03-05  Gavin Barraclough  <barraclough@apple.com>
     2
     3        putByIndex should throw in strict mode
     4        https://bugs.webkit.org/show_bug.cgi?id=80335
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Make the MethodTable PutByIndex trap take a boolean 'shouldThrow' parameter.
     9
     10        * bindings/js/SerializedScriptValue.cpp:
     11        (WebCore::CloneDeserializer::putProperty):
     12        * bindings/objc/WebScriptObject.mm:
     13        (-[WebScriptObject setWebScriptValueAtIndex:value:]):
     14        * bindings/scripts/CodeGeneratorJS.pm:
     15        (GenerateHeader):
     16        (GenerateImplementation):
     17        * bridge/NP_jsobject.cpp:
     18        (_NPN_SetProperty):
     19        * bridge/jni/jni_jsobject.mm:
     20        (JavaJSObject::setSlot):
     21        * bridge/runtime_array.cpp:
     22        (JSC::RuntimeArray::putByIndex):
     23        * bridge/runtime_array.h:
     24        (RuntimeArray):
     25
    1262012-03-05  Shinya Kawanaka  <shinyak@chromium.org>
    227
  • trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp

    r109196 r109866  
    12331233    void putProperty(JSArray* array, unsigned index, JSValue value)
    12341234    {
    1235         if (array->canSetIndex(index))
    1236             array->setIndex(m_exec->globalData(), index, value);
    1237         else
    1238             array->methodTable()->putByIndex(array, m_exec, index, value);
     1235        array->putDirectIndex(m_exec, index, value, false);
    12391236    }
    12401237
  • trunk/Source/WebCore/bindings/objc/WebScriptObject.mm

    r99993 r109866  
    487487
    488488    JSLock lock(SilenceAssertionsOnly);
    489     [self _imp]->methodTable()->putByIndex([self _imp], exec, index, convertObjcValueToValue(exec, &value, ObjcObjectType, [self _rootObject]));
     489    [self _imp]->methodTable()->putByIndex([self _imp], exec, index, convertObjcValueToValue(exec, &value, ObjcObjectType, [self _rootObject]), false);
    490490
    491491    if (exec->hadException()) {
  • trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

    r109515 r109866  
    777777    if ($hasSetter) {
    778778        push(@headerContent, "    static void put(JSC::JSCell*, JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);\n");
    779         push(@headerContent, "    static void putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue);\n") if $dataNode->extendedAttributes->{"CustomIndexedSetter"};
     779        push(@headerContent, "    static void putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue, bool shouldThrow);\n") if $dataNode->extendedAttributes->{"CustomIndexedSetter"};
    780780        push(@headerContent, "    bool putDelegate(JSC::ExecState*, const JSC::Identifier&, JSC::JSValue, JSC::PutPropertySlot&);\n") if $dataNode->extendedAttributes->{"CustomNamedSetter"};
    781781    }
     
    18561856
    18571857            if ($dataNode->extendedAttributes->{"CustomIndexedSetter"}) {
    1858                 push(@implContent, "void ${className}::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value)\n");
     1858                push(@implContent, "void ${className}::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool)\n");
    18591859                push(@implContent, "{\n");
    18601860                push(@implContent, "    ${className}* thisObject = jsCast<${className}*>(cell);\n");
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSFloat64Array.cpp

    r109035 r109866  
    201201}
    202202
    203 void JSFloat64Array::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value)
     203void JSFloat64Array::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool)
    204204{
    205205    JSFloat64Array* thisObject = jsCast<JSFloat64Array*>(cell);
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSFloat64Array.h

    r103295 r109866  
    4444    static bool getOwnPropertySlotByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);
    4545    static void put(JSC::JSCell*, JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);
    46     static void putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue);
     46    static void putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue, bool shouldThrow);
    4747    static const JSC::ClassInfo s_info;
    4848
  • trunk/Source/WebCore/bridge/NP_jsobject.cpp

    r99256 r109866  
    340340            obj->imp->methodTable()->put(obj->imp, exec, identifierFromNPIdentifier(exec, i->string()), convertNPVariantToValue(exec, variant, rootObject), slot);
    341341        } else
    342             obj->imp->methodTable()->putByIndex(obj->imp, exec, i->number(), convertNPVariantToValue(exec, variant, rootObject));
     342            obj->imp->methodTable()->putByIndex(obj->imp, exec, i->number(), convertNPVariantToValue(exec, variant, rootObject), false);
    343343        exec->clearException();
    344344        return true;
  • trunk/Source/WebCore/bridge/jni/jni_jsobject.mm

    r105698 r109866  
    394394    ExecState* exec = rootObject->globalObject()->globalExec();
    395395    JSLock lock(SilenceAssertionsOnly);
    396     _imp->methodTable()->putByIndex(_imp, exec, (unsigned)index, convertJObjectToValue(exec, value));
     396    _imp->methodTable()->putByIndex(_imp, exec, (unsigned)index, convertJObjectToValue(exec, value), false);
    397397}
    398398
  • trunk/Source/WebCore/bridge/runtime_array.cpp

    r103083 r109866  
    158158}
    159159
    160 void RuntimeArray::putByIndex(JSCell* cell, ExecState* exec, unsigned index, JSValue value)
     160void RuntimeArray::putByIndex(JSCell* cell, ExecState* exec, unsigned index, JSValue value, bool)
    161161{
    162162    RuntimeArray* thisObject = jsCast<RuntimeArray*>(cell);
  • trunk/Source/WebCore/bridge/runtime_array.h

    r103243 r109866  
    5656    static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
    5757    static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
    58     static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue);
     58    static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
    5959   
    6060    static bool deleteProperty(JSCell*, ExecState*, const Identifier &propertyName);
  • trunk/Source/WebKit/mac/ChangeLog

    r109860 r109866  
     12012-03-05  Gavin Barraclough  <barraclough@apple.com>
     2
     3        putByIndex should throw in strict mode
     4        https://bugs.webkit.org/show_bug.cgi?id=80335
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Make the MethodTable PutByIndex trap take a boolean 'shouldThrow' parameter.
     9
     10        * Plugins/Hosted/NetscapePluginInstanceProxy.mm:
     11        (WebKit::NetscapePluginInstanceProxy::setProperty):
     12
    1132012-03-05  Joseph Pecoraro  <pecoraro@apple.com>
    214
  • trunk/Source/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm

    r105698 r109866  
    10861086   
    10871087    JSValue value = demarshalValue(exec, valueData, valueLength);
    1088     object->methodTable()->putByIndex(object, exec, propertyName, value);
     1088    object->methodTable()->putByIndex(object, exec, propertyName, value, false);
    10891089   
    10901090    exec->clearException();
  • trunk/Source/WebKit2/ChangeLog

    r109860 r109866  
     12012-03-05  Gavin Barraclough  <barraclough@apple.com>
     2
     3        putByIndex should throw in strict mode
     4        https://bugs.webkit.org/show_bug.cgi?id=80335
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Make the MethodTable PutByIndex trap take a boolean 'shouldThrow' parameter.
     9
     10        * WebProcess/Plugins/Netscape/NPJSObject.cpp:
     11        (WebKit::NPJSObject::setProperty):
     12
    1132012-03-05  Joseph Pecoraro  <pecoraro@apple.com>
    214
  • trunk/Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp

    r99256 r109866  
    191191        m_jsObject->methodTable()->put(m_jsObject.get(), exec, identifierFromIdentifierRep(exec, identifierRep), jsValue, slot);
    192192    } else
    193         m_jsObject->methodTable()->putByIndex(m_jsObject.get(), exec, identifierRep->number(), jsValue);
     193        m_jsObject->methodTable()->putByIndex(m_jsObject.get(), exec, identifierRep->number(), jsValue, false);
    194194    exec->clearException();
    195195   
Note: See TracChangeset for help on using the changeset viewer.