Changeset 252202 in webkit


Ignore:
Timestamp:
Nov 7, 2019 12:36:51 PM (4 years ago)
Author:
Devin Rousso
Message:

Web Inspector: REGRESSION(r250087): inspector/model/remote-object.html is timing out
https://bugs.webkit.org/show_bug.cgi?id=202934
<rdar://problem/56270900>

Reviewed by Timothy Hatcher.

Source/JavaScriptCore:

In r250087, the inspector injected script was changed so that remote objects actually
iterate the keys of an array and generate a property descriptor for each. While this worked
fine (and was performant) for fetching remote objects, this was not efficient when creating
object previews, as that path wouldn't be limited by any sort of fetchCount, meaning that
a descriptor for every index would be created even though only the first 10 would be used.

Refactor the inspector injected script code so that both the fetch and preview paths only
examine exactly the number of properties desired instead of considering all of them and then
slicing to fit.

  • inspector/InjectedScriptSource.js:

(InjectedScript.prototype._getProperties):
(InjectedScript.prototype._forEachPropertyDescriptor): Added.
(InjectedScript.prototype._forEachPropertyDescriptor.createFakeValueDescriptor): Added.
(InjectedScript.prototype._forEachPropertyDescriptor.processDescriptor): Added.
(InjectedScript.prototype._forEachPropertyDescriptor.processProperty): Added.
(RemoteObject.prototype._generatePreview):
(RemoteObject.prototype._appendPropertyPreview): Added.
(RemoteObject.prototype._appendPropertyPreview.appendPreview): Added.
(InjectedScript.prototype._propertyDescriptors): Deleted.
(InjectedScript.prototype._propertyDescriptors.processProperties): Deleted.
(InjectedScript.prototype._propertyDescriptors.arrayIndexPropertyNames): Deleted.
(RemoteObject.prototype._appendPropertyPreviews): Deleted.

Source/WebInspectorUI:

  • UserInterface/Views/ObjectTreeView.js:

(WI.ObjectTreeView.addShowMoreIfNeeded):
Drive-by: ensure that the indeterminate progress spinner is added after the last button.

LayoutTests:

Split inspector/model/remote-object.html into separate tests for each type of object being
tested, as well as specialized tests for extremely large values. This allows us to better
know which specific expression can cause a timeout.

  • inspector/model/remote-object.html: Removed.
  • inspector/model/remote-object-expected.txt: Removed.
  • platform/mac-wk1/inspector/model/remote-object-expected.txt: Removed.
  • inspector/model/remote-object/array.html: Added.
  • inspector/model/remote-object/array-expected.txt: Added.
  • inspector/model/remote-object/array-large.html: Added.
  • inspector/model/remote-object/array-large-expected.txt: Added.
  • inspector/model/remote-object/boolean.html: Added.
  • inspector/model/remote-object/boolean-expected.txt: Added.
  • inspector/model/remote-object/class.html: Added.
  • inspector/model/remote-object/class-expected.txt: Added.
  • inspector/model/remote-object/date.html: Added.
  • inspector/model/remote-object/date-expected.txt: Added.
  • inspector/model/remote-object/error.html: Added.
  • inspector/model/remote-object/error-expected.txt: Added.
  • inspector/model/remote-object/function.html: Added.
  • inspector/model/remote-object/function-expected.txt: Added.
  • inspector/model/remote-object/immutable.html: Added.
  • inspector/model/remote-object/immutable-expected.txt: Added.
  • inspector/model/remote-object/iterator.html: Added.
  • inspector/model/remote-object/iterator-expected.txt: Added.
  • inspector/model/remote-object/iterator-large.html: Added.
  • inspector/model/remote-object/iterator-large-expected.txt: Added.
  • inspector/model/remote-object/map.html: Added.
  • inspector/model/remote-object/map-expected.txt: Added.
  • inspector/model/remote-object/map-large.html: Added.
  • inspector/model/remote-object/map-large-expected.txt: Added.
  • inspector/model/remote-object/null.html: Added.
  • inspector/model/remote-object/null-expected.txt: Added.
  • inspector/model/remote-object/number.html: Added.
  • inspector/model/remote-object/number-expected.txt: Added.
  • platform/mac-wk1/inspector/number-expected.txt: Added.
  • inspector/model/remote-object/object.html: Added.
  • inspector/model/remote-object/object-expected.txt: Added.
  • inspector/model/remote-object/object-large.html: Added.
  • inspector/model/remote-object/object-large-expected.txt: Added.
  • inspector/model/remote-object/promise.html: Added.
  • inspector/model/remote-object/promise-expected.txt: Added.
  • inspector/model/remote-object/regexp.html: Added.
  • inspector/model/remote-object/regexp-expected.txt: Added.
  • inspector/model/remote-object/set.html: Added.
  • inspector/model/remote-object/set-expected.txt: Added.
  • inspector/model/remote-object/set-large.html: Added.
  • inspector/model/remote-object/set-large-expected.txt: Added.
  • inspector/model/remote-object/string.html: Added.
  • inspector/model/remote-object/string-expected.txt: Added.
  • inspector/model/remote-object/string-large.html: Added.
  • inspector/model/remote-object/string-large-expected.txt: Added.
  • inspector/model/remote-object/undefined.html: Added.
  • inspector/model/remote-object/undefined-expected.txt: Added.
  • inspector/model/remote-object/dom.html: Renamed from LayoutTests/inspector/model/remote-object-dom.html.
  • inspector/model/remote-object/dom-expected.txt: Renamed from LayoutTests/inspector/model/remote-object-dom-expected.txt.
  • inspector/model/remote-object/iterators-mutated.html: Renamed from LayoutTests/inspector/model/remote-object-mutated-iterators.html.
  • inspector/model/remote-object/iterators-mutated-expected.txt: Renamed from LayoutTests/inspector/model/remote-object-mutated-iterators-expected.txt.
  • inspector/model/remote-object/resources/remote-object-utilities.js: Renamed from LayoutTests/inspector/model/resources/remote-object-utilities.js.
  • inspector/runtime/getDisplayableProperties.html:
  • inspector/runtime/getDisplayableProperties-expected.txt:
  • inspector/runtime/getProperties.html:
  • inspector/runtime/getProperties-expected.txt:

Drive-by: fix assertion for when the __proto__ is included if fetchStart is 0.

