Skip to content

Commit

Permalink
added wrapper
Browse files Browse the repository at this point in the history
added simple build script
MGmotors committed Nov 7, 2019
1 parent 23890a4 commit e6e5629
Showing 3 changed files with 156 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
release/
17 changes: 17 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/sh

# create needed folders if they dont exist already
mkdir -p release

# clean
rm ./release/MiniSATWrapper.js
cd ./src
make clean

# rebuild
emmake make
cd ..
cp ./src_js/MiniSATWrapper.js ./release/MiniSATWrapper.js
cp ./src/build/release/bin/minisat.js ./release/minisat.js
cp ./src/build/release/bin/minisat.wasm ./release/minisat.wasm
cp ./src/build/release/bin/minisat.wast ./release/minisat.wast
138 changes: 138 additions & 0 deletions src_js/MiniSATWrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/**
* A wrapper around the emscripten generated Module.
*/

// import the gluecode for miniSAT generated by emscripten
let miniSAT = require('./minisat.js');

let MiniSATWrapper = {};
/**
* Self-executing function to build the MiniSATWrapper
*/
(function (MiniSATWrapper) {
/**
* The constant page size for WebAssembly
*/
let WASM_PAGE_SIZE_BYTES = 65536;

/**
* How many Memory we need in Bytes. This value should be the same as the value of the '-s TOTAL_MEMORY' option for emcc during the build process.
*/
let INITIAL_TOTAL_MEMORY_BYTES = 67108864;

/**
* Number of memory pages we need
*/
MiniSATWrapper._INITAL_MEMORY_PAGES = Math.floor(INITIAL_TOTAL_MEMORY_BYTES / WASM_PAGE_SIZE_BYTES);

/**
* The Path where we look for the wasm binary created by emscripten.
*/
MiniSATWrapper._WASM_PATH = 'minisat.wasm';

/**
* Once we compiled the MiniSat binary we store it here. We can then instanciate the binary multiple times. Once for each run of MiniSat.
*/
MiniSATWrapper._compiledModule = undefined;

/**
* We create only one memory and save it here. We reset the memory between MiniSat runs.
*/
MiniSATWrapper._memory = undefined;

/**
* We cannot run more then one MiniSat instace at a time because they share the memory. So _locked should be true while MiniSat runs.
*/
MiniSATWrapper._locked = false;

/**
* We pass this function to the emscripten generated Module. The Module uses the function to get an instance of the MiniSat binary.
* See https://emscripten.org/docs/api_reference/module.html#Module.instantiateWasm.
*/
MiniSATWrapper._WASM_INITIALIZER = function (info, callback) {
WebAssembly.instantiate(MiniSATWrapper._compiledModule, info).then(instance => {
callback(instance);
});
return {};
}

/**
* Sets where we look for the wasm binary.
* This is only possible while the binary is not loaded and compiled.
*/
MiniSATWrapper.setWasmPath = function (path) {
if (MiniSATWrapper._compiledModule) {
return Promise.reject('The Binary was already loaded. Setting the path is only possible before the binary is loaded during init().');
} else {
MiniSATWrapper._WASM_PATH = path;
return Promise.resolve('Ok');
}
}

/**
* Loads and compiles the wasm binary and creates the memory we need.
*/
MiniSATWrapper.init = function () {
return fetch(MiniSATWrapper._WASM_PATH).then(response => {
return response.arrayBuffer()
}).then(buffer => {
return WebAssembly.compile(buffer);
}).then(compiledModule => {
MiniSATWrapper._compiledModule = compiledModule;
MiniSATWrapper._memory = new WebAssembly.Memory({ initial: MiniSATWrapper._INITAL_MEMORY_PAGES });
return Promise.resolve();
});
}

/**
* Run miniSAT.
* MiniSATWrapper.init() gets called if needed.
* @param {string} data - The contents of the file you want to work on with miniSAT
* @param {string[]} options - Further commandline options.
* @returns {Promise<[string,string]>} - array containing the console output at index 0 and the contents of the miniSAT generated file at position 1
*/
MiniSATWrapper.run = function (data, options) {
// Is there a miniSAT instance running?
if (MiniSATWrapper._locked) {
return Promise.reject('miniSAT is buisy at the Moment. Please try again.');
}
// Now one instance is running
MiniSATWrapper._locked = true;
// We build a promise...
let r = Promise.resolve('');
// if the MiniSATWrapper is not initalized, we need to initalize first.
if (!MiniSATWrapper._memory || !MiniSATWrapper._compiledModule) {
r = r.then(_ => {
return MiniSATWrapper.init();
}).then(_ => {
return Promise.resolve();
});
}
//
r = r.then(_ => {
// build a new promise that resolves with the result of the miniSAT invocation
return new Promise((resolve, reject) => {
// We want to use our existing memory and the precompiled binary
let moduleOpts = {
instantiateWasm: MiniSATWrapper._WASM_INITIALIZER,
'asm.js': false,
'wasmMemory': MiniSATWrapper._memory
};
// initalize the miniSAT module,...
miniSAT(moduleOpts).then(miniSATInstance=> {
// ... then invoke the main Method.
let result = miniSATInstance.runMiniSAT(data, options);
// Cleanup the Memory for the next run.
new Uint32Array(MiniSATWrapper._memory.buffer).fill(0);
// Memory is cleaned, and the miniSAT can continue
MiniSATWrapper._locked = false;
//
resolve(result);
});
});
});
return r;
}
})(MiniSATWrapper);

module.exports = MiniSATWrapper;

0 comments on commit e6e5629

Please sign in to comment.