commit 52d98a0908a25c0a60220529b2eaa7f88724a248
parent 460dd991693eb369923f8379b3d64799ec9b435a
Author: Atila Butkovits <abutkovits@mozilla.com>
Date: Thu, 9 Oct 2025 22:14:06 +0300
Revert "Bug 1992249: apply code formatting via Lando" for causing failures at browser_test_feature_jstracing_objtestutils.js.
This reverts commit 90a4dc6c5759cc7e9a3a59d0fc61caf198d2ad8b.
Revert "Bug 1992249 - Fix MapLike entries loop r=ochameau,devtools-reviewers,profiler-reviewers,canaltinova"
This reverts commit c7382062ea10daa2c5c4254331b94d03f0ff1548.
Revert "Bug 1992249 - Verify version when deserializing r=ochameau,devtools-reviewers"
This reverts commit 0408a16e1698ed8c0c5007c383666bb515bf5dca.
Revert "Bug 1992249 - Properly handle symbols with no description r=ochameau,devtools-reviewers"
This reverts commit 52062ee92d1bed8a6b5d72603e06ee9d27343fd0.
Revert "Bug 1992249 - Fix getter/setter magic value mismatch r=ochameau,devtools-reviewers"
This reverts commit 52e5d7788afd86d90ca3817d31e1db2fa38bbde9.
Revert "Bug 1992249 - Fix up code style r=ochameau,devtools-reviewers"
This reverts commit 1459bdab2dcf0d7c9aae9b53a4a19ea3dc897327.
Revert "Bug 1992249 - Move ValueSummaryReader into reps r=ochameau,devtools-reviewers,profiler-reviewers,canaltinova"
This reverts commit f2e93aca0dbb327b346c6965c81ef471a0c2cb82.
Diffstat:
9 files changed, 551 insertions(+), 1219 deletions(-)
diff --git a/devtools/client/shared/components/reps/reps/moz.build b/devtools/client/shared/components/reps/reps/moz.build
@@ -42,6 +42,5 @@ DevToolsModules(
"symbol.mjs",
"text-node.mjs",
"undefined.mjs",
- "value-summary-reader.mjs",
"window.mjs",
)
diff --git a/devtools/client/shared/components/reps/reps/value-summary-reader.mjs b/devtools/client/shared/components/reps/reps/value-summary-reader.mjs
@@ -1,564 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-const MAX_ARGUMENTS_TO_RECORD = 4;
-const ZERO_ARGUMENTS_MAGIC = -2;
-const EXPIRED_VALUES_MAGIC = -1;
-
-const EXPECTED_VALUE_SUMMARIES_VERSION = 1;
-
-const JSVAL_TYPE_DOUBLE = 0x00;
-const JSVAL_TYPE_INT32 = 0x01;
-const JSVAL_TYPE_BOOLEAN = 0x02;
-const JSVAL_TYPE_UNDEFINED = 0x03;
-const JSVAL_TYPE_NULL = 0x04;
-const JSVAL_TYPE_MAGIC = 0x05;
-const JSVAL_TYPE_STRING = 0x06;
-const JSVAL_TYPE_SYMBOL = 0x07;
-const JSVAL_TYPE_BIGINT = 0x09;
-const JSVAL_TYPE_OBJECT = 0x0c;
-
-const GETTER_SETTER_MAGIC = 0x0f;
-
-const GENERIC_OBJECT_HAS_DENSE_ELEMENTS = 1;
-const SYMBOL_NO_DESCRIPTION = 1;
-
-const NUMBER_IS_OUT_OF_LINE_MAGIC = 0xf;
-const MIN_INLINE_INT = -1;
-
-const STRING_ENCODING_LATIN1 = 0;
-const STRING_ENCODING_TWO_BYTE = 1;
-const STRING_ENCODING_UTF8 = 2;
-
-const OBJECT_KIND_NOT_IMPLEMENTED = 0;
-const OBJECT_KIND_ARRAY_LIKE = 1;
-const OBJECT_KIND_MAP_LIKE = 2;
-const OBJECT_KIND_FUNCTION = 3;
-const OBJECT_KIND_WRAPPED_PRIMITIVE_OBJECT = 4;
-const OBJECT_KIND_GENERIC_OBJECT = 5;
-const OBJECT_KIND_PROXY_OBJECT = 6;
-const OBJECT_KIND_EXTERNAL = 7;
-const OBJECT_KIND_ERROR = 8;
-
-const MAX_COLLECTION_VALUES = 16;
-
-const EXTERNAL_SUMMARY_EXPECTED_VERSION = 1;
-const EXTERNAL_SUMMARY_KIND_OTHER = 0;
-const EXTERNAL_SUMMARY_KIND_NODE = 1;
-const EXTERNAL_SUMMARY_KIND_EXCEPTION = 2;
-
-// const EXTERNAL_NODE_SUBKIND_OTHER = 0; (handled implicitly)
-const EXTERNAL_NODE_SUBKIND_ELEMENT = 1;
-const EXTERNAL_NODE_SUBKIND_ATTR = 2;
-const EXTERNAL_NODE_SUBKIND_DOCUMENT = 3;
-const EXTERNAL_NODE_SUBKIND_DOCUMENT_FRAGMENT = 4;
-const EXTERNAL_NODE_SUBKIND_TEXT = 5;
-const EXTERNAL_NODE_SUBKIND_COMMENT = 6;
-
-class BufferReader {
- #view;
- #index;
-
- constructor(buffer, index = 0) {
- this.#view = new DataView(buffer);
- this.#index = index;
- }
-
- setIndex(value) {
- this.#index = value;
- }
-
- getIndex() {
- return this.#index;
- }
-
- peekUint8() {
- return this.#view.getUint8(this.#index);
- }
-
- readUint8() {
- const result = this.#view.getUint8(this.#index);
- this.#index += 1;
- return result;
- }
-
- readUint16() {
- const result = this.#view.getUint16(this.#index, true);
- this.#index += 2;
- return result;
- }
-
- readUint32() {
- const result = this.#view.getUint32(this.#index, true);
- this.#index += 4;
- return result;
- }
-
- readInt8() {
- const result = this.#view.getInt8(this.#index);
- this.#index += 1;
- return result;
- }
-
- readInt16() {
- const result = this.#view.getInt16(this.#index, true);
- this.#index += 2;
- return result;
- }
-
- readInt32() {
- const result = this.#view.getInt32(this.#index, true);
- this.#index += 4;
- return result;
- }
-
- readFloat64() {
- const result = this.#view.getFloat64(this.#index, true);
- this.#index += 8;
- return result;
- }
-
- readString() {
- const encodingAndLength = this.readUint16();
- const length = encodingAndLength & ~(0b11 << 14);
- const encoding = encodingAndLength >> 14;
- if (length == 0) {
- return "";
- }
-
- let result = "";
- if (encoding == STRING_ENCODING_LATIN1) {
- const decoder = new TextDecoder("latin1");
- result = decoder.decode(
- this.#view.buffer.slice(this.#index, this.#index + length)
- );
- this.#index += length;
- } else if (encoding == STRING_ENCODING_UTF8) {
- const decoder = new TextDecoder("utf-8");
- result = decoder.decode(
- this.#view.buffer.slice(this.#index, this.#index + length)
- );
- this.#index += length;
- } else if (encoding == STRING_ENCODING_TWO_BYTE) {
- const decoder = new TextDecoder("utf-16"); // this isn't quite right, is it? ugh.
- const size = length * 2;
- result = decoder.decode(
- this.#view.buffer.slice(this.#index, this.#index + size)
- );
- this.#index += size;
- }
- return result;
- }
-}
-
-function readArrayLikeSummary(result, reader, depth, shapes) {
- const shapeId = reader.readUint32();
- const shape = shapes[shapeId];
-
- if (!shape || shape.length <= 0) {
- return;
- }
- result.class = shape[0];
-
- const preview = {};
- preview.kind = "ArrayLike";
-
- preview.items = [];
- preview.length = reader.readUint32();
- if (depth < 1) {
- for (let i = 0; i < preview.length && i < MAX_COLLECTION_VALUES; i++) {
- if (reader.peekUint8() === JSVAL_TYPE_MAGIC) {
- reader.readUint8();
- continue;
- }
-
- const nestedSummary = readValueSummary(reader, depth + 1, shapes);
- preview.items.push(nestedSummary);
- }
- }
-
- result.preview = preview;
-}
-
-function readFunctionSummary(result, reader) {
- result.class = "Function";
- result.name = reader.readString();
- result.parameterNames = [];
- const numParameterNames = reader.readUint32();
- for (let i = 0; i < numParameterNames && i < MAX_COLLECTION_VALUES; i++) {
- result.parameterNames.push(reader.readString());
- }
-}
-
-function readMapLikeSummary(result, reader, depth, shapes) {
- const shapeId = reader.readUint32();
- const shape = shapes[shapeId];
-
- if (!shape || shape.length <= 0) {
- return;
- }
- result.class = shape[0];
-
- const preview = {};
- preview.kind = "MapLike";
-
- preview.entries = [];
- preview.size = reader.readUint32();
- if (depth < 1) {
- for (let i = 0; i < preview.size && i < MAX_COLLECTION_VALUES; i++) {
- const keySummary = readValueSummary(reader, depth + 1, shapes);
- const valueSummary = readValueSummary(reader, depth + 1, shapes);
- preview.entries.push([
- {
- configurable: true,
- enumerable: true,
- writable: true,
- value: keySummary,
- },
- {
- configurable: true,
- enumerable: true,
- writable: true,
- value: valueSummary,
- },
- ]);
- }
- }
-
- result.preview = preview;
-}
-
-function readGenericObjectSummary(result, reader, flags, depth, shapes) {
- const shapeId = reader.readUint32();
- const shape = shapes[shapeId];
-
- if (!shape || shape.length <= 0) {
- return;
- }
- result.class = shape[0];
-
- const preview = {};
- preview.kind = "Object";
-
- const hasDenseElements = !!(flags & GENERIC_OBJECT_HAS_DENSE_ELEMENTS);
- const ownProperties = {};
- let ownPropertiesLength = reader.readUint32();
-
- if (depth < 1) {
- for (let i = 1; i < shape.length && i <= MAX_COLLECTION_VALUES; i++) {
- const header = reader.peekUint8();
- const id = shape[i];
- const desc = {
- configurable: true,
- enumerable: true,
- };
- if (header === GETTER_SETTER_MAGIC) {
- reader.readUint8();
- desc.get = readValueSummary(reader, depth + 1, shapes);
- desc.set = readValueSummary(reader, depth + 1, shapes);
- } else {
- const nestedSummary = readValueSummary(reader, depth + 1, shapes);
- desc.writable = true;
- desc.value = nestedSummary;
- }
- ownProperties[id] = desc;
- }
- }
-
- if (hasDenseElements) {
- const elementsLength = reader.readUint32();
- if (depth < 1) {
- for (let i = 0; i < elementsLength && i < MAX_COLLECTION_VALUES; i++) {
- if (reader.peekUint8() === JSVAL_TYPE_MAGIC) {
- reader.readUint8();
- continue;
- }
- ownPropertiesLength++;
- const nestedSummary = readValueSummary(reader, depth + 1, shapes);
- ownProperties[i] = {
- configurable: true,
- enumerable: true,
- writable: true,
- value: nestedSummary,
- };
- }
- }
- }
-
- preview.ownProperties = ownProperties;
- preview.ownPropertiesLength = ownPropertiesLength;
-
- result.preview = preview;
-}
-
-function readClassFromShape(result, reader, shapes) {
- const shapeId = reader.readUint32();
- const shape = shapes[shapeId];
-
- if (!shape || shape.length <= 0) {
- return;
- }
- result.class = shape[0];
-}
-
-function readNodeSummary(result, reader, depth, shapes) {
- const preview = {};
- preview.kind = "DOMNode";
- preview.nodeType = reader.readUint16();
- preview.nodeName = reader.readString().toLowerCase();
- const subkindAndIsConnected = reader.readUint8();
- const subkind = subkindAndIsConnected & ~(1 << 7);
- preview.isConnected = subkindAndIsConnected >> 7;
-
- if (subkind === EXTERNAL_NODE_SUBKIND_ELEMENT) {
- preview.attributes = {};
- preview.attributesLength = reader.readUint32();
- for (
- let i = 0;
- i < preview.attributesLength && i < MAX_COLLECTION_VALUES;
- i++
- ) {
- const attrName = reader.readString();
- const attrVal = reader.readString();
- preview.attributes[attrName] = attrVal;
- }
- } else if (subkind === EXTERNAL_NODE_SUBKIND_ATTR) {
- preview.value = reader.readString();
- } else if (subkind === EXTERNAL_NODE_SUBKIND_DOCUMENT) {
- preview.location = reader.readString();
- } else if (subkind === EXTERNAL_NODE_SUBKIND_DOCUMENT_FRAGMENT) {
- preview.childNodesLength = reader.readUint32();
- if (depth < 1) {
- preview.childNodes = [];
- for (
- let i = 0;
- i < preview.childNodesLength && i < MAX_COLLECTION_VALUES;
- i++
- ) {
- preview.childNodes.push(readValueSummary(reader, depth + 1, shapes));
- }
- }
- } else if (
- subkind === EXTERNAL_NODE_SUBKIND_TEXT ||
- subkind === EXTERNAL_NODE_SUBKIND_COMMENT
- ) {
- preview.textContent = reader.readString();
- }
-
- result.preview = preview;
-}
-
-function readExceptionSummary(result, reader, _depth, _shapes) {
- result.class = "Error";
- const preview = {};
- preview.kind = "DOMException";
- preview.name = reader.readString();
- preview.message = reader.readString();
- preview.code = reader.readUint16();
- preview.result = reader.readUint32();
- preview.lineNumber = reader.readUint32();
- preview.columnNumber = reader.readUint32();
- preview.stack = reader.readString();
- result.preview = preview;
-}
-
-function readExternalObjectSummary(result, reader, depth, shapes) {
- readClassFromShape(result, reader, shapes);
-
- const startIndex = reader.getIndex();
- const size = reader.readUint32();
- try {
- const version = reader.readUint8();
- if (version != EXTERNAL_SUMMARY_EXPECTED_VERSION) {
- return;
- }
-
- const kind = reader.readUint8();
- if (kind == EXTERNAL_SUMMARY_KIND_OTHER) {
- return;
- }
-
- switch (kind) {
- case EXTERNAL_SUMMARY_KIND_NODE: {
- readNodeSummary(result, reader, depth, shapes);
- break;
- }
- case EXTERNAL_SUMMARY_KIND_EXCEPTION: {
- readExceptionSummary(result, reader, depth, shapes);
- break;
- }
- default:
- }
- } finally {
- reader.setIndex(startIndex + size);
- }
-}
-
-function readErrorObjectSummary(result, reader, depth, shapes) {
- const shapeId = reader.readUint32();
- const shape = shapes[shapeId];
-
- if (!shape || shape.length <= 0) {
- return;
- }
-
- const preview = {};
- result.type = "object";
- result.class = shape[0];
- result.isError = true;
- preview.kind = "Error";
- preview.name = reader.readString();
- preview.message = reader.readString();
- preview.stack = reader.readString();
- preview.fileName = reader.readString();
- preview.lineNumber = reader.readUint32();
- preview.columnNumber = reader.readUint32();
- result.preview = preview;
-}
-
-function readObjectSummary(reader, flags, depth, shapes) {
- const result = {
- type: "object",
- class: undefined,
- ownPropertyLength: 0,
- isError: false,
- extensible: false,
- sealed: false,
- frozen: false,
- };
-
- const kind = reader.readUint8();
- switch (kind) {
- case OBJECT_KIND_NOT_IMPLEMENTED:
- readClassFromShape(result, reader, shapes);
- break;
- case OBJECT_KIND_ARRAY_LIKE:
- readArrayLikeSummary(result, reader, depth, shapes);
- break;
- case OBJECT_KIND_MAP_LIKE:
- readMapLikeSummary(result, reader, depth, shapes);
- break;
- case OBJECT_KIND_FUNCTION:
- readFunctionSummary(result, reader);
- break;
- case OBJECT_KIND_EXTERNAL:
- readExternalObjectSummary(result, reader, depth, shapes);
- break;
- case OBJECT_KIND_ERROR:
- readErrorObjectSummary(result, reader, depth, shapes);
- break;
- case OBJECT_KIND_WRAPPED_PRIMITIVE_OBJECT: {
- result.wrappedValue = readValueSummary(reader, depth, shapes);
- readGenericObjectSummary(result, reader, flags, depth, shapes);
- break;
- }
- case OBJECT_KIND_GENERIC_OBJECT: {
- readGenericObjectSummary(result, reader, flags, depth, shapes);
- break;
- }
- case OBJECT_KIND_PROXY_OBJECT: {
- readClassFromShape(result, reader, shapes);
- result.preview = {
- kind: "Object",
- ownProperties: Object.create(null),
- ownPropertiesLength: 0,
- };
- break;
- }
- default:
- throw new Error("Bad object kind");
- }
-
- return result;
-}
-
-function readValueSummary(reader, depth, shapes) {
- const header = reader.readUint8();
- const type = header & 0x0f;
- const flags = (header & 0xf0) >> 4;
- switch (type) {
- case JSVAL_TYPE_DOUBLE:
- if (flags == NUMBER_IS_OUT_OF_LINE_MAGIC) {
- const value = reader.readFloat64();
- if (value === Infinity) {
- return { type: "Infinity" };
- } else if (value === -Infinity) {
- return { type: "-Infinity" };
- } else if (Number.isNaN(value)) {
- return { type: "NaN" };
- } else if (!value && 1 / value === -Infinity) {
- return { type: "-0" };
- }
- return value;
- }
- return 0;
-
- case JSVAL_TYPE_INT32:
- if (flags === NUMBER_IS_OUT_OF_LINE_MAGIC) {
- return reader.readInt32();
- }
- return flags + MIN_INLINE_INT;
-
- case JSVAL_TYPE_BOOLEAN:
- return !!flags;
- case JSVAL_TYPE_NULL:
- return { type: "null" };
- case JSVAL_TYPE_UNDEFINED:
- return { type: "undefined" };
- case JSVAL_TYPE_SYMBOL:
- if (flags & SYMBOL_NO_DESCRIPTION) {
- return {
- type: "symbol",
- };
- }
- return {
- type: "symbol",
- name: reader.readString(),
- };
- case JSVAL_TYPE_BIGINT:
- return {
- type: "BigInt",
- text: reader.readString(),
- };
- case JSVAL_TYPE_STRING: {
- return reader.readString();
- }
- case JSVAL_TYPE_OBJECT: {
- return readObjectSummary(reader, flags, depth, shapes);
- }
- default:
- throw new Error("Bad value type");
- }
-}
-
-function bufferVersion(valuesBuffer) {
- const reader = new BufferReader(valuesBuffer, 0);
- const version = reader.readUint32();
- return version;
-}
-
-function getArgumentSummaries(valuesBuffer, shapes, valuesBufferIndex) {
- if (valuesBufferIndex === ZERO_ARGUMENTS_MAGIC) {
- return [];
- }
- if (valuesBufferIndex === EXPIRED_VALUES_MAGIC) {
- return "<missing>";
- }
- const theirVersion = bufferVersion(valuesBuffer);
- if (theirVersion != EXPECTED_VALUE_SUMMARIES_VERSION) {
- throw new Error(
- `Unexpected tracer arguments buffer format. Expected ${EXPECTED_VALUE_SUMMARIES_VERSION}, received ${theirVersion}.`
- );
- }
-
- const reader = new BufferReader(valuesBuffer, valuesBufferIndex);
- const argc = reader.readUint32();
- const args = new Array(argc);
- for (let i = 0; i < argc && i < MAX_ARGUMENTS_TO_RECORD; i++) {
- args[i] = readValueSummary(reader, 0, shapes);
- }
- return args;
-}
-
-export const ValueSummaryReader = { getArgumentSummaries };
diff --git a/js/public/Debug.h b/js/public/Debug.h
@@ -280,7 +280,7 @@ struct ValueSummary {
struct ObjectSummary {
// This is a special value for ValueSummary::typeAndFlags. It should be noted
// that this only works as long as 0xf is not a valid JS::ValueType.
- static const uint8_t GETTER_SETTER_MAGIC = 0x0f;
+ static const uint8_t GETTER_SETTER_MAGIC = 0xf0;
enum class Kind : uint8_t {
NotImplemented,
diff --git a/js/src/debugger/ExecutionTracer.cpp b/js/src/debugger/ExecutionTracer.cpp
@@ -668,8 +668,6 @@ void ValueSummaries::writeHeader(JS::ValueType type, uint8_t flags) {
JS::ValueSummary header;
header.type = type;
header.flags = flags;
- MOZ_ASSERT(*reinterpret_cast<uint8_t*>(&header) !=
- JS::ObjectSummary::GETTER_SETTER_MAGIC);
valueData_->writeBytes(reinterpret_cast<const uint8_t*>(&header),
sizeof(header));
}
diff --git a/js/src/jit-test/tests/debug/ExecutionTracer-traced-values.js b/js/src/jit-test/tests/debug/ExecutionTracer-traced-values.js
@@ -14,7 +14,7 @@ const JSVAL_TYPE_SYMBOL = 0x07;
const JSVAL_TYPE_BIGINT = 0x09;
const JSVAL_TYPE_OBJECT = 0x0c;
-const GETTER_SETTER_MAGIC = 0x0f;
+const GETTER_SETTER_MAGIC = 0xf0;
const GENERIC_OBJECT_HAS_DENSE_ELEMENTS = 1;
@@ -159,7 +159,6 @@ wrappedNumber.foo = 0;
function foobaz(a, a) {},
function barbaz(a, ...rest) {},
ccw.wrappedObject,
- {get testGetter() {return 42}},
].map(function f1(x) { return x; });`);
const trace = g.getExecutionTrace();
@@ -611,23 +610,5 @@ testSingleArgument(events.shift(), reader => {
assertEq(reader.readUint8(), JSVAL_TYPE_INT32 | inlinedInt32Flags(0));
});
-testSingleArgument(events.shift(), reader => {
- assertEq(reader.readUint8(), JSVAL_TYPE_OBJECT);
- assertEq(reader.readUint8(), OBJECT_KIND_GENERIC_OBJECT);
-
- let shape = trace[0].shapeSummaries[reader.readUint32()];
- assertEq(shape.length, 2);
- assertEq(shape[0], "Object");
- assertEq(shape[1], "testGetter");
-
- assertEq(reader.readUint32(), 1);
- assertEq(reader.readUint8(), GETTER_SETTER_MAGIC);
- assertEq(reader.readUint8(), JSVAL_TYPE_OBJECT);
- assertEq(reader.readUint8(), OBJECT_KIND_FUNCTION);
- assertEq(reader.readString(), "get testGetter");
- assertEq(reader.readUint32(), 0);
- assertEq(reader.readUint8(), JSVAL_TYPE_UNDEFINED);
-});
-
assertEq(events.length, 0);
diff --git a/tools/profiler/tests/browser/browser.toml b/tools/profiler/tests/browser/browser.toml
@@ -18,6 +18,7 @@ skip-if = ["!nightly_build"] # This features is only enabled on nightly via MOZ_
["browser_test_feature_jstracing_objtestutils.js"]
support-files = [
"browser_test_feature_jstracing_objtestutils.snapshot.mjs",
+ "value_summary_reader.mjs"
]
skip-if = [
# This features is only enabled on nightly via MOZ_EXECUTION_TRACING build flag
diff --git a/tools/profiler/tests/browser/browser_test_feature_jstracing_objtestutils.js b/tools/profiler/tests/browser/browser_test_feature_jstracing_objtestutils.js
@@ -9,7 +9,7 @@ const { XPCShellContentUtils } = ChromeUtils.importESModule(
"resource://testing-common/XPCShellContentUtils.sys.mjs"
);
const { ValueSummaryReader } = ChromeUtils.importESModule(
- "resource://devtools/client/shared/components/reps/reps/value-summary-reader.mjs"
+ "chrome://mochitests/content/browser/tools/profiler/tests/browser/value_summary_reader.mjs"
);
/**
diff --git a/tools/profiler/tests/browser/browser_test_feature_jstracing_objtestutils.snapshot.mjs b/tools/profiler/tests/browser/browser_test_feature_jstracing_objtestutils.snapshot.mjs
@@ -217,88 +217,7 @@ export default [
"frozen": false,
"preview": {
"kind": "MapLike",
- "entries": [
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "object",
- "class": "Object",
- "ownPropertyLength": 0,
- "isError": false,
- "extensible": false,
- "sealed": false,
- "frozen": false,
- "preview": {
- "kind": "Object",
- "ownProperties": {},
- "ownPropertiesLength": 1
- }
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "object",
- "class": "Object",
- "ownPropertyLength": 0,
- "isError": false,
- "extensible": false,
- "sealed": false,
- "frozen": false,
- "preview": {
- "kind": "Object",
- "ownProperties": {},
- "ownPropertiesLength": 1
- }
- }
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "object",
- "class": "Object",
- "ownPropertyLength": 0,
- "isError": false,
- "extensible": false,
- "sealed": false,
- "frozen": false,
- "preview": {
- "kind": "Object",
- "ownProperties": {},
- "ownPropertiesLength": 1
- }
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "object",
- "class": "Object",
- "ownPropertyLength": 0,
- "isError": false,
- "extensible": false,
- "sealed": false,
- "frozen": false,
- "preview": {
- "kind": "Object",
- "ownProperties": {},
- "ownPropertiesLength": 1
- }
- }
- }
- ]
- ],
+ "entries": [],
"size": 2
}
},
@@ -314,280 +233,7 @@ export default [
"frozen": false,
"preview": {
"kind": "MapLike",
- "entries": [
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "0"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 0
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "1"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 1
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "2"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 2
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "3"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 3
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "4"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 4
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "5"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 5
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "6"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 6
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "7"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 7
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "8"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 8
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "9"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 9
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "10"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 10
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "11"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 11
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "12"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 12
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "13"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 13
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "14"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 14
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "15"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 15
- }
- ]
- ],
+ "entries": [],
"size": 20
}
},
@@ -603,280 +249,7 @@ export default [
"frozen": false,
"preview": {
"kind": "MapLike",
- "entries": [
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "0"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 0
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "1"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 1
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "2"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 2
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "3"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 3
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "4"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 4
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "5"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 5
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "6"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 6
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "7"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 7
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "8"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 8
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "9"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 9
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "10"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 10
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "11"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 11
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "12"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 12
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "13"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 13
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "14"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 14
- }
- ],
- [
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": {
- "type": "symbol",
- "name": "15"
- }
- },
- {
- "configurable": true,
- "enumerable": true,
- "writable": true,
- "value": 15
- }
- ]
- ],
+ "entries": [],
"size": 331
}
},
diff --git a/tools/profiler/tests/browser/value_summary_reader.mjs b/tools/profiler/tests/browser/value_summary_reader.mjs
@@ -0,0 +1,544 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+const MAX_ARGUMENTS_TO_RECORD = 4;
+const ZERO_ARGUMENTS_MAGIC = -2;
+const EXPIRED_VALUES_MAGIC = -1;
+
+const JSVAL_TYPE_DOUBLE = 0x00;
+const JSVAL_TYPE_INT32 = 0x01;
+const JSVAL_TYPE_BOOLEAN = 0x02;
+const JSVAL_TYPE_UNDEFINED = 0x03;
+const JSVAL_TYPE_NULL = 0x04;
+const JSVAL_TYPE_MAGIC = 0x05;
+const JSVAL_TYPE_STRING = 0x06;
+const JSVAL_TYPE_SYMBOL = 0x07;
+const JSVAL_TYPE_BIGINT = 0x09;
+const JSVAL_TYPE_OBJECT = 0x0c;
+
+const GETTER_SETTER_MAGIC = 0xf0;
+
+const GENERIC_OBJECT_HAS_DENSE_ELEMENTS = 1;
+
+const NUMBER_IS_OUT_OF_LINE_MAGIC = 0xf;
+const MIN_INLINE_INT = -1;
+
+const STRING_ENCODING_LATIN1 = 0;
+const STRING_ENCODING_TWO_BYTE = 1;
+const STRING_ENCODING_UTF8 = 2;
+
+const OBJECT_KIND_NOT_IMPLEMENTED = 0;
+const OBJECT_KIND_ARRAY_LIKE = 1;
+const OBJECT_KIND_MAP_LIKE = 2;
+const OBJECT_KIND_FUNCTION = 3;
+const OBJECT_KIND_WRAPPED_PRIMITIVE_OBJECT = 4;
+const OBJECT_KIND_GENERIC_OBJECT = 5;
+const OBJECT_KIND_PROXY_OBJECT = 6;
+const OBJECT_KIND_EXTERNAL = 7;
+const OBJECT_KIND_ERROR = 8;
+
+const MAX_COLLECTION_VALUES = 16;
+
+const EXTERNAL_SUMMARY_EXPECTED_VERSION = 1;
+const EXTERNAL_SUMMARY_KIND_OTHER = 0;
+const EXTERNAL_SUMMARY_KIND_NODE = 1;
+const EXTERNAL_SUMMARY_KIND_EXCEPTION = 2;
+
+// const EXTERNAL_NODE_SUBKIND_OTHER = 0; (handled implicitly)
+const EXTERNAL_NODE_SUBKIND_ELEMENT = 1;
+const EXTERNAL_NODE_SUBKIND_ATTR = 2;
+const EXTERNAL_NODE_SUBKIND_DOCUMENT = 3;
+const EXTERNAL_NODE_SUBKIND_DOCUMENT_FRAGMENT = 4;
+const EXTERNAL_NODE_SUBKIND_TEXT = 5;
+const EXTERNAL_NODE_SUBKIND_COMMENT = 6;
+
+class BufferReader {
+ #view;
+ #index;
+
+ constructor(buffer, index = 0) {
+ this.#view = new DataView(buffer);
+ this.#index = index;
+ }
+
+ setIndex(value) {
+ this.#index = value;
+ }
+
+ getIndex() {
+ return this.#index;
+ }
+
+ peekUint8() {
+ return this.#view.getUint8(this.#index);
+ }
+
+ readUint8() {
+ const result = this.#view.getUint8(this.#index);
+ this.#index += 1;
+ return result;
+ }
+
+ readUint16() {
+ const result = this.#view.getUint16(this.#index, true);
+ this.#index += 2;
+ return result;
+ }
+
+ readUint32() {
+ const result = this.#view.getUint32(this.#index, true);
+ this.#index += 4;
+ return result;
+ }
+
+ readInt8() {
+ const result = this.#view.getInt8(this.#index);
+ this.#index += 1;
+ return result;
+ }
+
+ readInt16() {
+ const result = this.#view.getInt16(this.#index, true);
+ this.#index += 2;
+ return result;
+ }
+
+ readInt32() {
+ const result = this.#view.getInt32(this.#index, true);
+ this.#index += 4;
+ return result;
+ }
+
+ readFloat64() {
+ const result = this.#view.getFloat64(this.#index, true);
+ this.#index += 8;
+ return result;
+ }
+
+ readString() {
+ const encodingAndLength = this.readUint16();
+ const length = encodingAndLength & ~(0b11 << 14);
+ const encoding = encodingAndLength >> 14;
+ if (length == 0) {
+ return "";
+ }
+
+ let result = "";
+ if (encoding == STRING_ENCODING_LATIN1) {
+ const decoder = new TextDecoder("latin1");
+ result = decoder.decode(
+ this.#view.buffer.slice(this.#index, this.#index + length)
+ );
+ this.#index += length;
+ } else if (encoding == STRING_ENCODING_UTF8) {
+ const decoder = new TextDecoder("utf-8");
+ result = decoder.decode(
+ this.#view.buffer.slice(this.#index, this.#index + length)
+ );
+ this.#index += length;
+ } else if (encoding == STRING_ENCODING_TWO_BYTE) {
+ const decoder = new TextDecoder("utf-16"); // this isn't quite right, is it? ugh.
+ const size = length * 2;
+ result = decoder.decode(
+ this.#view.buffer.slice(this.#index, this.#index + size)
+ );
+ this.#index += size;
+ }
+ return result;
+ }
+}
+
+function readArrayLikeSummary(result, reader, flags, depth, shapes) {
+ const shapeId = reader.readUint32();
+ const shape = shapes[shapeId];
+
+ if (!shape || shape.length <= 0) {
+ return;
+ }
+ result.class = shape[0];
+
+ const preview = {};
+ preview.kind = "ArrayLike";
+
+ preview.items = [];
+ preview.length = reader.readUint32();
+ if (depth < 1) {
+ for (let i = 0; i < preview.length && i < MAX_COLLECTION_VALUES; i++) {
+ if (reader.peekUint8() == JSVAL_TYPE_MAGIC) {
+ reader.readUint8();
+ continue;
+ }
+
+ const nestedSummary = readValueSummary(reader, depth + 1, shapes);
+ preview.items.push(nestedSummary);
+ }
+ }
+
+ result.preview = preview;
+}
+
+function readFunctionSummary(result, reader) {
+ result.class = "Function";
+ result.name = reader.readString();
+ result.parameterNames = [];
+ const numParameterNames = reader.readUint32();
+ for (let i = 0; i < numParameterNames && i < MAX_COLLECTION_VALUES; i++) {
+ result.parameterNames.push(reader.readString());
+ }
+}
+
+function readMapLikeSummary(result, reader, flags, depth, shapes) {
+ const shapeId = reader.readUint32();
+ const shape = shapes[shapeId];
+
+ if (!shape || shape.length <= 0) {
+ return;
+ }
+ result.class = shape[0];
+
+ const preview = {};
+ preview.kind = "MapLike";
+
+ preview.entries = [];
+ preview.size = reader.readUint32();
+ if (depth < 1) {
+ for (let i = 0; i < preview.length && i < MAX_COLLECTION_VALUES; i++) {
+ const keySummary = readValueSummary(reader, depth + 1, shapes);
+ const valueSummary = readValueSummary(reader, depth + 1, shapes);
+ preview.entries.push([
+ {
+ configurable: true,
+ enumerable: true,
+ writable: true,
+ value: keySummary,
+ },
+ {
+ configurable: true,
+ enumerable: true,
+ writable: true,
+ value: valueSummary,
+ },
+ ]);
+ }
+ }
+
+ result.preview = preview;
+}
+
+function readGenericObjectSummary(result, reader, flags, depth, shapes) {
+ const shapeId = reader.readUint32();
+ const shape = shapes[shapeId];
+
+ if (!shape || shape.length <= 0) {
+ return;
+ }
+ result.class = shape[0];
+
+ const preview = {};
+ preview.kind = "Object";
+
+ const hasDenseElements = !!(flags & GENERIC_OBJECT_HAS_DENSE_ELEMENTS);
+ const ownProperties = {};
+ let ownPropertiesLength = reader.readUint32();
+
+ if (depth < 1) {
+ for (let i = 1; i < shape.length && i <= MAX_COLLECTION_VALUES; i++) {
+ const header = reader.peekUint8();
+ const id = shape[i];
+ const desc = {
+ configurable: true,
+ enumerable: true,
+ };
+ if (header == GETTER_SETTER_MAGIC) {
+ reader.readUint8();
+ desc.get = readValueSummary(reader, depth + 1, shapes);
+ desc.set = readValueSummary(reader, depth + 1, shapes);
+ } else {
+ const nestedSummary = readValueSummary(reader, depth + 1, shapes);
+ desc.writable = true;
+ desc.value = nestedSummary;
+ }
+ ownProperties[id] = desc;
+ }
+ }
+
+ if (hasDenseElements) {
+ const elementsLength = reader.readUint32();
+ if (depth < 1) {
+ for (let i = 0; i < elementsLength && i < MAX_COLLECTION_VALUES; i++) {
+ if (reader.peekUint8() == JSVAL_TYPE_MAGIC) {
+ reader.readUint8();
+ continue;
+ }
+ ownPropertiesLength++;
+ const nestedSummary = readValueSummary(reader, depth + 1, shapes);
+ ownProperties[i] = {
+ configurable: true,
+ enumerable: true,
+ writable: true,
+ value: nestedSummary,
+ };
+ }
+ }
+ }
+
+ preview.ownProperties = ownProperties;
+ preview.ownPropertiesLength = ownPropertiesLength;
+
+ result.preview = preview;
+}
+
+function readClassFromShape(result, reader, shapes) {
+ const shapeId = reader.readUint32();
+ const shape = shapes[shapeId];
+
+ if (!shape || shape.length <= 0) {
+ return;
+ }
+ result.class = shape[0];
+}
+
+function readNodeSummary(result, reader, depth, shapes) {
+ const preview = {};
+ preview.kind = "DOMNode";
+ preview.nodeType = reader.readUint16();
+ preview.nodeName = reader.readString().toLowerCase();
+ const subkindAndIsConnected = reader.readUint8();
+ const subkind = subkindAndIsConnected & ~(1 << 7);
+ preview.isConnected = subkindAndIsConnected >> 7;
+
+ if (subkind == EXTERNAL_NODE_SUBKIND_ELEMENT) {
+ preview.attributes = {};
+ preview.attributesLength = reader.readUint32();
+ for (
+ let i = 0;
+ i < preview.attributesLength && i < MAX_COLLECTION_VALUES;
+ i++
+ ) {
+ const attrName = reader.readString();
+ const attrVal = reader.readString();
+ preview.attributes[attrName] = attrVal;
+ }
+ } else if (subkind == EXTERNAL_NODE_SUBKIND_ATTR) {
+ preview.value = reader.readString();
+ } else if (subkind == EXTERNAL_NODE_SUBKIND_DOCUMENT) {
+ preview.location = reader.readString();
+ } else if (subkind == EXTERNAL_NODE_SUBKIND_DOCUMENT_FRAGMENT) {
+ preview.childNodesLength = reader.readUint32();
+ if (depth < 1) {
+ preview.childNodes = [];
+ for (
+ let i = 0;
+ i < preview.childNodesLength && i < MAX_COLLECTION_VALUES;
+ i++
+ ) {
+ preview.childNodes.push(readValueSummary(reader, depth + 1, shapes));
+ }
+ }
+ } else if (
+ subkind == EXTERNAL_NODE_SUBKIND_TEXT ||
+ subkind == EXTERNAL_NODE_SUBKIND_COMMENT
+ ) {
+ preview.textContent = reader.readString();
+ }
+
+ result.preview = preview;
+}
+
+function readExceptionSummary(result, reader, _depth, _shapes) {
+ result.class = "Error";
+ const preview = {};
+ preview.kind = "DOMException";
+ preview.name = reader.readString();
+ preview.message = reader.readString();
+ preview.code = reader.readUint16();
+ preview.result = reader.readUint32();
+ preview.lineNumber = reader.readUint32();
+ preview.columnNumber = reader.readUint32();
+ preview.stack = reader.readString();
+ result.preview = preview;
+}
+
+function readExternalObjectSummary(result, reader, depth, shapes) {
+ readClassFromShape(result, reader, shapes);
+
+ const startIndex = reader.getIndex();
+ const size = reader.readUint32();
+ try {
+ const version = reader.readUint8();
+ if (version != EXTERNAL_SUMMARY_EXPECTED_VERSION) {
+ return;
+ }
+
+ const kind = reader.readUint8();
+ if (kind == EXTERNAL_SUMMARY_KIND_OTHER) {
+ return;
+ }
+
+ switch (kind) {
+ case EXTERNAL_SUMMARY_KIND_NODE: {
+ readNodeSummary(result, reader, depth, shapes);
+ break;
+ }
+ case EXTERNAL_SUMMARY_KIND_EXCEPTION: {
+ readExceptionSummary(result, reader, depth, shapes);
+ break;
+ }
+ default:
+ }
+ } finally {
+ reader.setIndex(startIndex + size);
+ }
+}
+
+function readErrorObjectSummary(result, reader, depth, shapes) {
+ const shapeId = reader.readUint32();
+ const shape = shapes[shapeId];
+
+ if (!shape || shape.length <= 0) {
+ return;
+ }
+
+ const preview = {};
+ result.type = "object";
+ result.class = shape[0];
+ result.isError = true;
+ preview.kind = "Error";
+ preview.name = reader.readString();
+ preview.message = reader.readString();
+ preview.stack = reader.readString();
+ preview.fileName = reader.readString();
+ preview.lineNumber = reader.readUint32();
+ preview.columnNumber = reader.readUint32();
+ result.preview = preview;
+}
+
+function readObjectSummary(reader, flags, depth, shapes) {
+ const result = {
+ type: "object",
+ class: undefined,
+ ownPropertyLength: 0,
+ isError: false,
+ extensible: false,
+ sealed: false,
+ frozen: false,
+ };
+
+ const kind = reader.readUint8();
+ switch (kind) {
+ case OBJECT_KIND_NOT_IMPLEMENTED:
+ readClassFromShape(result, reader, shapes);
+ break;
+ case OBJECT_KIND_ARRAY_LIKE:
+ readArrayLikeSummary(result, reader, flags, depth, shapes);
+ break;
+ case OBJECT_KIND_MAP_LIKE:
+ readMapLikeSummary(result, reader, flags, depth, shapes);
+ break;
+ case OBJECT_KIND_FUNCTION:
+ readFunctionSummary(result, reader);
+ break;
+ case OBJECT_KIND_EXTERNAL:
+ readExternalObjectSummary(result, reader, depth, shapes);
+ break;
+ case OBJECT_KIND_ERROR:
+ readErrorObjectSummary(result, reader, depth, shapes);
+ break;
+ case OBJECT_KIND_WRAPPED_PRIMITIVE_OBJECT: {
+ result.wrappedValue = readValueSummary(reader, depth, shapes);
+ readGenericObjectSummary(result, reader, flags, depth, shapes);
+ break;
+ }
+ case OBJECT_KIND_GENERIC_OBJECT: {
+ readGenericObjectSummary(result, reader, flags, depth, shapes);
+ break;
+ }
+ case OBJECT_KIND_PROXY_OBJECT: {
+ readClassFromShape(result, reader, shapes);
+ result.preview = {
+ kind: "Object",
+ ownProperties: Object.create(null),
+ ownPropertiesLength: 0,
+ };
+ break;
+ }
+ default:
+ throw new Error("Bad object kind");
+ }
+
+ return result;
+}
+
+function readValueSummary(reader, depth, shapes) {
+ const header = reader.readUint8();
+ const type = header & 0x0f;
+ const flags = (header & 0xf0) >> 4;
+ switch (type) {
+ case JSVAL_TYPE_DOUBLE:
+ if (flags == NUMBER_IS_OUT_OF_LINE_MAGIC) {
+ const value = reader.readFloat64();
+ if (value === Infinity) {
+ return { type: "Infinity" };
+ } else if (value === -Infinity) {
+ return { type: "-Infinity" };
+ } else if (Number.isNaN(value)) {
+ return { type: "NaN" };
+ } else if (!value && 1 / value === -Infinity) {
+ return { type: "-0" };
+ }
+ return value;
+ }
+ return 0;
+
+ case JSVAL_TYPE_INT32:
+ if (flags == NUMBER_IS_OUT_OF_LINE_MAGIC) {
+ return reader.readInt32();
+ }
+ return flags + MIN_INLINE_INT;
+
+ case JSVAL_TYPE_BOOLEAN:
+ return !!flags;
+ case JSVAL_TYPE_NULL:
+ return { type: "null" };
+ case JSVAL_TYPE_UNDEFINED:
+ return { type: "undefined" };
+ case JSVAL_TYPE_SYMBOL:
+ return {
+ type: "symbol",
+ name: reader.readString(),
+ };
+ case JSVAL_TYPE_BIGINT:
+ return {
+ type: "BigInt",
+ text: reader.readString(),
+ };
+ case JSVAL_TYPE_STRING: {
+ return reader.readString();
+ }
+ case JSVAL_TYPE_OBJECT: {
+ return readObjectSummary(reader, flags, depth, shapes);
+ }
+ default:
+ throw new Error("Bad value type");
+ }
+}
+
+function getArgumentSummaries(valuesBuffer, shapes, valuesBufferIndex) {
+ if (valuesBufferIndex == ZERO_ARGUMENTS_MAGIC) {
+ return [];
+ }
+ if (valuesBufferIndex == EXPIRED_VALUES_MAGIC) {
+ return "<missing>";
+ }
+
+ let reader = new BufferReader(valuesBuffer, valuesBufferIndex);
+ let argc = reader.readUint32();
+ let args = new Array(argc);
+ for (let i = 0; i < argc && i < MAX_ARGUMENTS_TO_RECORD; i++) {
+ args[i] = readValueSummary(reader, 0, shapes);
+ }
+ return args;
+}
+
+export const ValueSummaryReader = { getArgumentSummaries };