added a way to build for and run asmjs

pull/63/head
Paul Shapiro 6 years ago
parent 979a130ee3
commit 3d64d6e0ba

@ -1,9 +1,9 @@
cmake_minimum_required(VERSION 3.4.1)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
project(MyMoneroCoreCpp)
option(MM_EM_ASMJS "Build for asmjs instead of wasm" OFF)
#
include_directories("build/boost/include") # must exist already - run bin/build-boost-emscripten.sh
#
@ -181,44 +181,53 @@ set_target_properties(
#
#
#
set(
EMCC_LINKER_FLAGS
set (
EMCC_LINKED_FLAGS___MM_BASE
#unsure if the -I...boost..include is necessary here due to include above
"-Wall -std=c++11 \
"-Wall -std=c++11 \
--bind -s MODULARIZE=1 \
-s 'EXPORT_NAME=\"MyMoneroCoreCpp\"' \
-Oz \
--llvm-lto 1 \
-s WASM=1 \
-s ASSERTIONS=0 \
-s ERROR_ON_UNDEFINED_SYMBOLS=0 \
--post-js ${CMAKE_CURRENT_LIST_DIR}/src/module-post.js \
-s \"BINARYEN_METHOD='native-wasm'\" \
-s ASSERTIONS=0 \
-s NO_DYNAMIC_EXECUTION=1 \
-s \"BINARYEN_TRAP_MODE='clamp'\" \
-s ALLOW_MEMORY_GROWTH=1 \
-s PRECISE_F32=1 \
-s 'EXPORT_NAME=\"MyMoneroCoreCpp\"' \
"
#
# -O0 \
# -g \
# --llvm-lto 0 \
# -s WASM=1 \
# -s ASSERTIONS=1 \
# -s DEMANGLE_SUPPORT=1 \
# -s ERROR_ON_UNDEFINED_SYMBOLS=0 \
#
#
# --closure 1 \
# -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]' \
# -s DISABLE_EXCEPTION_CATCHING=0 \
# -s EXPORTED_FUNCTIONS='[\"_sc_reduce\", \"_sc_reduce32\", \"_sc_check\", \"_sc_add\", \"_ge_fromfe_frombytes_vartime\", \"_ge_mul8\", \"_ge_p1p1_to_p3\", \"_ge_p3_tobytes\", \"_ge_scalarmult\", \"_ge_tobytes\", \"_sc_sub\", \"_sc_mulsub\", \"_ge_scalarmult_base\", \"_sc_0\", \"_ge_double_scalarmult_base_vartime\", \"_ge_double_scalarmult_precomp_vartime\", \"_ge_frombytes_vartime\", \"_ge_dsm_precomp\"]' \
# -s SAFE_HEAP=1
# -s DISABLE_EXCEPTION_CATCHING=0 \
)
if (MM_EM_ASMJS)
message(STATUS "> Building asmjs")
set(
EMCC_LINKER_FLAGS
"${EMCC_LINKED_FLAGS___MM_BASE} \
-s WASM=0 \
-s \"BINARYEN_METHOD='asmjs'\" \
-s ALLOW_MEMORY_GROWTH=0 \
"
# --closure 1 \
)
else ()
message(STATUS "> Building wasm")
set(
EMCC_LINKER_FLAGS
"${EMCC_LINKED_FLAGS___MM_BASE} \
-s WASM=1 \
-s \"BINARYEN_METHOD='native-wasm'\" \
-s ALLOW_MEMORY_GROWTH=1 \
--post-js ${CMAKE_CURRENT_LIST_DIR}/src/module-post.js \
"
# -g \
)
endif ()
# -s EXPORTED_FUNCTIONS='[\"_sc_reduce\", \"_sc_reduce32\", \"_sc_check\", \"_sc_add\", \"_ge_fromfe_frombytes_vartime\", \"_ge_mul8\", \"_ge_p1p1_to_p3\", \"_ge_p3_tobytes\", \"_ge_scalarmult\", \"_ge_tobytes\", \"_sc_sub\", \"_sc_mulsub\", \"_ge_scalarmult_base\", \"_sc_0\", \"_ge_double_scalarmult_base_vartime\", \"_ge_double_scalarmult_precomp_vartime\", \"_ge_frombytes_vartime\", \"_ge_dsm_precomp\"]' \
message(STATUS "EMCC_LINKER_FLAGS ${EMCC_LINKER_FLAGS}")
# extract the filename without an extension (NAME_WE)
add_executable(
@ -226,7 +235,7 @@ add_executable(
${SRC_FILES}
)
set_target_properties(MyMoneroCoreCpp PROPERTIES LINK_FLAGS "${EMCC_LINKER_FLAGS}")
#set_target_properties(MyMoneroCoreCpp PROPERTIES SUFFIX ".html")
# set_target_properties(MyMoneroCoreCpp PROPERTIES SUFFIX ".html")
target_link_libraries(
MyMoneroCoreCpp

@ -34,7 +34,7 @@ There is also a chain of build scripts which is capable of building a JS module
`monero_utils/MyMoneroCoreCpp.(js,wasm)` are produced by transpiling Monero core C++ code to JS via Emscripten (See *Building MyMoneroCoreCpp*). A Module instance is managed by `monero_utils/MyMoneroCoreBridge.js`.
A ready-made entrypoint for interacting with `MyMoneroCoreBridge` is located at `monero_utils/monero_utils.js` with usage `require("./monero_utils/monero_utils").then(function(monero_utils) { })` or `
A ready-made entrypoint for interacting with `MyMoneroCoreBridge` is located at `monero_utils/monero_utils.js` with usage `require("./monero_utils/monero_utils").then(function(monero_utils) { })`.
Many related utility functions and data structures are located throughout `monero_utils/`, `cryptonote_utils`, and `hostAPI`. Usage below.
@ -180,7 +180,7 @@ var decoded = monero_utils.decode_address("…", nettype);
Each of these functions is implemented<sup>*</sup> in `monero_utils/MyMoneroCoreBridge.js`, which you access through `monero_utils/monero_utils.js`<sup>\*\*</sup>.
The arguments and return values for these functions are very explicitly called out by [MyMoneroCoreBridge.js](https://github.com/mymonero/mymonero-core-js/blob/develop/monero_utils/MyMoneroCoreBridge.js), so that will be the most complete documentation for the moment. Return values are all embedded within a JS dictionary unless they're singular values. Errors are thrown when functions are called via `monero_utils`.
The arguments and return values for these functions are explicitly called out by [MyMoneroCoreBridge.js](https://github.com/mymonero/mymonero-core-js/blob/develop/monero_utils/MyMoneroCoreBridge.js), so that will be the most complete documentation for the moment. Return values are all embedded within a JS dictionary unless they're singular values. Errors are thrown when functions are called via `monero_utils`.
<sup>* The functions' actual implementations are in WebAssembly which is produced via emscripten from exactly matching C++ functions in [mymonero-core-cpp](https://github.com/mymonero/mymonero-core-cpp). This allows core implementation to be shared across all platforms.</sup>
@ -319,6 +319,7 @@ Or if you want to copy the build products to their distribution locations,
* Execute `bin/archive-emcpp.sh`
**NOTE** If you want to build for asmjs instead of wasm, edit `CMakeLists.txt` to turn the `MM_EM_ASMJS` option to `ON` before you run either the `build` or `archive` script. Finally, at every place you instantiate a `MyMoneroCoreBridge` instance, ensure that the `asmjs` flag passed as an init argument is set to `true` (If not, loading will not work).
## Contributors

@ -1,5 +1,7 @@
#!/bin/sh
bin/build-emcpp.sh &&
cp build/MyMoneroCoreCpp.js monero_utils/ &&
cp build/MyMoneroCoreCpp.wasm monero_utils/
bin/build-emcpp.sh &&
cp build/MyMoneroCoreCpp.js monero_utils/;
cp build/MyMoneroCoreCpp.wasm monero_utils/;
cp build/MyMoneroCoreCpp.wast monero_utils/;
cp build/MyMoneroCoreCpp.js.mem monero_utils/

@ -4,6 +4,6 @@
mkdir -p build &&
cd build &&
emconfigure cmake .. &&
emconfigure cmake .. &&
emmake cmake --build . &&
emmake make .

@ -624,9 +624,9 @@ module.exports = function(options)
const ENVIRONMENT_IS_WORKER = typeof importScripts==="function";
const ENVIRONMENT_IS_NODE = typeof process==="object" && process.browser !== true && typeof require==="function" && ENVIRONMENT_IS_WORKER == false; // we want this to be true for Electron but not for a WebView
const ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
var Module_template =
{
locateFile: function(filename, scriptDirectory)
var Module_template = {}
if (options.asmjs != true || options.wasm == true) { // wasm
Module_template["locateFile"] = function(filename, scriptDirectory)
{
// if (options["locateFile"]) {
// return options["locateFile"](filename, scriptDirectory)
@ -666,22 +666,18 @@ module.exports = function(options)
//
return fullPath
}
//
// NOTE: This requires src/module-post.js to be included as post-js in CMakeLists.txt under a wasm build
require("./MyMoneroCoreCpp")(Module_template).ready.then(function(thisModule)
{
const instance = new MyMoneroCoreBridge(thisModule);
resolve(instance);
}).catch(function(e) {
console.error("Error loading MyMoneroCoreCpp:", e);
reject(e);
});
} else { // this is synchronous so we can resolve immediately
resolve(new MyMoneroCoreBridge(require("./MyMoneroCoreCpp")(Module_template)))
}
// if (ENVIRONMENT_IS_WEB && ENVIRONMENT_IS_NODE) { // that means it's probably electron-renderer
// const fs = require("fs");
// const path = require("path");
// const filepath = path.normalize(path.join(__dirname, "MyMoneroCoreCpp.wasm"));
// const wasmBinary = fs.readFileSync(filepath)
// console.log("wasmBinary", wasmBinary)
// Module_template["wasmBinary"] = wasmBinary
// }
require("./MyMoneroCoreCpp")(Module_template).ready.then(function(thisModule)
{
const instance = new MyMoneroCoreBridge(thisModule);
resolve(instance);
}).catch(function(e) {
console.error("Error loading MyMoneroCoreCpp:", e);
reject(e);
});
});
};

File diff suppressed because one or more lines are too long

Binary file not shown.

@ -60,7 +60,7 @@ local_fns.isReady = false;
module.exports = local_fns;
//
//
const coreBridgeLoading_promise = require("./MyMoneroCoreBridge")({});
const coreBridgeLoading_promise = require("./MyMoneroCoreBridge")({asmjs: false});
coreBridgeLoading_promise.then(function(this__coreBridge_instance)
{
coreBridge_instance = this__coreBridge_instance;

@ -96,7 +96,7 @@ const moneroUtils_promise = new Promise(function(resolve, reject)
}
_try(0)
} else {
const coreBridgeLoading_promise = require('./MyMoneroCoreBridge')({}); // this returns a promise
const coreBridgeLoading_promise = require('./MyMoneroCoreBridge')({ asmjs: false }); // this returns a promise
coreBridgeLoading_promise.catch(function(e)
{
console.error("Error: ", e);

@ -28,15 +28,8 @@
"use strict";
//
console.time("Load module")
async function tests()
function tests(Module)
{
const monero_utils = await require("../monero_utils/monero_utils")
const Module = monero_utils.Module;
console.timeEnd("Load module")
console.log("Module", Module)
//
{
@ -198,4 +191,13 @@ async function tests()
console.log("decodeRct ret", ret_string)
}
}
tests()
console.time("Load module")
require('../monero_utils/MyMoneroCoreBridge')({asmjs: false}).then(function(instance)
{
console.timeEnd("Load module")
console.log("Loaded instance:", instance)
tests(instance.Module)
}).catch(function(e)
{
console.error("Exception while loading module:", e)
})
Loading…
Cancel
Save