mirror of
https://github.com/Z3Prover/z3
synced 2025-06-08 15:13:23 +00:00
Add high level bindings for js (#6048)
* [Draft] Added unfinished code for high level bindings for js * * Rewrote structure of js api files * Added more high level apis * Minor fixes * Fixed wasm github action * Fix JS test * Removed ContextOptions type * * Added Ints to JS Api * Added tests to JS Api * Added run-time checks for contexts * Removed default contexts * Merged Context and createContext so that the api behaves the sames as in other constructors * Added a test for Solver * Added Reals * Added classes for IntVals and RealVals * Added abillity to specify logic for solver * Try to make CI tests not fail * Changed APIs after a round of review * Fix test * Added BitVectors * Made sort into getter * Added initial JS docs * Added more coercible types * Removed done TODOs
This commit is contained in:
parent
3d00d1d56b
commit
7fdcbbaee9
37 changed files with 15973 additions and 643 deletions
119
src/api/js/scripts/make-cc-wrapper.ts
Normal file
119
src/api/js/scripts/make-cc-wrapper.ts
Normal file
|
@ -0,0 +1,119 @@
|
|||
// generates c wrappers with off-thread versions of specified functions
|
||||
|
||||
import path from 'path';
|
||||
import { asyncFuncs } from './async-fns';
|
||||
import { functions } from './parse-api';
|
||||
|
||||
export function makeCCWrapper() {
|
||||
let wrappers = [];
|
||||
|
||||
for (let fnName of asyncFuncs) {
|
||||
let fn = functions.find(f => f.name === fnName);
|
||||
if (fn == null) {
|
||||
throw new Error(`could not find definition for ${fnName}`);
|
||||
}
|
||||
let wrapper;
|
||||
if (fn.cRet === 'Z3_string') {
|
||||
wrapper = `wrapper_str`;
|
||||
} else if (['int', 'unsigned', 'void'].includes(fn.cRet) || fn.cRet.startsWith('Z3_')) {
|
||||
wrapper = `wrapper`;
|
||||
} else {
|
||||
throw new Error(`async function with unknown return type ${fn.cRet}`);
|
||||
}
|
||||
|
||||
wrappers.push(
|
||||
`
|
||||
extern "C" void async_${fn.name}(${fn.params
|
||||
.map(p => `${p.isConst ? 'const ' : ''}${p.cType}${p.isPtr ? '*' : ''} ${p.name}${p.isArray ? '[]' : ''}`)
|
||||
.join(', ')}) {
|
||||
${wrapper}<decltype(&${fn.name}), &${fn.name}>(${fn.params.map(p => `${p.name}`).join(', ')});
|
||||
}
|
||||
`.trim(),
|
||||
);
|
||||
}
|
||||
|
||||
return `// THIS FILE IS AUTOMATICALLY GENERATED BY ${path.basename(__filename)}
|
||||
// DO NOT EDIT IT BY HAND
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <emscripten.h>
|
||||
|
||||
#include "../../z3.h"
|
||||
|
||||
template<typename Fn, Fn fn, typename... Args>
|
||||
void wrapper(Args&&... args) {
|
||||
std::thread t([...args = std::forward<Args>(args)] {
|
||||
try {
|
||||
auto result = fn(args...);
|
||||
MAIN_THREAD_ASYNC_EM_ASM({
|
||||
resolve_async($0);
|
||||
}, result);
|
||||
} catch (std::exception& e) {
|
||||
MAIN_THREAD_ASYNC_EM_ASM({
|
||||
reject_async(new Error(UTF8ToString($0)));
|
||||
}, e.what());
|
||||
} catch (...) {
|
||||
MAIN_THREAD_ASYNC_EM_ASM({
|
||||
reject_async('failed with unknown exception');
|
||||
});
|
||||
}
|
||||
});
|
||||
t.detach();
|
||||
}
|
||||
|
||||
template<typename Fn, Fn fn, typename... Args>
|
||||
void wrapper_str(Args&&... args) {
|
||||
std::thread t([...args = std::forward<Args>(args)] {
|
||||
try {
|
||||
auto result = fn(args...);
|
||||
MAIN_THREAD_ASYNC_EM_ASM({
|
||||
resolve_async(UTF8ToString($0));
|
||||
}, result);
|
||||
} catch (std::exception& e) {
|
||||
MAIN_THREAD_ASYNC_EM_ASM({
|
||||
reject_async(new Error(UTF8ToString($0)));
|
||||
}, e.what());
|
||||
} catch (...) {
|
||||
MAIN_THREAD_ASYNC_EM_ASM({
|
||||
reject_async(new Error('failed with unknown exception'));
|
||||
});
|
||||
}
|
||||
});
|
||||
t.detach();
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Z3Exception : public std::exception {
|
||||
public:
|
||||
const std::string m_msg;
|
||||
Z3Exception(const std::string& msg) : m_msg(msg) {}
|
||||
virtual const char* what() const throw () {
|
||||
return m_msg.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
void throwy_error_handler(Z3_context ctx, Z3_error_code c) {
|
||||
throw Z3Exception(Z3_get_error_msg(ctx, c));
|
||||
}
|
||||
|
||||
void noop_error_handler(Z3_context ctx, Z3_error_code c) {
|
||||
// pass
|
||||
}
|
||||
|
||||
extern "C" void set_throwy_error_handler(Z3_context ctx) {
|
||||
Z3_set_error_handler(ctx, throwy_error_handler);
|
||||
}
|
||||
|
||||
extern "C" void set_noop_error_handler(Z3_context ctx) {
|
||||
Z3_set_error_handler(ctx, noop_error_handler);
|
||||
}
|
||||
|
||||
${wrappers.join('\n\n')}
|
||||
`;
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
console.log(makeCCWrapper());
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue