aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Baker <dave@matrix.org>2018-09-25 17:13:29 +0100
committerDavid Baker <dave@matrix.org>2018-09-25 17:13:29 +0100
commit263b94428a24caaa5b899ed7f73b896620e6cdf4 (patch)
treedacfa7322ee472d9a09e4bd56805bae0aad215c9
parentf29d8cdd7bf1faf8294f51624c633fb05c9a0e2f (diff)
Another day, another interface
Change the interface again, hopefully this time a bit more normal. Now we wrap the emscripten module completely and just expose the high level objects. The olm library export is now imported as normal (ie. returns a module rather than a function returning a module) but has an `init` method which *must* be called. This returns a promise which resolves when the module is ready. It also rejects if the module failed to set up, unlike before (and unlike the promise-not-a-promise that emscripten returns). Generally catch failures to init the module.
-rw-r--r--Makefile28
-rw-r--r--javascript/externs.js3
-rw-r--r--javascript/olm_post.js30
-rw-r--r--javascript/olm_pre.js1
-rw-r--r--javascript/olm_prefix.js3
-rw-r--r--javascript/olm_suffix.js23
-rw-r--r--javascript/test/megolm.spec.js10
-rw-r--r--javascript/test/olm.spec.js16
-rw-r--r--javascript/test/pk.spec.js10
9 files changed, 83 insertions, 41 deletions
diff --git a/Makefile b/Makefile
index dcd5cc1..d99c8fc 100644
--- a/Makefile
+++ b/Makefile
@@ -41,11 +41,22 @@ FUZZER_BINARIES := $(addprefix $(BUILD_DIR)/,$(basename $(FUZZER_SOURCES)))
FUZZER_DEBUG_BINARIES := $(patsubst $(BUILD_DIR)/fuzzers/fuzz_%,$(BUILD_DIR)/fuzzers/debug_%,$(FUZZER_BINARIES))
TEST_BINARIES := $(patsubst tests/%,$(BUILD_DIR)/tests/%,$(basename $(TEST_SOURCES)))
JS_OBJECTS := $(addprefix $(BUILD_DIR)/javascript/,$(OBJECTS))
+
+# pre & post are the js-pre/js-post options to emcc.
+# They are injected inside the modularised code and
+# processed by the optimiser.
JS_PRE := $(wildcard javascript/*pre.js)
JS_POST := javascript/olm_outbound_group_session.js \
javascript/olm_inbound_group_session.js \
javascript/olm_pk.js \
javascript/olm_post.js
+
+# The prefix & suffix are just added onto the start & end
+# of what comes out emcc, so are outside of the modularised
+# code and not seen by the opimiser.
+JS_PREFIX := javascript/olm_prefix.js
+JS_SUFFIX := javascript/olm_suffix.js
+
DOCS := tracing/README.html \
docs/megolm.html \
docs/olm.html \
@@ -67,6 +78,15 @@ EMCCFLAGS = --closure 1 --memory-init-file 0 -s NO_FILESYSTEM=1 -s INVOKE_RUN=0
# longer needed.
EMCCFLAGS += -s NO_BROWSER=1
+# Olm generally doesn't need a lot of memory to encrypt / decrypt its usual
+# payloads (ie. Matrix messages), but we do need about 128K of heap to encrypt
+# a 64K event (enough to store the ciphertext and the plaintext, bearing in
+# mind that the plaintext can only be 48K because base64). We also have about
+# 36K of statics. So let's have 256K of memory.
+# (This can't be changed by the app with wasm since it's baked into the wasm).
+EMCCFLAGS += -s TOTAL_STACK=65536 -s TOTAL_MEMORY=262144
+
+
EMCC.c = $(EMCC) $(CFLAGS) $(CPPFLAGS) -c
EMCC.cc = $(EMCC) $(CXXFLAGS) $(CPPFLAGS) -c
EMCC_LINK = $(EMCC) $(LDFLAGS) $(EMCCFLAGS)
@@ -147,13 +167,19 @@ $(STATIC_RELEASE_TARGET): $(RELEASE_OBJECTS)
js: $(JS_TARGET)
.PHONY: js
-$(JS_TARGET): $(JS_OBJECTS) $(JS_PRE) $(JS_POST) $(JS_EXPORTED_FUNCTIONS)
+# Note that the output file we give to emcc determines the name of the
+# wasm file baked into the js, hence messing around outputting to olm.js
+# and then renaming it.
+$(JS_TARGET): $(JS_OBJECTS) $(JS_PRE) $(JS_POST) $(JS_EXPORTED_FUNCTIONS) $(JS_PREFIX) $(JS_SUFFIX)
EMCC_CLOSURE_ARGS="--externs $(JS_EXTERNS)" $(EMCC_LINK) \
$(foreach f,$(JS_PRE),--pre-js $(f)) \
$(foreach f,$(JS_POST),--post-js $(f)) \
-s "EXPORTED_FUNCTIONS=@$(JS_EXPORTED_FUNCTIONS)" \
-s "EXTRA_EXPORTED_RUNTIME_METHODS=$(JS_EXTRA_EXPORTED_RUNTIME_METHODS)" \
$(JS_OBJECTS) -o $@
+ mv $@ javascript/olmtmp.js
+ cat $(JS_PREFIX) javascript/olmtmp.js $(JS_SUFFIX) > $@
+ rm javascript/olmtmp.js
build_tests: $(TEST_BINARIES)
diff --git a/javascript/externs.js b/javascript/externs.js
index 8ec5b02..752e937 100644
--- a/javascript/externs.js
+++ b/javascript/externs.js
@@ -1 +1,4 @@
var OLM_OPTIONS;
+var olm_exports;
+var onInitSuccess;
+var onInitFail;
diff --git a/javascript/olm_post.js b/javascript/olm_post.js
index 071021c..9e0294a 100644
--- a/javascript/olm_post.js
+++ b/javascript/olm_post.js
@@ -464,27 +464,11 @@ olm_exports["get_library_version"] = restore_stack(function() {
];
});
-// export the olm functions into the environment.
-//
-// make sure that we do this *after* populating olm_exports, so that we don't
-// get a half-built window.Olm if there is an exception.
-
-if (typeof module !== 'undefined' && module.exports) {
- // node / browserify
- for (var olm_export in olm_exports) {
- if (olm_exports.hasOwnProperty(olm_export)) {
- Module[olm_export] = olm_exports[olm_export];
- }
- }
-}
-
-if (typeof(window) !== 'undefined') {
- // We've been imported directly into a browser. Define the global 'Olm' object.
- // (we do this even if module.exports was defined, because it's useful to have
- // Olm in the global scope for browserified and webpacked apps.)
- window["Olm"] = olm_exports;
-}
-
-Module.then(function() {
+Module['onRuntimeInitialized'] = function() {
OLM_ERROR = Module['_olm_error']();
-});
+ if (onInitSuccess) onInitSuccess();
+};
+
+Module['onAbort'] = function(err) {
+ if (onInitFail) onInitFail(err);
+};
diff --git a/javascript/olm_pre.js b/javascript/olm_pre.js
index 673b868..4feff97 100644
--- a/javascript/olm_pre.js
+++ b/javascript/olm_pre.js
@@ -1,4 +1,3 @@
-var olm_exports = {};
var get_random_values;
if (typeof(window) !== 'undefined') {
diff --git a/javascript/olm_prefix.js b/javascript/olm_prefix.js
new file mode 100644
index 0000000..b33dfe9
--- /dev/null
+++ b/javascript/olm_prefix.js
@@ -0,0 +1,3 @@
+var olm_exports = {};
+var onInitSuccess;
+var onInitFail;
diff --git a/javascript/olm_suffix.js b/javascript/olm_suffix.js
new file mode 100644
index 0000000..023c0a5
--- /dev/null
+++ b/javascript/olm_suffix.js
@@ -0,0 +1,23 @@
+olm_exports['init'] = function() {
+ return new Promise(function(resolve, reject) {
+ onInitSuccess = function() {
+ resolve();
+ };
+ onInitFail = function(err) {
+ reject(err);
+ };
+ Module();
+ });
+};
+
+if (typeof(window) !== 'undefined') {
+ // We've been imported directly into a browser. Define the global 'Olm' object.
+ // (we do this even if module.exports was defined, because it's useful to have
+ // Olm in the global scope for browserified and webpacked apps.)
+ window["Olm"] = olm_exports;
+}
+
+// Emscripten sets the module exports to be its module
+// with wrapped c functions. Clobber it with our higher
+// level wrapper class.
+module.exports = olm_exports;
diff --git a/javascript/test/megolm.spec.js b/javascript/test/megolm.spec.js
index 9d5eb72..241d4bd 100644
--- a/javascript/test/megolm.spec.js
+++ b/javascript/test/megolm.spec.js
@@ -1,5 +1,6 @@
/*
Copyright 2016 OpenMarket Ltd
+Copyright 2018 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -16,17 +17,18 @@ limitations under the License.
"use strict";
-var Olm = require('../olm')();
+var Olm = require('../olm');
describe("megolm", function() {
var aliceSession, bobSession;
beforeEach(function(done) {
- Olm.then(function() {
+ Olm.init().then(function() {
+ aliceSession = new Olm.OutboundGroupSession();
+ bobSession = new Olm.InboundGroupSession();
+
done();
});
- aliceSession = new Olm.OutboundGroupSession();
- bobSession = new Olm.InboundGroupSession();
});
afterEach(function() {
diff --git a/javascript/test/olm.spec.js b/javascript/test/olm.spec.js
index 94fa87b..77dd712 100644
--- a/javascript/test/olm.spec.js
+++ b/javascript/test/olm.spec.js
@@ -1,5 +1,6 @@
/*
Copyright 2016 OpenMarket Ltd
+Copyright 2018 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -16,7 +17,7 @@ limitations under the License.
"use strict";
-var Olm = require('../olm')();
+var Olm = require('../olm');
if (!Object.keys) {
Object.keys = function(o) {
@@ -33,14 +34,15 @@ describe("olm", function() {
beforeEach(function(done) {
// This should really be in a beforeAll, but jasmine-node
// doesn't support that
- Olm.then(function() {
+ debugger;
+ Olm.init().then(function() {
+ aliceAccount = new Olm.Account();
+ bobAccount = new Olm.Account();
+ aliceSession = new Olm.Session();
+ bobSession = new Olm.Session();
+
done();
});
-
- aliceAccount = new Olm.Account();
- bobAccount = new Olm.Account();
- aliceSession = new Olm.Session();
- bobSession = new Olm.Session();
});
afterEach(function() {
diff --git a/javascript/test/pk.spec.js b/javascript/test/pk.spec.js
index 9f7dbfd..007882f 100644
--- a/javascript/test/pk.spec.js
+++ b/javascript/test/pk.spec.js
@@ -16,7 +16,7 @@ limitations under the License.
"use strict";
-var Olm = require('../olm')();
+var Olm = require('../olm');
if (!Object.keys) {
Object.keys = function(o) {
@@ -30,12 +30,12 @@ describe("pk", function() {
var encryption, decryption;
beforeEach(function(done) {
- Olm.then(function() {
+ Olm.init().then(function() {
+ encryption = new Olm.PkEncryption();
+ decryption = new Olm.PkDecryption();
+
done();
});
-
- encryption = new Olm.PkEncryption();
- decryption = new Olm.PkDecryption();
});
afterEach(function () {