Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(496)

Unified Diff: src/inspector/injected-script-source.js

Issue 2705533002: [inspector] remove iterators and for...of loops from injected-script-source (Closed)
Patch Set: ac Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/inspector/inspector-impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/inspector/injected-script-source.js
diff --git a/src/inspector/injected-script-source.js b/src/inspector/injected-script-source.js
index b52277a8ebec017a6deb3d3a590a8d66ae47f2ab..cc85c0b7f03ff378dc613cab59abced3a3badc31 100644
--- a/src/inspector/injected-script-source.js
+++ b/src/inspector/injected-script-source.js
@@ -335,12 +335,10 @@ InjectedScript.prototype = {
object = object.object;
}
- var descriptors = [];
- var iter = this._propertyDescriptors(object, ownProperties, accessorPropertiesOnly, undefined);
// Go over properties, wrap object values.
- for (var descriptor of iter) {
- if (subtype === "internal#scopeList" && descriptor.name === "length")
- continue;
+ var descriptors = this._propertyDescriptors(object, addPropertyIfNeeded, ownProperties, accessorPropertiesOnly);
+ for (var i = 0; i < descriptors.length; ++i) {
+ var descriptor = descriptors[i];
if ("get" in descriptor)
descriptor.get = this._wrapObject(descriptor.get, objectGroupName);
if ("set" in descriptor)
@@ -353,9 +351,18 @@ InjectedScript.prototype = {
descriptor.enumerable = false;
if ("symbol" in descriptor)
descriptor.symbol = this._wrapObject(descriptor.symbol, objectGroupName);
- push(descriptors, descriptor);
}
return descriptors;
+
+ /**
+ * @param {!Array<!Object>} descriptors
+ * @param {!Object} descriptor
+ * @return {boolean}
+ */
+ function addPropertyIfNeeded(descriptors, descriptor) {
+ push(descriptors, descriptor);
+ return true;
+ }
},
/**
@@ -375,62 +382,72 @@ InjectedScript.prototype = {
/**
* @param {!Object} object
+ * @param {!function(!Array<!Object>, !Object)} addPropertyIfNeeded
* @param {boolean=} ownProperties
* @param {boolean=} accessorPropertiesOnly
- * @param {?Array.<string>=} propertyNamesOnly
+ * @param {?Array<string>=} propertyNamesOnly
+ * @return {!Array<!Object>}
*/
- _propertyDescriptors: function*(object, ownProperties, accessorPropertiesOnly, propertyNamesOnly)
+ _propertyDescriptors: function(object, addPropertyIfNeeded, ownProperties, accessorPropertiesOnly, propertyNamesOnly)
{
+ var descriptors = [];
+ descriptors.__proto__ = null;
var propertyProcessed = { __proto__: null };
+ var subtype = InjectedScriptHost.subtype(object);
/**
- * @param {?Object} o
- * @param {!Iterable<string|symbol|number>|!Array<string|number|symbol>} properties
+ * @param {!Object} o
+ * @param {!Array<string|number|symbol>=} properties
+ * @param {number=} objectLength
+ * @return {boolean}
*/
- function* process(o, properties)
+ function process(o, properties, objectLength)
{
- for (var property of properties) {
+ // When properties is not provided, iterate over the object's indices.
+ var length = properties ? properties.length : objectLength;
+ for (var i = 0; i < length; ++i) {
+ var property = properties ? properties[i] : ("" + i);
+ if (propertyProcessed[property])
+ continue;
+ propertyProcessed[property] = true;
var name;
if (isSymbol(property))
name = /** @type {string} */ (injectedScript._describe(property));
else
name = typeof property === "number" ? ("" + property) : /** @type {string} */(property);
- if (propertyProcessed[property])
+ if (subtype === "internal#scopeList" && name === "length")
continue;
+ var descriptor;
try {
- propertyProcessed[property] = true;
- var descriptor = nullifyObjectProto(Object.getOwnPropertyDescriptor(o, property));
- if (descriptor) {
- if (accessorPropertiesOnly && !("get" in descriptor || "set" in descriptor))
- continue;
- if ("get" in descriptor && "set" in descriptor && name != "__proto__" && InjectedScriptHost.formatAccessorsAsProperties(object, descriptor.get) && !doesAttributeHaveObservableSideEffectOnGet(object, name)) {
- descriptor.value = object[property];
- descriptor.isOwn = true;
- delete descriptor.get;
- delete descriptor.set;
- }
- } else {
- // Not all bindings provide proper descriptors. Fall back to the writable, configurable property.
- if (accessorPropertiesOnly)
- continue;
- try {
- descriptor = { name: name, value: o[property], writable: false, configurable: false, enumerable: false, __proto__: null };
- if (o === object)
- descriptor.isOwn = true;
- yield descriptor;
- } catch (e) {
- // Silent catch.
- }
+ descriptor = Object.getOwnPropertyDescriptor(o, property);
+ var isAccessorProperty = descriptor && ("get" in descriptor || "set" in descriptor);
+ if (accessorPropertiesOnly && !isAccessorProperty)
continue;
+ if (descriptor && "get" in descriptor && "set" in descriptor && name !== "__proto__" &&
+ InjectedScriptHost.formatAccessorsAsProperties(object, descriptor.get) &&
+ !doesAttributeHaveObservableSideEffectOnGet(object, name)) {
+ descriptor.value = object[property];
+ descriptor.isOwn = true;
+ delete descriptor.get;
+ delete descriptor.set;
}
} catch (e) {
if (accessorPropertiesOnly)
continue;
- var descriptor = { __proto__: null };
- descriptor.value = e;
- descriptor.wasThrown = true;
+ descriptor = { value: e, wasThrown: true };
+ }
+
+ // Not all bindings provide proper descriptors. Fall back to the non-configurable, non-enumerable,
+ // non-writable property.
+ if (!descriptor) {
+ try {
+ descriptor = { value: o[property], writable: false };
+ } catch (e) {
+ // Silent catch.
+ continue;
+ }
}
descriptor.name = name;
@@ -438,66 +455,72 @@ InjectedScript.prototype = {
descriptor.isOwn = true;
if (isSymbol(property))
descriptor.symbol = property;
- yield descriptor;
+ descriptor = nullifyObjectProto(descriptor);
+ if (!addPropertyIfNeeded(descriptors, descriptor))
+ return false;
}
+ return true;
}
if (propertyNamesOnly) {
for (var i = 0; i < propertyNamesOnly.length; ++i) {
var name = propertyNamesOnly[i];
- for (var o = object; this._isDefined(o); o = this._objectPrototype(o)) {
+ for (var o = object; this._isDefined(o); o = this._objectPrototype(/** @type {!Object} */ (o))) {
+ o = /** @type {!Object} */ (o);
if (InjectedScriptHost.objectHasOwnProperty(o, name)) {
- for (var descriptor of process(o, [name]))
- yield descriptor;
+ if (!process(o, [name]))
+ return descriptors;
break;
}
if (ownProperties)
break;
}
}
- return;
- }
-
- /**
- * @param {number} length
- */
- function* arrayIndexNames(length)
- {
- for (var i = 0; i < length; ++i)
- yield "" + i;
+ return descriptors;
}
var skipGetOwnPropertyNames;
try {
- skipGetOwnPropertyNames = InjectedScriptHost.subtype(object) === "typedarray" && object.length > 500000;
+ skipGetOwnPropertyNames = subtype === "typedarray" && object.length > 500000;
} catch (e) {
}
- for (var o = object; this._isDefined(o); o = this._objectPrototype(o)) {
+ for (var o = object; this._isDefined(o); o = this._objectPrototype(/** @type {!Object} */ (o))) {
+ o = /** @type {!Object} */ (o);
if (InjectedScriptHost.subtype(o) === "proxy")
continue;
- if (skipGetOwnPropertyNames && o === object) {
- // Avoid OOM crashes from getting all own property names of a large TypedArray.
- for (var descriptor of process(o, arrayIndexNames(o.length)))
- yield descriptor;
- } else {
- // First call Object.keys() to enforce ordering of the property descriptors.
- for (var descriptor of process(o, Object.keys(/** @type {!Object} */ (o))))
- yield descriptor;
- for (var descriptor of process(o, Object.getOwnPropertyNames(/** @type {!Object} */ (o))))
- yield descriptor;
- }
- if (Object.getOwnPropertySymbols) {
- for (var descriptor of process(o, Object.getOwnPropertySymbols(/** @type {!Object} */ (o))))
- yield descriptor;
+
+ try {
+ if (skipGetOwnPropertyNames && o === object) {
+ if (!process(o, undefined, o.length))
+ return descriptors;
+ } else {
+ // First call Object.keys() to enforce ordering of the property descriptors.
+ if (!process(o, Object.keys(o)))
+ return descriptors;
+ if (!process(o, Object.getOwnPropertyNames(o)))
+ return descriptors;
+ }
+ if (Object.getOwnPropertySymbols) {
+ if (!process(o, Object.getOwnPropertySymbols(o)))
+ return descriptors;
+ }
+
+ if (ownProperties) {
+ var proto = this._objectPrototype(o);
+ if (proto && !accessorPropertiesOnly) {
+ var descriptor = { name: "__proto__", value: proto, writable: true, configurable: true, enumerable: false, isOwn: true, __proto__: null };
+ if (!addPropertyIfNeeded(descriptors, descriptor))
+ return descriptors;
+ }
+ }
+ } catch (e) {
}
- if (ownProperties) {
- var proto = this._objectPrototype(o);
- if (proto && !accessorPropertiesOnly)
- yield { name: "__proto__", value: proto, writable: true, configurable: true, enumerable: false, isOwn: true, __proto__: null };
+
+ if (ownProperties)
break;
- }
}
+ return descriptors;
},
/**
@@ -863,19 +886,15 @@ InjectedScript.RemoteObject.prototype = {
{
var preview = this._createEmptyPreview();
var firstLevelKeysCount = firstLevelKeys ? firstLevelKeys.length : 0;
-
var propertiesThreshold = {
properties: isTable ? 1000 : max(5, firstLevelKeysCount),
indexes: isTable ? 1000 : max(100, firstLevelKeysCount),
__proto__: null
};
+ var subtype = this.subtype;
try {
- var descriptors = injectedScript._propertyDescriptors(object, undefined, undefined, firstLevelKeys);
-
- this._appendPropertyDescriptors(preview, descriptors, propertiesThreshold, secondLevelKeys, isTable);
- if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0)
- return preview;
+ var descriptors = injectedScript._propertyDescriptors(object, addPropertyIfNeeded, false /* ownProperties */, undefined /* accessorPropertiesOnly */, firstLevelKeys);
// Add internal properties to preview.
var rawInternalProperties = InjectedScriptHost.getInternalProperties(object) || [];
@@ -886,64 +905,80 @@ InjectedScript.RemoteObject.prototype = {
entries = /** @type {!Array<*>} */(rawInternalProperties[i + 1]);
continue;
}
- push(internalProperties, {
+ var internalPropertyDescriptor = {
name: rawInternalProperties[i],
value: rawInternalProperties[i + 1],
isOwn: true,
enumerable: true,
__proto__: null
- });
+ };
+ if (!addPropertyIfNeeded(descriptors, internalPropertyDescriptor))
+ break;
}
- this._appendPropertyDescriptors(preview, internalProperties, propertiesThreshold, secondLevelKeys, isTable);
+ this._appendPropertyPreviewDescriptors(preview, descriptors, secondLevelKeys, isTable);
- if (this.subtype === "map" || this.subtype === "set" || this.subtype === "iterator")
+ if (subtype === "map" || subtype === "set" || subtype === "iterator")
this._appendEntriesPreview(entries, preview, skipEntriesPreview);
} catch (e) {}
return preview;
- },
-
- /**
- * @param {!RuntimeAgent.ObjectPreview} preview
- * @param {!Array.<*>|!Iterable.<*>} descriptors
- * @param {!Object} propertiesThreshold
- * @param {?Array.<string>=} secondLevelKeys
- * @param {boolean=} isTable
- */
- _appendPropertyDescriptors: function(preview, descriptors, propertiesThreshold, secondLevelKeys, isTable)
- {
- for (var descriptor of descriptors) {
- if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0)
- break;
- if (!descriptor || descriptor.wasThrown)
- continue;
- var name = descriptor.name;
+ /**
+ * @param {!Array<!Object>} descriptors
+ * @param {!Object} descriptor
+ * @return {boolean}
+ */
+ function addPropertyIfNeeded(descriptors, descriptor) {
+ if (descriptor.wasThrown)
+ return true;
// Ignore __proto__ property.
- if (name === "__proto__")
- continue;
+ if (descriptor.name === "__proto__")
+ return true;
// Ignore length property of array.
- if ((this.subtype === "array" || this.subtype === "typedarray") && name === "length")
- continue;
+ if ((subtype === "array" || subtype === "typedarray") && descriptor.name === "length")
+ return true;
// Ignore size property of map, set.
- if ((this.subtype === "map" || this.subtype === "set") && name === "size")
- continue;
+ if ((subtype === "map" || subtype === "set") && descriptor.name === "size")
+ return true;
// Never preview prototype properties.
if (!descriptor.isOwn)
- continue;
+ return true;
// Ignore computed properties unless they have getters.
- if (!("value" in descriptor)) {
- if (descriptor.get)
- this._appendPropertyPreview(preview, { name: name, type: "accessor", __proto__: null }, propertiesThreshold);
- continue;
+ if (!("value" in descriptor) && !descriptor.get)
+ return true;
+
+ if (toString(descriptor.name >>> 0) === descriptor.name)
+ propertiesThreshold.indexes--;
+ else
+ propertiesThreshold.properties--;
+
+ var canContinue = propertiesThreshold.indexes >= 0 && propertiesThreshold.properties >= 0;
+ if (!canContinue) {
+ preview.overflow = true;
+ return false;
}
+ push(descriptors, descriptor);
+ return true;
+ }
+ },
+ /**
+ * @param {!RuntimeAgent.ObjectPreview} preview
+ * @param {!Array.<*>|!Iterable.<*>} descriptors
+ * @param {?Array.<string>=} secondLevelKeys
+ * @param {boolean=} isTable
+ */
+ _appendPropertyPreviewDescriptors: function(preview, descriptors, secondLevelKeys, isTable)
+ {
+ for (var i = 0; i < descriptors.length; ++i) {
+ var descriptor = descriptors[i];
+ var name = descriptor.name;
var value = descriptor.value;
var type = typeof value;
@@ -951,9 +986,15 @@ InjectedScript.RemoteObject.prototype = {
if (type === "undefined" && injectedScript._isHTMLAllCollection(value))
type = "object";
+ // Ignore computed properties unless they have getters.
+ if (descriptor.get && !("value" in descriptor)) {
+ push(preview.properties, { name: name, type: "accessor", __proto__: null });
+ continue;
+ }
+
// Render own properties.
if (value === null) {
- this._appendPropertyPreview(preview, { name: name, type: "object", subtype: "null", value: "null", __proto__: null }, propertiesThreshold);
+ push(preview.properties, { name: name, type: "object", subtype: "null", value: "null", __proto__: null });
continue;
}
@@ -961,7 +1002,7 @@ InjectedScript.RemoteObject.prototype = {
if (InjectedScript.primitiveTypes[type]) {
if (type === "string" && value.length > maxLength)
value = this._abbreviateString(value, maxLength, true);
- this._appendPropertyPreview(preview, { name: name, type: type, value: toStringDescription(value), __proto__: null }, propertiesThreshold);
+ push(preview.properties, { name: name, type: type, value: toStringDescription(value), __proto__: null });
continue;
}
@@ -981,24 +1022,6 @@ InjectedScript.RemoteObject.prototype = {
description = this._abbreviateString(/** @type {string} */ (injectedScript._describe(value)), maxLength, subtype === "regexp");
property.value = description;
}
- this._appendPropertyPreview(preview, property, propertiesThreshold);
- }
- },
-
- /**
- * @param {!RuntimeAgent.ObjectPreview} preview
- * @param {!Object} property
- * @param {!Object} propertiesThreshold
- */
- _appendPropertyPreview: function(preview, property, propertiesThreshold)
- {
- if (toString(property.name >>> 0) === property.name)
- propertiesThreshold.indexes--;
- else
- propertiesThreshold.properties--;
- if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0) {
- preview.overflow = true;
- } else {
push(preview.properties, property);
}
},
« no previous file with comments | « no previous file | test/inspector/inspector-impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698