Ignore:
Timestamp:
May 19, 2015, 12:51:46 PM (10 years ago)
Author:
Yusuke Suzuki
Message:

Array.prototype methods must use ToLength
https://bugs.webkit.org/show_bug.cgi?id=144128

Reviewed by Oliver Hunt.

Source/JavaScriptCore:

Per https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength

This patch introduces ToLength and ToInteger JS implementation to encourage the DFG/FTL's inlining.
These implementations are located in GlobalObject.js.
And set to the JSGlobalObject with the private symbols @ToLength and @ToInteger manually.

  • builtins/Array.prototype.js:

(every):
(forEach):
(filter):
(map):
(some):
(fill):
(find):
(findIndex):
(includes):

  • builtins/ArrayConstructor.js:

(from):

  • builtins/GlobalObject.js: Copied from Source/JavaScriptCore/builtins/StringConstructor.js.

(ToInteger):
(ToLength):

  • builtins/StringConstructor.js:

(raw):

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):

  • runtime/JSGlobalObjectFunctions.h:

LayoutTests:

  • fast/profiler/built-in-function-calls-anonymous-expected.txt:
  • fast/profiler/built-in-function-calls-user-defined-function-expected.txt:
  • js/array-every-expected.txt:
  • js/array-fill-expected.txt:
  • js/array-filter-expected.txt:
  • js/array-find-expected.txt:
  • js/array-findIndex-expected.txt:
  • js/array-functions-non-arrays-expected.txt:
  • js/array-includes-expected.txt:
  • js/script-tests/array-every.js:

(throwError):

  • js/script-tests/array-fill.js:

(throwError):

  • js/script-tests/array-filter.js:

(throwError):

  • js/script-tests/array-find.js:

(throwError):

  • js/script-tests/array-findIndex.js:

(toObject):
(throwError):

  • js/script-tests/array-functions-non-arrays.js:

(throwError):

  • js/script-tests/array-includes.js:
