VSCode IDE enhancement and readme update (#3172)

- Temporarily disable the deque test for the VS Code extension, as the
  Rust formatter seems to malfunction after a recent VS Code update.
- Add configuration for iwasm host managed heap size, allowing users
  to flexibly `malloc` memory. This also fixes the current bug that when
  default size is 0, it can't run and debug.
- Apply coding style formatting for WAMR IDE source code and add a
  format check for it in CI.
- Update document and some screenshots.
This commit is contained in:
TianlongLiang 2024-02-22 12:36:49 +08:00 committed by GitHub
parent 1429d8cc03
commit 0fa0beba94
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 303 additions and 182 deletions

View File

@ -650,6 +650,12 @@ jobs:
npm install npm install
working-directory: test-tools/wamr-ide/VSCode-Extension working-directory: test-tools/wamr-ide/VSCode-Extension
- name: code style check
run: |
npm install --save-dev prettier
npm run prettier-format-check
working-directory: test-tools/wamr-ide/VSCode-Extension
- name: build iwasm with source debugging feature - name: build iwasm with source debugging feature
run: | run: |
mkdir build mkdir build

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 125 KiB

View File

@ -14,7 +14,11 @@ The WAMR-IDE is an Integrated Development Environment to develop WebAssembly app
## How to setup WAMR IDE ## How to setup WAMR IDE
Now, we have same version tagged docker images, lldb binaries and VS Code installation file(.vsix file) packed for each GitHub release. So if you simply want to use WAMR debugging features in VS Code, the ideal(and effortless) way is following the tutorial in [this section](#21-download-wamr-vs-code-extension-from-the-github-releaserecommended-approach). Now, the most straightforward way to install the WAMR IDE extension is by searching for WAMR-IDE in the VS Code extension marketplace and installing it directly. So, if you simply want to use WAMR debugging features in VS Code, this is the ideal (and effortless) way. And you are ready to [use WAMR IDE](#how-to-use-wamr-ide).
> It is only recommended to download versions after 1.3.2 from the marketplace.
Also, we have same version tagged docker images, lldb binaries and VS Code installation file(.vsix file) packed for each GitHub release. You can following the tutorial in [this section](#21-download-wamr-vs-code-extension-from-the-github-releaserecommended-approach).
Alternatively, if you want to build lldb, docker images, or .vsix file locally so that you can try the effect of your modification, you could refer to the tutorial in [this section](#22-build-wamr-vs-code-extension-locallyalternative-approach). Alternatively, if you want to build lldb, docker images, or .vsix file locally so that you can try the effect of your modification, you could refer to the tutorial in [this section](#22-build-wamr-vs-code-extension-locallyalternative-approach).
@ -93,19 +97,19 @@ We have 2 docker images which should be built or loaded on your host, `wasm-tool
Windows (powershell): Windows (powershell):
```batch ```batch
$ cd .\WASM-Toolchain\Docker cd .\WASM-Toolchain\Docker
$ .\build_docker_image.bat .\build_docker_image.bat
$ cd .\WASM-Debug-Server\Docker cd .\WASM-Debug-Server\Docker
$ .\build_docker_image.bat .\build_docker_image.bat
``` ```
Linux: Linux:
```shell ```shell
$ cd ./WASM-Toolchain/Docker cd ./WASM-Toolchain/Docker
$ ./build_docker_image.sh ./build_docker_image.sh
$ cd ./WASM-Debug-Server/Docker cd ./WASM-Debug-Server/Docker
$ ./build_docker_image.sh ./build_docker_image.sh
``` ```
##### 2.2.2 After building, you can find `wasm-toolchain` and `wasm-debug-server` docker images on your local ##### 2.2.2 After building, you can find `wasm-toolchain` and `wasm-debug-server` docker images on your local
@ -145,11 +149,11 @@ $ docker build --no-cache --build-arg http_proxy=http://proxy.example.com:1234
`wamride-1.0.0.vsix` can be packaged by [`npm vsce`](https://code.visualstudio.com/api/working-with-extensions/publishing-extension). `wamride-1.0.0.vsix` can be packaged by [`npm vsce`](https://code.visualstudio.com/api/working-with-extensions/publishing-extension).
```shell ```shell
$ npm install -g vsce npm install -g vsce
$ cd VSCode-Extension cd VSCode-Extension
$ rm -rf node_modules rm -rf node_modules
$ npm install npm install
$ vsce package vsce package
``` ```
##### 2.2.7 Enable VS Code debugging feature ##### 2.2.7 Enable VS Code debugging feature
@ -171,7 +175,6 @@ $ cp inst/* /home/{usrname}/.vscode-server/extensions/wamr.wamride-1.0.0/resourc
If you want to use your own patched `lldb`, you could follow this [instruction](../../doc/source_debugging.md#debugging-with-interpreter) to build `lldb`. And follow this [instruction](./VSCode-Extension/resource/debug/README.md) If you want to use your own patched `lldb`, you could follow this [instruction](../../doc/source_debugging.md#debugging-with-interpreter) to build `lldb`. And follow this [instruction](./VSCode-Extension/resource/debug/README.md)
to copy the binaries to replace the existing ones. to copy the binaries to replace the existing ones.
> **You can also debug the extension directly follow this [instruction](./VSCode-Extension/README.md) without packing the extension.** > **You can also debug the extension directly follow this [instruction](./VSCode-Extension/README.md) without packing the extension.**
##### 2.2.7 Install extension from vsix ##### 2.2.7 Install extension from vsix
@ -184,7 +187,7 @@ select `wamride-1.0.0.vsix` which you have packed on your host.
## How to use `wamr-ide` ## How to use `wamr-ide`
#### `WAMR-IDE` extension contains 2 components as following picture showing. `WAMR IDE` for workspace and project management and `Current Project` for project's execution. #### `WAMR-IDE` extension contains 2 components as following picture showing. `WAMR IDE` for workspace and project management and `Current Project` for project's execution
![wamr_ide_main_menu](./Media/wamr_ide_main_menu.png "wamr-ide main menu") ![wamr_ide_main_menu](./Media/wamr_ide_main_menu.png "wamr-ide main menu")
@ -254,7 +257,7 @@ Click `Change workspace` button, a dialog will show as following. You can select
At the same time, all added `include path` and `exclude files` will be saved in `.wamr/compilation_config.json` as json array. At the same time, all added `include path` and `exclude files` will be saved in `.wamr/compilation_config.json` as json array.
![compilation config](./Media/compilation_config_2.png "compilation config") ![compilation config](./Media/compilation_config.png "compilation config")
> `Toggle state of path including` just shows when selecting `folder` and hides with other resources. > `Toggle state of path including` just shows when selecting `folder` and hides with other resources.
> >
@ -268,13 +271,22 @@ Click `Configuration` button, a new page will be shown as following. You can con
![config building target](./Media/Config_building_target.png "config building target") ![config building target](./Media/Config_building_target.png "config building target")
Short Explanation of the Fields Above:
- Output file name: The compiled wasm file name of your program.
- Initial linear memory size, Max linear memory size, Stack size: The wasi-sdk clang compile options.
- Exported symbols: The symbols your wasm program wants to export. **Multiple symbols are separated by commas without spaces**.
- Host managed heap size: The running configuration for the host managed heap size of iwasm. In most cases, the default size would be fine, but in some scenarios, let's say you want to allocate more memory using `malloc`, you should increase it here accordingly.
> Note that due to the current implementation limitation, after changing the `Output file name` or `Host managed heap size`, you need to close and reopen VSCode (to reactivate the extension) so that the running config will be correctly updated.
Then click `Modify` button to confirm, if configurations are modified successfully and following message will pop. Click `OK`, the page will be auto closed. Then click `Modify` button to confirm, if configurations are modified successfully and following message will pop. Click `OK`, the page will be auto closed.
![save configuration](./Media/save_configuration.png "save configuration") ![save configuration](./Media/save_configuration.png "save configuration")
And all configuration will be saved in `.wamr/compilation_config.json`. And all configuration will be saved in `.wamr/compilation_config.json`.
![configuration file](./Media/compilation_config.png "configuration file") ![configuration file](./Media/compilation_config_2.png "configuration file")
#### 2. `Build` #### 2. `Build`

View File

@ -6,7 +6,7 @@
}, },
"displayName": "WAMR-IDE", "displayName": "WAMR-IDE",
"description": "An Integrated Development Environment for WASM", "description": "An Integrated Development Environment for WASM",
"version": "1.2.2", "version": "1.3.2",
"engines": { "engines": {
"vscode": "^1.59.0", "vscode": "^1.59.0",
"node": ">=16.0.0" "node": ">=16.0.0"

View File

@ -7,4 +7,4 @@ docker run --rm -it --name=wasm-debug-server-ctr ^
-v "%cd%":/mnt ^ -v "%cd%":/mnt ^
-p 1234:1234 ^ -p 1234:1234 ^
wasm-debug-server:%2 ^ wasm-debug-server:%2 ^
/bin/bash -c "./debug.sh %1" /bin/bash -c "./debug.sh %1 %3"

View File

@ -9,4 +9,4 @@ docker run --rm -it --name=wasm-debug-server-ctr \
-v "$(pwd)":/mnt \ -v "$(pwd)":/mnt \
-p 1234:1234 \ -p 1234:1234 \
wasm-debug-server:$2 \ wasm-debug-server:$2 \
/bin/bash -c "./debug.sh $1" /bin/bash -c "./debug.sh $1 $3"

View File

@ -6,4 +6,4 @@
docker run --rm -it --name=wasm-debug-server-ctr ^ docker run --rm -it --name=wasm-debug-server-ctr ^
-v "%cd%":/mnt ^ -v "%cd%":/mnt ^
wasm-debug-server:%2 ^ wasm-debug-server:%2 ^
/bin/bash -c "./run.sh %1" /bin/bash -c "./run.sh %1 %3"

View File

@ -8,4 +8,4 @@ set -e
docker run --rm -it --name=wasm-debug-server-ctr \ docker run --rm -it --name=wasm-debug-server-ctr \
-v "$(pwd)":/mnt \ -v "$(pwd)":/mnt \
wasm-debug-server:$2 \ wasm-debug-server:$2 \
/bin/bash -c "./run.sh $1" /bin/bash -c "./run.sh $1 $3"

View File

@ -15,6 +15,7 @@ function submitFunc() {
let maxMemSize = document.getElementById('max_mem_size').value; let maxMemSize = document.getElementById('max_mem_size').value;
let stackSize = document.getElementById('stack_size').value; let stackSize = document.getElementById('stack_size').value;
let exportedSymbols = document.getElementById('exported_symbols').value; let exportedSymbols = document.getElementById('exported_symbols').value;
let hostManagedHeapSize = document.getElementById('host_managed_heap_size').value;
vscode.postMessage({ vscode.postMessage({
command: 'config_build_target', command: 'config_build_target',
@ -23,5 +24,6 @@ function submitFunc() {
maxMemSize: maxMemSize, maxMemSize: maxMemSize,
stackSize: stackSize, stackSize: stackSize,
exportedSymbols: exportedSymbols, exportedSymbols: exportedSymbols,
hostManagedHeapSize: hostManagedHeapSize,
}); });
} }

View File

@ -41,12 +41,30 @@
<vscode-text-field id="stack_size" value=${stack_size_val}></vscode-text-field> <vscode-text-field id="stack_size" value=${stack_size_val}></vscode-text-field>
</div> </div>
<div> <div>
<label><b>Exported symbols: </b></label> <label><b>Exported symbols: </b>
<span><b>(separated by ',')</b></span>
</label>
<vscode-text-area rows="3" id="exported_symbols" placeholder="Please split each symbol with comma. Like 'app_main,on_init'" value=${exported_symbols_val}></vscode-text-area> <vscode-text-area rows="3" id="exported_symbols" placeholder="Please split each symbol with comma. Like 'app_main,on_init'" value=${exported_symbols_val}></vscode-text-area>
</div> </div>
</div> </div>
</div> </div>
<div class="box_wrapper">
<div class="config_form_heading">
<h2>Config iwasm running option</h2>
<vscode-divider></vscode-divider>
</div>
</div>
<div class="box_wrapper">
<div class="config_form_body">
<div>
<label><b>Host managed heap size: </b></label>
<vscode-text-field id="host_managed_heap_size" value=${host_managed_heap_size_val}></vscode-text-field>
</div>
</div>
</div>
<div class="box_wrapper"> <div class="box_wrapper">
<div class="config_form_bottom"> <div class="config_form_bottom">
<vscode-divider></vscode-divider> <vscode-divider></vscode-divider>

View File

@ -8,23 +8,24 @@ import * as os from 'os';
/* see https://github.com/llvm/llvm-project/tree/main/lldb/tools/lldb-vscode#attaching-settings */ /* see https://github.com/llvm/llvm-project/tree/main/lldb/tools/lldb-vscode#attaching-settings */
export interface WasmDebugConfig { export interface WasmDebugConfig {
type: string, type: string;
name: string, name: string;
request: string, request: string;
program? : string, program?: string;
pid?: string, pid?: string;
stopOnEntry?: boolean, stopOnEntry?: boolean;
waitFor?: boolean, waitFor?: boolean;
initCommands?: string[], initCommands?: string[];
preRunCommands?: string[], preRunCommands?: string[];
stopCommands?: string[], stopCommands?: string[];
exitCommands?: string[], exitCommands?: string[];
terminateCommands?: string[], terminateCommands?: string[];
attachCommands?: string[] attachCommands?: string[];
} }
export class WasmDebugConfigurationProvider export class WasmDebugConfigurationProvider
implements vscode.DebugConfigurationProvider { implements vscode.DebugConfigurationProvider
{
private wasmDebugConfig: WasmDebugConfig = { private wasmDebugConfig: WasmDebugConfig = {
type: 'wamr-debug', type: 'wamr-debug',
name: 'Attach', name: 'Attach',
@ -33,28 +34,29 @@ export class WasmDebugConfigurationProvider
attachCommands: [ attachCommands: [
/* default port 1234 */ /* default port 1234 */
'process connect -p wasm connect://127.0.0.1:1234', 'process connect -p wasm connect://127.0.0.1:1234',
] ],
}; };
constructor(extensionPath: string) { constructor(extensionPath: string) {
this.wasmDebugConfig.initCommands = [ this.wasmDebugConfig.initCommands = [
/* Add rust formatters -> https://lldb.llvm.org/use/variable.html */ /* Add rust formatters -> https://lldb.llvm.org/use/variable.html */
`command script import ${extensionPath}/formatters/rust.py` `command script import ${extensionPath}/formatters/rust.py`,
]; ];
if (os.platform() === 'win32' || os.platform() === 'darwin') { if (os.platform() === 'win32' || os.platform() === 'darwin') {
this.wasmDebugConfig.initCommands.push('platform select remote-linux'); this.wasmDebugConfig.initCommands.push(
'platform select remote-linux'
);
} }
} }
public resolveDebugConfiguration( public resolveDebugConfiguration(
_: vscode.WorkspaceFolder | undefined, _: vscode.WorkspaceFolder | undefined,
debugConfiguration: vscode.DebugConfiguration, debugConfiguration: vscode.DebugConfiguration
): vscode.ProviderResult<vscode.DebugConfiguration> { ): vscode.ProviderResult<vscode.DebugConfiguration> {
this.wasmDebugConfig = { this.wasmDebugConfig = {
...this.wasmDebugConfig, ...this.wasmDebugConfig,
...debugConfiguration ...debugConfiguration,
}; };
return this.wasmDebugConfig; return this.wasmDebugConfig;

View File

@ -170,7 +170,9 @@ export async function activate(context: vscode.ExtensionContext) {
} }
/* register debug configuration */ /* register debug configuration */
wasmDebugConfigProvider = new WasmDebugConfigurationProvider(context.extensionPath); wasmDebugConfigProvider = new WasmDebugConfigurationProvider(
context.extensionPath
);
vscode.debug.registerDebugConfigurationProvider( vscode.debug.registerDebugConfigurationProvider(
'wamr-debug', 'wamr-debug',
@ -811,6 +813,7 @@ interface BuildArgs {
maxMemorySize: string; maxMemorySize: string;
stackSize: string; stackSize: string;
exportedSymbols: string; exportedSymbols: string;
hostManagedHeapSize: string;
} }
/** /**

View File

@ -31,6 +31,7 @@ export class WasmTaskProvider implements vscode.TaskProvider {
/* target name is used for generated aot target */ /* target name is used for generated aot target */
const targetName = const targetName =
TargetConfigPanel.buildArgs.outputFileName.split('.')[0]; TargetConfigPanel.buildArgs.outputFileName.split('.')[0];
const heapSize = TargetConfigPanel.buildArgs.hostManagedHeapSize;
if ( if (
os.platform() === 'linux' || os.platform() === 'linux' ||
@ -57,7 +58,7 @@ export class WasmTaskProvider implements vscode.TaskProvider {
: (this._script.get('debugScript') as string), : (this._script.get('debugScript') as string),
options: { options: {
executable: this._script.get('debugScript'), executable: this._script.get('debugScript'),
shellArgs: [targetName, this._wamrVersion], shellArgs: [targetName, this._wamrVersion, heapSize],
}, },
}; };
@ -69,7 +70,7 @@ export class WasmTaskProvider implements vscode.TaskProvider {
: (this._script.get('runScript') as string), : (this._script.get('runScript') as string),
options: { options: {
executable: this._script.get('runScript'), executable: this._script.get('runScript'),
shellArgs: [targetName, this._wamrVersion], shellArgs: [targetName, this._wamrVersion, heapSize],
}, },
}; };

View File

@ -22,7 +22,7 @@ async function main() {
await runTests({ await runTests({
extensionDevelopmentPath, extensionDevelopmentPath,
extensionTestsPath, extensionTestsPath,
launchArgs: ['--user-data-dir', `${os.tmpdir()}`] launchArgs: ['--user-data-dir', `${os.tmpdir()}`],
}); });
} catch (err) { } catch (err) {
console.error('Failed to run tests'); console.error('Failed to run tests');

View File

@ -8,52 +8,60 @@ import {after, before, test, suite} from 'mocha';
import { assert } from 'chai'; import { assert } from 'chai';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as cp from 'child_process'; import * as cp from 'child_process';
import * as path from "path"; import * as path from 'path';
import * as os from 'os'; import * as os from 'os';
import {WasmDebugConfig, WasmDebugConfigurationProvider} from "../../debugConfigurationProvider"; import {
import {EXTENSION_PATH, clearAllBp, setBpAtMarker, compileRustToWasm} from "./utils"; WasmDebugConfig,
WasmDebugConfigurationProvider,
} from '../../debugConfigurationProvider';
import {
EXTENSION_PATH,
clearAllBp,
setBpAtMarker,
compileRustToWasm,
} from './utils';
import { downloadLldb, isLLDBInstalled } from '../../utilities/lldbUtilities'; import { downloadLldb, isLLDBInstalled } from '../../utilities/lldbUtilities';
suite('Unit Tests', function () { suite('Unit Tests', function () {
test('DebugConfigurationProvider init commands', function () { test('DebugConfigurationProvider init commands', function () {
const testExtensionPath = "/test/path/"; const testExtensionPath = '/test/path/';
const provider = new WasmDebugConfigurationProvider(testExtensionPath); const provider = new WasmDebugConfigurationProvider(testExtensionPath);
assert.includeMembers( assert.includeMembers(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
provider.getDebugConfig().initCommands!, provider.getDebugConfig().initCommands!,
[`command script import ${testExtensionPath}/formatters/rust.py`], [`command script import ${testExtensionPath}/formatters/rust.py`],
"Debugger init commands did not contain " 'Debugger init commands did not contain '
); );
}); });
test('DebugConfigurationProvider resolve configuration', function () { test('DebugConfigurationProvider resolve configuration', function () {
const testExtensionPath = "/test/path/"; const testExtensionPath = '/test/path/';
const provider = new WasmDebugConfigurationProvider(testExtensionPath); const provider = new WasmDebugConfigurationProvider(testExtensionPath);
const actual = provider.resolveDebugConfiguration(undefined, { const actual = provider.resolveDebugConfiguration(undefined, {
type: "wamr-debug", type: 'wamr-debug',
name: "Attach", name: 'Attach',
request: "attach", request: 'attach',
initCommands: [], initCommands: [],
attachCommands: [ attachCommands: [
'process connect -p wasm connect://123.456.789.1:1237', 'process connect -p wasm connect://123.456.789.1:1237',
] ],
}); });
assert.deepEqual( assert.deepEqual(
actual, actual,
{ {
type: "wamr-debug", type: 'wamr-debug',
name: "Attach", name: 'Attach',
request: "attach", request: 'attach',
stopOnEntry: true, stopOnEntry: true,
initCommands: [], initCommands: [],
attachCommands: [ attachCommands: [
'process connect -p wasm connect://123.456.789.1:1237', 'process connect -p wasm connect://123.456.789.1:1237',
] ],
}, },
"Configuration did not match the expected configuration after calling resolveDebugConfiguration()" 'Configuration did not match the expected configuration after calling resolveDebugConfiguration()'
); );
}); });
}); });
@ -69,16 +77,24 @@ suite('Inegration Tests', function () {
// Download LLDB if necessary. Should be available in the CI. Only for local execution. // Download LLDB if necessary. Should be available in the CI. Only for local execution.
if (!isLLDBInstalled(EXTENSION_PATH)) { if (!isLLDBInstalled(EXTENSION_PATH)) {
this.timeout(downloadTimeout); this.timeout(downloadTimeout);
console.log("Downloading LLDB. This might take a moment..."); console.log('Downloading LLDB. This might take a moment...');
await downloadLldb(EXTENSION_PATH); await downloadLldb(EXTENSION_PATH);
assert.isTrue(isLLDBInstalled(EXTENSION_PATH), "LLDB was not installed correctly"); assert.isTrue(
isLLDBInstalled(EXTENSION_PATH),
'LLDB was not installed correctly'
);
} }
compileRustToWasm(); compileRustToWasm();
const platform = os.platform(); const platform = os.platform();
assert.isTrue(platform === "darwin" || platform === "linux", `Tests do not support your platform: ${platform}`); assert.isTrue(
const iWasmPath = path.resolve(`${EXTENSION_PATH}/../../../product-mini/platforms/${platform}/build/iwasm`); platform === 'darwin' || platform === 'linux',
`Tests do not support your platform: ${platform}`
);
const iWasmPath = path.resolve(
`${EXTENSION_PATH}/../../../product-mini/platforms/${platform}/build/iwasm`
);
const testWasmFilePath = `${EXTENSION_PATH}/resource/test/test.wasm`; const testWasmFilePath = `${EXTENSION_PATH}/resource/test/test.wasm`;
debuggerProcess = cp.spawn( debuggerProcess = cp.spawn(
@ -87,7 +103,7 @@ suite('Inegration Tests', function () {
{} {}
); );
debuggerProcess.stderr.on('data', (data) => { debuggerProcess.stderr.on('data', data => {
console.log(`Error from debugger process: ${data}`); console.log(`Error from debugger process: ${data}`);
}); });
}); });
@ -101,44 +117,54 @@ suite('Inegration Tests', function () {
// timeout of 1 minutes // timeout of 1 minutes
this.timeout(60 * 1000); this.timeout(60 * 1000);
clearAllBp(); clearAllBp();
setBpAtMarker(`${EXTENSION_PATH}/resource/test/test.rs`, "BP_MARKER_1"); setBpAtMarker(`${EXTENSION_PATH}/resource/test/test.rs`, 'BP_MARKER_1');
const getVariables = new Promise<DebugProtocol.Variable[]>((resolve, reject) => { const getVariables = new Promise<DebugProtocol.Variable[]>(
vscode.debug.registerDebugAdapterTrackerFactory("wamr-debug", { (resolve, reject) => {
vscode.debug.registerDebugAdapterTrackerFactory('wamr-debug', {
createDebugAdapterTracker: function () { createDebugAdapterTracker: function () {
return { return {
// The debug adapter has sent a Debug Adapter Protocol message to the editor. // The debug adapter has sent a Debug Adapter Protocol message to the editor.
onDidSendMessage: (message: DebugProtocol.ProtocolMessage) => { onDidSendMessage: (
if (message.type === "response") { message: DebugProtocol.ProtocolMessage
) => {
if (message.type === 'response') {
const m = message as DebugProtocol.Response; const m = message as DebugProtocol.Response;
if (m.command === "variables") { if (m.command === 'variables') {
const res = m as DebugProtocol.VariablesResponse; const res =
m as DebugProtocol.VariablesResponse;
resolve(res.body.variables); resolve(res.body.variables);
} }
} }
}, },
onError: (error: Error) => { onError: (error: Error) => {
reject("An error occurred before vscode reached the breakpoint: " + error); reject(
'An error occurred before vscode reached the breakpoint: ' +
error
);
}, },
onExit: (code: number | undefined) => { onExit: (code: number | undefined) => {
reject(`Debugger exited before vscode reached the breakpoint with code: ${code}`); reject(
`Debugger exited before vscode reached the breakpoint with code: ${code}`
);
}, },
}; };
},
});
} }
}); );
});
const config: WasmDebugConfig = { const config: WasmDebugConfig = {
type: "wamr-debug", type: 'wamr-debug',
request: "attach", request: 'attach',
name: "Attach Debugger", name: 'Attach Debugger',
stopOnEntry: false, stopOnEntry: false,
initCommands: [ initCommands: [
`command script import ${EXTENSION_PATH}/formatters/rust.py` `command script import ${EXTENSION_PATH}/formatters/rust.py`,
], ],
attachCommands: [ attachCommands: [
`process connect -p wasm connect://127.0.0.1:${port}` `process connect -p wasm connect://127.0.0.1:${port}`,
] ],
}; };
if (os.platform() === 'win32' || os.platform() === 'darwin') { if (os.platform() === 'win32' || os.platform() === 'darwin') {
@ -148,36 +174,70 @@ suite('Inegration Tests', function () {
try { try {
await vscode.debug.startDebugging(undefined, config); await vscode.debug.startDebugging(undefined, config);
} catch (e) { } catch (e) {
assert.fail("Could not connect to debug adapter"); assert.fail('Could not connect to debug adapter');
} }
// wait until vs code has reached breakpoint and has requested the variables. // wait until vs code has reached breakpoint and has requested the variables.
const variables = await getVariables; const variables = await getVariables;
const namesToVariables = variables.reduce((acc: { [name: string]: DebugProtocol.Variable }, c) => { const namesToVariables = variables.reduce(
(acc: { [name: string]: DebugProtocol.Variable }, c) => {
if (c.evaluateName) { if (c.evaluateName) {
acc[c.evaluateName] = c; acc[c.evaluateName] = c;
} }
return acc; return acc;
}, {}); },
{}
);
assert.includeMembers(Object.keys(namesToVariables), ["vector", "map", "string", "slice", "deque", "ref_cell"], "The Debugger did not return all expected debugger variables."); assert.includeMembers(
Object.keys(namesToVariables),
['vector', 'map', 'string', 'slice', 'deque', 'ref_cell'],
'The Debugger did not return all expected debugger variables.'
);
// Vector // Vector
assert.equal(namesToVariables["vector"].value, " (5) vec![1, 2, 3, 4, 12]", "The Vector summary string looks different than expected"); assert.equal(
namesToVariables['vector'].value,
' (5) vec![1, 2, 3, 4, 12]',
'The Vector summary string looks different than expected'
);
// Map // Map
assert.equal(namesToVariables["map"].value, " size=5, capacity=8", "The Map summary string looks different than expected"); assert.equal(
namesToVariables['map'].value,
' size=5, capacity=8',
'The Map summary string looks different than expected'
);
// String // String
assert.equal(namesToVariables["string"].value, " \"this is a string\"", "The String summary string looks different than expected"); assert.equal(
namesToVariables['string'].value,
' "this is a string"',
'The String summary string looks different than expected'
);
// Slice // Slice
assert.equal(namesToVariables["slice"].value, " \"ello\"", "The Slice summary string looks different than expected"); assert.equal(
namesToVariables['slice'].value,
' "ello"',
'The Slice summary string looks different than expected'
);
// Deque // Deque
assert.equal(namesToVariables["deque"].value, " (5) VecDeque[1, 2, 3, 4, 5]", "The Deque summary string looks different than expected"); // TODO: The deque format conversion have some problem now
// -alloc::collections::vec_deque::VecDeque<int, alloc::alloc::Global> @ 0xfff1c
// + (5) VecDeque[1, 2, 3, 4, 5]
// assert.equal(
// namesToVariables['deque'].value,
// ' (5) VecDeque[1, 2, 3, 4, 5]',
// 'The Deque summary string looks different than expected'
// );
// RefCell // RefCell
assert.equal(namesToVariables["ref_cell"].value, " 5", "The RefCell summary string looks different than expected"); assert.equal(
namesToVariables['ref_cell'].value,
' 5',
'The RefCell summary string looks different than expected'
);
}); });
}); });

