Skip to content

Commit

Permalink
Merge pull request #1805 from microsoft/connor4312/wasm-12
Browse files Browse the repository at this point in the history
feat: make wasm variable store work
  • Loading branch information
connor4312 committed Sep 20, 2023
2 parents 676e7e7 + 903b783 commit 61a8b9f
Show file tree
Hide file tree
Showing 28 changed files with 1,481 additions and 534 deletions.
33 changes: 26 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
"@types/ws": "^8.5.3",
"@typescript-eslint/eslint-plugin": "^5.17.0",
"@typescript-eslint/parser": "^5.17.0",
"@vscode/dwarf-debugging": "^0.0.2",
"@vscode/test-electron": "^2.2.3",
"chai": "^4.3.6",
"chai-as-promised": "^7.1.1",
Expand Down
62 changes: 49 additions & 13 deletions src/adapter/breakpoints/breakpointBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import Cdp from '../../cdp/api';
import { LogTag } from '../../common/logging';
import { IPosition } from '../../common/positions';
import { absolutePathToFileUrl, urlToRegex } from '../../common/urlUtils';
import { absolutePathToFileUrl } from '../../common/urlUtils';
import Dap from '../../dap/api';
import { BreakpointManager } from '../breakpoints';
import { ISourceScript, IUiLocation, Source, SourceFromMap, base1To0 } from '../source';
Expand Down Expand Up @@ -314,7 +314,7 @@ export abstract class Breakpoint {

const promises: Promise<void>[] = [];
for (const uiLocation of uiLocations) {
promises.push(this._setByScriptId(thread, script, source.offsetSourceToScript(uiLocation)));
promises.push(this._setForSpecific(thread, script, source.offsetSourceToScript(uiLocation)));
}

// If we get a source map that references this script exact URL, then
Expand Down Expand Up @@ -480,7 +480,7 @@ export abstract class Breakpoint {

private async _setByUiLocation(thread: Thread, uiLocation: IUiLocation): Promise<void> {
await Promise.all(
uiLocation.source.scripts.map(script => this._setByScriptId(thread, script, uiLocation)),
uiLocation.source.scripts.map(script => this._setForSpecific(thread, script, uiLocation)),
);
}

Expand Down Expand Up @@ -539,7 +539,9 @@ export abstract class Breakpoint {
lcEqual(bp.args.location, lineColumn)) ||
(script.url &&
isSetByUrl(bp.args) &&
new RegExp(bp.args.urlRegex ?? '').test(script.url) &&
(bp.args.urlRegex
? new RegExp(bp.args.urlRegex).test(script.url)
: script.url === bp.args.url) &&
lcEqual(bp.args, lineColumn)),
);
}
Expand All @@ -549,36 +551,70 @@ export abstract class Breakpoint {
* at the provided script by url regexp already. This is used to deduplicate breakpoint
* requests to avoid triggering any logpoint breakpoints multiple times.
*/
protected hasSetOnLocationByRegexp(urlRegexp: string, lineColumn: LineColumn) {
protected hasSetOnLocationByUrl(kind: 're' | 'url', input: string, lineColumn: LineColumn) {
return this.cdpBreakpoints.find(bp => {
if (isSetByUrl(bp.args)) {
return bp.args.urlRegex === urlRegexp && lcEqual(bp.args, lineColumn);
if (!lcEqual(bp.args, lineColumn)) {
return false;
}

if (kind === 'url') {
return bp.args.urlRegex
? new RegExp(bp.args.urlRegex).test(input)
: bp.args.url === input;
} else {
return kind === 're' && bp.args.urlRegex === input;
}
}

const script = this._manager._sourceContainer.getScriptById(bp.args.location.scriptId);
if (script) {
return lcEqual(bp.args.location, lineColumn) && new RegExp(urlRegexp).test(script.url);
return lcEqual(bp.args.location, lineColumn) && kind === 're'
? new RegExp(input).test(script.url)
: script.url === input;
}

return undefined;
});
}

protected async _setForSpecific(thread: Thread, script: ISourceScript, lineColumn: LineColumn) {
// prefer to set on script URL for non-anonymous scripts, since url breakpoints
// will survive and be hit on reload.
if (script.url) {
return this._setByUrl(thread, script.url, lineColumn);
} else {
return this._setByScriptId(thread, script, lineColumn);
}
}

protected async _setByUrl(thread: Thread, url: string, lineColumn: LineColumn): Promise<void> {
return this._setByUrlRegexp(thread, urlToRegex(url), lineColumn);
lineColumn = base1To0(lineColumn);

const previous = this.hasSetOnLocationByUrl('url', url, lineColumn);
if (previous) {
if (previous.state === CdpReferenceState.Pending) {
await previous.done;
}

return;
}

return this._setAny(thread, {
url,
condition: this.getBreakCondition(),
...lineColumn,
});
}

protected async _setByUrlRegexp(
thread: Thread,
urlRegex: string,
lineColumn: LineColumn,
): Promise<void> {
lineColumn = {
columnNumber: lineColumn.columnNumber - 1,
lineNumber: lineColumn.lineNumber - 1,
};
lineColumn = base1To0(lineColumn);

const previous = this.hasSetOnLocationByRegexp(urlRegex, lineColumn);
const previous = this.hasSetOnLocationByUrl('re', urlRegex, lineColumn);
if (previous) {
if (previous.state === CdpReferenceState.Pending) {
await previous.done;
Expand Down
18 changes: 18 additions & 0 deletions src/adapter/dwarf/dwarfModuleProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*---------------------------------------------------------
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/

export const IDwarfModuleProvider = Symbol('IDwarfModuleProvider');

export interface IDwarfModuleProvider {
/**
* Loads the dwarf module if it exists.
*/
load(): Promise<typeof import('@vscode/dwarf-debugging') | undefined>;

/**
* Prompts the user to install the dwarf module (called if the module is
* not installed.)
*/
prompt(): void;
}
40 changes: 40 additions & 0 deletions src/adapter/dwarf/dwarfModuleProviderImpl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*---------------------------------------------------------
* Copyright (C) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------*/

import type * as dwf from '@vscode/dwarf-debugging';
import * as l10n from '@vscode/l10n';
import { inject, injectable } from 'inversify';
import Dap from '../../dap/api';
import { IDapApi } from '../../dap/connection';
import { IDwarfModuleProvider } from './dwarfModuleProvider';

const name = '@vscode/dwarf-debugging';

@injectable()
export class DwarfModuleProvider implements IDwarfModuleProvider {
private didPrompt = false;

constructor(@inject(IDapApi) private readonly dap: Dap.Api) {}

public async load(): Promise<typeof dwf | undefined> {
try {
return await import(name);
} catch {
return undefined;
}
}

public prompt() {
if (!this.didPrompt) {
this.didPrompt = true;
this.dap.output({
output: l10n.t(
'You may install the `{}` module via npm for enhanced WebAssembly debugging',
name,
),
category: 'console',
});
}
}
}
Loading

0 comments on commit 61a8b9f

Please sign in to comment.