Diff
Modified: trunk/LayoutTests/ChangeLog (218835 => 218836)
--- trunk/LayoutTests/ChangeLog 2017-06-27 15:59:48 UTC (rev 218835)
+++ trunk/LayoutTests/ChangeLog 2017-06-27 17:43:03 UTC (rev 218836)
@@ -1,3 +1,27 @@
+2017-06-27 Joseph Pecoraro <pecor...@apple.com>
+
+ Web Inspector: Crash generating object preview for ArrayIterator
+ https://bugs.webkit.org/show_bug.cgi?id=173754
+ <rdar://problem/32859012>
+
+ Reviewed by Saam Barati.
+
+ * platform/mac/inspector/model/remote-object-expected.txt:
+ * inspector/model/remote-object-expected.txt:
+ * inspector/model/remote-object.html:
+ Test generating a preview for an ArrayIterator that has had a `return` property added to it.
+
+ * inspector/model/remote-object-mutated-iterators-expected.txt: Added.
+ * inspector/model/remote-object-mutated-iterators.html: Added.
+ Test generating a preview for different iterators after the IteratorPrototypes have been mutated.
+
+ * inspector/model/resources/remote-object-utilities.js: Added.
+ (runInBrowserTest):
+ (TestPage.registerInitializer):
+ (TestPage.registerInitializer.checkComplete):
+ (TestPage.registerInitializer.window.runSteps):
+ Share code for remote-object dump tests.
+
2017-06-27 Frederic Wang <fw...@igalia.com>
Some tests to verify forbidden frame navigation time out
Modified: trunk/LayoutTests/inspector/model/remote-object-expected.txt (218835 => 218836)
--- trunk/LayoutTests/inspector/model/remote-object-expected.txt 2017-06-27 15:59:48 UTC (rev 218835)
+++ trunk/LayoutTests/inspector/model/remote-object-expected.txt 2017-06-27 17:43:03 UTC (rev 218836)
@@ -3922,6 +3922,79 @@
}
-----------------------------------------------------
+_expression_: iter = [1, 2][Symbol.iterator](); iter['return'] = function(){}; iter
+{
+ "_type": "object",
+ "_subtype": "iterator",
+ "_objectId": "<filtered>",
+ "_description": "Array Iterator",
+ "_preview": {
+ "_type": "object",
+ "_subtype": "iterator",
+ "_description": "Array Iterator",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": [
+ {
+ "_name": "array",
+ "_type": "object",
+ "_subtype": "array",
+ "_valuePreview": {
+ "_type": "object",
+ "_subtype": "array",
+ "_description": "Array",
+ "_lossless": true,
+ "_overflow": false,
+ "_size": 2,
+ "_properties": [
+ {
+ "_name": "0",
+ "_type": "number",
+ "_value": "1"
+ },
+ {
+ "_name": "1",
+ "_type": "number",
+ "_value": "2"
+ }
+ ],
+ "_entries": null
+ },
+ "_internal": true
+ },
+ {
+ "_name": "kind",
+ "_type": "string",
+ "_value": "value",
+ "_internal": true
+ }
+ ],
+ "_entries": [
+ {
+ "_value": {
+ "_type": "number",
+ "_description": "1",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ },
+ {
+ "_value": {
+ "_type": "number",
+ "_description": "2",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ }
+ ]
+ }
+}
+
+-----------------------------------------------------
_expression_: new Promise(function(){})
{
"_type": "object",
Added: trunk/LayoutTests/inspector/model/remote-object-mutated-iterators-expected.txt (0 => 218836)
--- trunk/LayoutTests/inspector/model/remote-object-mutated-iterators-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/model/remote-object-mutated-iterators-expected.txt 2017-06-27 17:43:03 UTC (rev 218836)
@@ -0,0 +1,598 @@
+
+-----------------------------------------------------
+_expression_: iter = 'alpha'[Symbol.iterator]()
+{
+ "_type": "object",
+ "_subtype": "iterator",
+ "_objectId": "<filtered>",
+ "_description": "String Iterator",
+ "_preview": {
+ "_type": "object",
+ "_subtype": "iterator",
+ "_description": "String Iterator",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": [
+ {
+ "_name": "string",
+ "_type": "string",
+ "_value": "alpha",
+ "_internal": true
+ }
+ ],
+ "_entries": [
+ {
+ "_value": {
+ "_type": "string",
+ "_description": "a",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ },
+ {
+ "_value": {
+ "_type": "string",
+ "_description": "l",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ },
+ {
+ "_value": {
+ "_type": "string",
+ "_description": "p",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ },
+ {
+ "_value": {
+ "_type": "string",
+ "_description": "h",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ },
+ {
+ "_value": {
+ "_type": "string",
+ "_description": "a",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ }
+ ]
+ }
+}
+
+-----------------------------------------------------
+_expression_: iter.__proto__.next = function(){}; iter
+{
+ "_type": "object",
+ "_subtype": "iterator",
+ "_objectId": "<filtered>",
+ "_description": "String Iterator",
+ "_preview": {
+ "_type": "object",
+ "_subtype": "iterator",
+ "_description": "String Iterator",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": [
+ {
+ "_name": "string",
+ "_type": "string",
+ "_value": "alpha",
+ "_internal": true
+ }
+ ],
+ "_entries": null
+ }
+}
+
+-----------------------------------------------------
+_expression_: map = new Map; map.set(1, 2); map.set('key', 'value'); iter = map[Symbol.iterator]()
+{
+ "_type": "object",
+ "_subtype": "iterator",
+ "_objectId": "<filtered>",
+ "_description": "Map Iterator",
+ "_preview": {
+ "_type": "object",
+ "_subtype": "iterator",
+ "_description": "Map Iterator",
+ "_lossless": false,
+ "_overflow": false,
+ "_properties": [
+ {
+ "_name": "map",
+ "_type": "object",
+ "_subtype": "map",
+ "_value": "Map",
+ "_internal": true
+ },
+ {
+ "_name": "kind",
+ "_type": "string",
+ "_value": "key+value",
+ "_internal": true
+ }
+ ],
+ "_entries": [
+ {
+ "_value": {
+ "_type": "object",
+ "_subtype": "array",
+ "_description": "Array",
+ "_lossless": true,
+ "_overflow": false,
+ "_size": 2,
+ "_properties": [
+ {
+ "_name": "0",
+ "_type": "number",
+ "_value": "1"
+ },
+ {
+ "_name": "1",
+ "_type": "number",
+ "_value": "2"
+ }
+ ],
+ "_entries": null
+ }
+ },
+ {
+ "_value": {
+ "_type": "object",
+ "_subtype": "array",
+ "_description": "Array",
+ "_lossless": true,
+ "_overflow": false,
+ "_size": 2,
+ "_properties": [
+ {
+ "_name": "0",
+ "_type": "string",
+ "_value": "key"
+ },
+ {
+ "_name": "1",
+ "_type": "string",
+ "_value": "value"
+ }
+ ],
+ "_entries": null
+ }
+ }
+ ]
+ }
+}
+
+-----------------------------------------------------
+_expression_: iter.__proto__.next = function(){}; iter
+{
+ "_type": "object",
+ "_subtype": "iterator",
+ "_objectId": "<filtered>",
+ "_description": "Map Iterator",
+ "_preview": {
+ "_type": "object",
+ "_subtype": "iterator",
+ "_description": "Map Iterator",
+ "_lossless": false,
+ "_overflow": false,
+ "_properties": [
+ {
+ "_name": "map",
+ "_type": "object",
+ "_subtype": "map",
+ "_value": "Map",
+ "_internal": true
+ },
+ {
+ "_name": "kind",
+ "_type": "string",
+ "_value": "key+value",
+ "_internal": true
+ }
+ ],
+ "_entries": null
+ }
+}
+
+-----------------------------------------------------
+_expression_: set = new Set; for (var i = 0; i <= 100; i++) set.add(i); iter = set[Symbol.iterator]()
+{
+ "_type": "object",
+ "_subtype": "iterator",
+ "_objectId": "<filtered>",
+ "_description": "Set Iterator",
+ "_preview": {
+ "_type": "object",
+ "_subtype": "iterator",
+ "_description": "Set Iterator",
+ "_lossless": false,
+ "_overflow": true,
+ "_properties": [
+ {
+ "_name": "set",
+ "_type": "object",
+ "_subtype": "set",
+ "_value": "Set",
+ "_internal": true
+ },
+ {
+ "_name": "kind",
+ "_type": "string",
+ "_value": "value",
+ "_internal": true
+ }
+ ],
+ "_entries": [
+ {
+ "_value": {
+ "_type": "number",
+ "_description": "0",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ },
+ {
+ "_value": {
+ "_type": "number",
+ "_description": "1",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ },
+ {
+ "_value": {
+ "_type": "number",
+ "_description": "2",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ },
+ {
+ "_value": {
+ "_type": "number",
+ "_description": "3",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ },
+ {
+ "_value": {
+ "_type": "number",
+ "_description": "4",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ }
+ ]
+ }
+}
+
+-----------------------------------------------------
+_expression_: iter.__proto__.next = function(){}; iter
+{
+ "_type": "object",
+ "_subtype": "iterator",
+ "_objectId": "<filtered>",
+ "_description": "Set Iterator",
+ "_preview": {
+ "_type": "object",
+ "_subtype": "iterator",
+ "_description": "Set Iterator",
+ "_lossless": false,
+ "_overflow": false,
+ "_properties": [
+ {
+ "_name": "set",
+ "_type": "object",
+ "_subtype": "set",
+ "_value": "Set",
+ "_internal": true
+ },
+ {
+ "_name": "kind",
+ "_type": "string",
+ "_value": "value",
+ "_internal": true
+ }
+ ],
+ "_entries": null
+ }
+}
+
+-----------------------------------------------------
+_expression_: arrayIter = [1,2,3][Symbol.iterator]()
+{
+ "_type": "object",
+ "_subtype": "iterator",
+ "_objectId": "<filtered>",
+ "_description": "Array Iterator",
+ "_preview": {
+ "_type": "object",
+ "_subtype": "iterator",
+ "_description": "Array Iterator",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": [
+ {
+ "_name": "array",
+ "_type": "object",
+ "_subtype": "array",
+ "_valuePreview": {
+ "_type": "object",
+ "_subtype": "array",
+ "_description": "Array",
+ "_lossless": true,
+ "_overflow": false,
+ "_size": 3,
+ "_properties": [
+ {
+ "_name": "0",
+ "_type": "number",
+ "_value": "1"
+ },
+ {
+ "_name": "1",
+ "_type": "number",
+ "_value": "2"
+ },
+ {
+ "_name": "2",
+ "_type": "number",
+ "_value": "3"
+ }
+ ],
+ "_entries": null
+ },
+ "_internal": true
+ },
+ {
+ "_name": "kind",
+ "_type": "string",
+ "_value": "value",
+ "_internal": true
+ }
+ ],
+ "_entries": [
+ {
+ "_value": {
+ "_type": "number",
+ "_description": "1",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ },
+ {
+ "_value": {
+ "_type": "number",
+ "_description": "2",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ },
+ {
+ "_value": {
+ "_type": "number",
+ "_description": "3",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ }
+ ]
+ }
+}
+
+-----------------------------------------------------
+_expression_: x = undefined; (function() { x = arguments; })(3, 'arg'); argumentsIter = x[Symbol.iterator]()
+{
+ "_type": "object",
+ "_subtype": "iterator",
+ "_objectId": "<filtered>",
+ "_description": "Array Iterator",
+ "_preview": {
+ "_type": "object",
+ "_subtype": "iterator",
+ "_description": "Array Iterator",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": [
+ {
+ "_name": "array",
+ "_type": "object",
+ "_subtype": "array",
+ "_valuePreview": {
+ "_type": "object",
+ "_subtype": "array",
+ "_description": "Arguments",
+ "_lossless": true,
+ "_overflow": false,
+ "_size": 2,
+ "_properties": [
+ {
+ "_name": "0",
+ "_type": "number",
+ "_value": "3"
+ },
+ {
+ "_name": "1",
+ "_type": "string",
+ "_value": "arg"
+ }
+ ],
+ "_entries": null
+ },
+ "_internal": true
+ },
+ {
+ "_name": "kind",
+ "_type": "string",
+ "_value": "value",
+ "_internal": true
+ }
+ ],
+ "_entries": [
+ {
+ "_value": {
+ "_type": "number",
+ "_description": "3",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ },
+ {
+ "_value": {
+ "_type": "string",
+ "_description": "arg",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ }
+ ]
+ }
+}
+
+-----------------------------------------------------
+_expression_: arrayIter.__proto__.next = function(){}; arrayIter
+{
+ "_type": "object",
+ "_subtype": "iterator",
+ "_objectId": "<filtered>",
+ "_description": "Array Iterator",
+ "_preview": {
+ "_type": "object",
+ "_subtype": "iterator",
+ "_description": "Array Iterator",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": [
+ {
+ "_name": "array",
+ "_type": "object",
+ "_subtype": "array",
+ "_valuePreview": {
+ "_type": "object",
+ "_subtype": "array",
+ "_description": "Array",
+ "_lossless": true,
+ "_overflow": false,
+ "_size": 3,
+ "_properties": [
+ {
+ "_name": "0",
+ "_type": "number",
+ "_value": "1"
+ },
+ {
+ "_name": "1",
+ "_type": "number",
+ "_value": "2"
+ },
+ {
+ "_name": "2",
+ "_type": "number",
+ "_value": "3"
+ }
+ ],
+ "_entries": null
+ },
+ "_internal": true
+ },
+ {
+ "_name": "kind",
+ "_type": "string",
+ "_value": "value",
+ "_internal": true
+ }
+ ],
+ "_entries": null
+ }
+}
+
+-----------------------------------------------------
+_expression_: argumentsIter.__proto__.next = function(){}; argumentsIter
+{
+ "_type": "object",
+ "_subtype": "iterator",
+ "_objectId": "<filtered>",
+ "_description": "Array Iterator",
+ "_preview": {
+ "_type": "object",
+ "_subtype": "iterator",
+ "_description": "Array Iterator",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": [
+ {
+ "_name": "array",
+ "_type": "object",
+ "_subtype": "array",
+ "_valuePreview": {
+ "_type": "object",
+ "_subtype": "array",
+ "_description": "Arguments",
+ "_lossless": true,
+ "_overflow": false,
+ "_size": 2,
+ "_properties": [
+ {
+ "_name": "0",
+ "_type": "number",
+ "_value": "3"
+ },
+ {
+ "_name": "1",
+ "_type": "string",
+ "_value": "arg"
+ }
+ ],
+ "_entries": null
+ },
+ "_internal": true
+ },
+ {
+ "_name": "kind",
+ "_type": "string",
+ "_value": "value",
+ "_internal": true
+ }
+ ],
+ "_entries": null
+ }
+}
+
Added: trunk/LayoutTests/inspector/model/remote-object-mutated-iterators.html (0 => 218836)
--- trunk/LayoutTests/inspector/model/remote-object-mutated-iterators.html (rev 0)
+++ trunk/LayoutTests/inspector/model/remote-object-mutated-iterators.html 2017-06-27 17:43:03 UTC (rev 218836)
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src=""
+<script src=""
+<script>
+function test()
+{
+ let steps = [
+ // String Iterator
+ {_expression_: `iter = 'alpha'[Symbol.iterator]()`},
+ {_expression_: `iter.__proto__.next = function(){}; iter`},
+
+ // Map Iterator
+ {_expression_: `map = new Map; map.set(1, 2); map.set('key', 'value'); iter = map[Symbol.iterator]()`},
+ {_expression_: `iter.__proto__.next = function(){}; iter`},
+
+ // Set Iterator
+ {_expression_: `set = new Set; for (var i = 0; i <= 100; i++) set.add(i); iter = set[Symbol.iterator]()`},
+ {_expression_: `iter.__proto__.next = function(){}; iter`},
+
+ // Array Iterator (array and arguments)
+ {_expression_: `arrayIter = [1,2,3][Symbol.iterator]()`},
+ {_expression_: `x = undefined; (function() { x = arguments; })(3, 'arg'); argumentsIter = x[Symbol.iterator]()`},
+ {_expression_: `arrayIter.__proto__.next = function(){}; arrayIter`},
+ {_expression_: `argumentsIter.__proto__.next = function(){}; argumentsIter`},
+ ];
+
+ if (!window.WebInspector) {
+ window.steps = steps;
+ return;
+ }
+
+ runSteps(steps);
+}
+</script>
+</head>
+<body _onload_="runTest(); runInBrowserTest();"></body>
+</html>
Modified: trunk/LayoutTests/inspector/model/remote-object.html (218835 => 218836)
--- trunk/LayoutTests/inspector/model/remote-object.html 2017-06-27 15:59:48 UTC (rev 218835)
+++ trunk/LayoutTests/inspector/model/remote-object.html 2017-06-27 17:43:03 UTC (rev 218836)
@@ -1,13 +1,13 @@
-<!doctype html>
+<!DOCTYPE html>
<html>
<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<meta charset="utf-8">
<script src=""
+<script src=""
<script>
function test()
{
- var currentStepIndex = 0;
- var steps = [
+ let steps = [
// Special:
// Null / undefined
@@ -159,6 +159,7 @@
{_expression_: "set = new Set; for (var i = 0; i <= 100; i++) set.add(i); set.values()"},
{_expression_: "map.entries()"},
{_expression_: "x = undefined; (function() { x = arguments; })(1, 'two'); x[Symbol.iterator]()"},
+ {_expression_: "iter = [1, 2][Symbol.iterator](); iter['return'] = function(){}; iter"},
// Promise
{_expression_: "new Promise(function(){})"},
@@ -191,61 +192,8 @@
return;
}
- function remoteObjectJSONFilter(key, value)
- {
- if (key === "_target" || key === "_hasChildren" || key === "_listeners")
- return undefined;
- if (key === "_objectId" || key === "_stackTrace")
- return "<filtered>";
- return value;
- }
-
- function runSteps() {
-
- function afterStep() {
- if (++currentStepIndex >= steps.length)
- InspectorTest.completeTest();
- }
-
- function runStep(step) {
- if (step.browserOnly) {
- afterStep();
- return;
- }
-
- WebInspector.runtimeManager.evaluateInInspectedWindow(step._expression_, {objectGroup: "test", doNotPauseOnExceptionsAndMuteConsole: true, generatePreview: true}, function(remoteObject, wasThrown) {
- InspectorTest.log("");
- InspectorTest.log("-----------------------------------------------------");
- InspectorTest.log("_expression_: " + step._expression_);
- InspectorTest.assert(remoteObject instanceof WebInspector.RemoteObject);
- InspectorTest.log(JSON.stringify(remoteObject, remoteObjectJSONFilter, " "));
- afterStep();
- });
- }
-
- for (var step of steps)
- runStep(step);
- }
-
- runSteps();
+ runSteps(steps);
}
-
-function runInBrowserTest()
-{
- if (window.testRunner)
- return;
-
- test(); // get steps.
-
- for (var step of steps) {
- console.info("_expression_", step._expression_);
- try {
- console.log(eval(step._expression_));
- } catch (e) {
- console.log("EXCEPTION: " + e);
- }
- }
-}
</script>
</head>
<body _onload_="window.loadEvent = event; runTest(); runInBrowserTest();">
Added: trunk/LayoutTests/inspector/model/resources/remote-object-utilities.js (0 => 218836)
--- trunk/LayoutTests/inspector/model/resources/remote-object-utilities.js (rev 0)
+++ trunk/LayoutTests/inspector/model/resources/remote-object-utilities.js 2017-06-27 17:43:03 UTC (rev 218836)
@@ -0,0 +1,50 @@
+function runInBrowserTest() {
+ if (window.testRunner)
+ return;
+
+ test(); // Populate window.steps.
+
+ for (let step of steps) {
+ console.info("_expression_", step._expression_);
+ try {
+ console.log(eval(step._expression_));
+ } catch (e) {
+ console.log("EXCEPTION: " + e);
+ }
+ }
+}
+
+TestPage.registerInitializer(() => {
+ function remoteObjectJSONFilter(key, value) {
+ if (key === "_target" || key === "_hasChildren" || key === "_listeners")
+ return undefined;
+ if (key === "_objectId" || key === "_stackTrace")
+ return "<filtered>";
+ return value;
+ }
+
+ window.runSteps = function(steps) {
+ let currentStepIndex = 0;
+
+ function checkComplete() {
+ if (++currentStepIndex >= steps.length)
+ InspectorTest.completeTest();
+ }
+
+ for (let {_expression_, browserOnly} of steps) {
+ if (browserOnly) {
+ checkComplete();
+ return;
+ }
+
+ WebInspector.runtimeManager.evaluateInInspectedWindow(_expression_, {objectGroup: "test", doNotPauseOnExceptionsAndMuteConsole: true, generatePreview: true}, (remoteObject, wasThrown) => {
+ InspectorTest.log("");
+ InspectorTest.log("-----------------------------------------------------");
+ InspectorTest.log("_expression_: " + _expression_);
+ InspectorTest.assert(remoteObject instanceof WebInspector.RemoteObject);
+ InspectorTest.log(JSON.stringify(remoteObject, remoteObjectJSONFilter, 2));
+ checkComplete();
+ });
+ }
+ };
+});
Modified: trunk/LayoutTests/platform/mac/inspector/model/remote-object-expected.txt (218835 => 218836)
--- trunk/LayoutTests/platform/mac/inspector/model/remote-object-expected.txt 2017-06-27 15:59:48 UTC (rev 218835)
+++ trunk/LayoutTests/platform/mac/inspector/model/remote-object-expected.txt 2017-06-27 17:43:03 UTC (rev 218836)
@@ -3925,6 +3925,79 @@
}
-----------------------------------------------------
+_expression_: iter = [1, 2][Symbol.iterator](); iter['return'] = function(){}; iter
+{
+ "_type": "object",
+ "_subtype": "iterator",
+ "_objectId": "<filtered>",
+ "_description": "Array Iterator",
+ "_preview": {
+ "_type": "object",
+ "_subtype": "iterator",
+ "_description": "Array Iterator",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": [
+ {
+ "_name": "array",
+ "_type": "object",
+ "_subtype": "array",
+ "_valuePreview": {
+ "_type": "object",
+ "_subtype": "array",
+ "_description": "Array",
+ "_lossless": true,
+ "_overflow": false,
+ "_size": 2,
+ "_properties": [
+ {
+ "_name": "0",
+ "_type": "number",
+ "_value": "1"
+ },
+ {
+ "_name": "1",
+ "_type": "number",
+ "_value": "2"
+ }
+ ],
+ "_entries": null
+ },
+ "_internal": true
+ },
+ {
+ "_name": "kind",
+ "_type": "string",
+ "_value": "value",
+ "_internal": true
+ }
+ ],
+ "_entries": [
+ {
+ "_value": {
+ "_type": "number",
+ "_description": "1",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ },
+ {
+ "_value": {
+ "_type": "number",
+ "_description": "2",
+ "_lossless": true,
+ "_overflow": false,
+ "_properties": null,
+ "_entries": null
+ }
+ }
+ ]
+ }
+}
+
+-----------------------------------------------------
_expression_: new Promise(function(){})
{
"_type": "object",
Modified: trunk/Source/_javascript_Core/ChangeLog (218835 => 218836)
--- trunk/Source/_javascript_Core/ChangeLog 2017-06-27 15:59:48 UTC (rev 218835)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-06-27 17:43:03 UTC (rev 218836)
@@ -1,3 +1,58 @@
+2017-06-27 Joseph Pecoraro <pecor...@apple.com>
+
+ Web Inspector: Crash generating object preview for ArrayIterator
+ https://bugs.webkit.org/show_bug.cgi?id=173754
+ <rdar://problem/32859012>
+
+ Reviewed by Saam Barati.
+
+ When Inspector generates an object preview for an ArrayIterator instance it made
+ a "clone" of the original ArrayIterator instance by constructing a new object with
+ the instance's structure. However, user code could have modified that instance's
+ structure, such as adding / removing properties. The `return` property had special
+ meaning, and our clone did not fill that slot. This approach is brittle in that
+ we weren't satisfying the expectations of an object with a particular Structure,
+ and the original goal of having Web Inspector peek values of built-in Iterators
+ was to avoid observable behavior.
+
+ This tightens Web Inspector's Iterator preview to only peek values if the
+ Iterators would actually be non-observable. It also builds an ArrayIterator
+ clone like a regular object construction.
+
+ * inspector/JSInjectedScriptHost.cpp:
+ (Inspector::cloneArrayIteratorObject):
+ Build up the Object from scratch with a new ArrayIterator prototype.
+
+ (Inspector::JSInjectedScriptHost::iteratorEntries):
+ Only clone and peek iterators if it would not be observable.
+ Also update iteration to be more in line with IterationOperations, such as when
+ we call iteratorClose.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::JSGlobalObject):
+ (JSC::JSGlobalObject::init):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::stringIteratorProtocolWatchpoint):
+ * runtime/JSGlobalObjectInlines.h:
+ (JSC::JSGlobalObject::isStringPrototypeIteratorProtocolFastAndNonObservable):
+ Add a StringIterator WatchPoint in line with the Array/Map/Set iterator watchpoints.
+
+ * runtime/JSMap.cpp:
+ (JSC::JSMap::isIteratorProtocolFastAndNonObservable):
+ (JSC::JSMap::canCloneFastAndNonObservable):
+ * runtime/JSMap.h:
+ * runtime/JSSet.cpp:
+ (JSC::JSSet::isIteratorProtocolFastAndNonObservable):
+ (JSC::JSSet::canCloneFastAndNonObservable):
+ * runtime/JSSet.h:
+ Promote isIteratorProtocolFastAndNonObservable to a method.
+
+ * runtime/JSObject.cpp:
+ (JSC::canDoFastPutDirectIndex):
+ * runtime/JSTypeInfo.h:
+ (JSC::TypeInfo::isArgumentsType):
+ Helper to detect if an Object is an Arguments type.
+
2017-06-26 Saam Barati <sbar...@apple.com>
RegExpPrototype.js builtin uses for-of iteration which is almost certainly incorrect
Modified: trunk/Source/_javascript_Core/inspector/JSInjectedScriptHost.cpp (218835 => 218836)
--- trunk/Source/_javascript_Core/inspector/JSInjectedScriptHost.cpp 2017-06-27 15:59:48 UTC (rev 218835)
+++ trunk/Source/_javascript_Core/inspector/JSInjectedScriptHost.cpp 2017-06-27 17:43:03 UTC (rev 218836)
@@ -26,6 +26,7 @@
#include "config.h"
#include "JSInjectedScriptHost.h"
+#include "ArrayIteratorPrototype.h"
#include "BuiltinNames.h"
#include "Completion.h"
#include "DateInstance.h"
@@ -33,6 +34,7 @@
#include "Error.h"
#include "InjectedScriptHost.h"
#include "IteratorOperations.h"
+#include "IteratorPrototype.h"
#include "JSArray.h"
#include "JSBoundFunction.h"
#include "JSCInlines.h"
@@ -357,7 +359,7 @@
array->putDirectIndex(exec, index++, constructInternalProperty(exec, "kind", jsNontrivialString(exec, kind)));
return array;
}
-
+
if (JSSetIterator* setIterator = jsDynamicCast<JSSetIterator*>(vm, value)) {
String kind;
switch (setIterator->kind()) {
@@ -508,14 +510,15 @@
return array;
}
-static JSObject* cloneArrayIteratorObject(ExecState* exec, VM& vm, JSObject* iteratorObject, JSValue nextIndex)
+static JSObject* cloneArrayIteratorObject(ExecState* exec, VM& vm, JSObject* iteratorObject, JSGlobalObject* globalObject, JSValue nextIndex, JSValue iteratedObject)
{
ASSERT(iteratorObject->type() == FinalObjectType);
- JSObject* clone = constructEmptyObject(exec, iteratorObject->structure());
+ JSObject* clone = constructEmptyObject(exec, ArrayIteratorPrototype::create(vm, globalObject, ArrayIteratorPrototype::createStructure(vm, globalObject, globalObject->iteratorPrototype())));
+ clone->putDirect(vm, vm.propertyNames->builtinNames().iteratedObjectPrivateName(), iteratedObject);
+ clone->putDirect(vm, vm.propertyNames->builtinNames().arrayIteratorKindPrivateName(), iteratorObject->getDirect(vm, vm.propertyNames->builtinNames().arrayIteratorKindPrivateName()));
clone->putDirect(vm, vm.propertyNames->builtinNames().arrayIteratorNextIndexPrivateName(), nextIndex);
- clone->putDirect(vm, vm.propertyNames->builtinNames().iteratedObjectPrivateName(), iteratorObject->getDirect(vm, vm.propertyNames->builtinNames().iteratedObjectPrivateName()));
+ clone->putDirect(vm, vm.propertyNames->builtinNames().arrayIteratorNextPrivateName(), iteratorObject->getDirect(vm, vm.propertyNames->builtinNames().arrayIteratorNextPrivateName()));
clone->putDirect(vm, vm.propertyNames->builtinNames().arrayIteratorIsDonePrivateName(), iteratorObject->getDirect(vm, vm.propertyNames->builtinNames().arrayIteratorIsDonePrivateName()));
- clone->putDirect(vm, vm.propertyNames->builtinNames().arrayIteratorNextPrivateName(), iteratorObject->getDirect(vm, vm.propertyNames->builtinNames().arrayIteratorNextPrivateName()));
return clone;
}
@@ -526,22 +529,34 @@
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
+
JSValue iterator;
+ JSGlobalObject* globalObject = exec->lexicalGlobalObject();
JSValue value = exec->uncheckedArgument(0);
- if (JSMapIterator* mapIterator = jsDynamicCast<JSMapIterator*>(vm, value))
- iterator = mapIterator->clone(exec);
- else if (JSSetIterator* setIterator = jsDynamicCast<JSSetIterator*>(vm, value))
- iterator = setIterator->clone(exec);
- else if (JSStringIterator* stringIterator = jsDynamicCast<JSStringIterator*>(vm, value))
- iterator = stringIterator->clone(exec);
- else {
- if (JSObject* iteratorObject = jsDynamicCast<JSObject*>(vm, value)) {
- // Array Iterators are created in JS for performance reasons. Thus the only way to know we have one is to
- // look for a property that is unique to them.
- if (JSValue nextIndex = iteratorObject->getDirect(vm, vm.propertyNames->builtinNames().arrayIteratorNextIndexPrivateName()))
- iterator = cloneArrayIteratorObject(exec, vm, iteratorObject, nextIndex);
+ if (JSMapIterator* mapIterator = jsDynamicCast<JSMapIterator*>(vm, value)) {
+ if (jsCast<JSMap*>(mapIterator->iteratedValue())->isIteratorProtocolFastAndNonObservable())
+ iterator = mapIterator->clone(exec);
+ } else if (JSSetIterator* setIterator = jsDynamicCast<JSSetIterator*>(vm, value)) {
+ if (jsCast<JSSet*>(setIterator->iteratedValue())->isIteratorProtocolFastAndNonObservable())
+ iterator = setIterator->clone(exec);
+ } else if (JSStringIterator* stringIterator = jsDynamicCast<JSStringIterator*>(vm, value)) {
+ if (globalObject->isStringPrototypeIteratorProtocolFastAndNonObservable())
+ iterator = stringIterator->clone(exec);
+ } else if (JSObject* iteratorObject = jsDynamicCast<JSObject*>(vm, value)) {
+ // Detect an ArrayIterator by checking for one of its unique private properties.
+ if (JSValue nextIndex = iteratorObject->getDirect(vm, vm.propertyNames->builtinNames().arrayIteratorNextIndexPrivateName())) {
+ JSValue iteratedObject = iteratorObject->getDirect(vm, vm.propertyNames->builtinNames().iteratedObjectPrivateName());
+ if (isJSArray(iteratedObject)) {
+ JSArray* array = jsCast<JSArray*>(iteratedObject);
+ if (array->isIteratorProtocolFastAndNonObservable())
+ iterator = cloneArrayIteratorObject(exec, vm, iteratorObject, globalObject, nextIndex, iteratedObject);
+ } else if (iteratedObject.isObject() && TypeInfo::isArgumentsType(asObject(iteratedObject)->type())) {
+ if (globalObject->isArrayPrototypeIteratorProtocolFastAndNonObservable())
+ iterator = cloneArrayIteratorObject(exec, vm, iteratorObject, globalObject, nextIndex, iteratedObject);
+ }
}
}
+ RETURN_IF_EXCEPTION(scope, { });
if (!iterator)
return jsUndefined();
@@ -548,32 +563,31 @@
unsigned numberToFetch = 5;
JSValue numberToFetchArg = exec->argument(1);
double fetchDouble = numberToFetchArg.toInteger(exec);
+ RETURN_IF_EXCEPTION(scope, { });
if (fetchDouble >= 0)
numberToFetch = static_cast<unsigned>(fetchDouble);
JSArray* array = constructEmptyArray(exec, nullptr);
- RETURN_IF_EXCEPTION(scope, JSValue());
+ RETURN_IF_EXCEPTION(scope, { });
for (unsigned i = 0; i < numberToFetch; ++i) {
JSValue next = iteratorStep(exec, iterator);
- if (UNLIKELY(scope.exception()))
+ if (UNLIKELY(scope.exception()) || next.isFalse())
break;
- if (next.isFalse())
- break;
JSValue nextValue = iteratorValue(exec, next);
- if (UNLIKELY(scope.exception()))
- break;
+ RETURN_IF_EXCEPTION(scope, { });
JSObject* entry = constructEmptyObject(exec);
entry->putDirect(exec->vm(), Identifier::fromString(exec, "value"), nextValue);
array->putDirectIndex(exec, i, entry);
- if (UNLIKELY(scope.exception()))
+ if (UNLIKELY(scope.exception())) {
+ scope.release();
+ iteratorClose(exec, iterator);
break;
+ }
}
- iteratorClose(exec, iterator);
-
return array;
}
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (218835 => 218836)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2017-06-27 15:59:48 UTC (rev 218835)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2017-06-27 17:43:03 UTC (rev 218836)
@@ -326,6 +326,7 @@
, m_arrayIteratorProtocolWatchpoint(IsWatched)
, m_mapIteratorProtocolWatchpoint(IsWatched)
, m_setIteratorProtocolWatchpoint(IsWatched)
+ , m_stringIteratorProtocolWatchpoint(IsWatched)
, m_mapSetWatchpoint(IsWatched)
, m_setAddWatchpoint(IsWatched)
, m_arraySpeciesWatchpoint(ClearWatchpoint)
@@ -937,7 +938,6 @@
m_arrayIteratorPrototypeNext = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_arrayIteratorProtocolWatchpoint);
m_arrayIteratorPrototypeNext->install();
}
-
{
ObjectPropertyCondition condition = setupAdaptiveWatchpoint(this->arrayPrototype(), m_vm.propertyNames->iteratorSymbol);
m_arrayPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_arrayIteratorProtocolWatchpoint);
@@ -949,7 +949,6 @@
m_mapIteratorPrototypeNextWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_mapIteratorProtocolWatchpoint);
m_mapIteratorPrototypeNextWatchpoint->install();
}
-
{
ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_mapPrototype.get(), m_vm.propertyNames->iteratorSymbol);
m_mapPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_mapIteratorProtocolWatchpoint);
@@ -961,7 +960,6 @@
m_setIteratorPrototypeNextWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_setIteratorProtocolWatchpoint);
m_setIteratorPrototypeNextWatchpoint->install();
}
-
{
ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_setPrototype.get(), m_vm.propertyNames->iteratorSymbol);
m_setPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_setIteratorProtocolWatchpoint);
@@ -969,6 +967,17 @@
}
{
+ ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_stringIteratorPrototype.get(), m_vm.propertyNames->next);
+ m_stringIteratorPrototypeNextWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_stringIteratorProtocolWatchpoint);
+ m_stringIteratorPrototypeNextWatchpoint->install();
+ }
+ {
+ ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_stringPrototype.get(), m_vm.propertyNames->iteratorSymbol);
+ m_stringPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_stringIteratorProtocolWatchpoint);
+ m_stringPrototypeSymbolIteratorWatchpoint->install();
+ }
+
+ {
ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_mapPrototype.get(), m_vm.propertyNames->set);
m_mapPrototypeSetWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_mapSetWatchpoint);
m_mapPrototypeSetWatchpoint->install();
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (218835 => 218836)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2017-06-27 15:59:48 UTC (rev 218835)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2017-06-27 17:43:03 UTC (rev 218836)
@@ -408,6 +408,7 @@
InlineWatchpointSet& arrayIteratorProtocolWatchpoint() { return m_arrayIteratorProtocolWatchpoint; }
InlineWatchpointSet& mapIteratorProtocolWatchpoint() { return m_mapIteratorProtocolWatchpoint; }
InlineWatchpointSet& setIteratorProtocolWatchpoint() { return m_setIteratorProtocolWatchpoint; }
+ InlineWatchpointSet& stringIteratorProtocolWatchpoint() { return m_stringIteratorProtocolWatchpoint; }
InlineWatchpointSet& mapSetWatchpoint() { return m_mapSetWatchpoint; }
InlineWatchpointSet& setAddWatchpoint() { return m_setAddWatchpoint; }
InlineWatchpointSet& arraySpeciesWatchpoint() { return m_arraySpeciesWatchpoint; }
@@ -416,6 +417,7 @@
InlineWatchpointSet m_arrayIteratorProtocolWatchpoint;
InlineWatchpointSet m_mapIteratorProtocolWatchpoint;
InlineWatchpointSet m_setIteratorProtocolWatchpoint;
+ InlineWatchpointSet m_stringIteratorProtocolWatchpoint;
InlineWatchpointSet m_mapSetWatchpoint;
InlineWatchpointSet m_setAddWatchpoint;
InlineWatchpointSet m_arraySpeciesWatchpoint;
@@ -425,6 +427,8 @@
std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_mapIteratorPrototypeNextWatchpoint;
std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_setPrototypeSymbolIteratorWatchpoint;
std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_setIteratorPrototypeNextWatchpoint;
+ std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_stringPrototypeSymbolIteratorWatchpoint;
+ std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_stringIteratorPrototypeNextWatchpoint;
std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_mapPrototypeSetWatchpoint;
std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_setPrototypeAddWatchpoint;
@@ -431,6 +435,7 @@
bool isArrayPrototypeIteratorProtocolFastAndNonObservable();
bool isMapPrototypeIteratorProtocolFastAndNonObservable();
bool isSetPrototypeIteratorProtocolFastAndNonObservable();
+ bool isStringPrototypeIteratorProtocolFastAndNonObservable();
bool isMapPrototypeSetFastAndNonObservable();
bool isSetPrototypeAddFastAndNonObservable();
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectInlines.h (218835 => 218836)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectInlines.h 2017-06-27 15:59:48 UTC (rev 218835)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectInlines.h 2017-06-27 17:43:03 UTC (rev 218836)
@@ -82,6 +82,11 @@
return setIteratorProtocolWatchpoint().isStillValid();
}
+ALWAYS_INLINE bool JSGlobalObject::isStringPrototypeIteratorProtocolFastAndNonObservable()
+{
+ return stringIteratorProtocolWatchpoint().isStillValid();
+}
+
ALWAYS_INLINE bool JSGlobalObject::isMapPrototypeSetFastAndNonObservable()
{
return mapSetWatchpoint().isStillValid();
Modified: trunk/Source/_javascript_Core/runtime/JSMap.cpp (218835 => 218836)
--- trunk/Source/_javascript_Core/runtime/JSMap.cpp 2017-06-27 15:59:48 UTC (rev 218835)
+++ trunk/Source/_javascript_Core/runtime/JSMap.cpp 2017-06-27 17:43:03 UTC (rev 218836)
@@ -45,27 +45,28 @@
return instance;
}
-bool JSMap::canCloneFastAndNonObservable(Structure* structure)
+bool JSMap::isIteratorProtocolFastAndNonObservable()
{
- auto isIteratorProtocolFastAndNonObservable = [&] () {
- JSGlobalObject* globalObject = this->globalObject();
- if (!globalObject->isMapPrototypeIteratorProtocolFastAndNonObservable())
- return false;
+ JSGlobalObject* globalObject = this->globalObject();
+ if (!globalObject->isMapPrototypeIteratorProtocolFastAndNonObservable())
+ return false;
- Structure* structure = this->structure();
- // This is the fast case. Many maps will be an original map.
- if (structure == globalObject->mapStructure())
- return true;
+ Structure* structure = this->structure();
+ // This is the fast case. Many maps will be an original map.
+ if (structure == globalObject->mapStructure())
+ return true;
- if (structure->storedPrototype() != globalObject->mapPrototype())
- return false;
+ if (structure->storedPrototype() != globalObject->mapPrototype())
+ return false;
- if (getDirectOffset(globalObject->vm(), globalObject->vm().propertyNames->iteratorSymbol) != invalidOffset)
- return false;
+ if (getDirectOffset(globalObject->vm(), globalObject->vm().propertyNames->iteratorSymbol) != invalidOffset)
+ return false;
- return true;
- };
+ return true;
+}
+bool JSMap::canCloneFastAndNonObservable(Structure* structure)
+{
auto setFastAndNonObservable = [&] (Structure* structure) {
JSGlobalObject* globalObject = structure->globalObject();
if (!globalObject->isMapPrototypeSetFastAndNonObservable())
Modified: trunk/Source/_javascript_Core/runtime/JSMap.h (218835 => 218836)
--- trunk/Source/_javascript_Core/runtime/JSMap.h 2017-06-27 15:59:48 UTC (rev 218835)
+++ trunk/Source/_javascript_Core/runtime/JSMap.h 2017-06-27 17:43:03 UTC (rev 218836)
@@ -56,6 +56,7 @@
add(exec, key, value);
}
+ bool isIteratorProtocolFastAndNonObservable();
bool canCloneFastAndNonObservable(Structure*);
JSMap* clone(ExecState*, VM&, Structure*);
Modified: trunk/Source/_javascript_Core/runtime/JSObject.cpp (218835 => 218836)
--- trunk/Source/_javascript_Core/runtime/JSObject.cpp 2017-06-27 15:59:48 UTC (rev 218835)
+++ trunk/Source/_javascript_Core/runtime/JSObject.cpp 2017-06-27 17:43:03 UTC (rev 218836)
@@ -2362,9 +2362,7 @@
{
return isJSArray(object)
|| isJSFinalObject(object)
- || object->type() == DirectArgumentsType
- || object->type() == ScopedArgumentsType
- || object->type() == ClonedArgumentsType;
+ || TypeInfo::isArgumentsType(object->type());
}
// Defined in ES5.1 8.12.9
Modified: trunk/Source/_javascript_Core/runtime/JSSet.cpp (218835 => 218836)
--- trunk/Source/_javascript_Core/runtime/JSSet.cpp 2017-06-27 15:59:48 UTC (rev 218835)
+++ trunk/Source/_javascript_Core/runtime/JSSet.cpp 2017-06-27 17:43:03 UTC (rev 218836)
@@ -45,27 +45,28 @@
return instance;
}
-bool JSSet::canCloneFastAndNonObservable(Structure* structure)
+bool JSSet::isIteratorProtocolFastAndNonObservable()
{
- auto isIteratorProtocolFastAndNonObservable = [&] () {
- JSGlobalObject* globalObject = this->globalObject();
- if (!globalObject->isSetPrototypeIteratorProtocolFastAndNonObservable())
- return false;
+ JSGlobalObject* globalObject = this->globalObject();
+ if (!globalObject->isSetPrototypeIteratorProtocolFastAndNonObservable())
+ return false;
- Structure* structure = this->structure();
- // This is the fast case. Many sets will be an original set.
- if (structure == globalObject->setStructure())
- return true;
+ Structure* structure = this->structure();
+ // This is the fast case. Many sets will be an original set.
+ if (structure == globalObject->setStructure())
+ return true;
- if (structure->storedPrototype() != globalObject->jsSetPrototype())
- return false;
+ if (structure->storedPrototype() != globalObject->jsSetPrototype())
+ return false;
- if (getDirectOffset(globalObject->vm(), globalObject->vm().propertyNames->iteratorSymbol) != invalidOffset)
- return false;
+ if (getDirectOffset(globalObject->vm(), globalObject->vm().propertyNames->iteratorSymbol) != invalidOffset)
+ return false;
- return true;
- };
+ return true;
+}
+bool JSSet::canCloneFastAndNonObservable(Structure* structure)
+{
auto addFastAndNonObservable = [&] (Structure* structure) {
JSGlobalObject* globalObject = structure->globalObject();
if (!globalObject->isSetPrototypeAddFastAndNonObservable())
Modified: trunk/Source/_javascript_Core/runtime/JSSet.h (218835 => 218836)
--- trunk/Source/_javascript_Core/runtime/JSSet.h 2017-06-27 15:59:48 UTC (rev 218835)
+++ trunk/Source/_javascript_Core/runtime/JSSet.h 2017-06-27 17:43:03 UTC (rev 218836)
@@ -52,6 +52,7 @@
return instance;
}
+ bool isIteratorProtocolFastAndNonObservable();
bool canCloneFastAndNonObservable(Structure*);
JSSet* clone(ExecState*, VM&, Structure*);
Modified: trunk/Source/_javascript_Core/runtime/JSTypeInfo.h (218835 => 218836)
--- trunk/Source/_javascript_Core/runtime/JSTypeInfo.h 2017-06-27 15:59:48 UTC (rev 218835)
+++ trunk/Source/_javascript_Core/runtime/JSTypeInfo.h 2017-06-27 17:43:03 UTC (rev 218836)
@@ -94,6 +94,13 @@
bool isImmutablePrototypeExoticObject() const { return isSetOnFlags2(IsImmutablePrototypeExoticObject); }
bool interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero() const { return isSetOnFlags2(InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero); }
+ static bool isArgumentsType(JSType type)
+ {
+ return type == DirectArgumentsType
+ || type == ScopedArgumentsType
+ || type == ClonedArgumentsType;
+ }
+
static ptrdiff_t flagsOffset()
{
return OBJECT_OFFSETOF(TypeInfo, m_flags);