Location:
trunk/Source/JavaScriptCore/builtins
Files:
3 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/builtins/Array.prototype.js

    r183749 r184582  
    3333   
    3434    var array = @Object(this);
    35     var length = array.length >>> 0;
    36    
     35    var length = @ToLength(array.length);
     36
    3737    if (typeof callback !== "function")
    3838        throw new @TypeError("Array.prototype.every callback must be a function");
     
    5959   
    6060    var array = @Object(this);
    61     var length = array.length >>> 0;
    62    
     61    var length = @ToLength(array.length);
     62
    6363    if (typeof callback !== "function")
    6464        throw new @TypeError("Array.prototype.forEach callback must be a function");
     
    8181   
    8282    var array = @Object(this);
    83     var length = array.length >>> 0;
    84    
     83    var length = @ToLength(array.length);
     84
    8585    if (typeof callback !== "function")
    8686        throw new @TypeError("Array.prototype.filter callback must be a function");
     
    110110   
    111111    var array = @Object(this);
    112     var length = array.length >>> 0;
    113    
     112    var length = @ToLength(array.length);
     113
    114114    if (typeof callback !== "function")
    115115        throw new @TypeError("Array.prototype.map callback must be a function");
     
    137137   
    138138    var array = @Object(this);
    139     var length = array.length >>> 0;
    140    
     139    var length = @ToLength(array.length);
     140
    141141    if (typeof callback !== "function")
    142142        throw new @TypeError("Array.prototype.some callback must be a function");
     
    161161        throw new @TypeError("Array.prototype.fill requires that |this| not be undefined");
    162162    var O = @Object(this);
    163     var len = O.length >>> 0;
     163    var len = @ToLength(O.length);
    164164    var relativeStart = 0;
    165165    if (arguments.length > 1 && arguments[1] !== undefined)
     
    202202   
    203203    var array = @Object(this);
    204     var length = array.length >>> 0;
    205    
     204    var length = @ToLength(array.length);
     205
    206206    if (typeof callback !== "function")
    207207        throw new @TypeError("Array.prototype.find callback must be a function");
     
    227227   
    228228    var array = @Object(this);
    229     var length = array.length >>> 0;
    230    
     229    var length = @ToLength(array.length);
     230
    231231    if (typeof callback !== "function")
    232232        throw new @TypeError("Array.prototype.findIndex callback must be a function");
     
    251251
    252252    var array = @Object(this);
    253     var length = array.length >>> 0;
     253    var length = @ToLength(array.length);
    254254
    255255    if (length === 0)
  • trunk/Source/JavaScriptCore/builtins/ArrayConstructor.js

    r183357 r184582  
    7777
    7878    var arrayLike = @Object(items);
    79 
    80     var maxSafeInteger = 9007199254740991;
    81     var numberValue = @Number(arrayLike.length);
    82     var lengthValue;
    83     if (numberValue != numberValue) {  // isNaN(numberValue)
    84         lengthValue = 0;
    85     } else if (numberValue === 0 || !@isFinite(numberValue)) {
    86         lengthValue = numberValue;
    87     } else {
    88         lengthValue = (numberValue > 0 ? 1 : -1) * @floor(@abs(numberValue));
    89     }
    90     // originally Math.min(Math.max(length, 0), maxSafeInteger));
    91     var arrayLikeLength = lengthValue > 0 ? (lengthValue < maxSafeInteger ? lengthValue : maxSafeInteger) : 0;
     79    var arrayLikeLength = @ToLength(arrayLike.length);
    9280
    9381    // TODO: Need isConstructor(thisObj) instead of typeof "function" check.
  • trunk/Source/JavaScriptCore/builtins/GlobalObject.js

    r184581 r184582  
    2424 */
    2525
    26 function raw(template) {
     26function ToInteger(target) {
    2727    "use strict";
    2828
    29     if (template === null || template === undefined)
    30         throw new @TypeError("String.raw requires template not be null or undefined");
    31     var cookedSegments = @Object(template);
     29    var numberValue = @Number(target);
    3230
    33     var rawValue = cookedSegments.raw;
    34     if (rawValue === null || rawValue === undefined)
    35         throw new @TypeError("String.raw requires template.raw not be null or undefined");
    36     var rawSegments = @Object(rawValue);
     31    // isNaN(numberValue)
     32    if (numberValue !== numberValue)
     33        return 0;
    3734
    38     var numberOfSubstitutions = arguments.length - 1;
     35    if (numberValue === 0 || !@isFinite(numberValue))
     36        return numberValue;
     37
     38    return (numberValue > 0 ? 1 : -1) * @floor(@abs(numberValue));
     39}
     40
     41function ToLength(target) {
     42    "use strict";
    3943
    4044    var maxSafeInteger = 0x1FFFFFFFFFFFFF;
    41     var numberValue = @Number(rawSegments.length);
    42     var lengthValue;
    43     if (numberValue !== numberValue)  // isNaN(numberValue)
    44         lengthValue = 0;
    45     else if (numberValue === 0 || !@isFinite(numberValue))
    46         lengthValue = numberValue;
    47     else
    48         lengthValue = (numberValue > 0 ? 1 : -1) * @floor(@abs(numberValue));
     45    var length = @ToInteger(target);
    4946    // originally Math.min(Math.max(length, 0), maxSafeInteger));
    50     var segmentCount = lengthValue > 0 ? (lengthValue < maxSafeInteger ? lengthValue : maxSafeInteger) : 0;
    51 
    52     if (segmentCount <= 0)
    53         return '';
    54 
    55     var stringElements = '';
    56     for (var i = 0; ; ++i) {
    57         var segment = @toString(rawSegments[i]);
    58         stringElements += segment;
    59 
    60         if ((i + 1) === segmentCount)
    61             return stringElements;
    62 
    63         if (i < numberOfSubstitutions) {
    64             var substitutionIndexInArguments = i + 1;
    65             var next = @toString(arguments[substitutionIndexInArguments]);
    66             stringElements += next;
    67         }
    68     }
     47    return length > 0 ? (length < maxSafeInteger ? length : maxSafeInteger) : 0;
    6948}
  • trunk/Source/JavaScriptCore/builtins/StringConstructor.js

    r184287 r184582  
    3838    var numberOfSubstitutions = arguments.length - 1;
    3939
    40     var maxSafeInteger = 0x1FFFFFFFFFFFFF;
    41     var numberValue = @Number(rawSegments.length);
    42     var lengthValue;
    43     if (numberValue !== numberValue)  // isNaN(numberValue)
    44         lengthValue = 0;
    45     else if (numberValue === 0 || !@isFinite(numberValue))
    46         lengthValue = numberValue;
    47     else
    48         lengthValue = (numberValue > 0 ? 1 : -1) * @floor(@abs(numberValue));
    49     // originally Math.min(Math.max(length, 0), maxSafeInteger));
    50     var segmentCount = lengthValue > 0 ? (lengthValue < maxSafeInteger ? lengthValue : maxSafeInteger) : 0;
     40    var segmentCount = @ToLength(rawSegments.length);
    5141
    5242    if (segmentCount <= 0)
Note: See TracChangeset for help on using the changeset viewer.