@yowasp/yosys 0.0.0-experimental4 → 0.37.13-dev.628

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,47 @@
1
+ YoWASP Yosys package
2
+ ====================
3
+
4
+ This package provides [Yosys][] binaries built for [WebAssembly][]. See the [overview of the YoWASP project][yowasp] for details.
5
+
6
+ At the moment, this package only provides an API allowing to run Yosys in a virtual filesystem; no binaries are provided.
7
+
8
+ This package does not provide access to `sby`, `yowasp-yosys-smtbmc`, and `yowasp-yosys-witness`; only the main `yosys` application is available.
9
+
10
+ [yosys]: https://github.com/YosysHQ/yosys/
11
+ [webassembly]: https://webassembly.org/
12
+ [yowasp]: https://yowasp.github.io/
13
+
14
+
15
+ API reference
16
+ -------------
17
+
18
+ This package provides one function:
19
+
20
+ - `runYosys` (alias `cmd:yosys`)
21
+
22
+ For more detail, see the documentation for [the JavaScript YoWASP runtime](https://github.com/YoWASP/runtime-js#api-reference).
23
+
24
+
25
+ Versioning
26
+ ----------
27
+
28
+ The version of this package is derived from the upstream Yosys package version in the `X.Y[.Z][+N]` format, and can be in one of the two formats, `X.Y.M` (for builds from release branches) or `X.(Y+1).N-dev.M` (for development builds), where the symbols are:
29
+
30
+ 1. `X`: Yosys major version
31
+ 2. `Y`: Yosys minor version
32
+ 3. `Z`: Yosys patch version; ignored if present
33
+ 4. `N`: matches the `N` in the `X.Y+N` upstream version, if present
34
+ 5. `M`: package build version; disambiguates different builds produced from the same Yosys source tree
35
+ 6. `-dev`: present only for packages built from unreleased Yosys snapshots; marks these packages as pre-releases
36
+
37
+ With this scheme, there is a direct correspondence between upstream versions and [SemVer][semver] NPM package versions.
38
+
39
+ Note that for development builds, the minor version is incremented as required by the SemVer comparison order. This means that an NPM package built from the upstream version `0.45+12` and the 120th commit in this repository will have the version `0.46.12-dev.120`. Because this is a pre-release package, it will not be matched by version specifiers such as `^0.46` or `>=0.46`.
40
+
41
+ [semver]: https://semver.org/
42
+
43
+
44
+ License
45
+ -------
46
+
47
+ This package is covered by the [ISC license](LICENSE.txt), which is the same as the [Yosys license](https://github.com/YosysHQ/yosys/blob/master/COPYING).
@@ -14,6 +14,15 @@ function wallClockNow() {
14
14
  const nanoseconds = now % 1e3 * 1e6;
15
15
  return { seconds, nanoseconds };
16
16
  }
17
+ var randomBytesImpl = function() {
18
+ throw "not implemented";
19
+ };
20
+ function setRandomBytesImpl(impl) {
21
+ randomBytesImpl = impl;
22
+ }
23
+ function getRandomBytes(len) {
24
+ return randomBytesImpl(Number(len));
25
+ }
17
26
  var IoError = class extends Error {
18
27
  };
19
28
  var InputStream = class {
@@ -201,9 +210,21 @@ var Descriptor = class _Descriptor {
201
210
  }
202
211
  return new _Descriptor(openEntry);
203
212
  }
213
+ read(length, offset) {
214
+ if (this.entry instanceof Directory)
215
+ throw "is-directory";
216
+ [length, offset] = [Number(length), Number(offset)];
217
+ return [this.entry.data.subarray(offset, offset + length), offset + length >= this.entry.data.byteLength];
218
+ }
204
219
  readViaStream(offset) {
205
220
  return new ReadStream(this.entry, offset);
206
221
  }
222
+ write(_buffer, _offset) {
223
+ if (this.entry instanceof Directory)
224
+ throw "is-directory";
225
+ console.error("Descriptor.write not implemented");
226
+ throw "unsupported";
227
+ }
207
228
  writeViaStream(offset) {
208
229
  return new WriteStream(this.entry, offset);
209
230
  }
@@ -253,13 +274,19 @@ function directoryFromTree(tree) {
253
274
  }
254
275
  return new Directory(files);
255
276
  }
256
- function directoryIntoTree(directory) {
277
+ function directoryIntoTree(directory, { decodeASCII = true } = {}) {
278
+ function isASCII(buffer) {
279
+ for (const byte of buffer)
280
+ if (byte < 32 && byte !== 9 && byte !== 10 && byte !== 13 || byte >= 127)
281
+ return false;
282
+ return true;
283
+ }
257
284
  const tree = {};
258
285
  for (const [filename, entry] of Object.entries(directory.files)) {
259
286
  if (entry instanceof File)
260
- tree[filename] = new TextDecoder().decode(entry.data);
287
+ tree[filename] = decodeASCII && isASCII(entry.data) ? new TextDecoder().decode(entry.data) : entry.data;
261
288
  if (entry instanceof Directory)
262
- tree[filename] = directoryIntoTree(entry);
289
+ tree[filename] = directoryIntoTree(entry, { decodeASCII });
263
290
  }
264
291
  return tree;
265
292
  }
@@ -280,6 +307,9 @@ var Environment = class {
280
307
  wallClock: {
281
308
  now: wallClockNow
282
309
  },
310
+ random: {
311
+ getRandomBytes
312
+ },
283
313
  io: {
284
314
  Error: IoError,
285
315
  InputStream,
@@ -339,51 +369,89 @@ var Environment = class {
339
369
 
340
370
  // node_modules/@yowasp/runtime/lib/api-base.js
341
371
  var BaseApplication = class {
342
- constructor(getResources, wasmModules, instantiate2, argv0) {
343
- this._resources = null;
344
- this.getResources = getResources;
345
- this.wasmModules = wasmModules;
372
+ constructor(resourceFileURL2, instantiate2, argv0) {
373
+ this.resourceFileURL = resourceFileURL2;
374
+ this.resources = null;
346
375
  this.instantiate = instantiate2;
347
376
  this.argv0 = argv0;
348
377
  }
349
- async run(args, files = {}, printLine = console.log) {
350
- if (this._resources === null)
351
- this._resources = await this.getResources();
378
+ async run(args = null, files = {}, { printLine = console.log, decodeASCII = true } = {}) {
379
+ if (this.resources === null)
380
+ this.resources = await this._fetchResources();
381
+ if (args === null)
382
+ return;
352
383
  const environment = new Environment();
353
384
  environment.args = [this.argv0].concat(args);
354
385
  environment.root = directoryFromTree(files);
355
- for (const [dirName, resourceFiles] of Object.entries(this._resources))
356
- environment.root.files[dirName] = directoryFromTree(resourceFiles);
386
+ for (const [dirName, dirContents] of Object.entries(this.resources.filesystem))
387
+ environment.root.files[dirName] = directoryFromTree(dirContents);
357
388
  environment.printLine = printLine;
358
389
  const wasmCommand = await this.instantiate(
359
- (filename) => this.wasmModules[filename],
390
+ (filename) => this.resources.modules[filename],
360
391
  { runtime: environment.exports }
361
392
  );
393
+ let error = null;
362
394
  try {
363
395
  wasmCommand.run.run();
364
396
  } catch (e) {
365
- if (!(e instanceof Exit && e.code === 0))
397
+ if (!(e instanceof Exit))
366
398
  throw e;
399
+ if (e instanceof Exit && e.code !== 0)
400
+ error = e;
367
401
  }
368
- for (const dirName of Object.keys(this._resources))
402
+ for (const dirName of Object.keys(this.resources.filesystem))
369
403
  delete environment.root.files[dirName];
370
- return directoryIntoTree(environment.root);
404
+ files = directoryIntoTree(environment.root, { decodeASCII });
405
+ if (error !== null) {
406
+ error.files = files;
407
+ throw error;
408
+ } else {
409
+ return files;
410
+ }
411
+ }
412
+ async _fetchResources() {
413
+ console.log(`[YoWASP runtime] Fetching resource bundle ${this.resourceFileURL}`);
414
+ const { modules, filesystem } = await import(this.resourceFileURL);
415
+ return {
416
+ modules: await this._fetchObject(modules, this._fetchWebAssembly),
417
+ filesystem: await this._fetchObject(filesystem, this._fetchUint8Array)
418
+ };
419
+ }
420
+ async _fetchObject(obj, fetchFn) {
421
+ for (const [key, value] of Object.entries(obj)) {
422
+ if (value instanceof URL) {
423
+ console.log(`[YoWASP runtime] Fetching resource file ${value}`);
424
+ obj[key] = await fetchFn(value);
425
+ } else if (typeof value === "string" || value instanceof Uint8Array) {
426
+ obj[key] = value;
427
+ } else {
428
+ obj[key] = await this._fetchObject(value, fetchFn);
429
+ }
430
+ }
431
+ return obj;
432
+ }
433
+ async _fetchUint8Array(_url) {
434
+ throw "not implemented";
435
+ }
436
+ async _fetchWebAssembly(_url) {
437
+ throw "not implemented";
371
438
  }
372
439
  };
373
440
 
374
441
  // node_modules/@yowasp/runtime/lib/api-browser.js
442
+ setRandomBytesImpl(function(length) {
443
+ const QUOTA = 65536;
444
+ const bytes = new Uint8Array(length);
445
+ for (var offset = 0; offset < length; offset += QUOTA)
446
+ crypto.getRandomValues(bytes.slice(offset, offset + QUOTA));
447
+ return bytes;
448
+ });
375
449
  var Application = class extends BaseApplication {
376
- constructor(baseURL, resourceFilenames, wasmFilenames, instantiate2, argv0) {
377
- async function getResources() {
378
- const resources = {};
379
- for (const [dirName, jsonFilename] of Object.entries(resourceFilenames))
380
- resources[dirName] = await fetch(new URL(jsonFilename, baseURL)).then((resp) => resp.json());
381
- return resources;
382
- }
383
- const wasmModules = {};
384
- for (const [modName, wasmFilename] of Object.entries(wasmFilenames))
385
- wasmModules[modName] = fetch(new URL(wasmFilename, baseURL)).then(WebAssembly.compileStreaming);
386
- super(getResources, wasmModules, instantiate2, argv0);
450
+ _fetchUint8Array(url) {
451
+ return fetch(url).then((resp) => resp.arrayBuffer()).then((buf) => new Uint8Array(buf));
452
+ }
453
+ _fetchWebAssembly(url) {
454
+ return fetch(url).then(WebAssembly.compileStreaming);
387
455
  }
388
456
  };
389
457
 
@@ -4537,16 +4605,12 @@ async function instantiate(getCoreModule, imports, instantiateCore = WebAssembly
4537
4605
  }
4538
4606
 
4539
4607
  // lib/api.js
4540
- var yosys = new Application(import.meta.url, {
4541
- "share": "./yosys-share.json"
4542
- }, {
4543
- "yosys.core.wasm": "./yosys.core.wasm",
4544
- "yosys.core2.wasm": "./yosys.core2.wasm",
4545
- "yosys.core3.wasm": "./yosys.core3.wasm",
4546
- "yosys.core4.wasm": "./yosys.core4.wasm"
4547
- }, instantiate, "yowasp-yosys");
4608
+ var resourceFileURL = new URL("./resources-yosys.js", import.meta.url);
4609
+ var yosys = new Application(resourceFileURL, instantiate, "yowasp-yosys");
4548
4610
  var runYosys = yosys.run.bind(yosys);
4611
+ var commands = { "yosys": runYosys };
4549
4612
  export {
4550
4613
  Exit,
4614
+ commands,
4551
4615
  runYosys
4552
4616
  };
@@ -1,5 +1,5 @@
1
1
  // node_modules/@yowasp/runtime/lib/api-node.js
2
- import { readFile } from "fs/promises";
2
+ import { randomBytes } from "crypto";
3
3
 
4
4
  // node_modules/@yowasp/runtime/lib/wasi-virt.js
5
5
  var Exit = class extends Error {
@@ -17,6 +17,15 @@ function wallClockNow() {
17
17
  const nanoseconds = now % 1e3 * 1e6;
18
18
  return { seconds, nanoseconds };
19
19
  }
20
+ var randomBytesImpl = function() {
21
+ throw "not implemented";
22
+ };
23
+ function setRandomBytesImpl(impl) {
24
+ randomBytesImpl = impl;
25
+ }
26
+ function getRandomBytes(len) {
27
+ return randomBytesImpl(Number(len));
28
+ }
20
29
  var IoError = class extends Error {
21
30
  };
22
31
  var InputStream = class {
@@ -204,9 +213,21 @@ var Descriptor = class _Descriptor {
204
213
  }
205
214
  return new _Descriptor(openEntry);
206
215
  }
216
+ read(length, offset) {
217
+ if (this.entry instanceof Directory)
218
+ throw "is-directory";
219
+ [length, offset] = [Number(length), Number(offset)];
220
+ return [this.entry.data.subarray(offset, offset + length), offset + length >= this.entry.data.byteLength];
221
+ }
207
222
  readViaStream(offset) {
208
223
  return new ReadStream(this.entry, offset);
209
224
  }
225
+ write(_buffer, _offset) {
226
+ if (this.entry instanceof Directory)
227
+ throw "is-directory";
228
+ console.error("Descriptor.write not implemented");
229
+ throw "unsupported";
230
+ }
210
231
  writeViaStream(offset) {
211
232
  return new WriteStream(this.entry, offset);
212
233
  }
@@ -256,13 +277,19 @@ function directoryFromTree(tree) {
256
277
  }
257
278
  return new Directory(files);
258
279
  }
259
- function directoryIntoTree(directory) {
280
+ function directoryIntoTree(directory, { decodeASCII = true } = {}) {
281
+ function isASCII(buffer) {
282
+ for (const byte of buffer)
283
+ if (byte < 32 && byte !== 9 && byte !== 10 && byte !== 13 || byte >= 127)
284
+ return false;
285
+ return true;
286
+ }
260
287
  const tree = {};
261
288
  for (const [filename, entry] of Object.entries(directory.files)) {
262
289
  if (entry instanceof File)
263
- tree[filename] = new TextDecoder().decode(entry.data);
290
+ tree[filename] = decodeASCII && isASCII(entry.data) ? new TextDecoder().decode(entry.data) : entry.data;
264
291
  if (entry instanceof Directory)
265
- tree[filename] = directoryIntoTree(entry);
292
+ tree[filename] = directoryIntoTree(entry, { decodeASCII });
266
293
  }
267
294
  return tree;
268
295
  }
@@ -283,6 +310,9 @@ var Environment = class {
283
310
  wallClock: {
284
311
  now: wallClockNow
285
312
  },
313
+ random: {
314
+ getRandomBytes
315
+ },
286
316
  io: {
287
317
  Error: IoError,
288
318
  InputStream,
@@ -340,53 +370,88 @@ var Environment = class {
340
370
  }
341
371
  };
342
372
 
373
+ // node_modules/@yowasp/runtime/lib/api-node.js
374
+ import { readFile } from "fs/promises";
375
+
343
376
  // node_modules/@yowasp/runtime/lib/api-base.js
344
377
  var BaseApplication = class {
345
- constructor(getResources, wasmModules, instantiate2, argv0) {
346
- this._resources = null;
347
- this.getResources = getResources;
348
- this.wasmModules = wasmModules;
378
+ constructor(resourceFileURL2, instantiate2, argv0) {
379
+ this.resourceFileURL = resourceFileURL2;
380
+ this.resources = null;
349
381
  this.instantiate = instantiate2;
350
382
  this.argv0 = argv0;
351
383
  }
352
- async run(args, files = {}, printLine = console.log) {
353
- if (this._resources === null)
354
- this._resources = await this.getResources();
384
+ async run(args = null, files = {}, { printLine = console.log, decodeASCII = true } = {}) {
385
+ if (this.resources === null)
386
+ this.resources = await this._fetchResources();
387
+ if (args === null)
388
+ return;
355
389
  const environment = new Environment();
356
390
  environment.args = [this.argv0].concat(args);
357
391
  environment.root = directoryFromTree(files);
358
- for (const [dirName, resourceFiles] of Object.entries(this._resources))
359
- environment.root.files[dirName] = directoryFromTree(resourceFiles);
392
+ for (const [dirName, dirContents] of Object.entries(this.resources.filesystem))
393
+ environment.root.files[dirName] = directoryFromTree(dirContents);
360
394
  environment.printLine = printLine;
361
395
  const wasmCommand = await this.instantiate(
362
- (filename) => this.wasmModules[filename],
396
+ (filename) => this.resources.modules[filename],
363
397
  { runtime: environment.exports }
364
398
  );
399
+ let error = null;
365
400
  try {
366
401
  wasmCommand.run.run();
367
402
  } catch (e) {
368
- if (!(e instanceof Exit && e.code === 0))
403
+ if (!(e instanceof Exit))
369
404
  throw e;
405
+ if (e instanceof Exit && e.code !== 0)
406
+ error = e;
370
407
  }
371
- for (const dirName of Object.keys(this._resources))
408
+ for (const dirName of Object.keys(this.resources.filesystem))
372
409
  delete environment.root.files[dirName];
373
- return directoryIntoTree(environment.root);
410
+ files = directoryIntoTree(environment.root, { decodeASCII });
411
+ if (error !== null) {
412
+ error.files = files;
413
+ throw error;
414
+ } else {
415
+ return files;
416
+ }
417
+ }
418
+ async _fetchResources() {
419
+ console.log(`[YoWASP runtime] Fetching resource bundle ${this.resourceFileURL}`);
420
+ const { modules, filesystem } = await import(this.resourceFileURL);
421
+ return {
422
+ modules: await this._fetchObject(modules, this._fetchWebAssembly),
423
+ filesystem: await this._fetchObject(filesystem, this._fetchUint8Array)
424
+ };
425
+ }
426
+ async _fetchObject(obj, fetchFn) {
427
+ for (const [key, value] of Object.entries(obj)) {
428
+ if (value instanceof URL) {
429
+ console.log(`[YoWASP runtime] Fetching resource file ${value}`);
430
+ obj[key] = await fetchFn(value);
431
+ } else if (typeof value === "string" || value instanceof Uint8Array) {
432
+ obj[key] = value;
433
+ } else {
434
+ obj[key] = await this._fetchObject(value, fetchFn);
435
+ }
436
+ }
437
+ return obj;
438
+ }
439
+ async _fetchUint8Array(_url) {
440
+ throw "not implemented";
441
+ }
442
+ async _fetchWebAssembly(_url) {
443
+ throw "not implemented";
374
444
  }
375
445
  };
376
446
 
377
447
  // node_modules/@yowasp/runtime/lib/api-node.js
448
+ setRandomBytesImpl(randomBytes);
378
449
  var Application = class extends BaseApplication {
379
- constructor(baseURL, resourceFilenames, wasmFilenames, instantiate2, argv0) {
380
- async function getResources() {
381
- const resources = {};
382
- for (const [dirName, jsonFilename] of Object.entries(resourceFilenames))
383
- resources[dirName] = JSON.parse(await readFile(new URL(jsonFilename, baseURL)));
384
- return resources;
385
- }
386
- const wasmModules = {};
387
- for (const [modName, wasmFilename] of Object.entries(wasmFilenames))
388
- wasmModules[modName] = readFile(new URL(wasmFilename, baseURL)).then(WebAssembly.compile);
389
- super(getResources, wasmModules, instantiate2, argv0);
450
+ _fetchUint8Array(url) {
451
+ return readFile(url);
452
+ }
453
+ _fetchWebAssembly(url) {
454
+ return readFile(url).then(WebAssembly.compile);
390
455
  }
391
456
  };
392
457
 
@@ -4540,16 +4605,12 @@ async function instantiate(getCoreModule, imports, instantiateCore = WebAssembly
4540
4605
  }
4541
4606
 
4542
4607
  // lib/api.js
4543
- var yosys = new Application(import.meta.url, {
4544
- "share": "./yosys-share.json"
4545
- }, {
4546
- "yosys.core.wasm": "./yosys.core.wasm",
4547
- "yosys.core2.wasm": "./yosys.core2.wasm",
4548
- "yosys.core3.wasm": "./yosys.core3.wasm",
4549
- "yosys.core4.wasm": "./yosys.core4.wasm"
4550
- }, instantiate, "yowasp-yosys");
4608
+ var resourceFileURL = new URL("./resources-yosys.js", import.meta.url);
4609
+ var yosys = new Application(resourceFileURL, instantiate, "yowasp-yosys");
4551
4610
  var runYosys = yosys.run.bind(yosys);
4611
+ var commands = { "yosys": runYosys };
4552
4612
  export {
4553
4613
  Exit,
4614
+ commands,
4554
4615
  runYosys
4555
4616
  };