Merge mozilla-central to autoland. a=merge on a CLOSED TREE

This commit is contained in:
Daniel Varga 2019-07-12 13:03:23 +03:00
Родитель ba0fa23495 883bfd385e
Коммит cf2048abd6
51 изменённых файлов: 680 добавлений и 180 удалений

Просмотреть файл

@ -1,5 +1,5 @@
This is the PDF.js project output, https://github.com/mozilla/pdf.js
Current extension version is: 2.2.224
Current extension version is: 2.3.13
Taken from upstream commit: a98ce9cb
Taken from upstream commit: 28326165

Просмотреть файл

@ -123,8 +123,8 @@ return /******/ (function(modules) { // webpackBootstrap
"use strict";
var pdfjsVersion = '2.2.224';
var pdfjsBuild = 'a98ce9cb';
var pdfjsVersion = '2.3.13';
var pdfjsBuild = '28326165';
var pdfjsSharedUtil = __w_pdfjs_require__(1);
@ -1304,7 +1304,7 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
return worker.messageHandler.sendWithPromise('GetDocRequest', {
docId,
apiVersion: '2.2.224',
apiVersion: '2.3.13',
source: {
data: source.data,
url: source.url,
@ -1633,7 +1633,6 @@ class PDFPageProxy {
const intentState = this.intentStates[renderingIntent];
if (!intentState.displayReadyCapability) {
intentState.receivingOperatorList = true;
intentState.displayReadyCapability = (0, _util.createPromiseCapability)();
intentState.operatorList = {
fnArray: [],
@ -1734,7 +1733,6 @@ class PDFPageProxy {
if (!intentState.opListReadCapability) {
opListTask = {};
opListTask.operatorListChanged = operatorListChanged;
intentState.receivingOperatorList = true;
intentState.opListReadCapability = (0, _util.createPromiseCapability)();
intentState.renderTasks = [];
intentState.renderTasks.push(opListTask);
@ -1833,7 +1831,7 @@ class PDFPageProxy {
_tryCleanup(resetStats = false) {
if (!this.pendingCleanup || Object.keys(this.intentStates).some(function (intent) {
const intentState = this.intentStates[intent];
return intentState.renderTasks.length !== 0 || intentState.receivingOperatorList;
return intentState.renderTasks.length !== 0 || !intentState.operatorList.lastChunk;
}, this)) {
return;
}
@ -1874,8 +1872,6 @@ class PDFPageProxy {
}
if (operatorListChunk.lastChunk) {
intentState.receivingOperatorList = false;
this._tryCleanup();
}
}
@ -2612,18 +2608,20 @@ class WorkerTransport {
const page = this.pageCache[data.pageIndex];
const intentState = page.intentStates[data.intent];
if (intentState.displayReadyCapability) {
intentState.displayReadyCapability.reject(new Error(data.error));
} else {
throw new Error(data.error);
}
if (intentState.operatorList) {
intentState.operatorList.lastChunk = true;
for (let i = 0; i < intentState.renderTasks.length; i++) {
intentState.renderTasks[i].operatorListChanged();
}
page._tryCleanup();
}
if (intentState.displayReadyCapability) {
intentState.displayReadyCapability.reject(new Error(data.error));
} else {
throw new Error(data.error);
}
}, this);
messageHandler.on('UnsupportedFeature', this._onUnsupportedFeature, this);
@ -3100,9 +3098,9 @@ const InternalRenderTask = function InternalRenderTaskClosure() {
return InternalRenderTask;
}();
const version = '2.2.224';
const version = '2.3.13';
exports.version = version;
const build = 'a98ce9cb';
const build = '28326165';
exports.build = build;
/***/ }),
@ -8642,7 +8640,7 @@ var renderTextLayer = function renderTextLayerClosure() {
this._layoutTextCtx.canvas.height = 0;
this._layoutTextCtx = null;
}
});
}).catch(() => {});
}
TextLayerRenderTask.prototype = {

Просмотреть файл

@ -123,8 +123,8 @@ return /******/ (function(modules) { // webpackBootstrap
"use strict";
const pdfjsVersion = '2.2.224';
const pdfjsBuild = 'a98ce9cb';
const pdfjsVersion = '2.3.13';
const pdfjsBuild = '28326165';
const pdfjsCoreWorker = __w_pdfjs_require__(1);
@ -240,7 +240,7 @@ var WorkerMessageHandler = {
var WorkerTasks = [];
const verbosity = (0, _util.getVerbosityLevel)();
let apiVersion = docParams.apiVersion;
let workerVersion = '2.2.224';
let workerVersion = '2.3.13';
if (apiVersion !== workerVersion) {
throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
@ -3176,22 +3176,9 @@ exports.Page = Page;
const FINGERPRINT_FIRST_BYTES = 1024;
const EMPTY_FINGERPRINT = '\x00\x00\x00\x00\x00\x00\x00' + '\x00\x00\x00\x00\x00\x00\x00\x00\x00';
function find(stream, needle, limit, backwards) {
const pos = stream.pos;
const end = stream.end;
if (pos + limit > end) {
limit = end - pos;
}
const strBuf = [];
for (let i = 0; i < limit; ++i) {
strBuf.push(String.fromCharCode(stream.getByte()));
}
const str = strBuf.join('');
stream.pos = pos;
function find(stream, needle, limit, backwards = false) {
(0, _util.assert)(limit > 0, 'The "limit" must be a positive integer.');
const str = (0, _util.bytesToString)(stream.peekBytes(limit));
const index = backwards ? str.lastIndexOf(needle) : str.indexOf(needle);
if (index === -1) {

Просмотреть файл

@ -622,6 +622,10 @@ let PDFViewerApplication = {
},
zoomIn(ticks) {
if (this.pdfViewer.isInPresentationMode) {
return;
}
let newScale = this.pdfViewer.currentScale;
do {
@ -634,6 +638,10 @@ let PDFViewerApplication = {
},
zoomOut(ticks) {
if (this.pdfViewer.isInPresentationMode) {
return;
}
let newScale = this.pdfViewer.currentScale;
do {
@ -8655,6 +8663,10 @@ class BaseViewer {
}
onePageRenderedCapability.promise.then(() => {
if (this.findController) {
this.findController.setDocument(pdfDocument);
}
if (pdfDocument.loadingParams['disableAutoFetch']) {
pagesCapability.resolve();
return;
@ -8688,10 +8700,6 @@ class BaseViewer {
source: this
});
if (this.findController) {
this.findController.setDocument(pdfDocument);
}
if (this.defaultRenderingQueue) {
this.update();
}
@ -11834,18 +11842,23 @@ function FirefoxPrintService(pdfDocument, pagesOverview, printContainer) {
FirefoxPrintService.prototype = {
layout() {
let pdfDocument = this.pdfDocument;
let printContainer = this.printContainer;
let body = document.querySelector('body');
const {
pdfDocument,
pagesOverview,
printContainer
} = this;
const body = document.querySelector('body');
body.setAttribute('data-pdfjsprinting', true);
for (let i = 0, ii = this.pagesOverview.length; i < ii; ++i) {
composePage(pdfDocument, i + 1, this.pagesOverview[i], printContainer);
for (let i = 0, ii = pagesOverview.length; i < ii; ++i) {
composePage(pdfDocument, i + 1, pagesOverview[i], printContainer);
}
},
destroy() {
this.printContainer.textContent = '';
const body = document.querySelector('body');
body.removeAttribute('data-pdfjsprinting');
}
};

Просмотреть файл

@ -20,7 +20,7 @@ origin:
# Human-readable identifier for this version/release
# Generally "version NNN", "tag SSS", "bookmark SSS"
release: version 2.2.224
release: version 2.3.13
# The package's license, where possible using the mnemonic from
# https://spdx.org/licenses/

Просмотреть файл

@ -69,6 +69,7 @@ export async function buildOriginalScopes(
const actor = (await generatedScopes).actor;
const scope = {
type: "function",
scopeKind: "",
actor,
bindings,
parent: null,

Просмотреть файл

@ -49,8 +49,6 @@ let breakpoints: { [string]: Object };
let eventBreakpoints: ?EventListenerActiveList;
let supportsWasm: boolean;
let shouldWaitForWorkers = false;
type Dependencies = {
threadFront: ThreadFront,
tabTarget: TabTarget,
@ -121,15 +119,23 @@ function listWorkerThreadFronts() {
return (Object.values(workerClients): any).map(({ thread }) => thread);
}
function forEachWorkerThread(iteratee) {
const promises = listWorkerThreadFronts().map(thread => iteratee(thread));
// Do not return promises for the caller to wait on unless a flag is set.
// Currently, worker threads are not guaranteed to respond to all requests,
// if we send a request while they are shutting down. See bug 1529163.
if (shouldWaitForWorkers) {
return Promise.all(promises);
}
function forEachThread(iteratee) {
// We have to be careful here to atomically initiate the operation on every
// thread, with no intervening await. Otherwise, other code could run and
// trigger additional thread operations. Requests on server threads will
// resolve in FIFO order, and this could result in client and server state
// going out of sync.
const mainThreadPromise = iteratee(threadFront);
const workerPromises = listWorkerThreadFronts().map(t => {
try {
iteratee(t);
} catch (e) {
// If a worker thread shuts down while sending the message then it will
// throw. Ignore these errors.
console.error(e);
}
});
return Promise.all([mainThreadPromise, ...workerPromises]);
}
function resume(thread: string): Promise<*> {
@ -186,10 +192,6 @@ function locationKey(location: BreakpointLocation) {
return `${(sourceUrl: any)}:${(sourceId: any)}:${line}:${(column: any)}`;
}
function waitForWorkers(shouldWait: boolean) {
shouldWaitForWorkers = shouldWait;
}
function detachWorkers() {
for (const thread of listWorkerThreadFronts()) {
thread.detach();
@ -217,7 +219,7 @@ function hasBreakpoint(location: BreakpointLocation) {
return !!breakpoints[locationKey(location)];
}
async function setBreakpoint(
function setBreakpoint(
location: BreakpointLocation,
options: BreakpointOptions
) {
@ -225,27 +227,14 @@ async function setBreakpoint(
options = maybeGenerateLogGroupId(options);
breakpoints[locationKey(location)] = { location, options };
// We have to be careful here to atomically initiate the setBreakpoint() call
// on every thread, with no intervening await. Otherwise, other code could run
// and change or remove the breakpoint before we finish calling setBreakpoint
// on all threads. Requests on server threads will resolve in FIFO order, and
// this could result in the breakpoint state here being out of sync with the
// breakpoints that are installed in the server.
const mainThreadPromise = threadFront.setBreakpoint(location, options);
await forEachWorkerThread(thread => thread.setBreakpoint(location, options));
await mainThreadPromise;
return forEachThread(thread => thread.setBreakpoint(location, options));
}
async function removeBreakpoint(location: PendingLocation) {
function removeBreakpoint(location: PendingLocation) {
maybeClearLogpoint((location: any));
delete breakpoints[locationKey((location: any))];
// Delay waiting on this promise, for the same reason as in setBreakpoint.
const mainThreadPromise = threadFront.removeBreakpoint(location);
await forEachWorkerThread(thread => thread.removeBreakpoint(location));
await mainThreadPromise;
return forEachThread(thread => thread.removeBreakpoint(location));
}
async function evaluateInFrame(script: Script, options: EvaluateParam) {
@ -325,20 +314,15 @@ async function getFrameScopes(frame: Frame): Promise<*> {
return sourceThreadFront.getEnvironment(frame.id);
}
async function pauseOnExceptions(
function pauseOnExceptions(
shouldPauseOnExceptions: boolean,
shouldPauseOnCaughtExceptions: boolean
): Promise<*> {
await threadFront.pauseOnExceptions(
shouldPauseOnExceptions,
// Providing opposite value because server
// uses "shouldIgnoreCaughtExceptions"
!shouldPauseOnCaughtExceptions
);
await forEachWorkerThread(thread =>
return forEachThread(thread =>
thread.pauseOnExceptions(
shouldPauseOnExceptions,
// Providing opposite value because server
// uses "shouldIgnoreCaughtExceptions"
!shouldPauseOnCaughtExceptions
)
);
@ -357,20 +341,18 @@ async function blackBox(
}
}
async function setSkipPausing(shouldSkip: boolean) {
await threadFront.skipBreakpoints(shouldSkip);
await forEachWorkerThread(thread => thread.skipBreakpoints(shouldSkip));
function setSkipPausing(shouldSkip: boolean) {
return forEachThread(thread => thread.skipBreakpoints(shouldSkip));
}
function interrupt(thread: string): Promise<*> {
return lookupThreadFront(thread).interrupt();
}
async function setEventListenerBreakpoints(ids: string[]) {
function setEventListenerBreakpoints(ids: string[]) {
eventBreakpoints = ids;
await threadFront.setActiveEventBreakpoints(ids);
await forEachWorkerThread(thread => thread.setActiveEventBreakpoints(ids));
return forEachThread(thread => thread.setActiveEventBreakpoints(ids));
}
// eslint-disable-next-line
@ -563,7 +545,6 @@ const clientCommands = {
setSkipPausing,
setEventListenerBreakpoints,
getEventListenerBreakpointTypes,
waitForWorkers,
detachWorkers,
hasWasmSupport,
lookupConsoleClient,

Просмотреть файл

@ -34,6 +34,7 @@ exports[`Frame getFrameTitle 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -86,6 +87,7 @@ exports[`Frame getFrameTitle 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -145,6 +147,7 @@ exports[`Frame library frame 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -198,6 +201,7 @@ exports[`Frame library frame 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -256,6 +260,7 @@ exports[`Frame user frame (not selected) 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -308,6 +313,7 @@ exports[`Frame user frame (not selected) 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -366,6 +372,7 @@ exports[`Frame user frame 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -418,6 +425,7 @@ exports[`Frame user frame 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {

Просмотреть файл

@ -31,6 +31,7 @@ exports[`Frames Blackboxed Frames filters blackboxed frames 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -75,6 +76,7 @@ exports[`Frames Blackboxed Frames filters blackboxed frames 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -121,6 +123,7 @@ exports[`Frames Blackboxed Frames filters blackboxed frames 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -165,6 +168,7 @@ exports[`Frames Blackboxed Frames filters blackboxed frames 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {

Просмотреть файл

@ -38,6 +38,7 @@ exports[`Group displays a group 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -110,6 +111,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -181,6 +183,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -227,6 +230,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -286,6 +290,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -332,6 +337,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -391,6 +397,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -437,6 +444,7 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -501,6 +509,7 @@ exports[`Group renders group with anonymous functions 1`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -573,6 +582,7 @@ exports[`Group renders group with anonymous functions 2`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -644,6 +654,7 @@ exports[`Group renders group with anonymous functions 2`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -689,6 +700,7 @@ exports[`Group renders group with anonymous functions 2`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -748,6 +760,7 @@ exports[`Group renders group with anonymous functions 2`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -793,6 +806,7 @@ exports[`Group renders group with anonymous functions 2`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -852,6 +866,7 @@ exports[`Group renders group with anonymous functions 2`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {
@ -897,6 +912,7 @@ exports[`Group renders group with anonymous functions 2`] = `
"function": null,
"object": null,
"parent": null,
"scopeKind": "",
"type": "block",
},
"source": Object {

Просмотреть файл

@ -457,6 +457,7 @@ export type Scope = {|
parameterNames: string[],
},
type: string,
scopeKind: string,
|};
export type MainThread = {

Просмотреть файл

@ -301,6 +301,7 @@ function generateClientScope(
parent: acc,
actor: `originalActor${i}`,
type: orig.type,
scopeKind: orig.scopeKind,
bindings: {
arguments: [],
variables,

Просмотреть файл

@ -15,6 +15,7 @@ import type { NamedValue } from "./types";
export type RenderableScope = {
type: $ElementType<Scope, "type">,
scopeKind: $ElementType<Scope, "scopeKind">,
actor: $ElementType<Scope, "actor">,
bindings: $ElementType<Scope, "bindings">,
parent: ?RenderableScope,
@ -109,3 +110,22 @@ export function getScope(
return null;
}
export function mergeScopes(
scope: RenderableScope,
parentScope: RenderableScope,
item: NamedValue,
parentItem: NamedValue
) {
if (scope.scopeKind == "function lexical" && parentScope.type == "function") {
const contents = (item.contents: any).concat(parentItem.contents);
contents.sort((a, b) => a.name.localeCompare(b.name));
return {
name: parentItem.name,
path: parentItem.path,
contents,
type: NODE_TYPES.BLOCK,
};
}
}

Просмотреть файл

@ -4,7 +4,7 @@
// @flow
import { getScope, type RenderableScope } from "./getScope";
import { getScope, mergeScopes, type RenderableScope } from "./getScope";
import type { Frame, Why, BindingContents } from "../../../types";
@ -32,9 +32,11 @@ export function getScopes(
let scope = frameScopes;
let scopeIndex = 1;
let prev = null,
prevItem = null;
while (scope) {
const scopeItem = getScope(
let scopeItem = getScope(
scope,
selectedFrame,
frameScopes,
@ -43,8 +45,16 @@ export function getScopes(
);
if (scopeItem) {
const mergedItem =
prev && prevItem ? mergeScopes(prev, scope, prevItem, scopeItem) : null;
if (mergedItem) {
scopeItem = mergedItem;
scopes.pop();
}
scopes.push(scopeItem);
}
prev = scope;
prevItem = scopeItem;
scopeIndex++;
scope = scope.parent;
}

Просмотреть файл

@ -125,6 +125,7 @@ function makeMockScope(
object: null,
function: null,
type,
scopeKind: "",
};
}

Просмотреть файл

@ -77,6 +77,7 @@ function findScopes(
return found.map(i => {
return {
type: i.type,
scopeKind: i.scopeKind,
displayName: i.displayName,
start: i.start,
end: i.end,

Просмотреть файл

@ -118,6 +118,7 @@ export type ScopeBindingList = {
export type SourceScope = {
type: "object" | "function" | "block",
scopeKind: string,
displayName: string,
start: SourceLocation,
end: SourceLocation,
@ -222,6 +223,7 @@ function toParsedScopes(
scope.type === "module" || scope.type === "function-body"
? "block"
: scope.type,
scopeKind: "",
displayName: scope.displayName,
bindings: scope.bindings,
children: toParsedScopes(scope.children, sourceId),

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -674,6 +674,7 @@ support-files =
examples/doc-scopes-xrays.html
examples/doc-message-run-to-completion.html
examples/doc-message-run-to-completion-frame.html
examples/doc-merge-scopes.html
[browser_dbg-asm.js]
[browser_dbg-audiocontext.js]
@ -813,4 +814,5 @@ skip-if = (os == 'linux' && debug) || (os == 'linux' && asan) || ccov #Bug 1456
[browser_dbg-old-breakpoint.js]
[browser_dbg-idb-run-to-completion.js]
[browser_dbg-scopes-xrays.js]
[browser_dbg-merge-scopes.js]
[browser_dbg-message-run-to-completion.js]

Просмотреть файл

@ -0,0 +1,38 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
function getLabel(dbg, index) {
return findElement(dbg, "scopeNode", index).innerText;
}
function expectLabels(dbg, array) {
for (let i = 0; i < array.length; i++) {
is(getLabel(dbg, i + 1), array[i], `Correct label ${array[i]} for index ${i + 1}`);
}
}
// Test that adjacent scopes are merged together as expected.
add_task(async function() {
const dbg = await initDebugger("doc-merge-scopes.html");
invokeInTab("run");
await waitForPaused(dbg, "doc-merge-scopes.html");
// Function body and function lexical scopes are merged together.
expectLabels(dbg, ["first", "<this>", "arguments", "x", "y", "z"]);
await resume(dbg);
await waitForPaused(dbg);
// Function body and inner lexical scopes are not merged together.
await toggleScopeNode(dbg, 4);
expectLabels(dbg, ["Block", "<this>", "y", "second", "arguments", "x"]);
await resume(dbg);
await waitForPaused(dbg);
// When there is a function body, function lexical, and inner lexical scope,
// the first two are merged together.
await toggleScopeNode(dbg, 4);
expectLabels(dbg, ["Block", "<this>", "z", "third", "arguments", "v", "x", "y"]);
});

Просмотреть файл

@ -33,41 +33,41 @@ add_task(async function() {
'The second element in the scope panel is "<this>"'
);
is(
getScopeNodeLabel(dbg, 3),
getScopeNodeLabel(dbg, 4),
"phonebook",
'The third element in the scope panel is "phonebook"'
'The fourth element in the scope panel is "phonebook"'
);
info("Expand `phonebook`");
await expandNode(dbg, 3);
is(
getScopeNodeLabel(dbg, 4),
"S",
'The fourth element in the scope panel is "S"'
);
info("Expand `S`");
await expandNode(dbg, 4);
is(
getScopeNodeLabel(dbg, 5),
"sarah",
'The fifth element in the scope panel is "sarah"'
);
is(
getScopeNodeLabel(dbg, 6),
"serena",
'The sixth element in the scope panel is "serena"'
"S",
'The fifth element in the scope panel is "S"'
);
info("Expand `sarah`");
info("Expand `S`");
await expandNode(dbg, 5);
is(
getScopeNodeLabel(dbg, 6),
"lastName",
'The sixth element in the scope panel is now "lastName"'
"sarah",
'The sixth element in the scope panel is "sarah"'
);
is(
getScopeNodeValue(dbg, 6),
getScopeNodeLabel(dbg, 7),
"serena",
'The seventh element in the scope panel is "serena"'
);
info("Expand `sarah`");
await expandNode(dbg, 6);
is(
getScopeNodeLabel(dbg, 7),
"lastName",
'The seventh element in the scope panel is now "lastName"'
);
is(
getScopeNodeValue(dbg, 7),
'"Doe"',
'The "lastName" element has the expected "Doe" value'
);
@ -81,8 +81,8 @@ add_task(async function() {
'The second element in the scope panel is "<this>"'
);
is(
getScopeNodeLabel(dbg, 3),
getScopeNodeLabel(dbg, 4),
"phonebook",
'The third element in the scope panel is "phonebook"'
'The fourth element in the scope panel is "phonebook"'
);
});

Просмотреть файл

@ -9,11 +9,6 @@ add_task(async function() {
const workerSource = findSource(dbg, "simple-worker.js");
// NOTE: by default we do not wait on worker
// commands to complete because the thread could be
// shutting down.
dbg.client.waitForWorkers(true);
await selectSource(dbg, "simple-worker.js");
await waitForSelectedSource(dbg, "simple-worker.js");
await addBreakpoint(dbg, workerSource, 1);

Просмотреть файл

@ -44,11 +44,6 @@ add_task(async function() {
const dbg = await initDebugger("doc-windowless-workers.html");
const mainThread = dbg.toolbox.threadFront.actor;
// NOTE: by default we do not wait on worker
// commands to complete because the thread could be
// shutting down.
dbg.client.waitForWorkers(true);
const workers = await getWorkers(dbg);
ok(workers.length == 2, "Got two workers");
const thread1 = workers[0].actor;

Просмотреть файл

@ -0,0 +1,29 @@
<script>
function run() {
setTimeout(first);
setTimeout(second);
setTimeout(third);
}
function first(x) {
let y = 0;
var z = 1;
debugger;
}
function second(x) {
if (second) {
let y = 0;
debugger;
}
}
function third(x) {
let y = 1;
if (y) {
let z = 0;
var v = 2;
debugger;
}
}
</script>

Просмотреть файл

@ -531,7 +531,6 @@ async function initDebugger(url, ...sources) {
await clearDebuggerPreferences();
const toolbox = await openNewTabAndToolbox(EXAMPLE_URL + url, "jsdebugger");
const dbg = createDebuggerContext(toolbox);
dbg.client.waitForWorkers(false);
await waitForSources(dbg, ...sources);
return dbg;

Просмотреть файл

@ -49,6 +49,8 @@ const EnvironmentActor = ActorClassWithSpec(environmentSpec, {
form.type = this.obj.type;
}
form.scopeKind = this.obj.scopeKind;
// Does this environment have a parent?
if (this.obj.parent) {
form.parent = this.threadActor

Просмотреть файл

@ -37,7 +37,8 @@ class BasicRenderingContext2D {
virtual void Transform(double aM11, double aM12, double aM21, double aM22,
double aDx, double aDy,
mozilla::ErrorResult& aError) = 0;
virtual already_AddRefed<DOMMatrix> GetTransform(mozilla::ErrorResult& aError) = 0;
virtual already_AddRefed<DOMMatrix> GetTransform(
mozilla::ErrorResult& aError) = 0;
virtual void SetTransform(double aM11, double aM12, double aM21, double aM22,
double aDx, double aDy,
mozilla::ErrorResult& aError) = 0;

Просмотреть файл

@ -95,7 +95,8 @@ class CanvasRenderingContext2D final : public nsICanvasRenderingContextInternal,
void Translate(double aX, double aY, mozilla::ErrorResult& aError) override;
void Transform(double aM11, double aM12, double aM21, double aM22, double aDx,
double aDy, mozilla::ErrorResult& aError) override;
already_AddRefed<DOMMatrix> GetTransform(mozilla::ErrorResult& aError) override;
already_AddRefed<DOMMatrix> GetTransform(
mozilla::ErrorResult& aError) override;
void SetTransform(double aM11, double aM12, double aM21, double aM22,
double aDx, double aDy,
mozilla::ErrorResult& aError) override;

Просмотреть файл

@ -75,8 +75,7 @@ class APZTestData {
}
void RecordHitResult(const ScreenPoint& aPoint,
const mozilla::gfx::CompositorHitTestInfo& aResult,
const LayersId& aLayersId,
const ViewID& aScrollId) {
const LayersId& aLayersId, const ViewID& aScrollId) {
mHitResults.AppendElement(HitResult{aPoint, aResult, aLayersId, aScrollId});
}
void RecordAdditionalData(const std::string& aKey,

Просмотреть файл

@ -105,8 +105,8 @@ already_AddRefed<gfx::DrawTarget> CanvasChild::CreateDrawTarget(
RefPtr<gfx::DrawTarget> dummyDt = gfx::Factory::CreateDrawTarget(
gfx::BackendType::SKIA, gfx::IntSize(1, 1), aFormat);
RefPtr<gfx::DrawTarget> dt =
MakeAndAddRef<gfx::DrawTargetRecording>(mRecorder, dummyDt, gfx::IntRect(gfx::IntPoint(0, 0), aSize));
RefPtr<gfx::DrawTarget> dt = MakeAndAddRef<gfx::DrawTargetRecording>(
mRecorder, dummyDt, gfx::IntRect(gfx::IntPoint(0, 0), aSize));
return dt.forget();
}

Просмотреть файл

@ -676,8 +676,8 @@ struct DIGroup {
RefPtr<gfx::DrawTarget> dummyDt = gfx::Factory::CreateDrawTarget(
gfx::BackendType::SKIA, gfx::IntSize(1, 1), format);
RefPtr<gfx::DrawTarget> dt =
gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, IntRect(IntPoint(0, 0), dtSize));
RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(
recorder, dummyDt, IntRect(IntPoint(0, 0), dtSize));
// Setup the gfxContext
RefPtr<gfxContext> context = gfxContext::CreateOrNull(dt);
GP("ctx-offset %f %f\n", bounds.x, bounds.y);
@ -1336,11 +1336,11 @@ void Grouper::ConstructItemInsideInactive(
// still
aGroup->ComputeGeometryChange(aItem, data, mTransform, mDisplayListBuilder);
// Temporarily restrict the image bounds to the bounds of the container so that
// clipped children within the container know about the clip. This ensures
// that the bounds passed to FlushItem are contained in the bounds of the clip
// so that we don't include items in the recording without including their
// corresponding clipping items.
// Temporarily restrict the image bounds to the bounds of the container so
// that clipped children within the container know about the clip. This
// ensures that the bounds passed to FlushItem are contained in the bounds of
// the clip so that we don't include items in the recording without including
// their corresponding clipping items.
IntRect oldClippedImageBounds = aGroup->mClippedImageBounds;
aGroup->mClippedImageBounds =
aGroup->mClippedImageBounds.Intersect(data->mRect);
@ -1607,10 +1607,9 @@ void WebRenderCommandBuilder::BuildWebRenderCommands(
}
}
if (ShouldDumpDisplayList(aDisplayListBuilder)) {
mBuilderDumpIndex[aBuilder.GetRenderRoot()] =
aBuilder.Dump(mDumpIndent + 1,
Some(mBuilderDumpIndex[aBuilder.GetRenderRoot()]),
Nothing());
mBuilderDumpIndex[aBuilder.GetRenderRoot()] = aBuilder.Dump(
mDumpIndent + 1, Some(mBuilderDumpIndex[aBuilder.GetRenderRoot()]),
Nothing());
}
MOZ_ASSERT(mRootStackingContexts == nullptr);
AutoRestore<wr::RenderRootArray<Maybe<StackingContextHelper>>*> rootScs(
@ -1684,10 +1683,9 @@ void WebRenderCommandBuilder::CreateWebRenderCommandsFromDisplayList(
if (dumpEnabled) {
// If we're inside a nested display list, print the WR DL items from the
// wrapper item before we start processing the nested items.
mBuilderDumpIndex[aBuilder.GetRenderRoot()] =
aBuilder.Dump(mDumpIndent + 1,
Some(mBuilderDumpIndex[aBuilder.GetRenderRoot()]),
Nothing());
mBuilderDumpIndex[aBuilder.GetRenderRoot()] = aBuilder.Dump(
mDumpIndent + 1, Some(mBuilderDumpIndex[aBuilder.GetRenderRoot()]),
Nothing());
}
mDumpIndent++;
@ -1796,10 +1794,9 @@ void WebRenderCommandBuilder::CreateWebRenderCommandsFromDisplayList(
}
if (dumpEnabled) {
mBuilderDumpIndex[aBuilder.GetRenderRoot()] =
aBuilder.Dump(mDumpIndent + 1,
Some(mBuilderDumpIndex[aBuilder.GetRenderRoot()]),
Nothing());
mBuilderDumpIndex[aBuilder.GetRenderRoot()] = aBuilder.Dump(
mDumpIndent + 1, Some(mBuilderDumpIndex[aBuilder.GetRenderRoot()]),
Nothing());
}
}
@ -2492,8 +2489,8 @@ Maybe<wr::ImageMask> WebRenderCommandBuilder::BuildWrMaskImage(
RefPtr<DrawTarget> dummyDt = Factory::CreateDrawTarget(
BackendType::SKIA, IntSize(1, 1), SurfaceFormat::A8);
RefPtr<DrawTarget> dt =
Factory::CreateRecordingDrawTarget(recorder, dummyDt, IntRect(IntPoint(0, 0), size));
RefPtr<DrawTarget> dt = Factory::CreateRecordingDrawTarget(
recorder, dummyDt, IntRect(IntPoint(0, 0), size));
RefPtr<gfxContext> context = gfxContext::CreateOrNull(dt);
MOZ_ASSERT(context);

Просмотреть файл

@ -343,8 +343,8 @@ void WebRenderLayerManager::EndTransactionWithoutLayer(
mWebRenderCommandBuilder.BuildWebRenderCommands(
builder, resourceUpdates, aDisplayList, aDisplayListBuilder,
mScrollDatas, std::move(aFilters));
builderDumpIndex = mWebRenderCommandBuilder.GetBuilderDumpIndex(
builder.GetRenderRoot());
builderDumpIndex =
mWebRenderCommandBuilder.GetBuilderDumpIndex(builder.GetRenderRoot());
containsSVGGroup = mWebRenderCommandBuilder.GetContainsSVGGroup();
} else {
// ViewToPaint does not have frame yet, then render only background clolor.

Просмотреть файл

@ -885,9 +885,7 @@ WebRenderThreadPool::WebRenderThreadPool() {
mThreadPool = wr_thread_pool_new();
}
WebRenderThreadPool::~WebRenderThreadPool() {
Release();
}
WebRenderThreadPool::~WebRenderThreadPool() { Release(); }
void WebRenderThreadPool::Release() {
if (mThreadPool) {
@ -896,7 +894,6 @@ void WebRenderThreadPool::Release() {
}
}
WebRenderProgramCache::WebRenderProgramCache(wr::WrThreadPool* aThreadPool) {
MOZ_ASSERT(aThreadPool);

Просмотреть файл

@ -12925,6 +12925,29 @@ bool DebuggerEnvironment::typeGetter(JSContext* cx, unsigned argc, Value* vp) {
return true;
}
bool DebuggerEnvironment::scopeKindGetter(JSContext* cx, unsigned argc,
Value* vp) {
THIS_DEBUGGER_ENVIRONMENT(cx, argc, vp, "get scopeKind", args, environment);
if (!environment->requireDebuggee(cx)) {
return false;
}
Maybe<ScopeKind> kind = environment->scopeKind();
if (kind.isSome()) {
const char* s = ScopeKindString(*kind);
JSAtom* str = Atomize(cx, s, strlen(s), PinAtom);
if (!str) {
return false;
}
args.rval().setString(str);
} else {
args.rval().setNull();
}
return true;
}
/* static */
bool DebuggerEnvironment::parentGetter(JSContext* cx, unsigned argc,
Value* vp) {
@ -13110,6 +13133,7 @@ bool DebuggerEnvironment::requireDebuggee(JSContext* cx) const {
const JSPropertySpec DebuggerEnvironment::properties_[] = {
JS_PSG("type", DebuggerEnvironment::typeGetter, 0),
JS_PSG("scopeKind", DebuggerEnvironment::scopeKindGetter, 0),
JS_PSG("parent", DebuggerEnvironment::parentGetter, 0),
JS_PSG("object", DebuggerEnvironment::objectGetter, 0),
JS_PSG("callee", DebuggerEnvironment::calleeGetter, 0),
@ -13163,6 +13187,15 @@ DebuggerEnvironmentType DebuggerEnvironment::type() const {
return DebuggerEnvironmentType::Object;
}
mozilla::Maybe<ScopeKind> DebuggerEnvironment::scopeKind() const {
if (!referent()->is<DebugEnvironmentProxy>()) {
return Nothing();
}
EnvironmentObject& env = referent()->as<DebugEnvironmentProxy>().environment();
Scope* scope = GetEnvironmentScope(env);
return scope ? Some(scope->kind()) : Nothing();
}
bool DebuggerEnvironment::getParent(
JSContext* cx, MutableHandleDebuggerEnvironment result) const {
// Don't bother switching compartments just to get env's parent.

Просмотреть файл

@ -1369,6 +1369,7 @@ class DebuggerEnvironment : public NativeObject {
HandleNativeObject debugger);
DebuggerEnvironmentType type() const;
mozilla::Maybe<ScopeKind> scopeKind() const;
MOZ_MUST_USE bool getParent(JSContext* cx,
MutableHandleDebuggerEnvironment result) const;
MOZ_MUST_USE bool getObject(JSContext* cx,
@ -1411,6 +1412,8 @@ class DebuggerEnvironment : public NativeObject {
static MOZ_MUST_USE bool construct(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool typeGetter(JSContext* cx, unsigned argc, Value* vp);
static MOZ_MUST_USE bool scopeKindGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool parentGetter(JSContext* cx, unsigned argc,
Value* vp);
static MOZ_MUST_USE bool objectGetter(JSContext* cx, unsigned argc,

Просмотреть файл

@ -75,6 +75,20 @@ properties from its prototype:
* "with", indicating that the environment was introduced by a `with`
statement.
`scopeKind`
: If this is a declarative environment, a string describing the kind of scope
which this environment is associated with, or `null` for other types of
environments. There is an assortment of possible scope kinds which can be
generated, with a selection of possible values below. Unlike the type
accessor, the categorization this performs is specific to SpiderMonkey's
implementation, and not derived from distinctions made in the ECMAScript
language specification.
* "function", indicating the top level body scope of a function for
arguments and 'var' variables.
* "function lexical", indicating the top level lexical scope in a function.
`parent`
: The environment that encloses this one (the "outer" environment, in
ECMAScript terminology), or `null` if this is the outermost environment.

Просмотреть файл

@ -4894,7 +4894,7 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::emitLexicalScope(
? ScopeKind::SimpleCatch
: ScopeKind::Catch;
} else {
kind = ScopeKind::Lexical;
kind = lexicalScope->kind();
}
if (!lse.emitScope(kind, lexicalScope->scopeBindings())) {

Просмотреть файл

@ -213,6 +213,7 @@ NameLocation EmitterScope::searchInEnclosingScope(JSAtom* name, Scope* scope,
case ScopeKind::StrictNamedLambda:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
case ScopeKind::FunctionLexical:
if (hasEnv) {
for (BindingIter bi(si.scope()); bi; bi++) {
if (bi.name() != name) {
@ -1014,6 +1015,7 @@ bool EmitterScope::leave(BytecodeEmitter* bce, bool nonLocal) {
case ScopeKind::Lexical:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
case ScopeKind::FunctionLexical:
if (!bce->emit1(hasEnvironment() ? JSOP_POPLEXICALENV
: JSOP_DEBUGLEAVELEXICALENV)) {
return false;

Просмотреть файл

@ -833,8 +833,8 @@ class FullParseHandler {
}
LexicalScopeNodeType newLexicalScope(LexicalScope::Data* bindings,
Node body) {
return new_<LexicalScopeNode>(bindings, body);
Node body, ScopeKind kind = ScopeKind::Lexical) {
return new_<LexicalScopeNode>(bindings, body, kind);
}
CallNodeType newNewExpression(uint32_t begin, Node ctor, Node args,

Просмотреть файл

@ -1544,12 +1544,15 @@ class BigIntLiteral : public ParseNode {
class LexicalScopeNode : public ParseNode {
LexicalScope::Data* bindings;
ParseNode* body;
ScopeKind kind_;
public:
LexicalScopeNode(LexicalScope::Data* bindings, ParseNode* body)
LexicalScopeNode(LexicalScope::Data* bindings, ParseNode* body,
ScopeKind kind = ScopeKind::Lexical)
: ParseNode(ParseNodeKind::LexicalScope, body->pn_pos),
bindings(bindings),
body(body) {}
body(body),
kind_(kind) {}
static bool test(const ParseNode& node) {
return node.isKind(ParseNodeKind::LexicalScope);
@ -1580,6 +1583,8 @@ class LexicalScopeNode : public ParseNode {
void setScopeBody(ParseNode* body) { this->body = body; }
bool isEmptyScope() const { return !bindings; }
ScopeKind kind() const { return kind_; }
};
class LabeledStatement : public NameNode {

Просмотреть файл

@ -1312,7 +1312,7 @@ Maybe<LexicalScope::Data*> ParserBase::newLexicalScopeData(
template <>
SyntaxParseHandler::LexicalScopeNodeType
PerHandlerParser<SyntaxParseHandler>::finishLexicalScope(
ParseContext::Scope& scope, Node body) {
ParseContext::Scope& scope, Node body, ScopeKind kind) {
if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
return null();
}
@ -1322,7 +1322,7 @@ PerHandlerParser<SyntaxParseHandler>::finishLexicalScope(
template <>
LexicalScopeNode* PerHandlerParser<FullParseHandler>::finishLexicalScope(
ParseContext::Scope& scope, ParseNode* body) {
ParseContext::Scope& scope, ParseNode* body, ScopeKind kind) {
if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
return nullptr;
}
@ -1332,7 +1332,7 @@ LexicalScopeNode* PerHandlerParser<FullParseHandler>::finishLexicalScope(
return nullptr;
}
return handler_.newLexicalScope(*bindings, body);
return handler_.newLexicalScope(*bindings, body, kind);
}
template <typename Unit>
@ -1959,7 +1959,7 @@ GeneralParser<ParseHandler, Unit>::functionBody(InHandling inHandling,
}
}
return finishLexicalScope(pc_->varScope(), body);
return finishLexicalScope(pc_->varScope(), body, ScopeKind::FunctionLexical);
}
JSFunction* AllocNewFunction(JSContext* cx, HandleAtom atom,
@ -7320,7 +7320,8 @@ GeneralParser<ParseHandler, Unit>::synthesizeConstructor(
handler_.addStatementToList(stmtList, exprStatement);
}
auto initializerBody = finishLexicalScope(pc_->varScope(), stmtList);
auto initializerBody = finishLexicalScope(pc_->varScope(), stmtList,
ScopeKind::FunctionLexical);
if (!initializerBody) {
return null();
}
@ -7528,7 +7529,8 @@ GeneralParser<ParseHandler, Unit>::fieldInitializerOpt(
// Set the function's body to the field assignment.
LexicalScopeNodeType initializerBody =
finishLexicalScope(pc_->varScope(), statementList);
finishLexicalScope(pc_->varScope(), statementList,
ScopeKind::FunctionLexical);
if (!initializerBody) {
return null();
}

Просмотреть файл

@ -549,7 +549,8 @@ class MOZ_STACK_CLASS PerHandlerParser : public ParserBase {
bool finishFunctionScopes(bool isStandaloneFunction);
LexicalScopeNodeType finishLexicalScope(ParseContext::Scope& scope,
Node body);
Node body,
ScopeKind kind = ScopeKind::Lexical);
bool finishFunction(
bool isStandaloneFunction = false,
IsFieldInitializer isFieldInitializer = IsFieldInitializer::No);

Просмотреть файл

@ -1283,7 +1283,8 @@ inline void js::GCMarker::eagerlyMarkChildren(Scope* scope) {
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
case ScopeKind::NamedLambda:
case ScopeKind::StrictNamedLambda: {
case ScopeKind::StrictNamedLambda:
case ScopeKind::FunctionLexical: {
LexicalScope::Data& data = scope->as<LexicalScope>().data();
names = &data.trailingNames;
length = data.length;

Просмотреть файл

@ -0,0 +1,26 @@
// Environment.prototype.scopeKind produces expected values.
load(libdir + 'eqArrayHelper.js');
var g = newGlobal({newCompartment: true});
var dbg = Debugger(g);
function getScopeKinds(text) {
const kinds = [];
dbg.onDebuggerStatement = frame => {
let env = frame.environment;
while (env) {
kinds.push(env.scopeKind);
env = env.parent;
}
};
g.eval(text);
return kinds;
}
assertEqArray(getScopeKinds("function f(x) { debugger; }; f()"),
["function", null, null]);
assertEqArray(getScopeKinds("function f(x) { let y = 0; debugger; }; f()"),
["function lexical", "function", null, null]);
assertEqArray(getScopeKinds("function f(x) { let y = 0; with(x) { debugger; } } f({})"),
[null, "function lexical", "function", null, null]);

Просмотреть файл

@ -1806,6 +1806,8 @@ class DebugEnvironmentProxyHandler : public BaseProxyHandler {
return nullptr;
}
friend Scope* js::GetEnvironmentScope(const JSObject& env);
/*
* In theory, every non-arrow function scope contains an 'arguments'
* bindings. However, the engine only adds a binding if 'arguments' is
@ -2380,6 +2382,10 @@ class DebugEnvironmentProxyHandler : public BaseProxyHandler {
} /* anonymous namespace */
Scope* js::GetEnvironmentScope(const JSObject& env) {
return DebugEnvironmentProxyHandler::getEnvironmentScope(env);
}
template <>
bool JSObject::is<js::DebugEnvironmentProxy>() const {
return IsDerivedProxyObject(this, &DebugEnvironmentProxyHandler::singleton);

Просмотреть файл

@ -890,6 +890,7 @@ extern JSObject* GetDebugEnvironmentForFrame(JSContext* cx,
jsbytecode* pc);
extern JSObject* GetDebugEnvironmentForGlobalLexicalEnvironment(JSContext* cx);
extern Scope* GetEnvironmentScope(const JSObject& env);
/* Provides debugger access to a environment. */
class DebugEnvironmentProxy : public ProxyObject {

Просмотреть файл

@ -973,6 +973,7 @@ static void PopEnvironment(JSContext* cx, EnvironmentIter& ei) {
case ScopeKind::Catch:
case ScopeKind::NamedLambda:
case ScopeKind::StrictNamedLambda:
case ScopeKind::FunctionLexical:
if (MOZ_UNLIKELY(cx->realm()->isDebuggee())) {
DebugEnvironments::onPopLexical(cx, ei);
}

Просмотреть файл

@ -519,6 +519,7 @@ static XDRResult XDRScope(XDRState<mode>* xdr, js::PrivateScriptData* data,
case ScopeKind::Catch:
case ScopeKind::NamedLambda:
case ScopeKind::StrictNamedLambda:
case ScopeKind::FunctionLexical:
MOZ_TRY(LexicalScope::XDR(xdr, scopeKind, enclosing, scope));
break;
case ScopeKind::With:

Просмотреть файл

@ -61,6 +61,8 @@ const char* js::ScopeKindString(ScopeKind kind) {
return "named lambda";
case ScopeKind::StrictNamedLambda:
return "strict named lambda";
case ScopeKind::FunctionLexical:
return "function lexical";
case ScopeKind::With:
return "with";
case ScopeKind::Eval:
@ -417,7 +419,8 @@ Scope* Scope::clone(JSContext* cx, HandleScope scope, HandleScope enclosing) {
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
case ScopeKind::NamedLambda:
case ScopeKind::StrictNamedLambda: {
case ScopeKind::StrictNamedLambda:
case ScopeKind::FunctionLexical: {
Rooted<UniquePtr<LexicalScope::Data>> dataClone(cx);
dataClone =
CopyScopeData<LexicalScope>(cx, &scope->as<LexicalScope>().data());
@ -490,6 +493,7 @@ uint32_t LexicalScope::firstFrameSlot() const {
case ScopeKind::Lexical:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
case ScopeKind::FunctionLexical:
// For intra-frame scopes, find the enclosing scope's next frame slot.
return nextFrameSlot(enclosing());
case ScopeKind::NamedLambda:
@ -515,6 +519,7 @@ uint32_t LexicalScope::nextFrameSlot(Scope* scope) {
case ScopeKind::Lexical:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
case ScopeKind::FunctionLexical:
return si.scope()->as<LexicalScope>().nextFrameSlot();
case ScopeKind::NamedLambda:
case ScopeKind::StrictNamedLambda:
@ -1416,6 +1421,7 @@ BindingIter::BindingIter(Scope* scope) {
case ScopeKind::Lexical:
case ScopeKind::SimpleCatch:
case ScopeKind::Catch:
case ScopeKind::FunctionLexical:
init(scope->as<LexicalScope>().data(),
scope->as<LexicalScope>().firstFrameSlot(), 0);
break;

Просмотреть файл

@ -60,6 +60,7 @@ enum class ScopeKind : uint8_t {
Catch,
NamedLambda,
StrictNamedLambda,
FunctionLexical,
// WithScope
With,
@ -91,6 +92,7 @@ static inline bool ScopeKindIsCatch(ScopeKind kind) {
static inline bool ScopeKindIsInBody(ScopeKind kind) {
return kind == ScopeKind::Lexical || kind == ScopeKind::SimpleCatch ||
kind == ScopeKind::Catch || kind == ScopeKind::With ||
kind == ScopeKind::FunctionLexical ||
kind == ScopeKind::FunctionBodyVar ||
kind == ScopeKind::ParameterExpressionVar;
}
@ -483,7 +485,8 @@ template <>
inline bool Scope::is<LexicalScope>() const {
return kind_ == ScopeKind::Lexical || kind_ == ScopeKind::SimpleCatch ||
kind_ == ScopeKind::Catch || kind_ == ScopeKind::NamedLambda ||
kind_ == ScopeKind::StrictNamedLambda;
kind_ == ScopeKind::StrictNamedLambda ||
kind_ == ScopeKind::FunctionLexical;
}
//
@ -1039,6 +1042,7 @@ void Scope::applyScopeDataTyped(F&& f) {
case ScopeKind::Catch:
case ScopeKind::NamedLambda:
case ScopeKind::StrictNamedLambda:
case ScopeKind::FunctionLexical:
f(&as<LexicalScope>().data());
break;
case ScopeKind::With:

Просмотреть файл

@ -122,6 +122,7 @@ static inline void AssertScopeMatchesEnvironment(Scope* scope,
case ScopeKind::Catch:
case ScopeKind::NamedLambda:
case ScopeKind::StrictNamedLambda:
case ScopeKind::FunctionLexical:
MOZ_ASSERT(&env->as<LexicalEnvironmentObject>().scope() ==
si.scope());
env = &env->as<LexicalEnvironmentObject>().enclosingEnvironment();