Skip to content

Commit

Permalink
Polyfill crypto to shim std::random_device in wasm builds
Browse files Browse the repository at this point in the history
  • Loading branch information
nick-thompson committed Feb 17, 2024
1 parent 0898ae4 commit df93faf
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 149 deletions.
133 changes: 57 additions & 76 deletions js/packages/offline-renderer/elementary-wasm.js

Large diffs are not rendered by default.

128 changes: 57 additions & 71 deletions js/packages/web-renderer/raw/elementary-wasm.js

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions wasm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,18 @@ target_compile_features(${TargetName} PRIVATE
target_link_libraries(${TargetName} PRIVATE
elem::runtime)

set(PRE "${CMAKE_CURRENT_SOURCE_DIR}/pre.js")

# We use these flags for compiling our wasm bundle such that the exported Module
# factory function asynchronously initializes the module. It's important for the browser
# and node.js contexts, whereas we want synchronous initialization for the webaudio worklet
set(EM_FLAGS_ASYNC "-lembind --closure 1 -s WASM=1 -s WASM_ASYNC_COMPILATION=1 -s MODULARIZE=1 -s SINGLE_FILE=1 -s ALLOW_MEMORY_GROWTH=1")
set(EM_FLAGS_ASYNC "--pre-js ${PRE} -lembind --closure 1 -s WASM=1 -s WASM_ASYNC_COMPILATION=1 -s MODULARIZE=1 -s ENVIRONMENT=shell -s SINGLE_FILE=1 -s ALLOW_MEMORY_GROWTH=1")

# We use these flags for compiling our wasm bundle such that the exported Module
# factory function _synchronously_ initializes the module. We use this specifically in the
# initialization of the web audio worklet where we don't necessarily have room to wait for
# an asynchronous init
set(EM_FLAGS_SYNC "-lembind --closure 1 -s WASM=1 -s WASM_ASYNC_COMPILATION=0 -s MODULARIZE=1 -s SINGLE_FILE=1 -s ALLOW_MEMORY_GROWTH=1")
set(EM_FLAGS_SYNC "--pre-js ${PRE} -lembind --closure 1 -s WASM=1 -s WASM_ASYNC_COMPILATION=0 -s MODULARIZE=1 -s ENVIRONMENT=shell -s SINGLE_FILE=1 -s ALLOW_MEMORY_GROWTH=1")

if ($ENV{ELEM_BUILD_ASYNC})
set_target_properties(${TargetName}
Expand Down
16 changes: 16 additions & 0 deletions wasm/pre.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// We use this to shim a crypto library in the WebAudioWorklet environment, which
// is necessary for Emscripten's implementation of std::random_device, which we need
// after pulling in signalsmith-stretch.
//
// I've seen some issues on esmcripten that seem to suggest an insecure polyfill like
// this should already be provided, but I'm getting runtime assertion errors that it's
// not available. An alternative solution would be to upstream a change to the stretch
// library to rely on an injected random device in C++ territory, so that for our case
// we could inject some simple PRNG.
globalThis.crypto = {
getRandomValues: (array) => {
for (var i = 0; i < array.length; i++) {
array[i] = (Math.random() * 256) | 0;
}
}
};

0 comments on commit df93faf

Please sign in to comment.