Location:
trunk
Files:
48 added
3 deleted
10 edited
2 copied
5 moved

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r252196 r252202  
     12019-11-07  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: REGRESSION(r250087): inspector/model/remote-object.html is timing out
     4        https://bugs.webkit.org/show_bug.cgi?id=202934
     5        <rdar://problem/56270900>
     6
     7        Reviewed by Timothy Hatcher.
     8
     9        Split inspector/model/remote-object.html into separate tests for each type of object being
     10        tested, as well as specialized tests for extremely large values. This allows us to better
     11        know which specific expression can cause a timeout.
     12
     13        * inspector/model/remote-object.html: Removed.
     14        * inspector/model/remote-object-expected.txt: Removed.
     15        * platform/mac-wk1/inspector/model/remote-object-expected.txt: Removed.
     16
     17        * inspector/model/remote-object/array.html: Added.
     18        * inspector/model/remote-object/array-expected.txt: Added.
     19        * inspector/model/remote-object/array-large.html: Added.
     20        * inspector/model/remote-object/array-large-expected.txt: Added.
     21        * inspector/model/remote-object/boolean.html: Added.
     22        * inspector/model/remote-object/boolean-expected.txt: Added.
     23        * inspector/model/remote-object/class.html: Added.
     24        * inspector/model/remote-object/class-expected.txt: Added.
     25        * inspector/model/remote-object/date.html: Added.
     26        * inspector/model/remote-object/date-expected.txt: Added.
     27        * inspector/model/remote-object/error.html: Added.
     28        * inspector/model/remote-object/error-expected.txt: Added.
     29        * inspector/model/remote-object/function.html: Added.
     30        * inspector/model/remote-object/function-expected.txt: Added.
     31        * inspector/model/remote-object/immutable.html: Added.
     32        * inspector/model/remote-object/immutable-expected.txt: Added.
     33        * inspector/model/remote-object/iterator.html: Added.
     34        * inspector/model/remote-object/iterator-expected.txt:  Added.
     35        * inspector/model/remote-object/iterator-large.html: Added.
     36        * inspector/model/remote-object/iterator-large-expected.txt: Added.
     37        * inspector/model/remote-object/map.html: Added.
     38        * inspector/model/remote-object/map-expected.txt: Added.
     39        * inspector/model/remote-object/map-large.html: Added.
     40        * inspector/model/remote-object/map-large-expected.txt: Added.
     41        * inspector/model/remote-object/null.html: Added.
     42        * inspector/model/remote-object/null-expected.txt: Added.
     43        * inspector/model/remote-object/number.html: Added.
     44        * inspector/model/remote-object/number-expected.txt: Added.
     45        * platform/mac-wk1/inspector/number-expected.txt: Added.
     46        * inspector/model/remote-object/object.html: Added.
     47        * inspector/model/remote-object/object-expected.txt: Added.
     48        * inspector/model/remote-object/object-large.html: Added.
     49        * inspector/model/remote-object/object-large-expected.txt: Added.
     50        * inspector/model/remote-object/promise.html: Added.
     51        * inspector/model/remote-object/promise-expected.txt: Added.
     52        * inspector/model/remote-object/regexp.html: Added.
     53        * inspector/model/remote-object/regexp-expected.txt: Added.
     54        * inspector/model/remote-object/set.html: Added.
     55        * inspector/model/remote-object/set-expected.txt: Added.
     56        * inspector/model/remote-object/set-large.html: Added.
     57        * inspector/model/remote-object/set-large-expected.txt: Added.
     58        * inspector/model/remote-object/string.html: Added.
     59        * inspector/model/remote-object/string-expected.txt: Added.
     60        * inspector/model/remote-object/string-large.html: Added.
     61        * inspector/model/remote-object/string-large-expected.txt: Added.
     62        * inspector/model/remote-object/undefined.html: Added.
     63        * inspector/model/remote-object/undefined-expected.txt: Added.
     64
     65        * inspector/model/remote-object/dom.html: Renamed from LayoutTests/inspector/model/remote-object-dom.html.
     66        * inspector/model/remote-object/dom-expected.txt: Renamed from LayoutTests/inspector/model/remote-object-dom-expected.txt.
     67        * inspector/model/remote-object/iterators-mutated.html: Renamed from LayoutTests/inspector/model/remote-object-mutated-iterators.html.
     68        * inspector/model/remote-object/iterators-mutated-expected.txt: Renamed from LayoutTests/inspector/model/remote-object-mutated-iterators-expected.txt.
     69
     70        * inspector/model/remote-object/resources/remote-object-utilities.js: Renamed from LayoutTests/inspector/model/resources/remote-object-utilities.js.
     71
     72        * inspector/runtime/getDisplayableProperties.html:
     73        * inspector/runtime/getDisplayableProperties-expected.txt:
     74        * inspector/runtime/getProperties.html:
     75        * inspector/runtime/getProperties-expected.txt:
     76        Drive-by: fix assertion for when the `__proto__` is included if `fetchStart` is 0.
     77
     78        * TestExpectations:
     79
    1802019-11-07  Tuomas Karkkainen  <tuomas.webkit@apple.com>
    281
  • trunk/LayoutTests/TestExpectations

    r252164 r252202  
    925925
    926926webkit.org/b/134982 inspector/debugger/setBreakpoint-dfg-and-modify-local.html [ Failure Pass ]
    927 
    928 webkit.org/b/202932 inspector/model/remote-object-weak-collection.html [ Pass Timeout Failure ]
    929 webkit.org/b/202934 inspector/model/remote-object.html [ Pass Timeout ]
    930927
    931928# These tests are fast enough in release but quite slow in debug builds.
  • trunk/LayoutTests/inspector/model/remote-object/dom.html

    r252201 r252202  
    33<head>
    44<meta charset="utf-8">
    5 <script src="../../http/tests/inspector/resources/inspector-test.js"></script>
     5<script src="../../../http/tests/inspector/resources/inspector-test.js"></script>
    66<script src="resources/remote-object-utilities.js"></script>
    77<script>
  • trunk/LayoutTests/inspector/model/remote-object/iterator-expected.txt

    r252201 r252202  
    11
    22-----------------------------------------------------
    3 EXPRESSION: iter = 'alpha'[Symbol.iterator]()
     3EXPRESSION: "a"[Symbol.iterator]()
    44{
    55  "_type": "object",
     
    1717        "_name": "string",
    1818        "_type": "string",
    19         "_value": "alpha",
     19        "_value": "a",
    2020        "_internal": true
    2121      }
     
    3131          "_entries": null
    3232        }
    33       },
     33      }
     34    ]
     35  }
     36}
     37
     38-----------------------------------------------------
     39EXPRESSION: "long string"[Symbol.iterator]()
     40{
     41  "_type": "object",
     42  "_subtype": "iterator",
     43  "_objectId": "<filtered>",
     44  "_description": "String Iterator",
     45  "_preview": {
     46    "_type": "object",
     47    "_subtype": "iterator",
     48    "_description": "String Iterator",
     49    "_lossless": false,
     50    "_overflow": true,
     51    "_properties": [
     52      {
     53        "_name": "string",
     54        "_type": "string",
     55        "_value": "long string",
     56        "_internal": true
     57      }
     58    ],
     59    "_entries": [
    3460      {
    3561        "_value": {
     
    4571        "_value": {
    4672          "_type": "string",
    47           "_description": "p",
     73          "_description": "o",
    4874          "_lossless": true,
    4975          "_overflow": false,
     
    5581        "_value": {
    5682          "_type": "string",
    57           "_description": "h",
     83          "_description": "n",
    5884          "_lossless": true,
    5985          "_overflow": false,
     
    6591        "_value": {
    6692          "_type": "string",
    67           "_description": "a",
    68           "_lossless": true,
    69           "_overflow": false,
    70           "_properties": null,
    71           "_entries": null
    72         }
    73       }
    74     ]
    75   }
    76 }
    77 
    78 -----------------------------------------------------
    79 EXPRESSION: iter.__proto__.next = function(){}; iter
    80 {
    81   "_type": "object",
    82   "_subtype": "iterator",
    83   "_objectId": "<filtered>",
    84   "_description": "String Iterator",
    85   "_preview": {
    86     "_type": "object",
    87     "_subtype": "iterator",
    88     "_description": "String Iterator",
     93          "_description": "g",
     94          "_lossless": true,
     95          "_overflow": false,
     96          "_properties": null,
     97          "_entries": null
     98        }
     99      },
     100      {
     101        "_value": {
     102          "_type": "string",
     103          "_description": " ",
     104          "_lossless": true,
     105          "_overflow": false,
     106          "_properties": null,
     107          "_entries": null
     108        }
     109      }
     110    ]
     111  }
     112}
     113
     114-----------------------------------------------------
     115EXPRESSION: [][Symbol.iterator]()
     116{
     117  "_type": "object",
     118  "_subtype": "iterator",
     119  "_objectId": "<filtered>",
     120  "_description": "Array Iterator",
     121  "_preview": {
     122    "_type": "object",
     123    "_subtype": "iterator",
     124    "_description": "Array Iterator",
    89125    "_lossless": true,
    90126    "_overflow": false,
    91127    "_properties": [
    92128      {
    93         "_name": "string",
    94         "_type": "string",
    95         "_value": "alpha",
    96         "_internal": true
    97       }
    98     ],
    99     "_entries": null
    100   }
    101 }
    102 
    103 -----------------------------------------------------
    104 EXPRESSION: map = new Map; map.set(1, 2); map.set('key', 'value'); iter = map[Symbol.iterator]()
     129        "_name": "array",
     130        "_type": "object",
     131        "_subtype": "array",
     132        "_valuePreview": {
     133          "_type": "object",
     134          "_subtype": "array",
     135          "_description": "Array",
     136          "_lossless": true,
     137          "_overflow": false,
     138          "_size": 0,
     139          "_properties": [],
     140          "_entries": null
     141        },
     142        "_internal": true
     143      },
     144      {
     145        "_name": "kind",
     146        "_type": "string",
     147        "_value": "value",
     148        "_internal": true
     149      }
     150    ],
     151    "_entries": []
     152  }
     153}
     154
     155-----------------------------------------------------
     156EXPRESSION: [1][Symbol.iterator]()
     157{
     158  "_type": "object",
     159  "_subtype": "iterator",
     160  "_objectId": "<filtered>",
     161  "_description": "Array Iterator",
     162  "_preview": {
     163    "_type": "object",
     164    "_subtype": "iterator",
     165    "_description": "Array Iterator",
     166    "_lossless": true,
     167    "_overflow": false,
     168    "_properties": [
     169      {
     170        "_name": "array",
     171        "_type": "object",
     172        "_subtype": "array",
     173        "_valuePreview": {
     174          "_type": "object",
     175          "_subtype": "array",
     176          "_description": "Array",
     177          "_lossless": true,
     178          "_overflow": false,
     179          "_size": 1,
     180          "_properties": [
     181            {
     182              "_name": "0",
     183              "_type": "number",
     184              "_value": "1"
     185            }
     186          ],
     187          "_entries": null
     188        },
     189        "_internal": true
     190      },
     191      {
     192        "_name": "kind",
     193        "_type": "string",
     194        "_value": "value",
     195        "_internal": true
     196      }
     197    ],
     198    "_entries": [
     199      {
     200        "_value": {
     201          "_type": "number",
     202          "_description": "1",
     203          "_lossless": true,
     204          "_overflow": false,
     205          "_properties": null,
     206          "_entries": null
     207        }
     208      }
     209    ]
     210  }
     211}
     212
     213-----------------------------------------------------
     214EXPRESSION: [1, "two", 3, "four", 5, "size"][Symbol.iterator]()
     215{
     216  "_type": "object",
     217  "_subtype": "iterator",
     218  "_objectId": "<filtered>",
     219  "_description": "Array Iterator",
     220  "_preview": {
     221    "_type": "object",
     222    "_subtype": "iterator",
     223    "_description": "Array Iterator",
     224    "_lossless": false,
     225    "_overflow": true,
     226    "_properties": [
     227      {
     228        "_name": "array",
     229        "_type": "object",
     230        "_subtype": "array",
     231        "_value": "Array",
     232        "_internal": true
     233      },
     234      {
     235        "_name": "kind",
     236        "_type": "string",
     237        "_value": "value",
     238        "_internal": true
     239      }
     240    ],
     241    "_entries": [
     242      {
     243        "_value": {
     244          "_type": "number",
     245          "_description": "1",
     246          "_lossless": true,
     247          "_overflow": false,
     248          "_properties": null,
     249          "_entries": null
     250        }
     251      },
     252      {
     253        "_value": {
     254          "_type": "string",
     255          "_description": "two",
     256          "_lossless": true,
     257          "_overflow": false,
     258          "_properties": null,
     259          "_entries": null
     260        }
     261      },
     262      {
     263        "_value": {
     264          "_type": "number",
     265          "_description": "3",
     266          "_lossless": true,
     267          "_overflow": false,
     268          "_properties": null,
     269          "_entries": null
     270        }
     271      },
     272      {
     273        "_value": {
     274          "_type": "string",
     275          "_description": "four",
     276          "_lossless": true,
     277          "_overflow": false,
     278          "_properties": null,
     279          "_entries": null
     280        }
     281      },
     282      {
     283        "_value": {
     284          "_type": "number",
     285          "_description": "5",
     286          "_lossless": true,
     287          "_overflow": false,
     288          "_properties": null,
     289          "_entries": null
     290        }
     291      }
     292    ]
     293  }
     294}
     295
     296-----------------------------------------------------
     297EXPRESSION: [1, "two", 3, "four", 5, "size"].keys()
     298{
     299  "_type": "object",
     300  "_subtype": "iterator",
     301  "_objectId": "<filtered>",
     302  "_description": "Array Iterator",
     303  "_preview": {
     304    "_type": "object",
     305    "_subtype": "iterator",
     306    "_description": "Array Iterator",
     307    "_lossless": false,
     308    "_overflow": true,
     309    "_properties": [
     310      {
     311        "_name": "array",
     312        "_type": "object",
     313        "_subtype": "array",
     314        "_value": "Array",
     315        "_internal": true
     316      },
     317      {
     318        "_name": "kind",
     319        "_type": "string",
     320        "_value": "key",
     321        "_internal": true
     322      }
     323    ],
     324    "_entries": [
     325      {
     326        "_value": {
     327          "_type": "number",
     328          "_description": "0",
     329          "_lossless": true,
     330          "_overflow": false,
     331          "_properties": null,
     332          "_entries": null
     333        }
     334      },
     335      {
     336        "_value": {
     337          "_type": "number",
     338          "_description": "1",
     339          "_lossless": true,
     340          "_overflow": false,
     341          "_properties": null,
     342          "_entries": null
     343        }
     344      },
     345      {
     346        "_value": {
     347          "_type": "number",
     348          "_description": "2",
     349          "_lossless": true,
     350          "_overflow": false,
     351          "_properties": null,
     352          "_entries": null
     353        }
     354      },
     355      {
     356        "_value": {
     357          "_type": "number",
     358          "_description": "3",
     359          "_lossless": true,
     360          "_overflow": false,
     361          "_properties": null,
     362          "_entries": null
     363        }
     364      },
     365      {
     366        "_value": {
     367          "_type": "number",
     368          "_description": "4",
     369          "_lossless": true,
     370          "_overflow": false,
     371          "_properties": null,
     372          "_entries": null
     373        }
     374      }
     375    ]
     376  }
     377}
     378
     379-----------------------------------------------------
     380EXPRESSION: [1, "two", 3, "four", 5, "size"].entries()
     381{
     382  "_type": "object",
     383  "_subtype": "iterator",
     384  "_objectId": "<filtered>",
     385  "_description": "Array Iterator",
     386  "_preview": {
     387    "_type": "object",
     388    "_subtype": "iterator",
     389    "_description": "Array Iterator",
     390    "_lossless": false,
     391    "_overflow": true,
     392    "_properties": [
     393      {
     394        "_name": "array",
     395        "_type": "object",
     396        "_subtype": "array",
     397        "_value": "Array",
     398        "_internal": true
     399      },
     400      {
     401        "_name": "kind",
     402        "_type": "string",
     403        "_value": "key+value",
     404        "_internal": true
     405      }
     406    ],
     407    "_entries": [
     408      {
     409        "_value": {
     410          "_type": "object",
     411          "_subtype": "array",
     412          "_description": "Array",
     413          "_lossless": true,
     414          "_overflow": false,
     415          "_size": 2,
     416          "_properties": [
     417            {
     418              "_name": "0",
     419              "_type": "number",
     420              "_value": "0"
     421            },
     422            {
     423              "_name": "1",
     424              "_type": "number",
     425              "_value": "1"
     426            }
     427          ],
     428          "_entries": null
     429        }
     430      },
     431      {
     432        "_value": {
     433          "_type": "object",
     434          "_subtype": "array",
     435          "_description": "Array",
     436          "_lossless": true,
     437          "_overflow": false,
     438          "_size": 2,
     439          "_properties": [
     440            {
     441              "_name": "0",
     442              "_type": "number",
     443              "_value": "1"
     444            },
     445            {
     446              "_name": "1",
     447              "_type": "string",
     448              "_value": "two"
     449            }
     450          ],
     451          "_entries": null
     452        }
     453      },
     454      {
     455        "_value": {
     456          "_type": "object",
     457          "_subtype": "array",
     458          "_description": "Array",
     459          "_lossless": true,
     460          "_overflow": false,
     461          "_size": 2,
     462          "_properties": [
     463            {
     464              "_name": "0",
     465              "_type": "number",
     466              "_value": "2"
     467            },
     468            {
     469              "_name": "1",
     470              "_type": "number",
     471              "_value": "3"
     472            }
     473          ],
     474          "_entries": null
     475        }
     476      },
     477      {
     478        "_value": {
     479          "_type": "object",
     480          "_subtype": "array",
     481          "_description": "Array",
     482          "_lossless": true,
     483          "_overflow": false,
     484          "_size": 2,
     485          "_properties": [
     486            {
     487              "_name": "0",
     488              "_type": "number",
     489              "_value": "3"
     490            },
     491            {
     492              "_name": "1",
     493              "_type": "string",
     494              "_value": "four"
     495            }
     496          ],
     497          "_entries": null
     498        }
     499      },
     500      {
     501        "_value": {
     502          "_type": "object",
     503          "_subtype": "array",
     504          "_description": "Array",
     505          "_lossless": true,
     506          "_overflow": false,
     507          "_size": 2,
     508          "_properties": [
     509            {
     510              "_name": "0",
     511              "_type": "number",
     512              "_value": "4"
     513            },
     514            {
     515              "_name": "1",
     516              "_type": "number",
     517              "_value": "5"
     518            }
     519          ],
     520          "_entries": null
     521        }
     522      }
     523    ]
     524  }
     525}
     526
     527-----------------------------------------------------
     528EXPRESSION: map = new Map; map.set(1, 2); map.set("key", "value"); map.values()
    105529{
    106530  "_type": "object",
     
    125549        "_name": "kind",
    126550        "_type": "string",
     551        "_value": "value",
     552        "_internal": true
     553      }
     554    ],
     555    "_entries": [
     556      {
     557        "_value": {
     558          "_type": "number",
     559          "_description": "2",
     560          "_lossless": true,
     561          "_overflow": false,
     562          "_properties": null,
     563          "_entries": null
     564        }
     565      },
     566      {
     567        "_value": {
     568          "_type": "string",
     569          "_description": "value",
     570          "_lossless": true,
     571          "_overflow": false,
     572          "_properties": null,
     573          "_entries": null
     574        }
     575      }
     576    ]
     577  }
     578}
     579
     580-----------------------------------------------------
     581EXPRESSION: map.keys()
     582{
     583  "_type": "object",
     584  "_subtype": "iterator",
     585  "_objectId": "<filtered>",
     586  "_description": "Map Iterator",
     587  "_preview": {
     588    "_type": "object",
     589    "_subtype": "iterator",
     590    "_description": "Map Iterator",
     591    "_lossless": false,
     592    "_overflow": false,
     593    "_properties": [
     594      {
     595        "_name": "map",
     596        "_type": "object",
     597        "_subtype": "map",
     598        "_value": "Map",
     599        "_internal": true
     600      },
     601      {
     602        "_name": "kind",
     603        "_type": "string",
     604        "_value": "key",
     605        "_internal": true
     606      }
     607    ],
     608    "_entries": [
     609      {
     610        "_value": {
     611          "_type": "number",
     612          "_description": "1",
     613          "_lossless": true,
     614          "_overflow": false,
     615          "_properties": null,
     616          "_entries": null
     617        }
     618      },
     619      {
     620        "_value": {
     621          "_type": "string",
     622          "_description": "key",
     623          "_lossless": true,
     624          "_overflow": false,
     625          "_properties": null,
     626          "_entries": null
     627        }
     628      }
     629    ]
     630  }
     631}
     632
     633-----------------------------------------------------
     634EXPRESSION: map.entries()
     635{
     636  "_type": "object",
     637  "_subtype": "iterator",
     638  "_objectId": "<filtered>",
     639  "_description": "Map Iterator",
     640  "_preview": {
     641    "_type": "object",
     642    "_subtype": "iterator",
     643    "_description": "Map Iterator",
     644    "_lossless": false,
     645    "_overflow": false,
     646    "_properties": [
     647      {
     648        "_name": "map",
     649        "_type": "object",
     650        "_subtype": "map",
     651        "_value": "Map",
     652        "_internal": true
     653      },
     654      {
     655        "_name": "kind",
     656        "_type": "string",
    127657        "_value": "key+value",
    128658        "_internal": true
     
    181711
    182712-----------------------------------------------------
    183 EXPRESSION: iter.__proto__.next = function(){}; iter
     713EXPRESSION: set = new Set; for (var i = 0; i <= 100; i++) set.add(i); set.values()
     714{
     715  "_type": "object",
     716  "_subtype": "iterator",
     717  "_objectId": "<filtered>",
     718  "_description": "Set Iterator",
     719  "_preview": {
     720    "_type": "object",
     721    "_subtype": "iterator",
     722    "_description": "Set Iterator",
     723    "_lossless": false,
     724    "_overflow": true,
     725    "_properties": [
     726      {
     727        "_name": "set",
     728        "_type": "object",
     729        "_subtype": "set",
     730        "_value": "Set",
     731        "_internal": true
     732      },
     733      {
     734        "_name": "kind",
     735        "_type": "string",
     736        "_value": "value",
     737        "_internal": true
     738      }
     739    ],
     740    "_entries": [
     741      {
     742        "_value": {
     743          "_type": "number",
     744          "_description": "0",
     745          "_lossless": true,
     746          "_overflow": false,
     747          "_properties": null,
     748          "_entries": null
     749        }
     750      },
     751      {
     752        "_value": {
     753          "_type": "number",
     754          "_description": "1",
     755          "_lossless": true,
     756          "_overflow": false,
     757          "_properties": null,
     758          "_entries": null
     759        }
     760      },
     761      {
     762        "_value": {
     763          "_type": "number",
     764          "_description": "2",
     765          "_lossless": true,
     766          "_overflow": false,
     767          "_properties": null,
     768          "_entries": null
     769        }
     770      },
     771      {
     772        "_value": {
     773          "_type": "number",
     774          "_description": "3",
     775          "_lossless": true,
     776          "_overflow": false,
     777          "_properties": null,
     778          "_entries": null
     779        }
     780      },
     781      {
     782        "_value": {
     783          "_type": "number",
     784          "_description": "4",
     785          "_lossless": true,
     786          "_overflow": false,
     787          "_properties": null,
     788          "_entries": null
     789        }
     790      }
     791    ]
     792  }
     793}
     794
     795-----------------------------------------------------
     796EXPRESSION: map.entries()
    184797{
    185798  "_type": "object",
     
    208821      }
    209822    ],
    210     "_entries": null
    211   }
    212 }
    213 
    214 -----------------------------------------------------
    215 EXPRESSION: set = new Set; for (var i = 0; i <= 100; i++) set.add(i); iter = set[Symbol.iterator]()
    216 {
    217   "_type": "object",
    218   "_subtype": "iterator",
    219   "_objectId": "<filtered>",
    220   "_description": "Set Iterator",
    221   "_preview": {
    222     "_type": "object",
    223     "_subtype": "iterator",
    224     "_description": "Set Iterator",
    225     "_lossless": false,
    226     "_overflow": true,
    227     "_properties": [
    228       {
    229         "_name": "set",
    230         "_type": "object",
    231         "_subtype": "set",
    232         "_value": "Set",
    233         "_internal": true
    234       },
    235       {
    236         "_name": "kind",
    237         "_type": "string",
    238         "_value": "value",
    239         "_internal": true
    240       }
    241     ],
    242     "_entries": [
    243       {
    244         "_value": {
    245           "_type": "number",
    246           "_description": "0",
    247           "_lossless": true,
    248           "_overflow": false,
    249           "_properties": null,
    250           "_entries": null
    251         }
    252       },
    253       {
    254         "_value": {
    255           "_type": "number",
    256           "_description": "1",
    257           "_lossless": true,
    258           "_overflow": false,
    259           "_properties": null,
    260           "_entries": null
    261         }
    262       },
    263       {
    264         "_value": {
    265           "_type": "number",
    266           "_description": "2",
    267           "_lossless": true,
    268           "_overflow": false,
    269           "_properties": null,
    270           "_entries": null
    271         }
    272       },
    273       {
    274         "_value": {
    275           "_type": "number",
    276           "_description": "3",
    277           "_lossless": true,
    278           "_overflow": false,
    279           "_properties": null,
    280           "_entries": null
    281         }
    282       },
    283       {
    284         "_value": {
    285           "_type": "number",
    286           "_description": "4",
    287           "_lossless": true,
    288           "_overflow": false,
    289           "_properties": null,
    290           "_entries": null
    291         }
    292       }
    293     ]
    294   }
    295 }
    296 
    297 -----------------------------------------------------
    298 EXPRESSION: iter.__proto__.next = function(){}; iter
    299 {
    300   "_type": "object",
    301   "_subtype": "iterator",
    302   "_objectId": "<filtered>",
    303   "_description": "Set Iterator",
    304   "_preview": {
    305     "_type": "object",
    306     "_subtype": "iterator",
    307     "_description": "Set Iterator",
    308     "_lossless": false,
    309     "_overflow": false,
    310     "_properties": [
    311       {
    312         "_name": "set",
    313         "_type": "object",
    314         "_subtype": "set",
    315         "_value": "Set",
    316         "_internal": true
    317       },
    318       {
    319         "_name": "kind",
    320         "_type": "string",
    321         "_value": "value",
    322         "_internal": true
    323       }
    324     ],
    325     "_entries": null
    326   }
    327 }
    328 
    329 -----------------------------------------------------
    330 EXPRESSION: arrayIter = [1,2,3][Symbol.iterator]()
     823    "_entries": [
     824      {
     825        "_value": {
     826          "_type": "object",
     827          "_subtype": "array",
     828          "_description": "Array",
     829          "_lossless": true,
     830          "_overflow": false,
     831          "_size": 2,
     832          "_properties": [
     833            {
     834              "_name": "0",
     835              "_type": "number",
     836              "_value": "1"
     837            },
     838            {
     839              "_name": "1",
     840              "_type": "number",
     841              "_value": "2"
     842            }
     843          ],
     844          "_entries": null
     845        }
     846      },
     847      {
     848        "_value": {
     849          "_type": "object",
     850          "_subtype": "array",
     851          "_description": "Array",
     852          "_lossless": true,
     853          "_overflow": false,
     854          "_size": 2,
     855          "_properties": [
     856            {
     857              "_name": "0",
     858              "_type": "string",
     859              "_value": "key"
     860            },
     861            {
     862              "_name": "1",
     863              "_type": "string",
     864              "_value": "value"
     865            }
     866          ],
     867          "_entries": null
     868        }
     869      }
     870    ]
     871  }
     872}
     873
     874-----------------------------------------------------
     875EXPRESSION: x = undefined; (function() { x = arguments; })(1, "two"); x[Symbol.iterator]()
    331876{
    332877  "_type": "object",
     
    348893          "_type": "object",
    349894          "_subtype": "array",
    350           "_description": "Array",
    351           "_lossless": true,
    352           "_overflow": false,
    353           "_size": 3,
     895          "_description": "Arguments",
     896          "_lossless": true,
     897          "_overflow": false,
     898          "_size": 2,
    354899          "_properties": [
    355900            {
     
    360905            {
    361906              "_name": "1",
    362               "_type": "number",
    363               "_value": "2"
    364             },
    365             {
    366               "_name": "2",
    367               "_type": "number",
    368               "_value": "3"
     907              "_type": "string",
     908              "_value": "two"
    369909            }
    370910          ],
     
    393933      {
    394934        "_value": {
    395           "_type": "number",
    396           "_description": "2",
    397           "_lossless": true,
    398           "_overflow": false,
    399           "_properties": null,
    400           "_entries": null
    401         }
    402       },
    403       {
    404         "_value": {
    405           "_type": "number",
    406           "_description": "3",
    407           "_lossless": true,
    408           "_overflow": false,
    409           "_properties": null,
    410           "_entries": null
    411         }
    412       }
    413     ]
    414   }
    415 }
    416 
    417 -----------------------------------------------------
    418 EXPRESSION: x = undefined; (function() { x = arguments; })(3, 'arg'); argumentsIter = x[Symbol.iterator]()
     935          "_type": "string",
     936          "_description": "two",
     937          "_lossless": true,
     938          "_overflow": false,
     939          "_properties": null,
     940          "_entries": null
     941        }
     942      }
     943    ]
     944  }
     945}
     946
     947-----------------------------------------------------
     948EXPRESSION: iter = [1, 2][Symbol.iterator](); iter["return"] = function(){}; iter
    419949{
    420950  "_type": "object",
     
    436966          "_type": "object",
    437967          "_subtype": "array",
    438           "_description": "Arguments",
     968          "_description": "Array",
    439969          "_lossless": true,
    440970          "_overflow": false,
    441971          "_size": 2,
    442           "_properties": [
    443             {
    444               "_name": "0",
    445               "_type": "number",
    446               "_value": "3"
    447             },
    448             {
    449               "_name": "1",
    450               "_type": "string",
    451               "_value": "arg"
    452             }
    453           ],
    454           "_entries": null
    455         },
    456         "_internal": true
    457       },
    458       {
    459         "_name": "kind",
    460         "_type": "string",
    461         "_value": "value",
    462         "_internal": true
    463       }
    464     ],
    465     "_entries": [
    466       {
    467         "_value": {
    468           "_type": "number",
    469           "_description": "3",
    470           "_lossless": true,
    471           "_overflow": false,
    472           "_properties": null,
    473           "_entries": null
    474         }
    475       },
    476       {
    477         "_value": {
    478           "_type": "string",
    479           "_description": "arg",
    480           "_lossless": true,
    481           "_overflow": false,
    482           "_properties": null,
    483           "_entries": null
    484         }
    485       }
    486     ]
    487   }
    488 }
    489 
    490 -----------------------------------------------------
    491 EXPRESSION: arrayIter.__proto__.next = function(){}; arrayIter
    492 {
    493   "_type": "object",
    494   "_subtype": "iterator",
    495   "_objectId": "<filtered>",
    496   "_description": "Array Iterator",
    497   "_preview": {
    498     "_type": "object",
    499     "_subtype": "iterator",
    500     "_description": "Array Iterator",
    501     "_lossless": true,
    502     "_overflow": false,
    503     "_properties": [
    504       {
    505         "_name": "array",
    506         "_type": "object",
    507         "_subtype": "array",
    508         "_valuePreview": {
    509           "_type": "object",
    510           "_subtype": "array",
    511           "_description": "Array",
    512           "_lossless": true,
    513           "_overflow": false,
    514           "_size": 3,
    515972          "_properties": [
    516973            {
     
    523980              "_type": "number",
    524981              "_value": "2"
    525             },
    526             {
    527               "_name": "2",
    528               "_type": "number",
    529               "_value": "3"
    530982            }
    531983          ],
     
    541993      }
    542994    ],
    543     "_entries": null
    544   }
    545 }
    546 
    547 -----------------------------------------------------
    548 EXPRESSION: argumentsIter.__proto__.next = function(){}; argumentsIter
    549 {
    550   "_type": "object",
    551   "_subtype": "iterator",
    552   "_objectId": "<filtered>",
    553   "_description": "Array Iterator",
    554   "_preview": {
    555     "_type": "object",
    556     "_subtype": "iterator",
    557     "_description": "Array Iterator",
    558     "_lossless": true,
    559     "_overflow": false,
    560     "_properties": [
    561       {
    562         "_name": "array",
    563         "_type": "object",
    564         "_subtype": "array",
    565         "_valuePreview": {
    566           "_type": "object",
    567           "_subtype": "array",
    568           "_description": "Arguments",
    569           "_lossless": true,
    570           "_overflow": false,
    571           "_size": 2,
    572           "_properties": [
    573             {
    574               "_name": "0",
    575               "_type": "number",
    576               "_value": "3"
    577             },
    578             {
    579               "_name": "1",
    580               "_type": "string",
    581               "_value": "arg"
    582             }
    583           ],
    584           "_entries": null
    585         },
    586         "_internal": true
    587       },
    588       {
    589         "_name": "kind",
    590         "_type": "string",
    591         "_value": "value",
    592         "_internal": true
    593       }
    594     ],
    595     "_entries": null
    596   }
    597 }
    598 
     995    "_entries": [
     996      {
     997        "_value": {
     998          "_type": "number",
     999          "_description": "1",
     1000          "_lossless": true,
     1001          "_overflow": false,
     1002          "_properties": null,
     1003          "_entries": null
     1004        }
     1005      },
     1006      {
     1007        "_value": {
     1008          "_type": "number",
     1009          "_description": "2",
     1010          "_lossless": true,
     1011          "_overflow": false,
     1012          "_properties": null,
     1013          "_entries": null
     1014        }
     1015      }
     1016    ]
     1017  }
     1018}
     1019
  • trunk/LayoutTests/inspector/model/remote-object/iterator-large-expected.txt

    r252201 r252202  
    11
    22-----------------------------------------------------
    3 EXPRESSION: iter = 'alpha'[Symbol.iterator]()
     3EXPRESSION: "0123456789".repeat(1000000 / 10)[Symbol.iterator]()
    44{
    55  "_type": "object",
     
    1111    "_subtype": "iterator",
    1212    "_description": "String Iterator",
    13     "_lossless": true,
    14     "_overflow": false,
     13    "_lossless": false,
     14    "_overflow": true,
    1515    "_properties": [
    1616      {
    1717        "_name": "string",
    1818        "_type": "string",
    19         "_value": "alpha",
     19        "_value": "01234567890123456789012345678901234567890123456789…1234567890123456789012345678901234567890123456789",
    2020        "_internal": true
    2121      }
     
    2525        "_value": {
    2626          "_type": "string",
    27           "_description": "a",
    28           "_lossless": true,
    29           "_overflow": false,
    30           "_properties": null,
    31           "_entries": null
    32         }
    33       },
    34       {
    35         "_value": {
    36           "_type": "string",
    37           "_description": "l",
    38           "_lossless": true,
    39           "_overflow": false,
    40           "_properties": null,
    41           "_entries": null
    42         }
    43       },
    44       {
    45         "_value": {
    46           "_type": "string",
    47           "_description": "p",
    48           "_lossless": true,
    49           "_overflow": false,
    50           "_properties": null,
    51           "_entries": null
    52         }
    53       },
    54       {
    55         "_value": {
    56           "_type": "string",
    57           "_description": "h",
    58           "_lossless": true,
    59           "_overflow": false,
    60           "_properties": null,
    61           "_entries": null
    62         }
    63       },
    64       {
    65         "_value": {
    66           "_type": "string",
    67           "_description": "a",
     27          "_description": "0",
     28          "_lossless": true,
     29          "_overflow": false,
     30          "_properties": null,
     31          "_entries": null
     32        }
     33      },
     34      {
     35        "_value": {
     36          "_type": "string",
     37          "_description": "1",
     38          "_lossless": true,
     39          "_overflow": false,
     40          "_properties": null,
     41          "_entries": null
     42        }
     43      },
     44      {
     45        "_value": {
     46          "_type": "string",
     47          "_description": "2",
     48          "_lossless": true,
     49          "_overflow": false,
     50          "_properties": null,
     51          "_entries": null
     52        }
     53      },
     54      {
     55        "_value": {
     56          "_type": "string",
     57          "_description": "3",
     58          "_lossless": true,
     59          "_overflow": false,
     60          "_properties": null,
     61          "_entries": null
     62        }
     63      },
     64      {
     65        "_value": {
     66          "_type": "string",
     67          "_description": "4",
    6868          "_lossless": true,
    6969          "_overflow": false,
     
    7777
    7878-----------------------------------------------------
    79 EXPRESSION: iter.__proto__.next = function(){}; iter
     79EXPRESSION: arr = new Int8Array(new ArrayBuffer(1000000)); arr[Symbol.iterator]()
    8080{
    8181  "_type": "object",
    8282  "_subtype": "iterator",
    8383  "_objectId": "<filtered>",
    84   "_description": "String Iterator",
     84  "_description": "Array Iterator",
    8585  "_preview": {
    8686    "_type": "object",
    8787    "_subtype": "iterator",
    88     "_description": "String Iterator",
    89     "_lossless": true,
     88    "_description": "Array Iterator",
     89    "_lossless": false,
    9090    "_overflow": false,
    9191    "_properties": [
    9292      {
    93         "_name": "string",
     93        "_name": "array",
     94        "_type": "object",
     95        "_subtype": "array",
     96        "_value": "Int8Array",
     97        "_internal": true
     98      },
     99      {
     100        "_name": "kind",
    94101        "_type": "string",
    95         "_value": "alpha",
     102        "_value": "value",
    96103        "_internal": true
    97104      }
     
    102109
    103110-----------------------------------------------------
    104 EXPRESSION: map = new Map; map.set(1, 2); map.set('key', 'value'); iter = map[Symbol.iterator]()
     111EXPRESSION: map = new Map; for (var i = 0; i < 1000000; i++) map.set(i, i); map[Symbol.iterator]()
    105112{
    106113  "_type": "object",
     
    113120    "_description": "Map Iterator",
    114121    "_lossless": false,
    115     "_overflow": false,
     122    "_overflow": true,
    116123    "_properties": [
    117124      {
     
    142149              "_name": "0",
    143150              "_type": "number",
     151              "_value": "0"
     152            },
     153            {
     154              "_name": "1",
     155              "_type": "number",
     156              "_value": "0"
     157            }
     158          ],
     159          "_entries": null
     160        }
     161      },
     162      {
     163        "_value": {
     164          "_type": "object",
     165          "_subtype": "array",
     166          "_description": "Array",
     167          "_lossless": true,
     168          "_overflow": false,
     169          "_size": 2,
     170          "_properties": [
     171            {
     172              "_name": "0",
     173              "_type": "number",
    144174              "_value": "1"
    145175            },
     
    147177              "_name": "1",
    148178              "_type": "number",
     179              "_value": "1"
     180            }
     181          ],
     182          "_entries": null
     183        }
     184      },
     185      {
     186        "_value": {
     187          "_type": "object",
     188          "_subtype": "array",
     189          "_description": "Array",
     190          "_lossless": true,
     191          "_overflow": false,
     192          "_size": 2,
     193          "_properties": [
     194            {
     195              "_name": "0",
     196              "_type": "number",
    149197              "_value": "2"
    150             }
    151           ],
    152           "_entries": null
    153         }
    154       },
    155       {
    156         "_value": {
    157           "_type": "object",
    158           "_subtype": "array",
    159           "_description": "Array",
    160           "_lossless": true,
    161           "_overflow": false,
    162           "_size": 2,
    163           "_properties": [
    164             {
    165               "_name": "0",
    166               "_type": "string",
    167               "_value": "key"
    168             },
    169             {
    170               "_name": "1",
    171               "_type": "string",
    172               "_value": "value"
     198            },
     199            {
     200              "_name": "1",
     201              "_type": "number",
     202              "_value": "2"
     203            }
     204          ],
     205          "_entries": null
     206        }
     207      },
     208      {
     209        "_value": {
     210          "_type": "object",
     211          "_subtype": "array",
     212          "_description": "Array",
     213          "_lossless": true,
     214          "_overflow": false,
     215          "_size": 2,
     216          "_properties": [
     217            {
     218              "_name": "0",
     219              "_type": "number",
     220              "_value": "3"
     221            },
     222            {
     223              "_name": "1",
     224              "_type": "number",
     225              "_value": "3"
     226            }
     227          ],
     228          "_entries": null
     229        }
     230      },
     231      {
     232        "_value": {
     233          "_type": "object",
     234          "_subtype": "array",
     235          "_description": "Array",
     236          "_lossless": true,
     237          "_overflow": false,
     238          "_size": 2,
     239          "_properties": [
     240            {
     241              "_name": "0",
     242              "_type": "number",
     243              "_value": "4"
     244            },
     245            {
     246              "_name": "1",
     247              "_type": "number",
     248              "_value": "4"
    173249            }
    174250          ],
     
    181257
    182258-----------------------------------------------------
    183 EXPRESSION: iter.__proto__.next = function(){}; iter
    184 {
    185   "_type": "object",
    186   "_subtype": "iterator",
    187   "_objectId": "<filtered>",
    188   "_description": "Map Iterator",
    189   "_preview": {
    190     "_type": "object",
    191     "_subtype": "iterator",
    192     "_description": "Map Iterator",
    193     "_lossless": false,
    194     "_overflow": false,
    195     "_properties": [
    196       {
    197         "_name": "map",
    198         "_type": "object",
    199         "_subtype": "map",
    200         "_value": "Map",
    201         "_internal": true
    202       },
    203       {
    204         "_name": "kind",
    205         "_type": "string",
    206         "_value": "key+value",
    207         "_internal": true
    208       }
    209     ],
    210     "_entries": null
    211   }
    212 }
    213 
    214 -----------------------------------------------------
    215 EXPRESSION: set = new Set; for (var i = 0; i <= 100; i++) set.add(i); iter = set[Symbol.iterator]()
     259EXPRESSION: set = new Set; for (var i = 0; i < 1000000; i++) set.add(i); set[Symbol.iterator]()
    216260{
    217261  "_type": "object",
     
    295339}
    296340
    297 -----------------------------------------------------
    298 EXPRESSION: iter.__proto__.next = function(){}; iter
    299 {
    300   "_type": "object",
    301   "_subtype": "iterator",
    302   "_objectId": "<filtered>",
    303   "_description": "Set Iterator",
    304   "_preview": {
    305     "_type": "object",
    306     "_subtype": "iterator",
    307     "_description": "Set Iterator",
    308     "_lossless": false,
    309     "_overflow": false,
    310     "_properties": [
    311       {
    312         "_name": "set",
    313         "_type": "object",
    314         "_subtype": "set",
    315         "_value": "Set",
    316         "_internal": true
    317       },
    318       {
    319         "_name": "kind",
    320         "_type": "string",
    321         "_value": "value",
    322         "_internal": true
    323       }
    324     ],
    325     "_entries": null
    326   }
    327 }
    328 
    329 -----------------------------------------------------
    330 EXPRESSION: arrayIter = [1,2,3][Symbol.iterator]()
    331 {
    332   "_type": "object",
    333   "_subtype": "iterator",
    334   "_objectId": "<filtered>",
    335   "_description": "Array Iterator",
    336   "_preview": {
    337     "_type": "object",
    338     "_subtype": "iterator",
    339     "_description": "Array Iterator",
    340     "_lossless": true,
    341     "_overflow": false,
    342     "_properties": [
    343       {
    344         "_name": "array",
    345         "_type": "object",
    346         "_subtype": "array",
    347         "_valuePreview": {
    348           "_type": "object",
    349           "_subtype": "array",
    350           "_description": "Array",
    351           "_lossless": true,
    352           "_overflow": false,
    353           "_size": 3,
    354           "_properties": [
    355             {
    356               "_name": "0",
    357               "_type": "number",
    358               "_value": "1"
    359             },
    360             {
    361               "_name": "1",
    362               "_type": "number",
    363               "_value": "2"
    364             },
    365             {
    366               "_name": "2",
    367               "_type": "number",
    368               "_value": "3"
    369             }
    370           ],
    371           "_entries": null
    372         },
    373         "_internal": true
    374       },
    375       {
    376         "_name": "kind",
    377         "_type": "string",
    378         "_value": "value",
    379         "_internal": true
    380       }
    381     ],
    382     "_entries": [
    383       {
    384         "_value": {
    385           "_type": "number",
    386           "_description": "1",
    387           "_lossless": true,
    388           "_overflow": false,
    389           "_properties": null,
    390           "_entries": null
    391         }
    392       },
    393       {
    394         "_value": {
    395           "_type": "number",
    396           "_description": "2",
    397           "_lossless": true,
    398           "_overflow": false,
    399           "_properties": null,
    400           "_entries": null
    401         }
    402       },
    403       {
    404         "_value": {
    405           "_type": "number",
    406           "_description": "3",
    407           "_lossless": true,
    408           "_overflow": false,
    409           "_properties": null,
    410           "_entries": null
    411         }
    412       }
    413     ]
    414   }
    415 }
    416 
    417 -----------------------------------------------------
    418 EXPRESSION: x = undefined; (function() { x = arguments; })(3, 'arg'); argumentsIter = x[Symbol.iterator]()
    419 {
    420   "_type": "object",
    421   "_subtype": "iterator",
    422   "_objectId": "<filtered>",
    423   "_description": "Array Iterator",
    424   "_preview": {
    425     "_type": "object",
    426     "_subtype": "iterator",
    427     "_description": "Array Iterator",
    428     "_lossless": true,
    429     "_overflow": false,
    430     "_properties": [
    431       {
    432         "_name": "array",
    433         "_type": "object",
    434         "_subtype": "array",
    435         "_valuePreview": {
    436           "_type": "object",
    437           "_subtype": "array",
    438           "_description": "Arguments",
    439           "_lossless": true,
    440           "_overflow": false,
    441           "_size": 2,
    442           "_properties": [
    443             {
    444               "_name": "0",
    445               "_type": "number",
    446               "_value": "3"
    447             },
    448             {
    449               "_name": "1",
    450               "_type": "string",
    451               "_value": "arg"
    452             }
    453           ],
    454           "_entries": null
    455         },
    456         "_internal": true
    457       },
    458       {
    459         "_name": "kind",
    460         "_type": "string",
    461         "_value": "value",
    462         "_internal": true
    463       }
    464     ],
    465     "_entries": [
    466       {
    467         "_value": {
    468           "_type": "number",
    469           "_description": "3",
    470           "_lossless": true,
    471           "_overflow": false,
    472           "_properties": null,
    473           "_entries": null
    474         }
    475       },
    476       {
    477         "_value": {
    478           "_type": "string",
    479           "_description": "arg",
    480           "_lossless": true,
    481           "_overflow": false,
    482           "_properties": null,
    483           "_entries": null
    484         }
    485       }
    486     ]
    487   }
    488 }
    489 
    490 -----------------------------------------------------
    491 EXPRESSION: arrayIter.__proto__.next = function(){}; arrayIter
    492 {
    493   "_type": "object",
    494   "_subtype": "iterator",
    495   "_objectId": "<filtered>",
    496   "_description": "Array Iterator",
    497   "_preview": {
    498     "_type": "object",
    499     "_subtype": "iterator",
    500     "_description": "Array Iterator",
    501     "_lossless": true,
    502     "_overflow": false,
    503     "_properties": [
    504       {
    505         "_name": "array",
    506         "_type": "object",
    507         "_subtype": "array",
    508         "_valuePreview": {
    509           "_type": "object",
    510           "_subtype": "array",
    511           "_description": "Array",
    512           "_lossless": true,
    513           "_overflow": false,
    514           "_size": 3,
    515           "_properties": [
    516             {
    517               "_name": "0",
    518               "_type": "number",
    519               "_value": "1"
    520             },
    521             {
    522               "_name": "1",
    523               "_type": "number",
    524               "_value": "2"
    525             },
    526             {
    527               "_name": "2",
    528               "_type": "number",
    529               "_value": "3"
    530             }
    531           ],
    532           "_entries": null
    533         },
    534         "_internal": true
    535       },
    536       {
    537         "_name": "kind",
    538         "_type": "string",
    539         "_value": "value",
    540         "_internal": true
    541       }
    542     ],
    543     "_entries": null
    544   }
    545 }
    546 
    547 -----------------------------------------------------
    548 EXPRESSION: argumentsIter.__proto__.next = function(){}; argumentsIter
    549 {
    550   "_type": "object",
    551   "_subtype": "iterator",
    552   "_objectId": "<filtered>",
    553   "_description": "Array Iterator",
    554   "_preview": {
    555     "_type": "object",
    556     "_subtype": "iterator",
    557     "_description": "Array Iterator",
    558     "_lossless": true,
    559     "_overflow": false,
    560     "_properties": [
    561       {
    562         "_name": "array",
    563         "_type": "object",
    564         "_subtype": "array",
    565         "_valuePreview": {
    566           "_type": "object",
    567           "_subtype": "array",
    568           "_description": "Arguments",
    569           "_lossless": true,
    570           "_overflow": false,
    571           "_size": 2,
    572           "_properties": [
    573             {
    574               "_name": "0",
    575               "_type": "number",
    576               "_value": "3"
    577             },
    578             {
    579               "_name": "1",
    580               "_type": "string",
    581               "_value": "arg"
    582             }
    583           ],
    584           "_entries": null
    585         },
    586         "_internal": true
    587       },
    588       {
    589         "_name": "kind",
    590         "_type": "string",
    591         "_value": "value",
    592         "_internal": true
    593       }
    594     ],
    595     "_entries": null
    596   }
    597 }
    598 
  • trunk/LayoutTests/inspector/model/remote-object/iterators-mutated.html

    r252201 r252202  
    33<head>
    44<meta charset="utf-8">
    5 <script src="../../http/tests/inspector/resources/inspector-test.js"></script>
     5<script src="../../../http/tests/inspector/resources/inspector-test.js"></script>
    66<script src="resources/remote-object-utilities.js"></script>
    77<script>
     
    99{
    1010    let steps = [
    11         // String Iterator
     11        // String
    1212        {expression: `iter = 'alpha'[Symbol.iterator]()`},
    1313        {expression: `iter.__proto__.next = function(){}; iter`},
    1414
    15         // Map Iterator
     15        // Map
    1616        {expression: `map = new Map; map.set(1, 2); map.set('key', 'value'); iter = map[Symbol.iterator]()`},
    1717        {expression: `iter.__proto__.next = function(){}; iter`},
    1818
    19         // Set Iterator
     19        // Set
    2020        {expression: `set = new Set; for (var i = 0; i <= 100; i++) set.add(i); iter = set[Symbol.iterator]()`},
    2121        {expression: `iter.__proto__.next = function(){}; iter`},
    2222
    23         // Array Iterator (array and arguments)
     23        // Array (array and arguments)
    2424        {expression: `arrayIter = [1,2,3][Symbol.iterator]()`},
    2525        {expression: `x = undefined; (function() { x = arguments; })(3, 'arg'); argumentsIter = x[Symbol.iterator]()`},
  • trunk/LayoutTests/inspector/model/remote-object/resources/remote-object-utilities.js

    r252201 r252202  
    1616
    1717TestPage.registerInitializer(() => {
    18     function remoteObjectJSONFilter(key, value) {
     18    function remoteObjectJSONFilter(filter, key, value) {
    1919        if (key === "_target" || key === "_hasChildren" || key === "_listeners")
    2020            return undefined;
     
    2323        if (typeof value === "bigint")
    2424            return "<filtered " + String(value) + "n>";
     25        if (filter && filter(key, value))
     26            return "<filtered>";
    2527        return value;
    2628    }
     
    3436        }
    3537
    36         for (let {expression, browserOnly} of steps) {
     38        for (let {expression, browserOnly, filter} of steps) {
    3739            if (browserOnly) {
    3840                checkComplete();
    3941                continue;
    4042            }
     43
     44            filter = remoteObjectJSONFilter.bind(null, filter);
    4145
    4246            WI.runtimeManager.evaluateInInspectedWindow(expression, {objectGroup: "test", doNotPauseOnExceptionsAndMuteConsole: true, generatePreview: true}, (remoteObject, wasThrown) => {
     
    4549                InspectorTest.log("EXPRESSION: " + expression);
    4650                InspectorTest.assert(remoteObject instanceof WI.RemoteObject);
    47                 InspectorTest.log(JSON.stringify(remoteObject, remoteObjectJSONFilter, 2));
     51                InspectorTest.log(JSON.stringify(remoteObject, filter, 2));
    4852                checkComplete();
    4953            });
  • trunk/LayoutTests/inspector/runtime/getDisplayableProperties-expected.txt

    r250087 r252202  
    164164Evaluating expression...
    165165Getting displayable properties with fetchCount 5...
    166 ASSERT: Should only get 5 properties.
    167166Properties:
    168167    "A"          =>  0 (number)  [writable | enumerable | configurable | isOwn]
     
    195194Evaluating expression...
    196195Getting displayable properties with fetchCount 5...
    197 ASSERT: Should only get 5 properties.
    198196Properties:
    199197    "0"          =>  "A" (string)  [writable | enumerable | configurable | isOwn]
  • trunk/LayoutTests/inspector/runtime/getDisplayableProperties.html

    r250087 r252202  
    4040                let properties = getDisplayablePropertiesResponse.properties;
    4141                if (properties) {
    42                     ProtocolTest.assert(!fetchCount || properties.length <= fetchCount, `Should only get ${fetchCount} properties.`);
     42                    ProtocolTest.assert(!fetchCount || properties.length <= fetchCount + (fetchStart ? 0 : 1), `Should only get ${fetchCount} properties.`);
    4343
    4444                    ProtocolTest.log("Properties:");
  • trunk/LayoutTests/inspector/runtime/getProperties-expected.txt

    r251618 r252202  
    150150Evaluating expression...
    151151Getting own properties with fetchCount 5...
    152 ASSERT: Should only get 5 properties.
    153152Properties:
    154153    "A"          =>  0 (number)  [writable | enumerable | configurable | isOwn]
     
    181180Evaluating expression...
    182181Getting own properties with fetchCount 5...
    183 ASSERT: Should only get 5 properties.
    184182Properties:
    185183    "0"          =>  "A" (string)  [writable | enumerable | configurable | isOwn]
  • trunk/LayoutTests/inspector/runtime/getProperties.html

    r251618 r252202  
    4444                let properties = getPropertiesResponse.properties;
    4545                if (properties) {
    46                     ProtocolTest.assert(!fetchCount || properties.length <= fetchCount, `Should only get ${fetchCount} properties.`);
     46                    ProtocolTest.assert(!fetchCount || properties.length <= fetchCount + (fetchStart ? 0 : 1), `Should only get ${fetchCount} properties.`);
    4747
    4848                    ProtocolTest.log("Properties:");
  • trunk/Source/JavaScriptCore/ChangeLog

    r252191 r252202  
     12019-11-07  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: REGRESSION(r250087): inspector/model/remote-object.html is timing out
     4        https://bugs.webkit.org/show_bug.cgi?id=202934
     5        <rdar://problem/56270900>
     6
     7        Reviewed by Timothy Hatcher.
     8
     9        In r250087, the inspector injected script was changed so that remote objects actually
     10        iterate the keys of an array and generate a property descriptor for each. While this worked
     11        fine (and was performant) for fetching remote objects, this was not efficient when creating
     12        object previews, as that path wouldn't be limited by any sort of `fetchCount`, meaning that
     13        a descriptor for every index would be created even though only the first 10 would be used.
     14
     15        Refactor the inspector injected script code so that both the fetch and preview paths only
     16        examine exactly the number of properties desired instead of considering all of them and then
     17        slicing to fit.
     18
     19        * inspector/InjectedScriptSource.js:
     20        (InjectedScript.prototype._getProperties):
     21        (InjectedScript.prototype._forEachPropertyDescriptor): Added.
     22        (InjectedScript.prototype._forEachPropertyDescriptor.createFakeValueDescriptor): Added.
     23        (InjectedScript.prototype._forEachPropertyDescriptor.processDescriptor): Added.
     24        (InjectedScript.prototype._forEachPropertyDescriptor.processProperty): Added.
     25        (RemoteObject.prototype._generatePreview):
     26        (RemoteObject.prototype._appendPropertyPreview): Added.
     27        (RemoteObject.prototype._appendPropertyPreview.appendPreview): Added.
     28        (InjectedScript.prototype._propertyDescriptors): Deleted.
     29        (InjectedScript.prototype._propertyDescriptors.processProperties): Deleted.
     30        (InjectedScript.prototype._propertyDescriptors.arrayIndexPropertyNames): Deleted.
     31        (RemoteObject.prototype._appendPropertyPreviews): Deleted.
     32
    1332019-11-07  Alexey Shvayka  <shvaikalesh@gmail.com>
    234
  • trunk/Source/JavaScriptCore/inspector/InjectedScriptSource.js

    r250087 r252202  
    592592            return false;
    593593
    594         let descriptors = this._propertyDescriptors(object, collectionMode, {fetchStart, fetchCount, nativeGettersAsValues});
    595 
    596         for (let i = 0; i < descriptors.length; ++i) {
    597             let descriptor = descriptors[i];
     594        let start = fetchStart || 0;
     595        if (start < 0)
     596            start = 0;
     597
     598        let count = fetchCount || 0;
     599        if (count < 0)
     600            count = 0;
     601
     602        // Always include __proto__ at the end, but only for the first fetch.
     603        let includeProto = !start;
     604
     605        let descriptors = [];
     606        this._forEachPropertyDescriptor(object, collectionMode, (descriptor) => {
     607            if (start > 0) {
     608                --start;
     609                return InjectedScript.PropertyFetchAction.Continue;
     610            }
     611
    598612            if ("get" in descriptor)
    599613                descriptor.get = RemoteObject.create(descriptor.get, objectGroupName);
     
    604618            if ("symbol" in descriptor)
    605619                descriptor.symbol = RemoteObject.create(descriptor.symbol, objectGroupName);
    606         }
    607 
     620            descriptors.push(descriptor);
     621
     622            if (includeProto && count && descriptors.length >= count && descriptor.name !== "__proto__")
     623                return InjectedScript.PropertyFetchAction.Stop;
     624
     625            return (count && descriptors.length >= count) ? InjectedScript.PropertyFetchAction.Stop : InjectedScript.PropertyFetchAction.Continue;
     626        }, {nativeGettersAsValues, includeProto});
    608627        return descriptors;
    609628    }
     
    626645    }
    627646
    628     _propertyDescriptors(object, collectionMode, {fetchStart, fetchCount, nativeGettersAsValues})
     647    _forEachPropertyDescriptor(object, collectionMode, callback, {nativeGettersAsValues, includeProto})
    629648    {
    630649        if (InjectedScriptHost.subtype(object) === "proxy")
    631             return [];
    632 
    633         let descriptors = [];
     650            return;
     651
    634652        let nameProcessed = new Set;
    635653
    636         let start = fetchStart || 0;
    637         if (start < 0)
    638             start = 0;
    639 
    640         let count = fetchCount || 0;
    641         if (count < 0)
    642             count = 0;
    643         else if (count > 0 && start > 0)
    644             count += start;
     654        // Handled below when `includeProto`.
     655        nameProcessed.add("__proto__");
    645656
    646657        function createFakeValueDescriptor(name, symbol, descriptor, isOwnProperty, possibleNativeBindingGetter)
     
    679690        {
    680691            // All properties.
    681             if (collectionMode & InjectedScript.CollectionMode.AllProperties) {
    682                 descriptors.push(descriptor);
    683                 return;
    684             }
     692            if (collectionMode & InjectedScript.CollectionMode.AllProperties)
     693                return callback(descriptor);
    685694
    686695            // Own properties.
    687             if (collectionMode & InjectedScript.CollectionMode.OwnProperties && isOwnProperty) {
    688                 descriptors.push(descriptor);
    689                 return;
    690             }
     696            if (collectionMode & InjectedScript.CollectionMode.OwnProperties && isOwnProperty)
     697                return callback(descriptor);
    691698
    692699            // Native Getter properties.
    693700            if (collectionMode & InjectedScript.CollectionMode.NativeGetterProperties) {
    694                 if (possibleNativeBindingGetter) {
    695                     descriptors.push(descriptor);
    696                     return;
     701                if (possibleNativeBindingGetter)
     702                    return callback(descriptor);
     703            }
     704        }
     705
     706        function processProperty(o, propertyName, isOwnProperty)
     707        {
     708            if (nameProcessed.has(propertyName))
     709                return InjectedScript.PropertyFetchAction.Continue;
     710
     711            nameProcessed.add(propertyName);
     712
     713            let name = toString(propertyName);
     714            let symbol = isSymbol(propertyName) ? propertyName : null;
     715
     716            let descriptor = Object.getOwnPropertyDescriptor(o, propertyName);
     717            if (!descriptor) {
     718                // FIXME: Bad descriptor. Can we get here?
     719                // Fall back to very restrictive settings.
     720                let fakeDescriptor = createFakeValueDescriptor(name, symbol, descriptor, isOwnProperty);
     721                return processDescriptor(fakeDescriptor, isOwnProperty);
     722            }
     723
     724            if (nativeGettersAsValues) {
     725                if (String(descriptor.get).endsWith("[native code]\n}") || (!descriptor.get && descriptor.hasOwnProperty("get") && !descriptor.set && descriptor.hasOwnProperty("set"))) {
     726                    // Developers may create such a descriptor, so we should be resilient:
     727                    // let x = {}; Object.defineProperty(x, "p", {get:undefined}); Object.getOwnPropertyDescriptor(x, "p")
     728                    let fakeDescriptor = createFakeValueDescriptor(name, symbol, descriptor, isOwnProperty, true);
     729                    return processDescriptor(fakeDescriptor, isOwnProperty, true);
    697730                }
    698731            }
    699         }
    700 
    701         function processProperties(o, properties, isOwnProperty)
    702         {
    703             for (let i = 0; i < properties.length; ++i) {
    704                 if (count && descriptors.length === count)
    705                     break;
    706 
    707                 let property = properties[i];
    708                 if (nameProcessed.has(property) || property === "__proto__")
    709                     continue;
    710 
    711                 nameProcessed.add(property);
    712 
    713                 let name = toString(property);
    714                 let symbol = isSymbol(property) ? property : null;
    715 
    716                 let descriptor = Object.getOwnPropertyDescriptor(o, property);
    717                 if (!descriptor) {
    718                     // FIXME: Bad descriptor. Can we get here?
    719                     // Fall back to very restrictive settings.
    720                     let fakeDescriptor = createFakeValueDescriptor(name, symbol, descriptor, isOwnProperty);
    721                     processDescriptor(fakeDescriptor, isOwnProperty);
    722                     continue;
    723                 }
    724 
    725                 if (nativeGettersAsValues) {
    726                     if (String(descriptor.get).endsWith("[native code]\n}") || (!descriptor.get && descriptor.hasOwnProperty("get") && !descriptor.set && descriptor.hasOwnProperty("set"))) {
    727                         // Developers may create such a descriptor, so we should be resilient:
    728                         // let x = {}; Object.defineProperty(x, "p", {get:undefined}); Object.getOwnPropertyDescriptor(x, "p")
    729                         let fakeDescriptor = createFakeValueDescriptor(name, symbol, descriptor, isOwnProperty, true);
    730                         processDescriptor(fakeDescriptor, isOwnProperty, true);
    731                         continue;
    732                     }
    733                 }
    734 
    735                 descriptor.name = name;
    736                 if (isOwnProperty)
    737                     descriptor.isOwn = true;
    738                 if (symbol)
    739                     descriptor.symbol = symbol;
    740                 processDescriptor(descriptor, isOwnProperty);
    741             }
    742         }
    743 
    744         function arrayIndexPropertyNames(o, length)
    745         {
    746             let array = [];
    747             for (let i = 0; i < length; ++i) {
    748                 if (i in o)
    749                     array.push("" + i);
    750             }
    751             return array;
     732
     733            descriptor.name = name;
     734            if (isOwnProperty)
     735                descriptor.isOwn = true;
     736            if (symbol)
     737                descriptor.symbol = symbol;
     738            return processDescriptor(descriptor, isOwnProperty);
    752739        }
    753740
     
    759746        for (let o = object; isDefined(o); o = Object.getPrototypeOf(o)) {
    760747            let isOwnProperty = o === object;
     748            let shouldBreak = false;
    761749
    762750            // FIXME: <https://webkit.org/b/201861> Web Inspector: show autocomplete entries for non-index properties on arrays
    763             if (isArrayLike && isOwnProperty)
    764                 processProperties(o, arrayIndexPropertyNames(o, object.length), isOwnProperty);
    765             else
    766                 processProperties(o, Object.getOwnPropertyNames(o), isOwnProperty);
    767 
    768             if (count && descriptors.length === count)
     751            if (isArrayLike && isOwnProperty) {
     752                for (let i = 0; i < o.length; ++i) {
     753                    if (!(i in o))
     754                        continue;
     755
     756                    let result = processProperty(o, toString(i), isOwnProperty);
     757                    shouldBreak = result === InjectedScript.PropertyFetchAction.Stop;
     758                    if (shouldBreak)
     759                        break;
     760                }
     761            } else {
     762                let propertyNames = Object.getOwnPropertyNames(o);
     763                for (let i = 0; i < propertyNames.length; ++i) {
     764                    let result = processProperty(o, propertyNames[i], isOwnProperty);
     765                    shouldBreak = result === InjectedScript.PropertyFetchAction.Stop;
     766                    if (shouldBreak)
     767                        break;
     768                }
     769            }
     770
     771            if (shouldBreak)
    769772                break;
    770773
    771774            if (Object.getOwnPropertySymbols) {
    772                 processProperties(o, Object.getOwnPropertySymbols(o), isOwnProperty);
    773 
    774                 if (count && descriptors.length === count)
    775                     break;
    776             }
     775                let propertySymbols = Object.getOwnPropertySymbols(o);
     776                for (let i = 0; i < propertySymbols.length; ++i) {
     777                    let result = processProperty(o, propertySymbols[i], isOwnProperty);
     778                    shouldBreak = result === InjectedScript.PropertyFetchAction.Stop;
     779                    if (shouldBreak)
     780                        break;
     781                }
     782            }
     783
     784            if (shouldBreak)
     785                break;
    777786
    778787            if (collectionMode === InjectedScript.CollectionMode.OwnProperties)
     
    780789        }
    781790
    782         // Always include __proto__ at the end, but only for the first fetch.
    783         if (!start) {
     791        if (includeProto) {
    784792            try {
    785793                if (object.__proto__)
    786                     descriptors.push({name: "__proto__", value: object.__proto__, writable: true, configurable: true, isOwn: true});
     794                    callback({name: "__proto__", value: object.__proto__, writable: true, configurable: true, isOwn: true});
    787795            } catch { }
    788             return descriptors;
    789         }
    790 
    791         return descriptors.slice(start);
     796        }
    792797    }
    793798
     
    890895    AllProperties: 1 << 2,          // all properties in the prototype chain.
    891896};
     897
     898InjectedScript.PropertyFetchAction = {
     899    Continue: Symbol("continue"),
     900    Stop: Symbol("stop"),
     901}
    892902
    893903var injectedScript = new InjectedScript;
     
    11421152            let internalPropertyDescriptors = injectedScript._internalPropertyDescriptors(object, true);
    11431153            if (internalPropertyDescriptors) {
    1144                 this._appendPropertyPreviews(object, preview, internalPropertyDescriptors, true, propertiesThreshold, firstLevelKeys, secondLevelKeys);
    1145                 if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0)
    1146                     return preview;
     1154                for (let i = 0; i < internalPropertyDescriptors.length; ++i) {
     1155                    let result = this._appendPropertyPreview(object, preview, internalPropertyDescriptors[i], propertiesThreshold, firstLevelKeys, secondLevelKeys, {internal: true});
     1156                    if (result === InjectedScript.PropertyFetchAction.Stop)
     1157                        return preview;
     1158                }
    11471159            }
    11481160
     
    11511163
    11521164            // Properties.
    1153             let descriptors = injectedScript._propertyDescriptors(object, InjectedScript.CollectionMode.AllProperties, {nativeGettersAsValues: true});
    1154             this._appendPropertyPreviews(object, preview, descriptors, false, propertiesThreshold, firstLevelKeys, secondLevelKeys);
    1155             if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0)
    1156                 return preview;
     1165            injectedScript._forEachPropertyDescriptor(object, InjectedScript.CollectionMode.AllProperties, (descriptor) => {
     1166                return this._appendPropertyPreview(object, preview, descriptor, propertiesThreshold, firstLevelKeys, secondLevelKeys);
     1167            }, {nativeGettersAsValues: true, includeProto: true})
    11571168        } catch {
    11581169            preview.lossless = false;
     
    11621173    }
    11631174
    1164     _appendPropertyPreviews(object, preview, descriptors, internal, propertiesThreshold, firstLevelKeys, secondLevelKeys)
    1165     {
    1166         for (let i = 0; i < descriptors.length; ++i) {
    1167             let descriptor = descriptors[i];
    1168 
    1169             // Seen enough.
    1170             if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0)
    1171                 break;
    1172 
    1173             // Error in descriptor.
    1174             if (descriptor.wasThrown) {
     1175    _appendPropertyPreview(object, preview, descriptor, propertiesThreshold, firstLevelKeys, secondLevelKeys, {internal} = {})
     1176    {
     1177        // Error in descriptor.
     1178        if (descriptor.wasThrown) {
     1179            preview.lossless = false;
     1180            return InjectedScript.PropertyFetchAction.Continue;
     1181        }
     1182
     1183        // Do not show "__proto__" in preview.
     1184        let name = descriptor.name;
     1185        if (name === "__proto__") {
     1186            // Non basic __proto__ objects may have interesting, non-enumerable, methods to show.
     1187            if (descriptor.value && descriptor.value.constructor
     1188                && descriptor.value.constructor !== Object
     1189                && descriptor.value.constructor !== Array
     1190                && descriptor.value.constructor !== RegExp)
    11751191                preview.lossless = false;
    1176                 continue;
    1177             }
    1178 
    1179             // Do not show "__proto__" in preview.
    1180             let name = descriptor.name;
    1181             if (name === "__proto__") {
    1182                 // Non basic __proto__ objects may have interesting, non-enumerable, methods to show.
    1183                 if (descriptor.value && descriptor.value.constructor
    1184                     && descriptor.value.constructor !== Object
    1185                     && descriptor.value.constructor !== Array
    1186                     && descriptor.value.constructor !== RegExp)
    1187                     preview.lossless = false;
    1188                 continue;
    1189             }
    1190 
    1191             // For arrays, only allow indexes.
    1192             if (this.subtype === "array" && !isUInt32(name))
    1193                 continue;
    1194 
    1195             // Do not show non-enumerable non-own properties.
    1196             // Special case to allow array indexes that may be on the prototype.
    1197             // Special case to allow native getters on non-RegExp objects.
    1198             if (!descriptor.enumerable && !descriptor.isOwn && !(this.subtype === "array" || (this.subtype !== "regexp" && descriptor.nativeGetter)))
    1199                 continue;
    1200 
    1201             // If we have a filter, only show properties in the filter.
    1202             // FIXME: Currently these filters do nothing on the backend.
    1203             if (firstLevelKeys && !firstLevelKeys.includes(name))
    1204                 continue;
    1205 
    1206             // Getter/setter.
    1207             if (!("value" in descriptor)) {
     1192            return InjectedScript.PropertyFetchAction.Continue;
     1193        }
     1194
     1195        // For arrays, only allow indexes.
     1196        if (this.subtype === "array" && !isUInt32(name))
     1197            return InjectedScript.PropertyFetchAction.Continue;
     1198
     1199        // Do not show non-enumerable non-own properties.
     1200        // Special case to allow array indexes that may be on the prototype.
     1201        // Special case to allow native getters on non-RegExp objects.
     1202        if (!descriptor.enumerable && !descriptor.isOwn && !(this.subtype === "array" || (this.subtype !== "regexp" && descriptor.nativeGetter)))
     1203            return InjectedScript.PropertyFetchAction.Continue;
     1204
     1205        // If we have a filter, only show properties in the filter.
     1206        // FIXME: Currently these filters do nothing on the backend.
     1207        if (firstLevelKeys && !firstLevelKeys.includes(name))
     1208            return InjectedScript.PropertyFetchAction.Continue;
     1209
     1210        function appendPreview(property) {
     1211            if (toString(property.name >>> 0) === property.name)
     1212                propertiesThreshold.indexes--;
     1213            else
     1214                propertiesThreshold.properties--;
     1215
     1216            if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0) {
     1217                preview.overflow = true;
    12081218                preview.lossless = false;
    1209                 this._appendPropertyPreview(preview, internal, {name, type: "accessor"}, propertiesThreshold);
    1210                 continue;
    1211             }
    1212 
    1213             // Null value.
    1214             let value = descriptor.value;
    1215             if (value === null) {
    1216                 this._appendPropertyPreview(preview, internal, {name, type: "object", subtype: "null", value: "null"}, propertiesThreshold);
    1217                 continue;
    1218             }
    1219 
    1220             // Ignore non-enumerable functions.
    1221             let type = typeof value;
    1222             if (!descriptor.enumerable && type === "function")
    1223                 continue;
    1224 
    1225             // Fix type of document.all.
    1226             if (InjectedScriptHost.isHTMLAllCollection(value))
    1227                 type = "object";
    1228 
    1229             // Primitive.
    1230             const maxLength = 100;
    1231             if (isPrimitiveValue(value) || isBigInt(value)) {
    1232                 if (type === "string" && value.length > maxLength) {
    1233                     value = this._abbreviateString(value, maxLength, true);
    1234                     preview.lossless = false;
    1235                 }
    1236                 this._appendPropertyPreview(preview, internal, {name, type, value: toStringDescription(value)}, propertiesThreshold);
    1237                 continue;
    1238             }
    1239 
    1240             // Symbol.
    1241             if (isSymbol(value)) {
    1242                 let symbolString = toString(value);
    1243                 if (symbolString.length > maxLength) {
    1244                     symbolString = this._abbreviateString(symbolString, maxLength, true);
    1245                     preview.lossless = false;
    1246                 }
    1247                 this._appendPropertyPreview(preview, internal, {name, type, value: symbolString}, propertiesThreshold);
    1248                 continue;
    1249             }
    1250 
    1251             // Object.
    1252             let property = {name, type};
    1253             let subtype = RemoteObject.subtype(value);
    1254             if (subtype)
    1255                 property.subtype = subtype;
    1256 
    1257             // Second level.
    1258             if ((secondLevelKeys === null || secondLevelKeys) || this._isPreviewableObject(value, object)) {
    1259                 // FIXME: If we want secondLevelKeys filter to continue we would need some refactoring.
    1260                 let subPreview = RemoteObject.createObjectPreviewForValue(value, value !== object, secondLevelKeys);
    1261                 property.valuePreview = subPreview;
    1262                 if (!subPreview.lossless)
    1263                     preview.lossless = false;
    1264                 if (subPreview.overflow)
    1265                     preview.overflow = true;
    1266             } else {
    1267                 let description = "";
    1268                 if (type !== "function" || subtype === "class") {
    1269                     let fullDescription;
    1270                     if (subtype === "class")
    1271                         fullDescription = "class " + value.name;
    1272                     else if (subtype === "node")
    1273                         fullDescription = RemoteObject.nodePreview(value);
    1274                     else
    1275                         fullDescription = RemoteObject.describe(value);
    1276                     description = this._abbreviateString(fullDescription, maxLength, subtype === "regexp");
    1277                 }
    1278                 property.value = description;
     1219                return InjectedScript.PropertyFetchAction.Stop;
     1220            }
     1221
     1222            if (internal)
     1223                property.internal = true;
     1224
     1225            preview.properties.push(property);
     1226            return InjectedScript.PropertyFetchAction.Continue;
     1227        }
     1228
     1229        // Getter/setter.
     1230        if (!("value" in descriptor)) {
     1231            preview.lossless = false;
     1232            return appendPreview({name, type: "accessor"});
     1233        }
     1234
     1235        // Null value.
     1236        let value = descriptor.value;
     1237        if (value === null)
     1238            return appendPreview({name, type: "object", subtype: "null", value: "null"});
     1239
     1240        // Ignore non-enumerable functions.
     1241        let type = typeof value;
     1242        if (!descriptor.enumerable && type === "function")
     1243            return InjectedScript.PropertyFetchAction.Continue;
     1244
     1245        // Fix type of document.all.
     1246        if (InjectedScriptHost.isHTMLAllCollection(value))
     1247            type = "object";
     1248
     1249        // Primitive.
     1250        const maxLength = 100;
     1251        if (isPrimitiveValue(value) || isBigInt(value)) {
     1252            if (type === "string" && value.length > maxLength) {
     1253                value = this._abbreviateString(value, maxLength, true);
    12791254                preview.lossless = false;
    12801255            }
    1281 
    1282             this._appendPropertyPreview(preview, internal, property, propertiesThreshold);
    1283         }
    1284     }
    1285 
    1286     _appendPropertyPreview(preview, internal, property, propertiesThreshold)
    1287     {
    1288         if (toString(property.name >>> 0) === property.name)
    1289             propertiesThreshold.indexes--;
    1290         else
    1291             propertiesThreshold.properties--;
    1292 
    1293         if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0) {
    1294             preview.overflow = true;
     1256            return appendPreview({name, type, value: toStringDescription(value)});
     1257        }
     1258
     1259        // Symbol.
     1260        if (isSymbol(value)) {
     1261            let symbolString = toString(value);
     1262            if (symbolString.length > maxLength) {
     1263                symbolString = this._abbreviateString(symbolString, maxLength, true);
     1264                preview.lossless = false;
     1265            }
     1266            return appendPreview({name, type, value: symbolString});
     1267        }
     1268
     1269        // Object.
     1270        let property = {name, type};
     1271        let subtype = RemoteObject.subtype(value);
     1272        if (subtype)
     1273            property.subtype = subtype;
     1274
     1275        // Second level.
     1276        if ((secondLevelKeys === null || secondLevelKeys) || this._isPreviewableObject(value, object)) {
     1277            // FIXME: If we want secondLevelKeys filter to continue we would need some refactoring.
     1278            let subPreview = RemoteObject.createObjectPreviewForValue(value, value !== object, secondLevelKeys);
     1279            property.valuePreview = subPreview;
     1280            if (!subPreview.lossless)
     1281                preview.lossless = false;
     1282            if (subPreview.overflow)
     1283                preview.overflow = true;
     1284        } else {
     1285            let description = "";
     1286            if (type !== "function" || subtype === "class") {
     1287                let fullDescription;
     1288                if (subtype === "class")
     1289                    fullDescription = "class " + value.name;
     1290                else if (subtype === "node")
     1291                    fullDescription = RemoteObject.nodePreview(value);
     1292                else
     1293                    fullDescription = RemoteObject.describe(value);
     1294                description = this._abbreviateString(fullDescription, maxLength, subtype === "regexp");
     1295            }
     1296            property.value = description;
    12951297            preview.lossless = false;
    1296             return;
    1297         }
    1298 
    1299         if (internal)
    1300             property.internal = true;
    1301 
    1302         preview.properties.push(property);
     1298        }
     1299
     1300        return appendPreview(property);
    13031301    }
    13041302
  • trunk/Source/WebInspectorUI/ChangeLog

    r252201 r252202  
     12019-11-07  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: REGRESSION(r250087): inspector/model/remote-object.html is timing out
     4        https://bugs.webkit.org/show_bug.cgi?id=202934
     5        <rdar://problem/56270900>
     6
     7        Reviewed by Timothy Hatcher.
     8
     9        * UserInterface/Views/ObjectTreeView.js:
     10        (WI.ObjectTreeView.addShowMoreIfNeeded):
     11        Drive-by: ensure that the indeterminate progress spinner is added after the last button.
     12
    1132019-11-07  Devin Rousso  <drousso@apple.com>
    214
  • trunk/Source/WebInspectorUI/UserInterface/Views/ObjectTreeView.js

    r251227 r252202  
    148148
    149149                let spinner = new WI.IndeterminateProgressSpinner;
    150                 button.insertAdjacentElement("afterend", spinner.element);
     150                buttons.lastValue.insertAdjacentElement("afterend", spinner.element);
    151151
    152152                handleClick();
Note: See TracChangeset for help on using the changeset viewer.