From a1e0fc3b88ed4305f942fadbea66b29a3934721c Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 16 Aug 2019 15:03:52 +0200 Subject: crypto worker refactoring --- src/crypto/nodeEmscriptenLoader.ts | 102 +++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/crypto/nodeEmscriptenLoader.ts (limited to 'src/crypto/nodeEmscriptenLoader.ts') diff --git a/src/crypto/nodeEmscriptenLoader.ts b/src/crypto/nodeEmscriptenLoader.ts new file mode 100644 index 000000000..6d6a7306b --- /dev/null +++ b/src/crypto/nodeEmscriptenLoader.ts @@ -0,0 +1,102 @@ + +import { EmscEnvironment } from "./emscInterface"; +import { CryptoImplementation } from "./cryptoImplementation"; + +import fs = require("fs"); + +export class NodeEmscriptenLoader { + private cachedEmscEnvironment: EmscEnvironment | undefined = undefined; + private cachedEmscEnvironmentPromise: + | Promise + | undefined = undefined; + + private async getWasmBinary(): Promise { + // @ts-ignore + const akonoGetData = global.__akono_getData; + if (akonoGetData) { + // We're running embedded node on Android + console.log("reading wasm binary from akono"); + const data = akonoGetData("taler-emscripten-lib.wasm"); + // The data we get is base64-encoded binary data + let buf = new Buffer(data, 'base64'); + return new Uint8Array(buf); + + } else { + // We're in a normal node environment + const binaryPath = __dirname + "/../../../emscripten/taler-emscripten-lib.wasm"; + console.log("reading from", binaryPath); + const wasmBinary = new Uint8Array(fs.readFileSync(binaryPath)); + return wasmBinary; + } + } + + async getEmscriptenEnvironment(): Promise { + if (this.cachedEmscEnvironment) { + return this.cachedEmscEnvironment; + } + + if (this.cachedEmscEnvironmentPromise) { + return this.cachedEmscEnvironmentPromise; + } + + let lib: any; + + const wasmBinary = await this.getWasmBinary(); + + return new Promise((resolve, reject) => { + // Arguments passed to the emscripten prelude + const libArgs = { + wasmBinary, + onRuntimeInitialized: () => { + if (!lib) { + console.error("fatal emscripten initialization error"); + return; + } + this.cachedEmscEnvironmentPromise = undefined; + this.cachedEmscEnvironment = new EmscEnvironment(lib); + resolve(this.cachedEmscEnvironment); + }, + }; + + // Make sure that TypeScript doesn't try + // to check the taler-emscripten-lib. + const indirectRequire = require; + + const g = global; + + // unavoidable hack, so that emscripten detects + // the environment as node even though importScripts + // is present. + + // @ts-ignore + const savedImportScripts = g.importScripts; + // @ts-ignore + delete g.importScripts; + // @ts-ignore + const savedCrypto = g.crypto; + // @ts-ignore + delete g.crypto; + + // Assume that the code is run from the build/ directory. + const libFn = indirectRequire( + "../../../emscripten/taler-emscripten-lib.js", + ); + lib = libFn(libArgs); + + // @ts-ignore + g.importScripts = savedImportScripts; + // @ts-ignore + g.crypto = savedCrypto; + + if (!lib) { + throw Error("could not load taler-emscripten-lib.js"); + } + + if (!lib.ccall) { + throw Error( + "sanity check failed: taler-emscripten lib does not have 'ccall'", + ); + } + }); + } +} -- cgit v1.2.3