From df793f9f3079ec2f6db0194d465d4c2d5237ec7d Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Fri, 6 Dec 2024 12:14:57 -0800 Subject: [PATCH 1/6] fixes for newer emscripten thread handling behavior --- .../js/examples/high-level/miracle-sudoku.ts | 4 +-- src/api/js/examples/low-level/example-raw.ts | 17 ++++++++-- src/api/js/examples/low-level/test-ts-api.ts | 5 +-- src/api/js/scripts/build-wasm.ts | 6 ++-- src/api/js/scripts/make-cc-wrapper.ts | 32 +++++++++++++++++++ src/api/js/src/low-level/async-wrapper.js | 2 ++ 6 files changed, 53 insertions(+), 13 deletions(-) diff --git a/src/api/js/examples/high-level/miracle-sudoku.ts b/src/api/js/examples/high-level/miracle-sudoku.ts index 093d599f32d..763581ae781 100644 --- a/src/api/js/examples/high-level/miracle-sudoku.ts +++ b/src/api/js/examples/high-level/miracle-sudoku.ts @@ -1,4 +1,4 @@ -import { init } from '../../build/node'; +import { init } from '../../build/node.js'; import type { Solver, Arith } from '../../build/node'; @@ -198,8 +198,6 @@ function parseSudoku(str: string) { ......... ......... `); - - em.PThread.terminateAllThreads(); })().catch(e => { console.error('error', e); process.exit(1); diff --git a/src/api/js/examples/low-level/example-raw.ts b/src/api/js/examples/low-level/example-raw.ts index 2790f959449..68e7997e6f9 100644 --- a/src/api/js/examples/low-level/example-raw.ts +++ b/src/api/js/examples/low-level/example-raw.ts @@ -1,6 +1,6 @@ // @ts-ignore we're not going to bother with types for this import process from 'process'; -import { init, Z3_error_code } from '../../build/node'; +import { init, Z3_error_code } from '../../build/node.js'; // demonstrates use of the raw API @@ -58,10 +58,21 @@ import { init, Z3_error_code } from '../../build/node'; } console.log('confirming error messages work:', Z3.get_error_msg(ctx, Z3.get_error_code(ctx))); + Z3.global_param_set('verbose', '0'); + let result = await Z3.eval_smtlib2_string(ctx, ` + (declare-const p Bool) + (declare-const q Bool) + (declare-const r Bool) + (declare-const s Bool) + (declare-const t Bool) + (assert ((_ pbeq 5 2 1 3 3 2) p q r s t)) + (check-sat) + (get-model) + `); + console.log('checking string evaluation', result); + Z3.dec_ref(ctx, strAst); Z3.del_context(ctx); - - em.PThread.terminateAllThreads(); })().catch(e => { console.error('error', e); process.exit(1); diff --git a/src/api/js/examples/low-level/test-ts-api.ts b/src/api/js/examples/low-level/test-ts-api.ts index 3eaef5bfe2d..7e69f1e0686 100644 --- a/src/api/js/examples/low-level/test-ts-api.ts +++ b/src/api/js/examples/low-level/test-ts-api.ts @@ -20,7 +20,7 @@ import type { Z3_sort, Z3_symbol, } from '../../build/node'; -import { init, Z3_ast_kind, Z3_lbool, Z3_sort_kind, Z3_symbol_kind } from '../../build/node'; +import { init, Z3_ast_kind, Z3_lbool, Z3_sort_kind, Z3_symbol_kind } from '../../build/node.js'; let printf = (str: string, ...args: unknown[]) => console.log(sprintf(str.replace(/\n$/, ''), ...args)); @@ -383,9 +383,6 @@ let printf = (str: string, ...args: unknown[]) => console.log(sprintf(str.replac await bitvector_example2(); await unsat_core_and_proof_example(); - - // shut down - em.PThread.terminateAllThreads(); })().catch(e => { console.error('error', e); process.exit(1); diff --git a/src/api/js/scripts/build-wasm.ts b/src/api/js/scripts/build-wasm.ts index 497b67c10cb..a5b57ee3ff7 100644 --- a/src/api/js/scripts/build-wasm.ts +++ b/src/api/js/scripts/build-wasm.ts @@ -40,7 +40,7 @@ function spawnSync(command: string, opts: SpawnOptions = {}) { } function exportedFuncs(): string[] { - const extras = ['_malloc', '_set_throwy_error_handler', '_set_noop_error_handler', ...asyncFuncs.map(f => '_async_' + f)]; + const extras = ['_malloc', '_free', '_set_throwy_error_handler', '_set_noop_error_handler', ...asyncFuncs.map(f => '_async_' + f)]; // TODO(ritave): This variable is unused in original script, find out if it's important const fns: any[] = (functions as any[]).filter(f => !asyncFuncs.includes(f.name)); @@ -66,10 +66,10 @@ fs.mkdirSync(path.dirname(ccWrapperPath), { recursive: true }); fs.writeFileSync(ccWrapperPath, makeCCWrapper()); const fns = JSON.stringify(exportedFuncs()); -const methods = '["ccall","FS","allocate","UTF8ToString","intArrayFromString","ALLOC_NORMAL"]'; +const methods = '["PThread","ccall","FS","UTF8ToString","intArrayFromString"]'; const libz3a = path.normalize('../../../build/libz3.a'); spawnSync( - `emcc build/async-fns.cc ${libz3a} --std=c++20 --pre-js src/low-level/async-wrapper.js -g2 -pthread -fexceptions -s WASM_BIGINT -s USE_PTHREADS=1 -s PTHREAD_POOL_SIZE=0 -s PTHREAD_POOL_SIZE_STRICT=0 -s MODULARIZE=1 -s 'EXPORT_NAME="initZ3"' -s EXPORTED_RUNTIME_METHODS=${methods} -s EXPORTED_FUNCTIONS=${fns} -s DISABLE_EXCEPTION_CATCHING=0 -s SAFE_HEAP=0 -s DEMANGLE_SUPPORT=1 -s TOTAL_MEMORY=2GB -s TOTAL_STACK=20MB -I z3/src/api/ -o build/z3-built.js`, + `emcc build/async-fns.cc ${libz3a} --std=c++20 --pre-js src/low-level/async-wrapper.js -g2 -pthread -fexceptions -s WASM_BIGINT -s USE_PTHREADS=1 -s PTHREAD_POOL_SIZE=0 -s PTHREAD_POOL_SIZE_STRICT=0 -s MODULARIZE=1 -s 'EXPORT_NAME="initZ3"' -s EXPORTED_RUNTIME_METHODS=${methods} -s EXPORTED_FUNCTIONS=${fns} -s DISABLE_EXCEPTION_CATCHING=0 -s SAFE_HEAP=0 -s TOTAL_MEMORY=2GB -s TOTAL_STACK=20MB -I z3/src/api/ -o build/z3-built.js`, ); fs.rmSync(ccWrapperPath); diff --git a/src/api/js/scripts/make-cc-wrapper.ts b/src/api/js/scripts/make-cc-wrapper.ts index 2b7ca253608..bf98219e2f3 100644 --- a/src/api/js/scripts/make-cc-wrapper.ts +++ b/src/api/js/scripts/make-cc-wrapper.ts @@ -58,8 +58,24 @@ void wrapper(Args&&... args) { reject_async('failed with unknown exception'); }); } + MAIN_THREAD_ASYNC_EM_ASM({ + // this clears the earliest timeout + // not necessarily the one corresponding to this thread + // but that's ok + clearTimeout(threadTimeouts.shift()); + }); }); t.detach(); + EM_ASM({ + // https://github.com/emscripten-core/emscripten/issues/23092 + // in Node.js, the process will die if there is no active work + // which can happen while the thread is spawning + // or while it is running + // so we set a timeout here so it stays alive + // this needs to be longer than it could conceivably take to call the one function + // it gets cleared as soon as the thread actually finishes + threadTimeouts.push(setTimeout(() => {}, 600000)); + }); } template @@ -79,8 +95,24 @@ void wrapper_str(Args&&... args) { reject_async(new Error('failed with unknown exception')); }); } + MAIN_THREAD_ASYNC_EM_ASM({ + // this clears the earliest timeout + // not necessarily the one corresponding to this thread + // but that's ok + clearTimeout(threadTimeouts.shift()); + }); }); t.detach(); + EM_ASM({ + // https://github.com/emscripten-core/emscripten/issues/23092 + // in Node.js, the process will die if there is no active work + // which can happen while the thread is spawning + // or while it is running + // so we set a timeout here so it stays alive + // this needs to be longer than it could conceivably take to call the one function + // it gets cleared as soon as the thread actually finishes + threadTimeouts.push(setTimeout(() => {}, 600000)); + }); } diff --git a/src/api/js/src/low-level/async-wrapper.js b/src/api/js/src/low-level/async-wrapper.js index 78b3fee5382..f4e62e51a64 100644 --- a/src/api/js/src/low-level/async-wrapper.js +++ b/src/api/js/src/low-level/async-wrapper.js @@ -1,6 +1,8 @@ // this wrapper works with async-fns to provide promise-based off-thread versions of some functions // It's prepended directly by emscripten to the resulting z3-built.js +let threadTimeouts = []; + let capability = null; function resolve_async(val) { // setTimeout is a workaround for https://github.com/emscripten-core/emscripten/issues/15900 From 2d903aae873cedda9cf1a30ac027f77f88bd7492 Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Fri, 6 Dec 2024 12:23:31 -0800 Subject: [PATCH 2/6] fix return type for async wrapper functions --- src/api/js/scripts/make-ts-wrapper.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/api/js/scripts/make-ts-wrapper.ts b/src/api/js/scripts/make-ts-wrapper.ts index 56860946796..6eb81c80609 100644 --- a/src/api/js/scripts/make-ts-wrapper.ts +++ b/src/api/js/scripts/make-ts-wrapper.ts @@ -339,8 +339,10 @@ function makeTsWrapper() { `.trim(); } + // async functions are invocations of the wrapper from make-ts-wrapper.ts + // the wrapper spawns a thread and returns void, so we need to use void as the return type here // prettier-ignore - let invocation = `Mod.ccall('${isAsync ? "async_" : ""}${fn.name}', '${cReturnType}', ${JSON.stringify(ctypes)}, [${args.map(toEm).join(", ")}])`; + let invocation = `Mod.ccall('${isAsync ? "async_" : ""}${fn.name}', '${isAsync ? 'void' : cReturnType}', ${JSON.stringify(ctypes)}, [${args.map(toEm).join(", ")}])`; if (isAsync) { invocation = `await Mod.async_call(() => ${invocation})`; From d93a8fd3f069913b542ed26844442f53cdc611b1 Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Fri, 6 Dec 2024 12:30:09 -0800 Subject: [PATCH 3/6] update prettier --- .../js/examples/high-level/miracle-sudoku.ts | 4 +++- .../js/examples/high-level/using_smtlib2.ts | 5 ++--- src/api/js/examples/low-level/example-raw.ts | 7 +++++-- src/api/js/package-lock.json | 14 ++++++------- src/api/js/package.json | 3 +-- src/api/js/scripts/build-wasm.ts | 8 ++++++- src/api/js/scripts/make-ts-wrapper.ts | 21 ++++++++++++------- src/api/js/src/high-level/high-level.test.ts | 13 +++++------- src/api/js/src/high-level/types.ts | 4 ++++ src/api/js/src/low-level/index.ts | 4 ++-- 10 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/api/js/examples/high-level/miracle-sudoku.ts b/src/api/js/examples/high-level/miracle-sudoku.ts index 763581ae781..c42c04a95fd 100644 --- a/src/api/js/examples/high-level/miracle-sudoku.ts +++ b/src/api/js/examples/high-level/miracle-sudoku.ts @@ -157,7 +157,9 @@ function parseSudoku(str: string) { async function solve(str: string) { let solver = new Z3.Solver(); - let cells = Array.from({ length: 9 }, (_, col) => Array.from({ length: 9 }, (_, row) => Z3.Int.const(`c_${row}_${col}`))); + let cells = Array.from({ length: 9 }, (_, col) => + Array.from({ length: 9 }, (_, row) => Z3.Int.const(`c_${row}_${col}`)), + ); for (let { row, col, value } of parseSudoku(str)) { solver.add(cells[row][col].eq(value)); } diff --git a/src/api/js/examples/high-level/using_smtlib2.ts b/src/api/js/examples/high-level/using_smtlib2.ts index e9275b7bfbf..7faf7063d01 100644 --- a/src/api/js/examples/high-level/using_smtlib2.ts +++ b/src/api/js/examples/high-level/using_smtlib2.ts @@ -25,12 +25,11 @@ import assert from 'assert'; const model = solver.model(); let modelStr = model.sexpr(); modelStr = modelStr.replace(/\n/g, ' '); - console.log("Model: ", modelStr); + console.log('Model: ', modelStr); const exprs = z3.ast_from_string(modelStr); console.log(exprs); - })().catch(e => { console.error('error', e); process.exit(1); -}); \ No newline at end of file +}); diff --git a/src/api/js/examples/low-level/example-raw.ts b/src/api/js/examples/low-level/example-raw.ts index 68e7997e6f9..4cdb075ab0f 100644 --- a/src/api/js/examples/low-level/example-raw.ts +++ b/src/api/js/examples/low-level/example-raw.ts @@ -59,7 +59,9 @@ import { init, Z3_error_code } from '../../build/node.js'; console.log('confirming error messages work:', Z3.get_error_msg(ctx, Z3.get_error_code(ctx))); Z3.global_param_set('verbose', '0'); - let result = await Z3.eval_smtlib2_string(ctx, ` + let result = await Z3.eval_smtlib2_string( + ctx, + ` (declare-const p Bool) (declare-const q Bool) (declare-const r Bool) @@ -68,7 +70,8 @@ import { init, Z3_error_code } from '../../build/node.js'; (assert ((_ pbeq 5 2 1 3 3 2) p q r s t)) (check-sat) (get-model) - `); + `, + ); console.log('checking string evaluation', result); Z3.dec_ref(ctx, strAst); diff --git a/src/api/js/package-lock.json b/src/api/js/package-lock.json index 432e0056888..3e3911ec69a 100644 --- a/src/api/js/package-lock.json +++ b/src/api/js/package-lock.json @@ -14,13 +14,12 @@ "devDependencies": { "@types/jest": "^27.5.1", "@types/node": "^17.0.8", - "@types/prettier": "^2.6.1", "@types/sprintf-js": "^1.1.2", "check-engine": "^1.10.1", "iter-tools": "^7.3.1", "jest": "^28.1.0", "npm-run-all": "^4.1.5", - "prettier": "^2.5.1", + "prettier": "^3.4.2", "rimraf": "^3.0.2", "sprintf-js": "^1.1.2", "ts-expect": "^1.3.0", @@ -5880,15 +5879,16 @@ } }, "node_modules/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", + "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", "dev": true, + "license": "MIT", "bin": { - "prettier": "bin-prettier.js" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=10.13.0" + "node": ">=14" }, "funding": { "url": "https://github.com/prettier/prettier?sponsor=1" diff --git a/src/api/js/package.json b/src/api/js/package.json index bc6e006d4be..e272ad45695 100644 --- a/src/api/js/package.json +++ b/src/api/js/package.json @@ -42,13 +42,12 @@ "devDependencies": { "@types/jest": "^27.5.1", "@types/node": "^17.0.8", - "@types/prettier": "^2.6.1", "@types/sprintf-js": "^1.1.2", "check-engine": "^1.10.1", "iter-tools": "^7.3.1", "jest": "^28.1.0", "npm-run-all": "^4.1.5", - "prettier": "^2.5.1", + "prettier": "^3.4.2", "rimraf": "^3.0.2", "sprintf-js": "^1.1.2", "ts-expect": "^1.3.0", diff --git a/src/api/js/scripts/build-wasm.ts b/src/api/js/scripts/build-wasm.ts index a5b57ee3ff7..970ed06f01a 100644 --- a/src/api/js/scripts/build-wasm.ts +++ b/src/api/js/scripts/build-wasm.ts @@ -40,7 +40,13 @@ function spawnSync(command: string, opts: SpawnOptions = {}) { } function exportedFuncs(): string[] { - const extras = ['_malloc', '_free', '_set_throwy_error_handler', '_set_noop_error_handler', ...asyncFuncs.map(f => '_async_' + f)]; + const extras = [ + '_malloc', + '_free', + '_set_throwy_error_handler', + '_set_noop_error_handler', + ...asyncFuncs.map(f => '_async_' + f), + ]; // TODO(ritave): This variable is unused in original script, find out if it's important const fns: any[] = (functions as any[]).filter(f => !asyncFuncs.includes(f.name)); diff --git a/src/api/js/scripts/make-ts-wrapper.ts b/src/api/js/scripts/make-ts-wrapper.ts index 6eb81c80609..277684d2b8f 100644 --- a/src/api/js/scripts/make-ts-wrapper.ts +++ b/src/api/js/scripts/make-ts-wrapper.ts @@ -10,7 +10,7 @@ assert(process.argv.length === 4, `Usage: ${process.argv[0]} ${process.argv[1]} const wrapperFilePath = process.argv[2]; const typesFilePath = process.argv[3]; -function makeTsWrapper() { +async function makeTsWrapper() { const subtypes = { __proto__: null, Z3_sort: 'Z3_ast', @@ -464,13 +464,18 @@ export async function init(initModule: any) { `; return { - wrapperDocument: prettier.format(wrapperDocument, { singleQuote: true, parser: 'typescript' }), - typesDocument: prettier.format(typesDocument, { singleQuote: true, parser: 'typescript' }), + wrapperDocument: await prettier.format(wrapperDocument, { singleQuote: true, parser: 'typescript' }), + typesDocument: await prettier.format(typesDocument, { singleQuote: true, parser: 'typescript' }), }; } -const { wrapperDocument, typesDocument } = makeTsWrapper(); -fs.mkdirSync(path.dirname(wrapperFilePath), { recursive: true }); -fs.writeFileSync(wrapperFilePath, wrapperDocument); -fs.mkdirSync(path.dirname(typesFilePath), { recursive: true }); -fs.writeFileSync(typesFilePath, typesDocument); +(async () => { + const { wrapperDocument, typesDocument } = await makeTsWrapper(); + fs.mkdirSync(path.dirname(wrapperFilePath), { recursive: true }); + fs.writeFileSync(wrapperFilePath, wrapperDocument); + fs.mkdirSync(path.dirname(typesFilePath), { recursive: true }); + fs.writeFileSync(typesFilePath, typesDocument); +})().catch(e => { + console.error(e); + process.exit(1); +}); diff --git a/src/api/js/src/high-level/high-level.test.ts b/src/api/js/src/high-level/high-level.test.ts index b3ed6e82f69..fb8805d99a7 100644 --- a/src/api/js/src/high-level/high-level.test.ts +++ b/src/api/js/src/high-level/high-level.test.ts @@ -374,7 +374,6 @@ describe('high-level', () => { }); }); - describe('bitvectors', () => { it('can do simple proofs', async () => { const { BitVec, Concat, Implies, isBitVecVal } = api.Context('main'); @@ -413,7 +412,6 @@ describe('high-level', () => { }); }); - describe('arrays', () => { it('Example 1', async () => { const Z3 = api.Context('main'); @@ -848,7 +846,7 @@ describe('high-level', () => { }); describe('optimize', () => { - it("maximization problem over reals", async () => { + it('maximization problem over reals', async () => { const { Real, Optimize } = api.Context('main'); const opt = new Optimize(); @@ -858,9 +856,9 @@ describe('high-level', () => { opt.add(x.ge(0), y.ge(0), z.ge(0)); opt.add(x.le(1), y.le(1), z.le(1)); - opt.maximize(x.mul(7).add(y.mul(9)).sub(z.mul(3))) + opt.maximize(x.mul(7).add(y.mul(9)).sub(z.mul(3))); - const result = await opt.check() + const result = await opt.check(); expect(result).toStrictEqual('sat'); const model = opt.model(); expect(model.eval(x).eqIdentity(Real.val(1))).toBeTruthy(); @@ -868,7 +866,7 @@ describe('high-level', () => { expect(model.eval(z).eqIdentity(Real.val(0))).toBeTruthy(); }); - it("minimization problem over integers using addSoft", async () => { + it('minimization problem over integers using addSoft', async () => { const { Int, Optimize } = api.Context('main'); const opt = new Optimize(); @@ -884,7 +882,7 @@ describe('high-level', () => { opt.add(z.le(5)); opt.minimize(z); - const result = await opt.check() + const result = await opt.check(); expect(result).toStrictEqual('sat'); const model = opt.model(); expect(model.eval(x).eqIdentity(Int.val(1))).toBeTruthy(); @@ -892,5 +890,4 @@ describe('high-level', () => { expect(model.eval(z).eqIdentity(Int.val(5))).toBeTruthy(); }); }); - }); diff --git a/src/api/js/src/high-level/types.ts b/src/api/js/src/high-level/types.ts index 02b95951ead..a9bad412598 100644 --- a/src/api/js/src/high-level/types.ts +++ b/src/api/js/src/high-level/types.ts @@ -37,6 +37,7 @@ export type AnyExpr = export type AnyAst = AnyExpr | AnySort | FuncDecl; /** @hidden */ +// prettier-ignore export type SortToExprMap, Name extends string = 'main'> = S extends BoolSort ? Bool : S extends ArithSort @@ -50,6 +51,7 @@ export type SortToExprMap, Name extends string = 'main'> : never; /** @hidden */ +// prettier-ignore export type CoercibleFromMap, Name extends string = 'main'> = S extends bigint ? Arith : S extends number | CoercibleRational @@ -75,6 +77,7 @@ export type CoercibleToExpr = number | bigint | bo export type CoercibleToArith = number | string | bigint | CoercibleRational | Arith; /** @hidden */ +// prettier-ignore export type CoercibleToMap, Name extends string = 'main'> = T extends Bool ? boolean | Bool : T extends IntNum @@ -1656,6 +1659,7 @@ export interface SMTSet = [Sort, ...Sort[]], diff --git a/src/api/js/src/low-level/index.ts b/src/api/js/src/low-level/index.ts index 4a842bab6bb..1791eae27cd 100644 --- a/src/api/js/src/low-level/index.ts +++ b/src/api/js/src/low-level/index.ts @@ -1,4 +1,4 @@ export * from './types.__GENERATED__'; export * from './wrapper.__GENERATED__'; -export type Z3Core = Awaited>['Z3']; -export type Z3LowLevel = Awaited>; +export type Z3Core = Awaited>['Z3']; +export type Z3LowLevel = Awaited>; From bd41f85b2c28aebb513e8797ce564022e8648eac Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Fri, 6 Dec 2024 12:57:14 -0800 Subject: [PATCH 4/6] update typescript and fix errors --- src/api/js/package-lock.json | 220 ++++++++++++++++++------ src/api/js/package.json | 4 +- src/api/js/src/high-level/high-level.ts | 2 +- src/api/js/src/high-level/types.ts | 2 +- 4 files changed, 169 insertions(+), 59 deletions(-) diff --git a/src/api/js/package-lock.json b/src/api/js/package-lock.json index 3e3911ec69a..16b017d3b7f 100644 --- a/src/api/js/package-lock.json +++ b/src/api/js/package-lock.json @@ -25,8 +25,8 @@ "ts-expect": "^1.3.0", "ts-jest": "^28.0.3", "ts-node": "^10.8.0", - "typedoc": "^0.23.16", - "typescript": "^4.8.4" + "typedoc": "^0.27.3", + "typescript": "^5.7.2" }, "engines": { "node": ">=16" @@ -713,6 +713,18 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@gerrit0/mini-shiki": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-1.24.1.tgz", + "integrity": "sha512-PNP/Gjv3VqU7z7DjRgO3F9Ok5frTKqtpV+LJW1RzMcr2zpRk0ulhEWnbcNGXzPC7BZyWMIHrkfQX2GZRfxrn6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/engine-oniguruma": "^1.24.0", + "@shikijs/types": "^1.24.0", + "@shikijs/vscode-textmate": "^9.3.0" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1456,6 +1468,35 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.24.0.tgz", + "integrity": "sha512-Eua0qNOL73Y82lGA4GF5P+G2+VXX9XnuUxkiUuwcxQPH4wom+tE39kZpBFXfUuwNYxHSkrSxpB1p4kyRW0moSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "1.24.0", + "@shikijs/vscode-textmate": "^9.3.0" + } + }, + "node_modules/@shikijs/types": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.24.0.tgz", + "integrity": "sha512-aptbEuq1Pk88DMlCe+FzXNnBZ17LCiLIGWAeCWhoFDzia5Q5Krx3DgnULLiouSdd6+LUM39XwXGppqYE0Ghtug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^9.3.0", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-9.3.0.tgz", + "integrity": "sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==", + "dev": true, + "license": "MIT" + }, "node_modules/@sinclair/typebox": { "version": "0.24.46", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.46.tgz", @@ -1554,6 +1595,16 @@ "@types/node": "*" } }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", @@ -1612,6 +1663,13 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/yargs": { "version": "17.0.13", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", @@ -2316,6 +2374,19 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -5371,12 +5442,6 @@ "node": ">=6" } }, - "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true - }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -5414,6 +5479,16 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -5505,18 +5580,38 @@ "tmpl": "1.0.5" } }, - "node_modules/marked": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.1.1.tgz", - "integrity": "sha512-0cNMnTcUJPxbA6uWmCmjWz4NJRe/0Xfk2NhXCUHjew9qJzFN20krFnsUe7QynwqOwa5m1fZ4UDg0ycKFVC0ccw==", + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, - "bin": { - "marked": "bin/marked.js" + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" }, - "engines": { - "node": ">= 12" + "bin": { + "markdown-it": "bin/markdown-it.mjs" } }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" + }, "node_modules/memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", @@ -5933,6 +6028,16 @@ "node": ">= 6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -6095,17 +6200,6 @@ "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", "dev": true }, - "node_modules/shiki": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.11.1.tgz", - "integrity": "sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==", - "dev": true, - "dependencies": { - "jsonc-parser": "^3.0.0", - "vscode-oniguruma": "^1.6.1", - "vscode-textmate": "^6.0.0" - } - }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -6605,24 +6699,26 @@ } }, "node_modules/typedoc": { - "version": "0.23.16", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.16.tgz", - "integrity": "sha512-rumYsCeNRXlyuZVzefD7050n7ptL2uudsCJg50dY0v/stKniqIlRpvx/F/6expC0/Q6Dbab+g/JpZuB7Sw90FA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.27.3.tgz", + "integrity": "sha512-oWT7zDS5oIaxYL5yOikBX4cL99CpNAZn6mI24JZQxsYuIHbtguSSwJ7zThuzNNwSE0wqhlfTSd99HgqKu2aQXQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { + "@gerrit0/mini-shiki": "^1.24.0", "lunr": "^2.3.9", - "marked": "^4.0.19", - "minimatch": "^5.1.0", - "shiki": "^0.11.1" + "markdown-it": "^14.1.0", + "minimatch": "^9.0.5", + "yaml": "^2.6.1" }, "bin": { "typedoc": "bin/typedoc" }, "engines": { - "node": ">= 14.14" + "node": ">= 18" }, "peerDependencies": { - "typescript": "4.6.x || 4.7.x || 4.8.x" + "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x" } }, "node_modules/typedoc/node_modules/brace-expansion": { @@ -6630,33 +6726,39 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/typedoc/node_modules/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/typical": { @@ -6669,6 +6771,13 @@ "node": ">=8" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -6750,18 +6859,6 @@ "spdx-expression-parse": "^3.0.0" } }, - "node_modules/vscode-oniguruma": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz", - "integrity": "sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==", - "dev": true - }, - "node_modules/vscode-textmate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-6.0.0.tgz", - "integrity": "sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==", - "dev": true - }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -6897,6 +6994,19 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/yaml": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", + "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/yargs": { "version": "17.7.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", diff --git a/src/api/js/package.json b/src/api/js/package.json index e272ad45695..8e0b4c912eb 100644 --- a/src/api/js/package.json +++ b/src/api/js/package.json @@ -53,8 +53,8 @@ "ts-expect": "^1.3.0", "ts-jest": "^28.0.3", "ts-node": "^10.8.0", - "typedoc": "^0.23.16", - "typescript": "^4.8.4" + "typedoc": "^0.27.3", + "typescript": "^5.7.2" }, "license": "MIT", "dependencies": { diff --git a/src/api/js/src/high-level/high-level.ts b/src/api/js/src/high-level/high-level.ts index 7f1859c67b4..405d4a5e5a9 100644 --- a/src/api/js/src/high-level/high-level.ts +++ b/src/api/js/src/high-level/high-level.ts @@ -741,7 +741,7 @@ export function createApi(Z3: Z3Core): Z3HighLevel { }, val( - value: bigint | number | boolean, + value: bigint | number | boolean | string, bits: Bits | BitVecSort, ): BitVecNum { if (value === true) { diff --git a/src/api/js/src/high-level/types.ts b/src/api/js/src/high-level/types.ts index a9bad412598..37d9c8f2157 100644 --- a/src/api/js/src/high-level/types.ts +++ b/src/api/js/src/high-level/types.ts @@ -71,7 +71,7 @@ export type CoercibleToBitVec = number | bigint | boolean | CoercibleRational | Expr; +export type CoercibleToExpr = number | string | bigint | boolean | CoercibleRational | Expr; /** @hidden */ export type CoercibleToArith = number | string | bigint | CoercibleRational | Arith; From d0f8db45d345cb2a9a30ad6a85cf2c25e61cad0a Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Fri, 6 Dec 2024 13:03:40 -0800 Subject: [PATCH 5/6] update emscripten version in CI --- .github/workflows/wasm-release.yml | 2 +- .github/workflows/wasm.yml | 2 +- src/api/js/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/wasm-release.yml b/.github/workflows/wasm-release.yml index ed5dacec810..ce7145703e8 100644 --- a/.github/workflows/wasm-release.yml +++ b/.github/workflows/wasm-release.yml @@ -10,7 +10,7 @@ defaults: working-directory: src/api/js env: - EM_VERSION: 3.1.15 + EM_VERSION: 3.1.73 permissions: contents: read # to fetch code (actions/checkout) diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml index 8e157f5a465..0ea9688f1ee 100644 --- a/.github/workflows/wasm.yml +++ b/.github/workflows/wasm.yml @@ -10,7 +10,7 @@ defaults: working-directory: src/api/js env: - EM_VERSION: 3.1.15 + EM_VERSION: 3.1.73 permissions: contents: read # to fetch code (actions/checkout) diff --git a/src/api/js/README.md b/src/api/js/README.md index f53428bbdee..3b695073feb 100644 --- a/src/api/js/README.md +++ b/src/api/js/README.md @@ -7,7 +7,7 @@ The readme for the bindings themselves is located in [`PUBLISHED_README.md`](./P ## Building -You'll need to have emscripten set up, along with all of its dependencies. The easiest way to do that is with [emsdk](https://github.com/emscripten-core/emsdk). +You'll need to have emscripten set up, along with all of its dependencies. The easiest way to do that is with [emsdk](https://github.com/emscripten-core/emsdk). Newer versions of emscripten may break the build; you can find the version used in CI in [this file](https://github.com/Z3Prover/z3/blob/master/.github/workflows/wasm.yml#L13). Then run `npm i` to install dependencies, `npm run build:ts` to build the TypeScript wrapper, and `npm run build:wasm` to build the wasm artifact. From e6b78c34eb4311355bc3227699cfdfad91cc40aa Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Fri, 6 Dec 2024 13:05:21 -0800 Subject: [PATCH 6/6] update js readme about tests --- src/api/js/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/js/README.md b/src/api/js/README.md index 3b695073feb..d5d8f14eca3 100644 --- a/src/api/js/README.md +++ b/src/api/js/README.md @@ -17,4 +17,4 @@ Consult the file [build-wasm.ts](https://github.com/Z3Prover/z3/blob/master/src/ ## Tests -Current tests are very minimal: [`test-ts-api.ts`](./test-ts-api.ts) contains a couple real cases translated very mechanically from [this file](https://github.com/Z3Prover/z3/blob/90fd3d82fce20d45ed2eececdf65545bab769503/examples/c/test_capi.c). +Run `npm test` after building to run tests.