diff --git a/src/function/dide-netlist/index.ts b/src/function/dide-netlist/index.ts index caf6e6c..66ae7b1 100644 --- a/src/function/dide-netlist/index.ts +++ b/src/function/dide-netlist/index.ts @@ -1,244 +1,34 @@ import * as vscode from 'vscode'; import * as fspath from 'path'; -import * as fs from 'fs'; -import * as os from 'os'; - -import { WASI } from 'wasi'; - +import { Worker } from 'worker_threads'; +import { hdlFile, hdlPath } from '../../hdlFs'; +import { t } from '../../i18n'; +import { gotoDefinition, saveAsPdf, saveAsSvg } from './api'; +import { getIconConfig } from '../../hdlFs/icons'; import { AbsPath, opeParam, ReportType, YosysOutput } from '../../global'; +import { PathSet } from '../../global/util'; + import { hdlParam } from '../../hdlParser'; -import { hdlDir, hdlFile, hdlPath } from '../../hdlFs'; import { defaultMacro, doFastApi } from '../../hdlParser/util'; import { HdlFile } from '../../hdlParser/core'; -import { t } from '../../i18n'; -import { HdlLangID } from '../../global/enum'; -import { getIconConfig } from '../../hdlFs/icons'; -import { getDiskLetters, PathSet } from '../../global/util'; -import { gotoDefinition, saveAsPdf, saveAsSvg } from './api'; -import { Worker } from 'worker_threads'; - type SynthMode = 'before' | 'after' | 'RTL'; +interface SimpleOpe { + workspacePath: string, + libCommonPath: string, + prjPath: string, + extensionPath: string +} -class Netlist { - context: vscode.ExtensionContext; - wsName: string; - libName: string; +const workerScriptPath = hdlPath.join(__dirname, 'worker.js'); + +class NetlistRender { panel?: vscode.WebviewPanel; - wasm?: WebAssembly.Module; + constructor() { - constructor(context: vscode.ExtensionContext) { - this.context = context; - this.wsName = '{workspace}'; - this.libName = '{library}'; } - public async open(uri: vscode.Uri, moduleName: string, option = {}) { - const pathset = new PathSet(); - const path = hdlPath.toSlash(uri.fsPath); - - let moduleFile = hdlParam.getHdlFile(path); - // 没有说明是单文件模式,直接打开解析 - if (!moduleFile) { - const standardPath = hdlPath.toSlash(path); - const response = await doFastApi(standardPath, 'common'); - const langID = hdlFile.getLanguageId(standardPath); - const projectType = hdlParam.getHdlFileProjectType(standardPath, 'common'); - moduleFile = new HdlFile( - standardPath, langID, - response?.macro || defaultMacro, - response?.content || [], - projectType, - 'common' - ); - // 从 hdlParam 中去除,避免干扰全局 - hdlParam.removeFromHdlFile(moduleFile); - - // const message = t('error.common.not-valid-hdl-file'); - // const errorMsg = path + ' ' + message + ' ' + opeParam.prjInfo.hardwareSrcPath + '\n' + opeParam.prjInfo.hardwareSimPath; - // vscode.window.showErrorMessage(errorMsg); - // return undefined; - } - - for (const hdlModule of moduleFile.getAllHdlModules()) { - const hdlDependence = hdlParam.getAllDependences(path, hdlModule.name); - if (hdlDependence) { - // include 宏在后续会被正确处理,所以只需要处理 others 即可 - hdlDependence.others.forEach(path => pathset.add(path)); - } - } - pathset.add(path); - - const prjFiles = [...pathset.files]; - - console.log(prjFiles); - console.log(opeParam.prjInfo.prjPath); - - if (!this.wasm) { - const wasm = await this.loadWasm(); - this.wasm = wasm; - } - - const targetYs = this.makeYs(prjFiles, moduleName); - if (!targetYs || !this.wasm) { - return; - } - - const wasm = this.wasm; - const wasiResult = await this.makeWasi(targetYs, moduleName); - - if (wasiResult === undefined) { - return; - } - const { wasi, fd } = wasiResult; - - const netlistPayloadFolder = hdlPath.join(opeParam.prjInfo.prjPath, 'netlist'); - const targetJson = hdlPath.join(netlistPayloadFolder, moduleName + '.json'); - hdlFile.rmSync(targetJson); - - await vscode.window.withProgress({ - location: vscode.ProgressLocation.Notification, - title: t('info.netlist.generate-network'), - cancellable: true - }, async (_, token) => { - token.onCancellationRequested(() => { - console.log('cancel'); - fs.closeSync(fd); - }); - - const instance = WebAssembly.instantiate(wasm, { - wasi_snapshot_preview1: wasi.wasiImport - }); - try { - const exitCode = wasi.start(instance); - } catch (error) { - console.error(error); - } - }); - - if (!fs.existsSync(targetJson)) { - fs.closeSync(fd); - const logFilePath = hdlPath.join(opeParam.prjInfo.prjPath, 'netlist', moduleName + '.log'); - const res = await vscode.window.showErrorMessage( - t('error.cannot-gen-netlist'), - { title: t('error.look-up-log'), value: true } - ) - if (res?.value) { - const document = await vscode.workspace.openTextDocument(vscode.Uri.file(logFilePath)); - await vscode.window.showTextDocument(document); - } - return; - } - - this.create(moduleName, fd); - } - - private getSynthMode(): SynthMode { - const configuration = vscode.workspace.getConfiguration(); - return configuration.get('digital-ide.function.netlist.schema-mode') || 'before'; - } - - private makeYs(files: AbsPath[], topModule: string) { - const netlistPayloadFolder = hdlPath.join(opeParam.prjInfo.prjPath, 'netlist'); - hdlDir.mkdir(netlistPayloadFolder); - const target = hdlPath.join(netlistPayloadFolder, topModule + '.ys'); - const targetJson = hdlPath.join(netlistPayloadFolder, topModule + '.json').replace(opeParam.workspacePath, this.wsName); - - const scripts: string[] = []; - for (const file of files) { - const langID = hdlFile.getLanguageId(file); - if (langID === HdlLangID.Unknown || langID === HdlLangID.Vhdl) { - vscode.window.showErrorMessage(t('info.netlist.not-support-vhdl')); - return undefined; - } - - if (file.startsWith(opeParam.workspacePath)) { - const constraintPath = file.replace(opeParam.workspacePath, this.wsName); - scripts.push(`read_verilog -sv -formal -overwrite ${constraintPath}`); - } else if (file.startsWith(opeParam.prjInfo.libCommonPath)) { - const constraintPath = file.replace(opeParam.prjInfo.libCommonPath, this.libName); - scripts.push(`read_verilog -sv -formal -overwrite ${constraintPath}`); - } - } - - const mode = this.getSynthMode(); - switch (mode) { - case 'before': - scripts.push('design -reset-vlog; proc;'); - break; - case 'after': - scripts.push('design -reset-vlog; proc; opt_clean;'); - break; - case 'RTL': - scripts.push('synth -run coarse;'); - break; - } - scripts.push(`write_json ${targetJson}`); - const ysCode = scripts.join('\n'); - hdlFile.writeFile(target, ysCode); - return target.replace(opeParam.workspacePath, this.wsName); - } - - public async getPreopens() { - const basepreopens = { - '/share': hdlPath.join(opeParam.extensionPath, 'resources', 'dide-netlist', 'static', 'share'), - [this.wsName ]: opeParam.workspacePath, - [this.libName]: opeParam.prjInfo.libCommonPath - }; - if (os.platform() === 'win32') { - const mounts = await getDiskLetters(); - for (const mountName of mounts) { - const realMount = mountName + '/'; - basepreopens[realMount.toLowerCase()] = realMount; - basepreopens[realMount.toUpperCase()] = realMount; - } - } else { - basepreopens['/'] = '/'; - } - return basepreopens; - } - - private async makeWasi(target: string, logName: string) { - // 创建日志文件路径 - const logFilePath = hdlPath.join(opeParam.prjInfo.prjPath, 'netlist', logName + '.log'); - hdlFile.removeFile(logFilePath); - const logFd = fs.openSync(logFilePath, 'a'); - - try { - const wasiOption = { - version: 'preview1', - args: [ - 'yosys', - '-s', - target - ], - preopens: await this.getPreopens(), - stdin: process.stdin.fd, - stdout: process.stdout.fd, - stderr: logFd, - env: process.env - }; - - const wasi = new WASI(wasiOption); - return { wasi, fd: logFd }; - } catch (error) { - fs.closeSync(logFd); - return undefined; - } - } - - private async loadWasm() { - const netlistWasmPath = hdlPath.join(opeParam.extensionPath, 'resources', 'dide-netlist', 'static', 'yosys.wasm'); - if (!hdlPath.exist(netlistWasmPath)) { - vscode.window.showErrorMessage(t('info.netlist.not-found-payload')); - throw Error(t('info.netlist.not-found-payload')); - } - const binary = fs.readFileSync(netlistWasmPath); - const wasm = await WebAssembly.compile(binary); - return wasm; - } - - private create(moduleName: string, fd: number) { + public create(moduleName: string) { // Create panel this.panel = vscode.window.createWebviewPanel( 'Netlist', @@ -252,7 +42,6 @@ class Netlist { ); this.panel.onDidDispose(() => { - fs.closeSync(fd); }); const previewHtml = this.getWebviewContent(); @@ -280,15 +69,11 @@ class Netlist { }); } } - - public send() { - - } public getWebviewContent() { const netlistPath = hdlPath.join(opeParam.extensionPath, 'resources', 'dide-netlist', 'view'); const htmlIndexPath = hdlPath.join(netlistPath, 'index.html'); - + const html = hdlFile.readFile(htmlIndexPath)?.replace(/( { const absLocalPath = fspath.resolve(netlistPath, $2); const webviewUri = this.panel?.webview.asWebviewUri(vscode.Uri.file(absLocalPath)); @@ -297,80 +82,61 @@ class Netlist { }); return html; } +} - public getJsonPathFromYs(path: AbsPath): AbsPath | undefined { - for (const line of fs.readFileSync(path, { encoding: 'utf-8' }).split('\n')) { - if (line.trim().startsWith('write_json')) { - const path = line.split(/\s+/).at(1); - if (path) { - const realPath = path - .replace(this.wsName, opeParam.workspacePath) - .replace(this.libName, opeParam.prjInfo.libCommonPath); - return hdlPath.toSlash(realPath); - } - } - } - return undefined; +async function generateFilelist(path: AbsPath): Promise { + const pathset = new PathSet(); + path = hdlPath.toSlash(path); + + let moduleFile = hdlParam.getHdlFile(path); + // 没有说明是单文件模式,直接打开解析 + if (!moduleFile) { + const standardPath = hdlPath.toSlash(path); + const response = await doFastApi(standardPath, 'common'); + const langID = hdlFile.getLanguageId(standardPath); + const projectType = hdlParam.getHdlFileProjectType(standardPath, 'common'); + moduleFile = new HdlFile( + standardPath, langID, + response?.macro || defaultMacro, + response?.content || [], + projectType, + 'common' + ); + // 从 hdlParam 中去除,避免干扰全局 + hdlParam.removeFromHdlFile(moduleFile); + + // const message = t('error.common.not-valid-hdl-file'); + // const errorMsg = path + ' ' + message + ' ' + opeParam.prjInfo.hardwareSrcPath + '\n' + opeParam.prjInfo.hardwareSimPath; + // vscode.window.showErrorMessage(errorMsg); + // return undefined; } - public async runYs(uri: vscode.Uri) { - const ysPath = hdlPath.toSlash(uri.fsPath); - const targetJson = this.getJsonPathFromYs(ysPath); - const name = ysPath.split('/').at(-1) as string; - const wasiResult = await this.makeWasi(ysPath, name); - - if (wasiResult === undefined) { - return; - } - const { wasi, fd } = wasiResult; - - if (targetJson) { - hdlFile.rmSync(targetJson); - } - - if (!this.wasm) { - const wasm = await this.loadWasm(); - this.wasm = wasm; - } - const wasm = this.wasm; - - await vscode.window.withProgress({ - location: vscode.ProgressLocation.Notification, - title: t('info.netlist.generate-network'), - cancellable: true - }, async () => { - const instance = await WebAssembly.instantiate(wasm, { - wasi_snapshot_preview1: wasi.wasiImport - }); - const exitCode = wasi.start(instance); - }); - - if (targetJson && !fs.existsSync(targetJson)) { - fs.closeSync(fd); - const logFilePath = hdlPath.join(opeParam.prjInfo.prjPath, 'netlist', name + '.log'); - const res = await vscode.window.showErrorMessage( - t('error.cannot-gen-netlist'), - { title: t('error.look-up-log'), value: true } - ) - if (res?.value) { - const document = await vscode.workspace.openTextDocument(vscode.Uri.file(logFilePath)); - await vscode.window.showTextDocument(document); - } + for (const hdlModule of moduleFile.getAllHdlModules()) { + const hdlDependence = hdlParam.getAllDependences(path, hdlModule.name); + if (hdlDependence) { + // include 宏在后续会被正确处理,所以只需要处理 others 即可 + hdlDependence.others.forEach(path => pathset.add(path)); } } + pathset.add(path); + + const filelist = [...pathset.files]; + + console.log(filelist); + console.log(opeParam.prjInfo.prjPath); + + return filelist; } -export async function openNetlistViewer(context: vscode.ExtensionContext, uri: vscode.Uri, moduleName: string) { - const viewer = new Netlist(context); - viewer.open(uri, moduleName); +function generateOpe(): SimpleOpe { + return { + workspacePath: opeParam.workspacePath, + extensionPath: opeParam.extensionPath, + libCommonPath: opeParam.prjInfo.libCommonPath, + prjPath: opeParam.prjInfo.prjPath + }; } -export async function runYsScript(context: vscode.ExtensionContext, uri: vscode.Uri) { - const viewer = new Netlist(context); - viewer.runYs(uri); -} - - function registerMessageEvent(panel: vscode.WebviewPanel) { panel.webview.onDidReceiveMessage(message => { const { command, data } = message; @@ -389,4 +155,126 @@ function registerMessageEvent(panel: vscode.WebviewPanel) { break; } }); -} \ No newline at end of file +} + +function waitForFinish(worker: Worker): Promise { + return new Promise(resolve => { + worker.on('message', message => { + if (message.command === 'finish') { + resolve(); + } + }); + }); +} + +function checkResource() { + const netlistWasmPath = hdlPath.join(opeParam.extensionPath, 'resources', 'dide-netlist', 'static', 'yosys.wasm'); + if (!hdlPath.exist(netlistWasmPath)) { + vscode.window.showErrorMessage(t('info.netlist.not-found-payload')); + throw Error(t('info.netlist.not-found-payload')); + } +} + +export async function openNetlistViewer(context: vscode.ExtensionContext, uri: vscode.Uri, moduleName: string) { + checkResource(); + const worker = new Worker(workerScriptPath); + + worker.on('message', message => { + const command = message.command; + const data = message.data; + switch (command) { + case 'error-log-file': + showErrorLogFile(data); + break; + + default: + break; + } + }); + + const configuration = vscode.workspace.getConfiguration(); + const mode = configuration.get('digital-ide.function.netlist.schema-mode') || 'before'; + const filelist = await generateFilelist(uri.fsPath); + const ope = generateOpe(); + + worker.postMessage({ + command: 'open', + data: { + path: uri.fsPath, + moduleName, mode, + filelist, + ope + } + }); + + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: t('info.netlist.generate-network'), + cancellable: true + }, async (_, token) => { + token.onCancellationRequested(() => { + worker.terminate(); + }); + + await waitForFinish(worker); + }); + + worker.terminate(); + + const render = new NetlistRender(); + render.create(moduleName); +} + +async function showErrorLogFile(data: any) { + const { logFilePath } = data; + const res = await vscode.window.showErrorMessage( + t('error.cannot-gen-netlist'), + { title: t('error.look-up-log'), value: true } + ) + if (res?.value) { + const document = await vscode.workspace.openTextDocument(vscode.Uri.file(logFilePath)); + await vscode.window.showTextDocument(document); + } +} + +export async function runYsScript(context: vscode.ExtensionContext, uri: vscode.Uri) { + checkResource(); + const worker = new Worker(workerScriptPath); + + worker.on('message', message => { + const command = message.command; + const data = message.data; + switch (command) { + case 'error-log-file': + showErrorLogFile(data); + break; + + default: + break; + } + }); + + const ope = generateOpe(); + + worker.postMessage({ + command: 'run', + data: { + path: uri.fsPath, + ope + } + }); + + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: t('info.netlist.generate-network'), + cancellable: true + }, async (_, token) => { + token.onCancellationRequested(() => { + worker.terminate(); + }); + + await waitForFinish(worker); + }); + + worker.terminate(); +} diff --git a/src/function/dide-netlist/worker.ts b/src/function/dide-netlist/worker.ts index 7cc5be7..5c776c1 100644 --- a/src/function/dide-netlist/worker.ts +++ b/src/function/dide-netlist/worker.ts @@ -1,4 +1,25 @@ -import { isMainThread, Worker, parentPort } from 'worker_threads'; +import { parentPort } from 'worker_threads'; +import * as childProcess from 'child_process'; +import * as fs from 'fs'; +import * as os from 'os'; + +import { WASI } from 'wasi'; + +type SynthMode = 'before' | 'after' | 'RTL'; +type AbsPath = string; +enum HdlLangID { + Verilog = 'verilog', + SystemVerilog = 'systemverilog', + Vhdl = 'vhdl', + Unknown = 'Unknown' +}; + +interface SimpleOpe { + workspacePath: string, + libCommonPath: string, + prjPath: string, + extensionPath: string +} if (parentPort) { parentPort.on('message', message => { @@ -6,13 +27,323 @@ if (parentPort) { const data = message.data; switch (command) { - case 'ys': - + case 'open': + open(data); + break; + case 'run': + run(data); break; - default: break; } }); } +async function open(data: any) { + const { path, moduleName, mode, filelist, ope } = data; + const viewer = new Netlist(ope); + viewer.open(path, moduleName, filelist, mode); +} + +async function run(data: any) { + const { path, ope } = data; + const viewer = new Netlist(ope); + viewer.runYs(path); +} + +function getDiskLetters(): Promise { + return new Promise((resolve, reject) => { + // 调用 wmic 命令获取磁盘信息 + childProcess.exec('wmic logicaldisk get name', (error, stdout, stderr) => { + if (error) { + reject(`Error: ${error.message}`); + return; + } + + if (stderr) { + reject(`Stderr: ${stderr}`); + return; + } + + // 解析命令输出 + const disks = stdout + .split('\n') // 按行分割 + .map(line => line.trim()) // 去除每行的空白字符 + .filter(line => /^[A-Z]:$/.test(line)); // 过滤出盘符(如 C:, D:) + + resolve(disks); + }); + }); +} + +function mkdir(path: AbsPath): boolean { + if (!path) { + return false; + } + // 如果存在则直接退出 + if (fs.existsSync(path)) { + return true; + } + + try { + fs.mkdirSync(path, {recursive:true}); + return true; + } + catch (error) { + fs.mkdirSync(path, {recursive:true}); + } + return false; +} + +function join(...paths: string[]): AbsPath { + return paths.join('/'); +} + +function isVlog(file: AbsPath): boolean { + const exts = ['.v', '.vh', '.vl', '.sv']; + for (const ext of exts) { + if (file.toLowerCase().endsWith(ext)) { + return true; + } + } + return false; +} + +class Netlist { + wsName: string; + libName: string; + ope: SimpleOpe; + wasm?: WebAssembly.Module; + + constructor(ope: SimpleOpe) { + this.wsName = '{workspace}'; + this.libName = '{library}'; + this.ope = ope; + } + + public async open(path: string, moduleName: string, filelist: AbsPath[], mode: SynthMode) { + + if (!this.wasm) { + const wasm = await this.loadWasm(); + this.wasm = wasm; + } + + const targetYs = this.makeYs(filelist, moduleName, mode); + if (!targetYs || !this.wasm) { + return; + } + + const wasm = this.wasm; + const wasiResult = await this.makeWasi(targetYs, moduleName); + + if (wasiResult === undefined) { + return; + } + const { wasi, fd } = wasiResult; + + const netlistPayloadFolder = join(this.ope.prjPath, 'netlist'); + const targetJson = join(netlistPayloadFolder, moduleName + '.json'); + if (fs.existsSync(targetJson)) { + fs.rmSync(targetJson); + } + + const instance = await WebAssembly.instantiate(wasm, { + wasi_snapshot_preview1: wasi.wasiImport + }); + + try { + const exitCode = wasi.start(instance); + } catch (error) { + if (parentPort) { + parentPort.postMessage({ + command: 'finish', + data: { error } + }); + } + } + + if (!fs.existsSync(targetJson)) { + fs.closeSync(fd); + const logFilePath = join(this.ope.prjPath, 'netlist', moduleName + '.log'); + if (parentPort) { + parentPort.postMessage({ + command: 'error-log-file', + data: { logFilePath } + }); + } + } + + if (parentPort) { + parentPort.postMessage({ + command: 'finish', + data: {} + }); + } + } + + private makeYs(files: AbsPath[], topModule: string, mode: SynthMode) { + const netlistPayloadFolder = join(this.ope.prjPath, 'netlist'); + mkdir(netlistPayloadFolder); + const target = join(netlistPayloadFolder, topModule + '.ys'); + const targetJson = join(netlistPayloadFolder, topModule + '.json').replace(this.ope.workspacePath, this.wsName); + + const scripts: string[] = []; + + for (const file of files) { + if (!isVlog(file)) { + return undefined; + } + + if (file.startsWith(this.ope.workspacePath)) { + const constraintPath = file.replace(this.ope.workspacePath, this.wsName); + scripts.push(`read_verilog -sv -formal -overwrite ${constraintPath}`); + } else if (file.startsWith(this.ope.libCommonPath)) { + const constraintPath = file.replace(this.ope.libCommonPath, this.libName); + scripts.push(`read_verilog -sv -formal -overwrite ${constraintPath}`); + } + } + + switch (mode) { + case 'before': + scripts.push('design -reset-vlog; proc;'); + break; + case 'after': + scripts.push('design -reset-vlog; proc; opt_clean;'); + break; + case 'RTL': + scripts.push('synth -run coarse;'); + break; + } + scripts.push(`write_json ${targetJson}`); + const ysCode = scripts.join('\n'); + fs.writeFileSync(target, ysCode, { encoding: 'utf-8' }); + return target.replace(this.ope.workspacePath, this.wsName); + } + + public async getPreopens() { + const basepreopens = { + '/share': join(this.ope.extensionPath, 'resources', 'dide-netlist', 'static', 'share'), + [this.wsName ]: this.ope.workspacePath, + [this.libName]: this.ope.libCommonPath + }; + if (os.platform() === 'win32') { + const mounts = await getDiskLetters(); + for (const mountName of mounts) { + const realMount = mountName + '/'; + basepreopens[realMount.toLowerCase()] = realMount; + basepreopens[realMount.toUpperCase()] = realMount; + } + } else { + basepreopens['/'] = '/'; + } + return basepreopens; + } + + private async makeWasi(target: string, logName: string) { + // 创建日志文件路径 + const logFilePath = join(this.ope.prjPath, 'netlist', logName + '.log'); + if (fs.existsSync(logFilePath)) { + fs.rmSync(logFilePath) + } + const logFd = fs.openSync(logFilePath, 'a'); + + try { + const wasiOption = { + version: 'preview1', + args: [ + 'yosys', + '-s', + target + ], + preopens: await this.getPreopens(), + stdin: process.stdin.fd, + stdout: process.stdout.fd, + stderr: logFd, + env: process.env + }; + + const wasi = new WASI(wasiOption); + return { wasi, fd: logFd }; + } catch (error) { + fs.closeSync(logFd); + return undefined; + } + } + + private async loadWasm() { + const netlistWasmPath = join(this.ope.extensionPath, 'resources', 'dide-netlist', 'static', 'yosys.wasm'); + const binary = fs.readFileSync(netlistWasmPath); + const wasm = await WebAssembly.compile(binary); + return wasm; + } + + public getJsonPathFromYs(path: AbsPath): AbsPath | undefined { + for (const line of fs.readFileSync(path, { encoding: 'utf-8' }).split('\n')) { + if (line.trim().startsWith('write_json')) { + const path = line.split(/\s+/).at(1); + if (path) { + const realPath = path + .replace(this.wsName, this.ope.workspacePath) + .replace(this.libName, this.ope.libCommonPath); + return realPath.replace(/\\/g,"\/"); + } + } + } + return undefined; + } + + public async runYs(path: string) { + const ysPath = path.replace(/\\/g,"\/"); + const targetJson = this.getJsonPathFromYs(ysPath); + const name = ysPath.split('/').at(-1) as string; + const wasiResult = await this.makeWasi(ysPath, name); + + if (wasiResult === undefined) { + return; + } + const { wasi, fd } = wasiResult; + + if (targetJson) { + fs.rmSync(targetJson); + } + + if (!this.wasm) { + const wasm = await this.loadWasm(); + this.wasm = wasm; + } + const wasm = this.wasm; + + const instance = await WebAssembly.instantiate(wasm, { + wasi_snapshot_preview1: wasi.wasiImport + }); + + try { + const exitCode = wasi.start(instance); + } catch (error) { + if (parentPort) { + parentPort.postMessage({ + command: 'finish', + data: { error } + }); + } + } + + if (targetJson && !fs.existsSync(targetJson)) { + fs.closeSync(fd); + const logFilePath = join(this.ope.prjPath, 'netlist', name + '.log'); + if (parentPort) { + parentPort.postMessage({ + command: 'error-log-file', + data: { logFilePath } + }); + } + } + + if (parentPort) { + parentPort.postMessage({ + command: 'finish', + data: {} + }); + } + } +} \ No newline at end of file diff --git a/src/global/util.ts b/src/global/util.ts index 2e036e7..619d964 100644 --- a/src/global/util.ts +++ b/src/global/util.ts @@ -263,28 +263,3 @@ export function getUserHomeDir(): AbsPath { const path = process.env.HOME || process.env.USERPROFILE || os.homedir(); return hdlPath.toSlash(path); } - -export function getDiskLetters(): Promise { - return new Promise((resolve, reject) => { - // 调用 wmic 命令获取磁盘信息 - childProcess.exec('wmic logicaldisk get name', (error, stdout, stderr) => { - if (error) { - reject(`Error: ${error.message}`); - return; - } - - if (stderr) { - reject(`Stderr: ${stderr}`); - return; - } - - // 解析命令输出 - const disks = stdout - .split('\n') // 按行分割 - .map(line => line.trim()) // 去除每行的空白字符 - .filter(line => /^[A-Z]:$/.test(line)); // 过滤出盘符(如 C:, D:) - - resolve(disks); - }); - }); -} \ No newline at end of file diff --git a/src/hdlFs/file.ts b/src/hdlFs/file.ts index aa2afd5..6b832ed 100644 --- a/src/hdlFs/file.ts +++ b/src/hdlFs/file.ts @@ -5,8 +5,6 @@ import { AbsPath, RelPath } from '../global'; import { HdlLangID } from '../global/enum'; import { verilogExts, vhdlExts, systemVerilogExts, hdlExts } from '../global/lang'; import * as hdlPath from './path'; -import { HdlFileProjectType } from '../hdlParser/common'; -import { opeParam } from '../global'; import { hdlIgnore } from '../manager/ignore'; import { hdlDir } from '.'; diff --git a/src/manager/ignore.ts b/src/manager/ignore.ts index 007e1c8..b4f236f 100644 --- a/src/manager/ignore.ts +++ b/src/manager/ignore.ts @@ -1,6 +1,5 @@ -import * as vscode from 'vscode'; import { AbsPath, opeParam } from '../global'; -import { hdlFile, hdlPath } from '../hdlFs'; +import { hdlPath } from '../hdlFs'; import * as fs from 'fs'; import * as fspath from 'path'; import { minimatch } from 'minimatch';