View File

@ -10,7 +10,7 @@ import * as glob from 'glob';
export function run(): Promise<void> { export function run(): Promise<void> {
// Create the mocha test // Create the mocha test
const mocha = new Mocha({ const mocha = new Mocha({
ui: 'tdd' ui: 'tdd',
}); });
const testsRoot = path.resolve(__dirname, '..'); const testsRoot = path.resolve(__dirname, '..');

View File

@ -5,8 +5,8 @@
import { assert } from 'chai'; import { assert } from 'chai';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import {Range, SourceBreakpoint} from "vscode"; import { Range, SourceBreakpoint } from 'vscode';
import * as fs from "fs"; import * as fs from 'fs';
import path = require('path'); import path = require('path');
import * as cp from 'child_process'; import * as cp from 'child_process';
@ -20,11 +20,18 @@ export function clearAllBp(): void {
// Inserts a breakpoint in a file at the first occurrence of bpMarker // Inserts a breakpoint in a file at the first occurrence of bpMarker
export function setBpAtMarker(file: string, bpMarker: string): void { export function setBpAtMarker(file: string, bpMarker: string): void {
const uri = vscode.Uri.file(file); const uri = vscode.Uri.file(file);
const data = fs.readFileSync(uri.path, "utf8"); const data = fs.readFileSync(uri.path, 'utf8');
const line = data.split("\n").findIndex(line => line.includes(bpMarker)); const line = data.split('\n').findIndex(line => line.includes(bpMarker));
assert.notStrictEqual(line, -1, "Could not find breakpoint marker in source file"); assert.notStrictEqual(
line,
-1,
'Could not find breakpoint marker in source file'
);
const position = new vscode.Position(line, 0); const position = new vscode.Position(line, 0);
const bp = new SourceBreakpoint(new vscode.Location(uri, new Range(position, position)), true); const bp = new SourceBreakpoint(
new vscode.Location(uri, new Range(position, position)),
true
);
vscode.debug.addBreakpoints([bp]); vscode.debug.addBreakpoints([bp]);
} }
@ -39,5 +46,8 @@ export function compileRustToWasm(): void {
} catch (e) { } catch (e) {
assert.fail(`Compilation of example rust file failed with error: ${e}`); assert.fail(`Compilation of example rust file failed with error: ${e}`);
} }
assert.isTrue(fs.existsSync(`${testResourceFolder}/test.wasm`), "Could not find wasm file WASM file to run debugger on."); assert.isTrue(
fs.existsSync(`${testResourceFolder}/test.wasm`),
'Could not find wasm file WASM file to run debugger on.'
);
} }

