[inspector] remove iterators and for...of loops from injected-script-source
BUG=chromium:686003 Review-Url: https://codereview.chromium.org/2705533002 Cr-Commit-Position: refs/heads/master@{#43595}
This commit is contained in:
parent
9ef1e35bc6
commit
3a20c322bb
@ -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;
|
||||
|
||||
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 (Object.getOwnPropertySymbols) {
|
||||
for (var descriptor of process(o, Object.getOwnPropertySymbols(/** @type {!Object} */ (o))))
|
||||
yield descriptor;
|
||||
}
|
||||
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 {!Array<!Object>} descriptors
|
||||
* @param {!Object} descriptor
|
||||
* @return {boolean}
|
||||
*/
|
||||
function addPropertyIfNeeded(descriptors, descriptor) {
|
||||
if (descriptor.wasThrown)
|
||||
return true;
|
||||
|
||||
// Ignore __proto__ property.
|
||||
if (descriptor.name === "__proto__")
|
||||
return true;
|
||||
|
||||
// Ignore length property of array.
|
||||
if ((subtype === "array" || subtype === "typedarray") && descriptor.name === "length")
|
||||
return true;
|
||||
|
||||
// Ignore size property of map, set.
|
||||
if ((subtype === "map" || subtype === "set") && descriptor.name === "size")
|
||||
return true;
|
||||
|
||||
// Never preview prototype properties.
|
||||
if (!descriptor.isOwn)
|
||||
return true;
|
||||
|
||||
// Ignore computed properties unless they have getters.
|
||||
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 {!Object} propertiesThreshold
|
||||
* @param {?Array.<string>=} secondLevelKeys
|
||||
* @param {boolean=} isTable
|
||||
*/
|
||||
_appendPropertyDescriptors: function(preview, descriptors, propertiesThreshold, secondLevelKeys, isTable)
|
||||
_appendPropertyPreviewDescriptors: function(preview, descriptors, secondLevelKeys, isTable)
|
||||
{
|
||||
for (var descriptor of descriptors) {
|
||||
if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0)
|
||||
break;
|
||||
if (!descriptor || descriptor.wasThrown)
|
||||
continue;
|
||||
|
||||
for (var i = 0; i < descriptors.length; ++i) {
|
||||
var descriptor = descriptors[i];
|
||||
var name = descriptor.name;
|
||||
|
||||
// Ignore __proto__ property.
|
||||
if (name === "__proto__")
|
||||
continue;
|
||||
|
||||
// Ignore length property of array.
|
||||
if ((this.subtype === "array" || this.subtype === "typedarray") && name === "length")
|
||||
continue;
|
||||
|
||||
// Ignore size property of map, set.
|
||||
if ((this.subtype === "map" || this.subtype === "set") && name === "size")
|
||||
continue;
|
||||
|
||||
// Never preview prototype properties.
|
||||
if (!descriptor.isOwn)
|
||||
continue;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
},
|
||||
|
@ -162,6 +162,20 @@ void InspectorClientImpl::disconnect() {
|
||||
session_.reset();
|
||||
}
|
||||
|
||||
bool InspectorClientImpl::formatAccessorsAsProperties(
|
||||
v8::Local<v8::Value> object) {
|
||||
v8::Isolate* isolate = v8::Isolate::GetCurrent();
|
||||
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||
v8::Local<v8::Private> shouldFormatAccessorsPrivate = v8::Private::ForApi(
|
||||
isolate, v8::String::NewFromUtf8(isolate, "allowAccessorFormatting",
|
||||
v8::NewStringType::kNormal)
|
||||
.ToLocalChecked());
|
||||
CHECK(object->IsObject());
|
||||
return object.As<v8::Object>()
|
||||
->HasPrivate(context, shouldFormatAccessorsPrivate)
|
||||
.FromMaybe(false);
|
||||
}
|
||||
|
||||
v8::Local<v8::Context> InspectorClientImpl::ensureDefaultContextInGroup(int) {
|
||||
CHECK(isolate_);
|
||||
return context_.Get(isolate_);
|
||||
|
@ -38,6 +38,7 @@ class InspectorClientImpl : public v8_inspector::V8InspectorClient {
|
||||
|
||||
private:
|
||||
// V8InspectorClient implementation.
|
||||
bool formatAccessorsAsProperties(v8::Local<v8::Value>) override;
|
||||
v8::Local<v8::Context> ensureDefaultContextInGroup(
|
||||
int context_group_id) override;
|
||||
double currentTimeMS() override;
|
||||
|
@ -382,7 +382,8 @@ class InspectorExtension : public v8::Extension {
|
||||
"native function setMaxAsyncTaskStacks();"
|
||||
"native function breakProgram();"
|
||||
"native function createObjectWithStrictCheck();"
|
||||
"native function callWithScheduledBreak();") {}
|
||||
"native function callWithScheduledBreak();"
|
||||
"native function allowAccessorFormatting();") {}
|
||||
|
||||
virtual v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate(
|
||||
v8::Isolate* isolate, v8::Local<v8::String> name) {
|
||||
@ -427,6 +428,13 @@ class InspectorExtension : public v8::Extension {
|
||||
.FromJust()) {
|
||||
return v8::FunctionTemplate::New(
|
||||
isolate, InspectorExtension::CallWithScheduledBreak);
|
||||
} else if (name->Equals(context, v8::String::NewFromUtf8(
|
||||
isolate, "allowAccessorFormatting",
|
||||
v8::NewStringType::kNormal)
|
||||
.ToLocalChecked())
|
||||
.FromJust()) {
|
||||
return v8::FunctionTemplate::New(
|
||||
isolate, InspectorExtension::AllowAccessorFormatting);
|
||||
}
|
||||
return v8::Local<v8::FunctionTemplate>();
|
||||
}
|
||||
@ -525,6 +533,24 @@ class InspectorExtension : public v8::Extension {
|
||||
nullptr);
|
||||
session->cancelPauseOnNextStatement();
|
||||
}
|
||||
|
||||
static void AllowAccessorFormatting(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
if (args.Length() != 1 || !args[0]->IsObject()) {
|
||||
fprintf(stderr, "Internal error: allowAccessorFormatting('object').");
|
||||
Exit();
|
||||
}
|
||||
v8::Local<v8::Object> object = args[0].As<v8::Object>();
|
||||
v8::Isolate* isolate = args.GetIsolate();
|
||||
v8::Local<v8::Private> shouldFormatAccessorsPrivate = v8::Private::ForApi(
|
||||
isolate, v8::String::NewFromUtf8(isolate, "allowAccessorFormatting",
|
||||
v8::NewStringType::kNormal)
|
||||
.ToLocalChecked());
|
||||
object
|
||||
->SetPrivate(isolate->GetCurrentContext(), shouldFormatAccessorsPrivate,
|
||||
v8::Null(isolate))
|
||||
.ToChecked();
|
||||
}
|
||||
};
|
||||
|
||||
v8::Local<v8::String> ToString(v8::Isolate* isolate,
|
||||
|
@ -100,3 +100,730 @@ Running test: testInheritingArrayPropertiesPreview
|
||||
subtype : array
|
||||
type : object
|
||||
}
|
||||
|
||||
Running test: testShortTypedArrayPropertiesPreview
|
||||
{
|
||||
description : Uint8Array(3)
|
||||
overflow : false
|
||||
properties : [
|
||||
[0] : {
|
||||
name : 0
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[1] : {
|
||||
name : 1
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[2] : {
|
||||
name : 2
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
]
|
||||
subtype : typedarray
|
||||
type : object
|
||||
}
|
||||
|
||||
Running test: testLongTypedArrayPropertiesPreview
|
||||
{
|
||||
description : Uint8Array(500001)
|
||||
overflow : true
|
||||
properties : [
|
||||
[0] : {
|
||||
name : 0
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[1] : {
|
||||
name : 1
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[2] : {
|
||||
name : 2
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[3] : {
|
||||
name : 3
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[4] : {
|
||||
name : 4
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[5] : {
|
||||
name : 5
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[6] : {
|
||||
name : 6
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[7] : {
|
||||
name : 7
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[8] : {
|
||||
name : 8
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[9] : {
|
||||
name : 9
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[10] : {
|
||||
name : 10
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[11] : {
|
||||
name : 11
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[12] : {
|
||||
name : 12
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[13] : {
|
||||
name : 13
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[14] : {
|
||||
name : 14
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[15] : {
|
||||
name : 15
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[16] : {
|
||||
name : 16
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[17] : {
|
||||
name : 17
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[18] : {
|
||||
name : 18
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[19] : {
|
||||
name : 19
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[20] : {
|
||||
name : 20
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[21] : {
|
||||
name : 21
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[22] : {
|
||||
name : 22
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[23] : {
|
||||
name : 23
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[24] : {
|
||||
name : 24
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[25] : {
|
||||
name : 25
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[26] : {
|
||||
name : 26
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[27] : {
|
||||
name : 27
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[28] : {
|
||||
name : 28
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[29] : {
|
||||
name : 29
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[30] : {
|
||||
name : 30
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[31] : {
|
||||
name : 31
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[32] : {
|
||||
name : 32
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[33] : {
|
||||
name : 33
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[34] : {
|
||||
name : 34
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[35] : {
|
||||
name : 35
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[36] : {
|
||||
name : 36
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[37] : {
|
||||
name : 37
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[38] : {
|
||||
name : 38
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[39] : {
|
||||
name : 39
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[40] : {
|
||||
name : 40
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[41] : {
|
||||
name : 41
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[42] : {
|
||||
name : 42
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[43] : {
|
||||
name : 43
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[44] : {
|
||||
name : 44
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[45] : {
|
||||
name : 45
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[46] : {
|
||||
name : 46
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[47] : {
|
||||
name : 47
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[48] : {
|
||||
name : 48
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[49] : {
|
||||
name : 49
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[50] : {
|
||||
name : 50
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[51] : {
|
||||
name : 51
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[52] : {
|
||||
name : 52
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[53] : {
|
||||
name : 53
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[54] : {
|
||||
name : 54
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[55] : {
|
||||
name : 55
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[56] : {
|
||||
name : 56
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[57] : {
|
||||
name : 57
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[58] : {
|
||||
name : 58
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[59] : {
|
||||
name : 59
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[60] : {
|
||||
name : 60
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[61] : {
|
||||
name : 61
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[62] : {
|
||||
name : 62
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[63] : {
|
||||
name : 63
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[64] : {
|
||||
name : 64
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[65] : {
|
||||
name : 65
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[66] : {
|
||||
name : 66
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[67] : {
|
||||
name : 67
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[68] : {
|
||||
name : 68
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[69] : {
|
||||
name : 69
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[70] : {
|
||||
name : 70
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[71] : {
|
||||
name : 71
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[72] : {
|
||||
name : 72
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[73] : {
|
||||
name : 73
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[74] : {
|
||||
name : 74
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[75] : {
|
||||
name : 75
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[76] : {
|
||||
name : 76
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[77] : {
|
||||
name : 77
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[78] : {
|
||||
name : 78
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[79] : {
|
||||
name : 79
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[80] : {
|
||||
name : 80
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[81] : {
|
||||
name : 81
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[82] : {
|
||||
name : 82
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[83] : {
|
||||
name : 83
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[84] : {
|
||||
name : 84
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[85] : {
|
||||
name : 85
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[86] : {
|
||||
name : 86
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[87] : {
|
||||
name : 87
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[88] : {
|
||||
name : 88
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[89] : {
|
||||
name : 89
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[90] : {
|
||||
name : 90
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[91] : {
|
||||
name : 91
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[92] : {
|
||||
name : 92
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[93] : {
|
||||
name : 93
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[94] : {
|
||||
name : 94
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[95] : {
|
||||
name : 95
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[96] : {
|
||||
name : 96
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[97] : {
|
||||
name : 97
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[98] : {
|
||||
name : 98
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
[99] : {
|
||||
name : 99
|
||||
type : number
|
||||
value : 0
|
||||
}
|
||||
]
|
||||
subtype : typedarray
|
||||
type : object
|
||||
}
|
||||
|
||||
Running test: testSetPropertiesPreview
|
||||
{
|
||||
description : Set(3)
|
||||
entries : [
|
||||
[0] : {
|
||||
value : {
|
||||
description : 1
|
||||
overflow : false
|
||||
properties : [
|
||||
]
|
||||
type : number
|
||||
}
|
||||
}
|
||||
[1] : {
|
||||
value : {
|
||||
description : 2
|
||||
overflow : false
|
||||
properties : [
|
||||
]
|
||||
type : number
|
||||
}
|
||||
}
|
||||
[2] : {
|
||||
value : {
|
||||
description : 3
|
||||
overflow : false
|
||||
properties : [
|
||||
]
|
||||
type : number
|
||||
}
|
||||
}
|
||||
]
|
||||
overflow : false
|
||||
properties : [
|
||||
]
|
||||
subtype : set
|
||||
type : object
|
||||
}
|
||||
|
||||
Running test: testBigSetPropertiesPreview
|
||||
{
|
||||
description : Set(10)
|
||||
entries : [
|
||||
[0] : {
|
||||
value : {
|
||||
description : 0
|
||||
overflow : false
|
||||
properties : [
|
||||
]
|
||||
type : number
|
||||
}
|
||||
}
|
||||
[1] : {
|
||||
value : {
|
||||
description : 1
|
||||
overflow : false
|
||||
properties : [
|
||||
]
|
||||
type : number
|
||||
}
|
||||
}
|
||||
[2] : {
|
||||
value : {
|
||||
description : 2
|
||||
overflow : false
|
||||
properties : [
|
||||
]
|
||||
type : number
|
||||
}
|
||||
}
|
||||
[3] : {
|
||||
value : {
|
||||
description : 3
|
||||
overflow : false
|
||||
properties : [
|
||||
]
|
||||
type : number
|
||||
}
|
||||
}
|
||||
[4] : {
|
||||
value : {
|
||||
description : 4
|
||||
overflow : false
|
||||
properties : [
|
||||
]
|
||||
type : number
|
||||
}
|
||||
}
|
||||
]
|
||||
overflow : true
|
||||
properties : [
|
||||
]
|
||||
subtype : set
|
||||
type : object
|
||||
}
|
||||
|
||||
Running test: testMixedSetPropertiesPreview
|
||||
{
|
||||
description : Set(10)
|
||||
entries : [
|
||||
[0] : {
|
||||
value : {
|
||||
description : 0
|
||||
overflow : false
|
||||
properties : [
|
||||
]
|
||||
type : number
|
||||
}
|
||||
}
|
||||
[1] : {
|
||||
value : {
|
||||
description : 1
|
||||
overflow : false
|
||||
properties : [
|
||||
]
|
||||
type : number
|
||||
}
|
||||
}
|
||||
[2] : {
|
||||
value : {
|
||||
description : 2
|
||||
overflow : false
|
||||
properties : [
|
||||
]
|
||||
type : number
|
||||
}
|
||||
}
|
||||
[3] : {
|
||||
value : {
|
||||
description : 3
|
||||
overflow : false
|
||||
properties : [
|
||||
]
|
||||
type : number
|
||||
}
|
||||
}
|
||||
[4] : {
|
||||
value : {
|
||||
description : 4
|
||||
overflow : false
|
||||
properties : [
|
||||
]
|
||||
type : number
|
||||
}
|
||||
}
|
||||
]
|
||||
overflow : true
|
||||
properties : [
|
||||
[0] : {
|
||||
name : _prop_0
|
||||
type : number
|
||||
value : 1
|
||||
}
|
||||
[1] : {
|
||||
name : _prop_1
|
||||
type : number
|
||||
value : 1
|
||||
}
|
||||
[2] : {
|
||||
name : _prop_2
|
||||
type : number
|
||||
value : 1
|
||||
}
|
||||
[3] : {
|
||||
name : _prop_3
|
||||
type : number
|
||||
value : 1
|
||||
}
|
||||
[4] : {
|
||||
name : _prop_4
|
||||
type : number
|
||||
value : 1
|
||||
}
|
||||
]
|
||||
subtype : set
|
||||
type : object
|
||||
}
|
||||
|
||||
Running test: testObjInheritsGetterProperty
|
||||
{
|
||||
description : Object
|
||||
overflow : false
|
||||
properties : [
|
||||
[0] : {
|
||||
name : propNotNamedProto
|
||||
type : number
|
||||
value : NaN
|
||||
}
|
||||
]
|
||||
type : object
|
||||
}
|
||||
|
@ -43,6 +43,26 @@ var inheritingObj = {};
|
||||
var inheritingArr = [];
|
||||
inheritingObj.prototype = obj;
|
||||
inheritingArr.prototype = arr;
|
||||
|
||||
var shortTypedArray = new Uint8Array(3);
|
||||
var longTypedArray = new Uint8Array(500001);
|
||||
var set = new Set([1, 2, 3]);
|
||||
var bigSet = new Set();
|
||||
var mixedSet = new Set();
|
||||
for (var i = 0; i < 10; i++) {
|
||||
bigSet.add(i);
|
||||
mixedSet["_prop_" + i] = 1;
|
||||
mixedSet.add(i);
|
||||
}
|
||||
|
||||
var deterministicNativeFunction = Math.log;
|
||||
var parentObj = {};
|
||||
Object.defineProperty(parentObj, 'propNotNamedProto', {
|
||||
get: deterministicNativeFunction,
|
||||
set: function() {}
|
||||
});
|
||||
var objInheritsGetterProperty = {__proto__: parentObj};
|
||||
allowAccessorFormatting(objInheritsGetterProperty);
|
||||
`);
|
||||
|
||||
InspectorTest.runTestSuite([
|
||||
@ -72,5 +92,47 @@ InspectorTest.runTestSuite([
|
||||
Protocol.Runtime.evaluate({ "expression": "inheritingArr", "generatePreview": true })
|
||||
.then(result => InspectorTest.logMessage(result.result.result.preview))
|
||||
.then(next);
|
||||
},
|
||||
|
||||
function testShortTypedArrayPropertiesPreview(next)
|
||||
{
|
||||
Protocol.Runtime.evaluate({ "expression": "shortTypedArray", "generatePreview": true })
|
||||
.then(result => InspectorTest.logMessage(result.result.result.preview))
|
||||
.then(next);
|
||||
},
|
||||
|
||||
function testLongTypedArrayPropertiesPreview(next)
|
||||
{
|
||||
Protocol.Runtime.evaluate({ "expression": "longTypedArray", "generatePreview": true })
|
||||
.then(result => InspectorTest.logMessage(result.result.result.preview))
|
||||
.then(next);
|
||||
},
|
||||
|
||||
function testSetPropertiesPreview(next)
|
||||
{
|
||||
Protocol.Runtime.evaluate({ "expression": "set", "generatePreview": true })
|
||||
.then(result => InspectorTest.logMessage(result.result.result.preview))
|
||||
.then(next);
|
||||
},
|
||||
|
||||
function testBigSetPropertiesPreview(next)
|
||||
{
|
||||
Protocol.Runtime.evaluate({ "expression": "bigSet", "generatePreview": true })
|
||||
.then(result => InspectorTest.logMessage(result.result.result.preview))
|
||||
.then(next);
|
||||
},
|
||||
|
||||
function testMixedSetPropertiesPreview(next)
|
||||
{
|
||||
Protocol.Runtime.evaluate({ "expression": "mixedSet", "generatePreview": true })
|
||||
.then(result => InspectorTest.logMessage(result.result.result.preview))
|
||||
.then(next);
|
||||
},
|
||||
|
||||
function testObjInheritsGetterProperty(next)
|
||||
{
|
||||
Protocol.Runtime.evaluate({ "expression": "objInheritsGetterProperty", "generatePreview": true })
|
||||
.then(result => InspectorTest.logMessage(result.result.result.preview))
|
||||
.then(next);
|
||||
}
|
||||
]);
|
||||
|
@ -37,3 +37,8 @@ Internal properties
|
||||
[[BoundArgs]] object undefined
|
||||
[[BoundThis]] object undefined
|
||||
[[TargetFunction]] function undefined
|
||||
Properties of Object that throws on length access
|
||||
__proto__ own object undefined
|
||||
length own no value, getter
|
||||
Properties of TypedArray without length
|
||||
__proto__ own object undefined
|
||||
|
@ -176,6 +176,46 @@ function callbackEvalBound(result)
|
||||
function callbackPropertiesBound(result)
|
||||
{
|
||||
logGetPropertiesResult("Bound function", result);
|
||||
return { callback: callbackStartObjectThrowsLength };
|
||||
}
|
||||
|
||||
|
||||
// Object throws on length access
|
||||
|
||||
function callbackStartObjectThrowsLength() {
|
||||
var expression = "({get length() { throw 'Length called'; }})";
|
||||
return { command: "Runtime.evaluate", params: {expression: expression}, callback: callbackEvalObjectThrowsLength };
|
||||
}
|
||||
function callbackEvalObjectThrowsLength(result) {
|
||||
var id = result.result.objectId;
|
||||
if (id === undefined)
|
||||
throw new Error("objectId is expected");
|
||||
return {
|
||||
command: "Runtime.getProperties", params: {objectId: id, ownProperties: true}, callback: callbackPropertiesObjectThrowsLength
|
||||
};
|
||||
}
|
||||
function callbackPropertiesObjectThrowsLength(result) {
|
||||
logGetPropertiesResult("Object that throws on length access", result);
|
||||
return { callback: callbackStartTypedArrayWithoutLength };
|
||||
}
|
||||
|
||||
|
||||
// Typed array without length
|
||||
|
||||
function callbackStartTypedArrayWithoutLength() {
|
||||
var expression = "({__proto__: Uint8Array.prototype})";
|
||||
return { command: "Runtime.evaluate", params: {expression: expression}, callback: callbackEvalTypedArrayWithoutLength };
|
||||
}
|
||||
function callbackEvalTypedArrayWithoutLength(result) {
|
||||
var id = result.result.objectId;
|
||||
if (id === undefined)
|
||||
throw new Error("objectId is expected");
|
||||
return {
|
||||
command: "Runtime.getProperties", params: {objectId: id, ownProperties: true}, callback: callbackPropertiesTypedArrayWithoutLength
|
||||
};
|
||||
}
|
||||
function callbackPropertiesTypedArrayWithoutLength(result) {
|
||||
logGetPropertiesResult("TypedArray without length", result);
|
||||
return; // End of test
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user