Skip to content

Commit

Permalink
Asynchronous WasmThemis initialization (#507)
Browse files Browse the repository at this point in the history
It turns out that WebAssembly is compiled and loaded asynchronously [1].
There is an option for synchronous compilation, but Chrome and Electron
support only asynchronous loading. This means that one cannot simply
call C functions. We need to wait for WebAssembly to be compiled and
Emscripten runtime to boot. This is performed automatically if the whole
application is compiled by Emscripten, but Themis is a library.

Emscripten provides an "onRuntimeInitialized" callback which is called
when Emscripten startup is complete and C functions can be called.
Expose an interface to this callback as JavaScript promise which is
resolved once initialization is complete. The users should call Themis
functions only after this promise is resolved. (Alternatively, they can
wait for a second or two.)

This behavior is not reproduced by unit tests because Mocha launches
asynchronously too and it manages to start testing after WasmThemis
loading is complete. But we can test that the promise is resolved.

[1]: https://emscripten.org/docs/compiling/WebAssembly.html#wasm-files-and-compilation
  • Loading branch information
ilammy committed Jul 23, 2019
1 parent 3bb9256 commit 8c8acea
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/wrappers/themis/wasm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ Then import it into your project:
const themis = require('wasm-themis')
```

Finally, wait for WebAssembly code to be loaded:

```javascript
themis.initialized.then(function() {
//
// Now you can use "themis" functions
//
})
```

([_Browserify_ your code][browserify] to use WasmThemis in web apps.)

[browserify]: http://browserify.org
Expand Down
18 changes: 18 additions & 0 deletions src/wrappers/themis/wasm/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
* WasmThemis module entry point.
*/

const libthemis = require('./libthemis.js')

Object.assign(module.exports
, require('./secure_cell.js')
, require('./secure_comparator.js')
Expand All @@ -25,3 +27,19 @@ Object.assign(module.exports
, require('./secure_session.js')
, require('./themis_error.js')
)

let resolveInitialization
let initializationPromise = new Promise(function(resolve) {
resolveInitialization = resolve
})

/**
* Themis initialization promise.
*
* Resolved when Themis is loaded and ready to use.
*/
module.exports.initialized = initializationPromise

libthemis["onRuntimeInitialized"] = function() {
resolveInitialization()
}
7 changes: 7 additions & 0 deletions src/wrappers/themis/wasm/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ describe('wasm-themis', function() {
() => new Uint8Array([27, 18, 28, 18, 28]),
{ value: [3, 14, 15, 92, 6] }
]
describe('initialization', function() {
it('resolves "initialized" promise', function(done) {
themis.initialized.then(function() {
done()
})
})
})
describe('KeyPair', function() {
it('generates EC key pairs', function() {
let pair = new themis.KeyPair()
Expand Down

0 comments on commit 8c8acea

Please sign in to comment.