'use strict'; // generates c wrappers with off-thread versions of specified functions let path = require('path'); let { functions } = require('./parse-api.js'); let asyncFns = require('./async-fns.js'); let wrappers = []; for (let fnName of asyncFns) { 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}(${fn.params.map(p => `${p.name}`).join(', ')}); } `.trim(), ); } console.log(`// THIS FILE IS AUTOMATICALLY GENERATED BY ${path.basename(__filename)} // DO NOT EDIT IT BY HAND #include #include #include "../../z3.h" template void wrapper(Args&&... args) { std::thread t([...args = std::forward(args)] { try { auto result = fn(args...); MAIN_THREAD_ASYNC_EM_ASM({ resolve_async($0); }, result); } catch (...) { MAIN_THREAD_ASYNC_EM_ASM({ reject_async('failed with unknown exception'); }); throw; } }); t.detach(); } template void wrapper_str(Args&&... args) { std::thread t([...args = std::forward(args)] { try { auto result = fn(args...); MAIN_THREAD_ASYNC_EM_ASM({ resolve_async(UTF8ToString($0)); }, result); } catch (...) { MAIN_THREAD_ASYNC_EM_ASM({ reject_async('failed with unknown exception'); }); throw; } }); t.detach(); } ${wrappers.join('\n\n')}`);