Skip to content

Commit 79fdfee

Browse files
committed
wasm: simplify using Process
If a Process method call crashes, a subsequent Process method call might succeed. This complicates DocumentLinter's implementation. Change Process so its methods continue to crash if a method ever crashed before. This commit should not change behavior.
1 parent ed45c6c commit 79fdfee

File tree

1 file changed

+15
-41
lines changed

1 file changed

+15
-41
lines changed

wasm/quick-lint-js.js

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,7 @@ class DocumentLinter {
7373
let parser;
7474
try {
7575
process = await this._documentProcessManager.getOrCreateProcessAsync();
76-
// BEGIN CRITICAL SECTION (no awaiting below)
77-
this._documentProcessManager.checkIfProcessCrashed(process);
7876
parser = process.createDocumentForVSCode();
79-
// END CRITICAL SECTION (no awaiting above)
8077
} catch (e) {
8178
if (e instanceof ProcessCrashed) {
8279
this._documentProcessManager.processCrashed(process);
@@ -121,12 +118,7 @@ class DocumentLinter {
121118
}
122119
if (this._parser !== null) {
123120
try {
124-
// BEGIN CRITICAL SECTION (no awaiting below)
125-
this._documentProcessManager.checkIfProcessCrashed(
126-
this._parser.process
127-
);
128121
this._parser.dispose();
129-
// END CRITICAL SECTION (no awaiting above)
130122
} catch (e) {
131123
if (e instanceof ProcessCrashed) {
132124
this._documentProcessManager.processCrashed(this._parser.process);
@@ -206,21 +198,13 @@ class DocumentLinter {
206198
case DocumentLinterState.PARSER_LOADED:
207199
this._pendingChanges.push(...changes);
208200
try {
209-
this._documentProcessManager.checkIfProcessCrashed(
210-
this._parser.process
211-
);
212201
for (let change of this._pendingChanges) {
213202
this._parser.replaceText(change.range, change.text);
214203
}
215204
this._pendingChanges.length = 0;
216205
// END CRITICAL SECTION (no awaiting above)
217206

218-
// BEGIN CRITICAL SECTION (no awaiting below)
219-
this._documentProcessManager.checkIfProcessCrashed(
220-
this._parser.process
221-
);
222207
let diags = this._parser.lint();
223-
// END CRITICAL SECTION (no awaiting above)
224208
this._document.setDiagnostics(diags);
225209
} catch (e) {
226210
// END CRITICAL SECTION (no awaiting above)
@@ -254,7 +238,6 @@ class DocumentLinter {
254238
// BEGIN CRITICAL SECTION (no awaiting below)
255239
assertEqual(this._state, DocumentLinterState.PARSER_UNINITIALIZED);
256240
try {
257-
this._documentProcessManager.checkIfProcessCrashed(this._parser.process);
258241
this._parser.replaceText(
259242
{
260243
start: { line: 0, character: 0 },
@@ -266,10 +249,7 @@ class DocumentLinter {
266249
this._state = DocumentLinterState.PARSER_LOADED;
267250
// END CRITICAL SECTION (no awaiting above)
268251

269-
// BEGIN CRITICAL SECTION (no awaiting below)
270-
this._documentProcessManager.checkIfProcessCrashed(this._parser.process);
271252
let diags = this._parser.lint();
272-
// END CRITICAL SECTION (no awaiting above)
273253
this._document.setDiagnostics(diags);
274254
} catch (e) {
275255
if (e instanceof ProcessCrashed) {
@@ -293,14 +273,10 @@ class DocumentLinter {
293273
let process;
294274
try {
295275
process = await this._documentProcessManager.getOrCreateProcessAsync();
296-
// BEGIN CRITICAL SECTION (no awaiting below)
297-
this._documentProcessManager.checkIfProcessCrashed(process);
298276
let parser = process.createDocumentForVSCode();
299-
// END CRITICAL SECTION (no awaiting above)
300277

301278
// BEGIN CRITICAL SECTION (no awaiting below)
302279
assertEqual(this._state, DocumentLinterState.RECOVERING);
303-
this._documentProcessManager.checkIfProcessCrashed(process);
304280
parser.replaceText(
305281
{
306282
start: { line: 0, character: 0 },
@@ -313,10 +289,7 @@ class DocumentLinter {
313289
this._state = DocumentLinterState.PARSER_LOADED;
314290
// END CRITICAL SECTION (no awaiting above)
315291

316-
// BEGIN CRITICAL SECTION (no awaiting below)
317-
this._documentProcessManager.checkIfProcessCrashed(process);
318292
diags = parser.lint();
319-
// END CRITICAL SECTION (no awaiting above)
320293
} catch (e) {
321294
this._parser = null;
322295
this._parserPromise = null;
@@ -355,15 +328,6 @@ class DocumentProcessManager {
355328
}
356329
}
357330

358-
checkIfProcessCrashed(process) {
359-
if (!(process instanceof Process)) {
360-
throw new TypeError(`Expected Process, but got ${process}`);
361-
}
362-
if (this._process !== process) {
363-
throw new ProcessCrashed();
364-
}
365-
}
366-
367331
async createNewProcessAsync() {
368332
let processFactory = await this._processFactoryPromise;
369333
let process = await processFactory.createProcessAsync();
@@ -490,12 +454,12 @@ let nextProcessIDForDebugging = 1;
490454
// A WebAssembly instance.
491455
//
492456
// If a Process crashes, every DocumentForVSCode or DocumentForWebDemo
493-
// associated with its creating Process is tainted and should not be used
494-
// anymore.
457+
// associated with its creating Process is tainted.
495458
class Process {
496459
constructor(wasmInstance) {
497460
this._idForDebugging = nextProcessIDForDebugging++;
498461
this._wasmInstance = wasmInstance;
462+
this._crashedException = null;
499463

500464
let process = this;
501465
function wrap(name) {
@@ -504,11 +468,21 @@ class Process {
504468
}
505469
let func = wasmInstance.exports[name];
506470
return (...args) => {
507-
exports.maybeInjectFault(process, name);
471+
if (process._crashedException !== null) {
472+
throw process._crashedException;
473+
}
508474
try {
509-
return func(...args);
475+
exports.maybeInjectFault(process, name);
476+
try {
477+
return func(...args);
478+
} catch (e) {
479+
throw new ProcessCrashedWithUnknownError(e);
480+
}
510481
} catch (e) {
511-
throw new ProcessCrashedWithUnknownError(e);
482+
if (e instanceof ProcessCrashed) {
483+
process._crashedException = e;
484+
}
485+
throw e;
512486
}
513487
};
514488
}

0 commit comments

Comments
 (0)