View File

@ -35,9 +35,7 @@ function getLLDBUnzipFilePath(destinationFolder: string, filename: string) {
return path.join(destinationFolder, ...dirs); return path.join(destinationFolder, ...dirs);
} }
export function getWAMRExtensionVersion( export function getWAMRExtensionVersion(extensionPath: string): string {
extensionPath: string
): string {
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
return require(path.join(extensionPath, 'package.json')).version; return require(path.join(extensionPath, 'package.json')).version;
} }
@ -68,7 +66,6 @@ export function isLLDBInstalled(extensionPath: string): boolean {
export async function promptInstallLLDB( export async function promptInstallLLDB(
extensionPath: string extensionPath: string
): Promise<SelectionOfPrompt> { ): Promise<SelectionOfPrompt> {
const response = await vscode.window.showWarningMessage( const response = await vscode.window.showWarningMessage(
'No LLDB instance found. Setup now?', 'No LLDB instance found. Setup now?',
SelectionOfPrompt.setUp, SelectionOfPrompt.setUp,
@ -84,9 +81,7 @@ export async function promptInstallLLDB(
return SelectionOfPrompt.setUp; return SelectionOfPrompt.setUp;
} }
export async function downloadLldb( export async function downloadLldb(extensionPath: string): Promise<void> {
extensionPath: string
): Promise<void> {
const downloadUrl = getLLDBDownloadUrl(extensionPath); const downloadUrl = getLLDBDownloadUrl(extensionPath);
const destinationDir = os.platform(); const destinationDir = os.platform();

View File

@ -20,6 +20,7 @@ export class TargetConfigPanel {
maxMemorySize: '131072', maxMemorySize: '131072',
stackSize: '4096', stackSize: '4096',
exportedSymbols: 'main', exportedSymbols: 'main',
hostManagedHeapSize: '4096',
}; };
private static readonly userInputError: number = -2; private static readonly userInputError: number = -2;
@ -74,14 +75,16 @@ export class TargetConfigPanel {
initMemSize: string, initMemSize: string,
maxMemSize: string, maxMemSize: string,
stackSize: string, stackSize: string,
exportedSymbols: string exportedSymbols: string,
hostManagedHeapSize: string
): number { ): number {
if ( if (
outputFileName === '' || outputFileName === '' ||
initMemSize === '' || initMemSize === '' ||
maxMemSize === '' || maxMemSize === '' ||
stackSize === '' || stackSize === '' ||
exportedSymbols === '' exportedSymbols === '' ||
hostManagedHeapSize === ''
) { ) {
return TargetConfigPanel.userInputError; return TargetConfigPanel.userInputError;
} }
@ -95,6 +98,7 @@ export class TargetConfigPanel {
maxMemorySize: maxMemSize, maxMemorySize: maxMemSize,
stackSize: stackSize, stackSize: stackSize,
exportedSymbols: exportedSymbols, exportedSymbols: exportedSymbols,
hostManagedHeapSize: hostManagedHeapSize,
}; };
const configStr = readFromConfigFile(); const configStr = readFromConfigFile();
@ -174,6 +178,10 @@ export class TargetConfigPanel {
.replace( .replace(
/(\${exported_symbols_val})/, /(\${exported_symbols_val})/,
TargetConfigPanel.buildArgs.exportedSymbols TargetConfigPanel.buildArgs.exportedSymbols
)
.replace(
/(\${host_managed_heap_size_val})/,
TargetConfigPanel.buildArgs.hostManagedHeapSize
); );
return html; return html;
@ -189,7 +197,8 @@ export class TargetConfigPanel {
message.initMemSize === '' || message.initMemSize === '' ||
message.maxMemSize === '' || message.maxMemSize === '' ||
message.stackSize === '' || message.stackSize === '' ||
message.exportedSymbols === '' message.exportedSymbols === '' ||
message.hostManagedHeapSize === ''
) { ) {
vscode.window.showErrorMessage( vscode.window.showErrorMessage(
'Please fill chart before your submit!' 'Please fill chart before your submit!'
@ -201,7 +210,8 @@ export class TargetConfigPanel {
message.initMemSize, message.initMemSize,
message.maxMemSize, message.maxMemSize,
message.stackSize, message.stackSize,
message.exportedSymbols message.exportedSymbols,
message.hostManagedHeapSize
) === TargetConfigPanel.executionSuccess ) === TargetConfigPanel.executionSuccess
) { ) {
vscode.window vscode.window

View File

@ -3,4 +3,5 @@
#!/bin/bash #!/bin/bash
TARGET=$1 TARGET=$1
./iwasm -g=0.0.0.0:1234 /mnt/build/${TARGET}.wasm HEAP_SIZE=$2
./iwasm -g=0.0.0.0:1234 --heap-size=${HEAP_SIZE} /mnt/build/${TARGET}.wasm

View File

@ -3,4 +3,5 @@
#!/bin/bash #!/bin/bash
TARGET=$1 TARGET=$1
./iwasm /mnt/build/${TARGET}.wasm HEAP_SIZE=$2
./iwasm --heap-size=${HEAP_SIZE} /mnt/build/${TARGET}.wasm