├── .babelrc ├── .gitignore ├── LICENSE ├── README.md ├── benchmark ├── .gitkeep └── benchmark.js ├── bin ├── .gitkeep └── build.sh ├── compiler ├── es5 │ ├── eufa-asyn-worker.js │ ├── eufa-library.js │ ├── eufa-post-compile.js │ └── eufa-umd-wrapper.js ├── eufa-asyn-worker.js ├── eufa-library.js ├── eufa-post-compile.js └── eufa-umd-wrapper.js ├── dist ├── .gitignore ├── .gitkeep ├── eufa-asyn-worker.js ├── eufa-module.data ├── eufa-module.js ├── eufa-module.wasm ├── eufa-module.wasm.map ├── eufa-module.wast ├── eufa-umd.min.js └── eufa-umd.min.js.map ├── gulpfile.js ├── package-lock.json ├── package.json ├── src ├── .gitkeep ├── array │ ├── array.h │ ├── sort.cc │ └── sort.h ├── build.cc ├── cache │ ├── cache.h │ ├── clear.cc │ ├── del.cc │ ├── freeze.cc │ ├── get.cc │ └── set.cc ├── dlib │ ├── dlib.h │ ├── dnn.cc │ ├── dnn.h │ ├── kmeans.cc │ ├── kmeans.h │ ├── library │ │ └── source.bc │ └── model │ │ └── mnist_network.mnist.dlib ├── encryptor │ ├── base64.cc │ ├── base64.h │ ├── encryptor.h │ ├── md5.cc │ ├── md5.h │ ├── sha1.cc │ └── sha1.h ├── file │ ├── file.cc │ └── file.h ├── global.cc ├── global.h ├── math │ ├── math.cc │ └── math.h ├── string │ ├── string.cc │ └── string.h └── tensorflow │ ├── bazel │ ├── BUILD │ ├── CROSSTOOL │ ├── GRAPH │ ├── LICENSE │ └── README.md │ ├── tensorflow.cc │ └── tensorflow.h ├── test ├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .postcssrc.js ├── README.md ├── build │ ├── build.js │ ├── check-versions.js │ ├── dev-client.js │ ├── dev-server.js │ ├── utils.js │ ├── vue-loader.conf.js │ ├── webpack.base.conf.js │ ├── webpack.dev.conf.js │ └── webpack.prod.conf.js ├── config │ ├── dev.env.js │ ├── index.js │ └── prod.env.js ├── index.html ├── package-lock.json ├── package.json ├── src │ ├── App.vue │ └── main.js └── static │ ├── .gitkeep │ ├── eufa-asyn-worker.js │ ├── eufa-module.wasm │ ├── mnist │ ├── t10k-images-idx3-ubyte.dat │ ├── t10k-labels-idx1-ubyte.dat │ ├── train-images-idx3-ubyte.dat │ └── train-labels-idx1-ubyte.dat │ ├── mnist_network.mnist.dlib │ └── testcases │ ├── mnist_test_1.bmp │ ├── mnist_test_3.bmp │ ├── mnist_test_4.bmp │ └── mnist_test_6.bmp └── tools ├── .gitignore ├── decode_sections.py └── setup.py /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015" 4 | ], 5 | "plugins": [] 6 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .idea/ 3 | npm-debug.log 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------- 2 | The PHP License, version 3.01 3 | Copyright (c) 1999 - 2017 The PHP Group. All rights reserved. 4 | -------------------------------------------------------------------- 5 | 6 | 7 | -------------------------------------------------------------------- 8 | The Eufa, MIT License 9 | 10 | Copyright (c) 2017 YHSPY 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in all 20 | copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 28 | SOFTWARE. 29 | -------------------------------------------------------------------- -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Eufa 2 | A high efficient utility functions library written in webassembly with profiling tools. 3 | 4 | ## Features 5 | 6 | * High efficiency; 7 | * Automatically caching WebAssembly binary into indexedDB; 8 | * UMD supported, easy to use in frontend; 9 | * Part of functions moved from [php-src](https://github.com/php/php-src); 10 | * The maximum availabe memory space is up to 64MB; 11 | * Profiling tools embedded. 12 | 13 | ## Using 14 | 15 | ```shell 16 | # Install efua through npm 17 | npm install eufa --save 18 | 19 | ``` 20 | 21 | > Please move *'eufa-module.wasm'* from `node_modules` to some place where you can fetch it by xhr call. 22 | 23 | ```javascript 24 | import eufa from 'eufa'; 25 | 26 | // Init eufa first 27 | eufa.init('static/eufa-module.wasm', () => { 28 | console.log(eufa.Encryptor.base64_encode('Hello WebAssembly, hello Eufa :)')); 29 | }); 30 | ``` 31 | 32 | ## Build 33 | 34 | ### Pre-requisite 35 | 36 | Install Emscripten SDK from official installing [website](https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html). 37 | 38 | 39 | ### Commands 40 | ```shell 41 | # Install dependencies; 42 | npm install 43 | 44 | # Build 45 | npm run build; 46 | 47 | # Run test; 48 | npm run test 49 | 50 | # Run benchmark test; 51 | npm run benchmark 52 | ``` 53 | 54 | ### Dependencies 55 | * Chrome v58 or higher (headless supported) 56 | * Node v8.2.1 57 | * NPM v5.3.0 58 | * Gulp v3.9.1 59 | * Emsdk (emscripten v1.37.13) 60 | * Binaryen latest version 61 | * DLib C++ Library latest version 62 | 63 | ### Classes 64 | 65 | * Math 66 | > Eufa.Math.i64_add 67 | 68 | > Eufa.Math.f64_add 69 | 70 | > Eufa.Math.i64_minus 71 | 72 | > Eufa.Math.f64_minus 73 | 74 | > Eufa.Math.i64_multiply 75 | 76 | > Eufa.Math.f64_multiply 77 | 78 | > Eufa.Math.i64_divide 79 | 80 | > Eufa.Math.f64_divide 81 | 82 | > Eufa.Math.i64_abs\ 83 | 84 | > Eufa.Math.f64_abs\ 85 | 86 | > Eufa.Math.i64_sqrt\ 87 | 88 | > Eufa.Math.f64_sqrt\ 89 | 90 | * String 91 | 92 | > Eufa.String.capitalize\ 93 | 94 | * Array 95 | 96 | > Eufa.Array.num_sort\ 97 | 98 | > Eufa.Array.num_rsort\ 99 | 100 | * Encryptor 101 | 102 | > Eufa.Encryptor.base64_encode\ 103 | 104 | > Eufa.Encryptor.base64_decode\ 105 | 106 | > Eufa.Encryptor.md5\ 107 | 108 | > Eufa.Encryptor.sha1\ 109 | 110 | * Cache 111 | 112 | > Eufa.Cache.set\ 113 | 114 | > Eufa.Cache.get\ 115 | 116 | > Eufa.Cache.del\ 117 | 118 | > Eufa.Cache.clear\<\> 119 | 120 | ## Tools (WIP) 121 | Eufa try embedding some useful wasm profiling tools which wrote in Python, feel free to use them according to the following documentation. 122 | 123 | ### Installation 124 | ```shell 125 | # Install package; 126 | python3 tools/setup.py install 127 | ``` 128 | 129 | 130 | ### Using 131 | ```shell 132 | # Analyze the sections of a wasm module; 133 | eufa-ds --module 134 | ``` 135 | 136 | 137 | ## Copyright 138 | 139 | The Eufa, MIT License. 140 | The PHP License, version 3.01. 141 | 142 | -------------------------------------------------------------------------------- /benchmark/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/benchmark/.gitkeep -------------------------------------------------------------------------------- /benchmark/benchmark.js: -------------------------------------------------------------------------------- 1 | const CDP = require('chrome-remote-interface'); 2 | const chromeLauncher = require('chrome-launcher'); 3 | const fs = require('fs'); 4 | const Table = require('easy-table'); 5 | const ora = require('ora'); 6 | const chalk = require('chalk'); 7 | 8 | // Launch chrome in headless mode; 9 | var spinner = ora('[Eufa] calculating for benchmark...'); 10 | spinner.start(); 11 | 12 | chromeLauncher.launch({ 13 | chromeFlags: ['--headless'], 14 | port: 9222 15 | }).then(chrome => { 16 | CDP(client => { 17 | const { Runtime } = client; 18 | const wasmPath = './dist/eufa-module.wasm'; 19 | const modulePath = './dist/eufa-module.js' 20 | fs.stat(wasmPath, (err, stats) => { 21 | if (stats.isFile()) { 22 | fs.readFile(wasmPath, (err, data) => { 23 | if (err) throw err; 24 | let strPresent = data.reduce((pre, value) => { 25 | return `${pre} ${value}` 26 | }); 27 | fs.readFile(modulePath, 'utf8', (err, data) => { 28 | const code = `new Promise((resolve, reject) => { 29 | var Module = {}, Eufa = {}; 30 | Module.wasmBinary = \`${strPresent}\`.trim().split(/[\\s\\r\\n]+/g).map(str => parseInt(str, 10)); 31 | function callback () { 32 | let i_testWithOperands = (method, operandCount = 2, times = 1e+7) => { 33 | let startTime = performance.now(); 34 | let sum = 0; 35 | for (let j = 0; j < times; j++) { 36 | let _x = Math.round(Math.random() * 1e+7) + 100; 37 | let _y = Math.round(Math.random() * 1e+7) + 100; 38 | if (operandCount === 1) { 39 | sum += method(_x); 40 | } 41 | if (operandCount === 2) { 42 | sum += method(_x, _y); 43 | } 44 | } 45 | return (performance.now() - startTime).toFixed(3); 46 | } 47 | 48 | let f_testWithOperands = (method, operandCount = 2, times = 1e+7) => { 49 | let startTime = performance.now(); 50 | let sum = 0; 51 | for (let j = 0; j < times; j++) { 52 | let _x = Math.random() * 1e+7 + 100; 53 | let _y = Math.random() * 1e+7 + 100; 54 | 55 | if (operandCount === 1) { 56 | sum += method(_x); 57 | } 58 | if (operandCount === 2) { 59 | sum += method(_x, _y); 60 | } 61 | } 62 | return (performance.now() - startTime).toFixed(3); 63 | } 64 | 65 | let s_testWithOperands = (method, times = 1e+7) => { 66 | let startTime = performance.now(); 67 | for (let j = 0; j < times; j++) { 68 | method('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'); 69 | } 70 | return (performance.now() - startTime).toFixed(3); 71 | } 72 | 73 | var data = [ 74 | { 75 | method: 'i64_add/+', 76 | times: '1e+7', 77 | nativeResult: i_testWithOperands((x, y) => { return x + y; }), 78 | wasmResult: i_testWithOperands(Eufa.Math.i64_add) 79 | }, 80 | { 81 | method: 'i64_minus/-', 82 | times: '1e+7', 83 | nativeResult: i_testWithOperands((x, y) => { return x - y; }), 84 | wasmResult: i_testWithOperands(Eufa.Math.i64_minus) 85 | }, 86 | { 87 | method: 'i64_multiply/*', 88 | times: '1e+7', 89 | nativeResult: i_testWithOperands((x, y) => { return x * y; }), 90 | wasmResult: i_testWithOperands(Eufa.Math.i64_multiply) 91 | }, 92 | { 93 | method: 'i64_divide//', 94 | times: '1e+7', 95 | nativeResult: i_testWithOperands((x, y) => { return x / y; }), 96 | wasmResult: i_testWithOperands(Eufa.Math.i64_divide) 97 | }, 98 | { 99 | method: 'i64_sqrt/Math.sqrt', 100 | times: '1e+7', 101 | nativeResult: i_testWithOperands(x => { return Math.sqrt(x); }, 1), 102 | wasmResult: i_testWithOperands(Eufa.Math.i64_sqrt, 1) 103 | }, 104 | { 105 | method: 'f64_sqrt/Math.sqrt', 106 | times: '1e+7', 107 | nativeResult: f_testWithOperands(x => { return Math.sqrt(x); }, 1), 108 | wasmResult: f_testWithOperands(Eufa.Math.f64_sqrt, 1) 109 | }, 110 | { 111 | method: 'ptr_capitalize/String.prototype.toUpperCase', 112 | times: '1e+6', 113 | nativeResult: s_testWithOperands(x => { return x.toUpperCase(); }, 1e+4), 114 | wasmResult: s_testWithOperands(Eufa.String.capitalize, 1e+4) 115 | } 116 | ]; 117 | 118 | resolve(JSON.stringify(data)); 119 | } 120 | ${data.replace(/\/n/g, '//n')} 121 | }).catch(err => { 122 | throw err; 123 | });`; 124 | Runtime.evaluate({ 125 | expression: code, 126 | awaitPromise: true 127 | }).then(response => { 128 | let data = JSON.parse(response.result.value); 129 | let table = new Table; 130 | data.forEach(function(item) { 131 | table.cell('Methods', item.method); 132 | table.cell('Times', item.times); 133 | table.cell('WebAssembly(ms)', item.wasmResult); 134 | table.cell('Native(ms)', item.nativeResult); 135 | table.cell('Percent(%)', (100 * (item.nativeResult - item.wasmResult) / item.nativeResult).toFixed(5)); 136 | table.newRow(); 137 | }); 138 | chrome.kill(); 139 | spinner.succeed('[Eufa] calculating for benchmark... done\n'); 140 | // Print result; 141 | console.log(table.toString()); 142 | // Exit current pricess; 143 | process.exit(0); 144 | }).catch(err => { 145 | chrome.kill(); 146 | spinner.fail(err); 147 | process.exit(1); 148 | }); 149 | }); 150 | }); 151 | } 152 | }); 153 | }).on('error', (err) => { 154 | // Cannot connect to the remote endpoint 155 | console.error(err); 156 | }); 157 | }); 158 | -------------------------------------------------------------------------------- /bin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/bin/.gitkeep -------------------------------------------------------------------------------- /bin/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Global 4 | EUFA_SOURCE_FOLDER='compiler/es5' 5 | 6 | EUFA_BABEL_TRANSFORM_LIST='eufa-post-compile.js eufa-umd-wrapper.js eufa-library.js eufa-asyn-worker.js' 7 | EUFA_POST_COMPILE_EMBED_LIST='eufa-post-compile.js' 8 | EUFA_LIBRARY='eufa-library.js' 9 | EUFA_WORKER='eufa-asyn-worker.js' 10 | 11 | # Gulp flags 12 | EUFA_UMD_WRAPPER='eufa-umd-wrapper.js' 13 | EUFA_UMD_MODULE='eufa-module.js' 14 | 15 | 16 | # Babel transform 17 | if [ $(command -v node) ] 18 | then 19 | for file in $EUFA_BABEL_TRANSFORM_LIST 20 | do 21 | node node_modules/babel-cli/bin/babel.js compiler/$file -o $EUFA_SOURCE_FOLDER/$file 22 | done 23 | else 24 | echo "[Eufa] Command 'node' not found, please install 'node' first." 25 | exit 1 26 | fi 27 | 28 | 29 | # Emcc compiling 30 | if [ $(command -v emcc) ] 31 | then 32 | # Compiling 33 | _TSTRING="" 34 | 35 | for file in $EUFA_POST_COMPILE_EMBED_LIST 36 | do 37 | _TSTRING="${_TSTRING} --post-js $EUFA_SOURCE_FOLDER/$file" 38 | done 39 | 40 | emcc src/build.cc $_TSTRING \ 41 | \ 42 | -s ASSERTIONS=0 \ 43 | -s SAFE_HEAP=0 \ 44 | -s WASM=1 \ 45 | -s TOTAL_MEMORY=64MB \ 46 | -s FORCE_FILESYSTEM=1 \ 47 | -s DISABLE_EXCEPTION_CATCHING=0 \ 48 | -s EMULATE_FUNCTION_POINTER_CASTS=0 \ 49 | -s ALIASING_FUNCTION_POINTERS=0 \ 50 | \ 51 | -O3 \ 52 | \ 53 | -std=c++11 \ 54 | \ 55 | -I/usr/local/include \ 56 | -L/usr/local/lib \ 57 | \ 58 | -o dist/eufa-module.js \ 59 | \ 60 | --js-library $EUFA_SOURCE_FOLDER/$EUFA_LIBRARY \ 61 | --use-preload-plugins \ 62 | # -Werror 63 | 64 | # Output .wast (.wat was prefered) 65 | if [ $(command -v wasm-dis) ] 66 | then 67 | wasm-dis ./dist/eufa-module.wasm $1> ./dist/eufa-module.wast 68 | else 69 | echo "[Eufa] command 'wasm-dis' not found, please check your global PATH and try again." 70 | fi 71 | else 72 | echo "[Eufa] Command 'emcc' not found, please install 'emsdk' first." 73 | exit 1 74 | fi 75 | 76 | 77 | # Copying main files 78 | cp compiler/es5/$EUFA_UMD_WRAPPER ./dist/$EUFA_UMD_WRAPPER 79 | cp compiler/es5/$EUFA_WORKER ./dist/$EUFA_WORKER 80 | 81 | 82 | # Combining and replacing 83 | if [ $(command -v gulp) ] && [ $(command -v node) ] 84 | then 85 | gulp default -m $EUFA_UMD_MODULE -w $EUFA_UMD_WRAPPER 86 | else 87 | echo "[Eufa] command 'gulp' or 'node' is not found, please install them and try again." 88 | exit 1 89 | fi 90 | 91 | exit 0 92 | -------------------------------------------------------------------------------- /compiler/es5/eufa-asyn-worker.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var getFileData = function getFileData(url) { 4 | var chunkSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1024 * 1024; 5 | 6 | var xhr = new XMLHttpRequest(); 7 | xhr.open('HEAD', url, false); 8 | xhr.send(null); 9 | if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); 10 | var datalength = Number(xhr.getResponseHeader("Content-length")); 11 | var header; 12 | var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; 13 | 14 | var chunkSize = 1024 * 1024 * 64; // Chunk size in bytes 15 | 16 | if (!hasByteServing) chunkSize = datalength; 17 | 18 | var from = 0; 19 | var to = chunkSize - 1; 20 | to = Math.min(to, datalength - 1); 21 | 22 | if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!"); 23 | if (to > datalength - 1) throw new Error("only " + datalength + " bytes available! programmer error!"); 24 | 25 | // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available. 26 | var xhr = new XMLHttpRequest(); 27 | xhr.open('GET', url, false); 28 | if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); 29 | 30 | // Some hints to the browser that we want binary data. 31 | if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer'; 32 | if (xhr.overrideMimeType) { 33 | xhr.overrideMimeType('text/plain; charset=x-user-defined'); 34 | } 35 | 36 | xhr.send(null); 37 | if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); 38 | if (xhr.response !== undefined) { 39 | return new Uint8Array(xhr.response || []); 40 | } else { 41 | return intArrayFromString(xhr.responseText || '', true); 42 | } 43 | }; 44 | 45 | onmessage = function onmessage(event) { 46 | postMessage({ 47 | content: getFileData(event.data.url) 48 | }); 49 | }; 50 | -------------------------------------------------------------------------------- /compiler/es5/eufa-library.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | mergeInto(LibraryManager.library, { 4 | print_i8_string: function print_i8_string(offset, length) { 5 | var arr = []; 6 | for (var i = 0; i < length; i++) { 7 | arr.push(Module.getValue(offset + i, 'i8')); 8 | } 9 | console.log('[Eufa-wasm-debug]', new TextDecoder().decode(new Uint8Array(arr))); 10 | }, 11 | print_i32_array: function print_i32_array(offset, length) { 12 | var arr = []; 13 | for (var i = 0; i < length; i++) { 14 | arr.push(Module.getValue(offset + 4 * i, 'i32')); 15 | } 16 | console.log('[Eufa-wasm-debug]', arr); 17 | }, 18 | print_i32: function print_i32(int) { 19 | console.log('[Eufa-wasm-debug]', int); 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /compiler/es5/eufa-post-compile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); 4 | 5 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; 6 | 7 | __ATPRERUN__.push(function () { 8 | FS.createPreloadedFile('/', 'mnist_network.mnist.dlib', Eufa.options.wasmStaticDir + 'mnist_network.mnist.dlib', true, true); 9 | }); 10 | // Push callback into execution queue 11 | __ATPOSTRUN__.push(function () { 12 | // Alias 13 | for (var key in Module) { 14 | if (Module.hasOwnProperty(key)) { 15 | Eufa[key] = Module[key]; 16 | } 17 | } 18 | 19 | // Wrapper 20 | Eufa.Math = {}, Eufa.String = {}, Eufa.Encryptor = {}, Eufa.Helper = {}, Eufa.Array = {}, Eufa.Tensorflow = {}, Eufa.Cache = {}, Eufa.DLib = {}; 21 | 22 | // Helper 23 | // Web wrokers for synchronous binary XHRs. 24 | var asyn_reader = void 0; 25 | if (typeof Worker === 'undefined' ? 'undefined' : _typeof(Worker)) { 26 | asyn_reader = new Worker(Eufa.options.wasmStaticDir + (Eufa.options.wasmWorker || 'eufa-asyn-worker.js')); 27 | } 28 | 29 | if (asyn_reader) { 30 | Eufa.Helper.asyncReader = function (parent, name, url) { 31 | var createLazyFile = function createLazyFile(parent, name, url, canRead, canWrite, content) { 32 | function LazyUint8Array() { 33 | this.lengthKnown = false; 34 | this.chunks = []; // Loaded chunks. Index is the chunk number 35 | } 36 | LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) { 37 | if (idx > this.length - 1 || idx < 0) { 38 | return undefined; 39 | } 40 | var chunkOffset = idx % this.chunkSize; 41 | var chunkNum = idx / this.chunkSize | 0; 42 | return this.getter(chunkNum)[chunkOffset]; 43 | }; 44 | LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) { 45 | this.getter = getter; 46 | }; 47 | LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() { 48 | var chunkSize = 1024 * 1024; 49 | var lazyArray = this; 50 | lazyArray.setDataGetter(function () { 51 | var chunkNum = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 52 | 53 | if (typeof lazyArray.chunks[chunkNum] === "undefined") { 54 | lazyArray.chunks[chunkNum] = content; 55 | } 56 | if (typeof lazyArray.chunks[chunkNum] === "undefined") throw new Error("doXHR failed!"); 57 | return lazyArray.chunks[chunkNum]; 58 | }); 59 | 60 | var datalength = this.getter().length; 61 | chunkSize = datalength; 62 | 63 | this._length = datalength; 64 | this._chunkSize = chunkSize; 65 | this.lengthKnown = true; 66 | }; 67 | if (typeof XMLHttpRequest !== 'undefined') { 68 | // if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc'; 69 | var lazyArray = new LazyUint8Array(); 70 | lazyArray.cacheLength(); 71 | var properties = { isDevice: false, contents: lazyArray }; 72 | } else { 73 | var properties = { isDevice: false, url: url }; 74 | } 75 | 76 | var node = FS.createFile(parent, name, properties, canRead, canWrite); 77 | // This is a total hack, but I want to get this lazy file code out of the 78 | // core of MEMFS. If we want to keep this lazy file concept I feel it should 79 | // be its own thin LAZYFS proxying calls to MEMFS. 80 | if (properties.contents) { 81 | node.contents = properties.contents; 82 | } else if (properties.url) { 83 | node.contents = null; 84 | node.url = properties.url; 85 | } 86 | // Add a function that defers querying the file size until it is asked the first time. 87 | Object.defineProperties(node, { 88 | usedBytes: { 89 | get: function get() { 90 | return this.contents.length; 91 | } 92 | } 93 | }); 94 | // override each stream op with one that tries to force load the lazy file first 95 | var stream_ops = {}; 96 | var keys = Object.keys(node.stream_ops); 97 | keys.forEach(function (key) { 98 | var fn = node.stream_ops[key]; 99 | stream_ops[key] = function forceLoadLazyFile() { 100 | if (!FS.forceLoadFile(node)) { 101 | throw new FS.ErrnoError(ERRNO_CODES.EIO); 102 | } 103 | return fn.apply(null, arguments); 104 | }; 105 | }); 106 | // use a custom read function 107 | stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) { 108 | if (!FS.forceLoadFile(node)) { 109 | throw new FS.ErrnoError(ERRNO_CODES.EIO); 110 | } 111 | var contents = stream.node.contents; 112 | if (position >= contents._length) return 0; 113 | var size = contents._length; 114 | assert(size >= 0); 115 | if (contents.slice) { 116 | // normal array 117 | for (var i = 0; i < size; i++) { 118 | buffer[offset + i] = contents[position + i]; 119 | } 120 | } else { 121 | for (var i = 0; i < size; i++) { 122 | // LazyUint8Array from sync binary XHR 123 | buffer[offset + i] = contents.get(position + i); 124 | } 125 | } 126 | return size; 127 | }; 128 | node.stream_ops = stream_ops; 129 | return node; 130 | }; 131 | asyn_reader.onmessage = function (event) { 132 | createLazyFile(parent, name, url, true, true, event.data.content); 133 | }; 134 | asyn_reader.postMessage({ url: url }); 135 | }; 136 | } 137 | 138 | Eufa.Helper.malloc_str = function (str) { 139 | // Get length, includes '\0' 140 | var _size = Module.lengthBytesUTF8(str) + 1; 141 | // Allocate memeory 142 | var _buff = Module._malloc(_size); 143 | if (!_buff) { 144 | throw '[Eufa] Unavailable to allocate memory!'; 145 | } 146 | // Copy date to memeory 147 | Module.stringToUTF8(str, _buff, _size); 148 | return [_buff, _size]; 149 | }; 150 | 151 | Eufa.Helper.cache_malloc_str = function (str) { 152 | // Get length, includes '\0' 153 | var _size = Module.lengthBytesUTF8(str) + 1; 154 | // Allocate memeory 155 | var _buff = Module["asm"]["_cache_malloc"](_size); 156 | if (!_buff) { 157 | throw '[Eufa] Unavailable to allocate memory!'; 158 | } 159 | // Copy date to memeory 160 | Module.stringToUTF8(str, _buff, _size); 161 | return [_buff, _size]; 162 | }; 163 | 164 | Eufa.Helper.call_str_memeory_method = function (method, str) { 165 | var preProcess = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 166 | 167 | var _Eufa$Helper$malloc_s = Eufa.Helper.malloc_str(str), 168 | _Eufa$Helper$malloc_s2 = _slicedToArray(_Eufa$Helper$malloc_s, 2), 169 | _buff = _Eufa$Helper$malloc_s2[0], 170 | _size = _Eufa$Helper$malloc_s2[1]; 171 | // Before process 172 | 173 | 174 | if (preProcess) { 175 | var _preProcess = preProcess(_buff, _size); 176 | 177 | var _preProcess2 = _slicedToArray(_preProcess, 2); 178 | 179 | _buff = _preProcess2[0]; 180 | _size = _preProcess2[1]; 181 | } 182 | // Core 183 | var _offset_buff = method(_buff, _size); 184 | // Read back from the same memory 185 | var result = Module.UTF8ToString(_offset_buff); 186 | // Free up memory 187 | Module._free(_buff); 188 | 189 | return result; 190 | }; 191 | 192 | Eufa.Helper.call_array_memeory_method = function (method, array) { 193 | var reverse = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 194 | 195 | var _sizeof_double = Module["asm"]["_sizeof_type_double"](); 196 | var _size = array.length * _sizeof_double; 197 | // Allocate memeory 198 | var _buff = Module._malloc(_size); 199 | // Copy date to memeory 200 | for (var i = 0; i < array.length; i++) { 201 | Module.setValue(_buff + _sizeof_double * i, array[i], 'double'); 202 | } 203 | // Core 204 | var _offset_buff = method(_buff, array.length); 205 | // Read back from the same memorys 206 | var result = []; 207 | if (!reverse) { 208 | for (var i = 0; i < array.length; i++) { 209 | result.push(Module.getValue(_offset_buff + _sizeof_double * i, 'double')); 210 | } 211 | } else { 212 | for (var i = array.length - 1; i >= 0; i--) { 213 | result.push(Module.getValue(_offset_buff + _sizeof_double * i, 'double')); 214 | } 215 | } 216 | 217 | // Free up memory 218 | Module._free(_buff); 219 | 220 | return result; 221 | }; 222 | 223 | Eufa.Helper.fetchFile = function (fileName, url) { 224 | var _Eufa$Helper$malloc_s3 = Eufa.Helper.malloc_str(fileName), 225 | _Eufa$Helper$malloc_s4 = _slicedToArray(_Eufa$Helper$malloc_s3, 2), 226 | _f_buff = _Eufa$Helper$malloc_s4[0], 227 | _f_size = _Eufa$Helper$malloc_s4[1]; 228 | 229 | var _Eufa$Helper$malloc_s5 = Eufa.Helper.malloc_str(url), 230 | _Eufa$Helper$malloc_s6 = _slicedToArray(_Eufa$Helper$malloc_s5, 2), 231 | _u_buff = _Eufa$Helper$malloc_s6[0], 232 | _u_size = _Eufa$Helper$malloc_s6[1]; 233 | 234 | Module["asm"]["_fetchFile"](_f_buff, _u_buff); 235 | Module._free(_f_buff); 236 | Module._free(_u_buff); 237 | }; 238 | 239 | // Math 240 | Eufa.Math.i64_add = Module["asm"]["_i64_add"]; 241 | Eufa.Math.f64_add = Module["asm"]["_f64_add"]; 242 | Eufa.Math.i64_minus = Module["asm"]["_i64_minus"]; 243 | Eufa.Math.f64_minus = Module["asm"]["_f64_minus"]; 244 | Eufa.Math.i64_multiply = Module["asm"]["_i64_multiply"]; 245 | Eufa.Math.f64_multiply = Module["asm"]["_f64_multiply"]; 246 | Eufa.Math.i64_divide = Module["asm"]["_i64_divide"]; 247 | Eufa.Math.f64_divide = Module["asm"]["_f64_divide"]; 248 | Eufa.Math.i64_abs = Module["asm"]["_i64_abs"]; 249 | Eufa.Math.f64_abs = Module["asm"]["_f64_abs"]; 250 | Eufa.Math.i64_sqrt = Module["asm"]["_i64_sqrt"]; 251 | Eufa.Math.f64_sqrt = Module["asm"]["_f64_sqrt"]; 252 | 253 | // Tensorflow 254 | Eufa.Tensorflow.tf_version = function () { 255 | var _buff = Module["asm"]["_tf_version"](); 256 | var result = Module.UTF8ToString(_buff); 257 | Module._free(_buff); 258 | return result; 259 | }; 260 | 261 | // String 262 | Eufa.String.capitalize = function (str) { 263 | return Eufa.Helper.call_str_memeory_method(Module["asm"]["_capitalize"], str); 264 | }; 265 | 266 | // Encryptor 267 | Eufa.Encryptor.base64_encode = function (str) { 268 | return Eufa.Helper.call_str_memeory_method(Module["asm"]["_base64_encode"], str); 269 | }; 270 | 271 | Eufa.Encryptor.base64_decode = function (str) { 272 | return Eufa.Helper.call_str_memeory_method(Module["asm"]["_base64_decode_ex"], str); 273 | }; 274 | 275 | Eufa.Encryptor.md5 = function (str) { 276 | return Eufa.Helper.call_str_memeory_method(Module["asm"]["_md5"], str, function (_buff, _size) { 277 | return [_buff, _size - 1]; 278 | }); 279 | }; 280 | 281 | Eufa.Encryptor.sha1 = function (str) { 282 | return Eufa.Helper.call_str_memeory_method(Module["asm"]["_sha1"], str, function (_buff, _size) { 283 | return [_buff, _size - 1]; 284 | }); 285 | }; 286 | 287 | Eufa.Array.num_sort = function (array) { 288 | return Eufa.Helper.call_array_memeory_method(Module["asm"]["_num_sort"], array); 289 | }; 290 | 291 | Eufa.Array.num_rsort = function (array) { 292 | return Eufa.Helper.call_array_memeory_method(Module["asm"]["_num_sort"], array, true); 293 | }; 294 | 295 | // Cache 296 | var EUFA_CACHE_TYPE_NUM = 1; 297 | var EUFA_CACHE_TYPE_STR = 2; 298 | var EUFA_CACHE_TYPE_OBJ = 3; 299 | var EUFA_CACHE_TYPE_ARR = 4; 300 | var EUFA_CACHE_TYPE_NONE = 0; 301 | Eufa.Cache.set = function (key, value) { 302 | var _Eufa$Helper$cache_ma = Eufa.Helper.cache_malloc_str(key.toString()), 303 | _Eufa$Helper$cache_ma2 = _slicedToArray(_Eufa$Helper$cache_ma, 2), 304 | _kbuff = _Eufa$Helper$cache_ma2[0], 305 | _ksize = _Eufa$Helper$cache_ma2[1]; 306 | 307 | if (Object.prototype.toString.call(value) === '[object Number]') { 308 | console.log('[Eufa] A cache of number set.'); 309 | Module["asm"]["_cache_set_type"](_kbuff, EUFA_CACHE_TYPE_NUM); 310 | Module["asm"]["_cache_set_kv_num"](_kbuff, value); 311 | } 312 | if (Object.prototype.toString.call(value) === '[object String]') { 313 | console.log('[Eufa] A cache of string set.'); 314 | 315 | var _Eufa$Helper$cache_ma3 = Eufa.Helper.cache_malloc_str(value), 316 | _Eufa$Helper$cache_ma4 = _slicedToArray(_Eufa$Helper$cache_ma3, 2), 317 | _vbuff = _Eufa$Helper$cache_ma4[0], 318 | _vsize = _Eufa$Helper$cache_ma4[1]; 319 | 320 | Module["asm"]["_cache_set_type"](_kbuff, EUFA_CACHE_TYPE_STR); 321 | Module["asm"]["_cache_set_kv_str"](_kbuff, _vbuff); 322 | } 323 | if (Object.prototype.toString.call(value) === '[object Array]') { 324 | console.log('[Eufa] A cache of array set.'); 325 | 326 | var _Eufa$Helper$cache_ma5 = Eufa.Helper.cache_malloc_str(JSON.stringify(value)), 327 | _Eufa$Helper$cache_ma6 = _slicedToArray(_Eufa$Helper$cache_ma5, 2), 328 | _vbuff = _Eufa$Helper$cache_ma6[0], 329 | _vsize = _Eufa$Helper$cache_ma6[1]; 330 | 331 | Module["asm"]["_cache_set_type"](_kbuff, EUFA_CACHE_TYPE_ARR); 332 | Module["asm"]["_cache_set_kv_str"](_kbuff, _vbuff); 333 | } 334 | if (Object.prototype.toString.call(value) === '[object Object]') { 335 | console.log('[Eufa] A cache of object set.'); 336 | 337 | var _Eufa$Helper$cache_ma7 = Eufa.Helper.cache_malloc_str(JSON.stringify(value)), 338 | _Eufa$Helper$cache_ma8 = _slicedToArray(_Eufa$Helper$cache_ma7, 2), 339 | _vbuff = _Eufa$Helper$cache_ma8[0], 340 | _vsize = _Eufa$Helper$cache_ma8[1]; 341 | 342 | Module["asm"]["_cache_set_type"](_kbuff, EUFA_CACHE_TYPE_OBJ); 343 | Module["asm"]["_cache_set_kv_str"](_kbuff, _vbuff); 344 | } 345 | }; 346 | 347 | Eufa.Cache.get = function (key) { 348 | var _Eufa$Helper$malloc_s7 = Eufa.Helper.malloc_str(key), 349 | _Eufa$Helper$malloc_s8 = _slicedToArray(_Eufa$Helper$malloc_s7, 2), 350 | _kbuff = _Eufa$Helper$malloc_s8[0], 351 | _ksize = _Eufa$Helper$malloc_s8[1]; 352 | 353 | var type = Module["asm"]["_searchTypeNode"](_kbuff); 354 | 355 | if (type === EUFA_CACHE_TYPE_NONE) { 356 | return null; 357 | } 358 | 359 | if (type === EUFA_CACHE_TYPE_NUM) { 360 | return Module["asm"]["_cache_get_kv_num"](_kbuff); 361 | } 362 | 363 | if (type === EUFA_CACHE_TYPE_STR) { 364 | return Module.UTF8ToString(Module["asm"]["_cache_get_kv_str"](_kbuff)); 365 | } 366 | 367 | if (type === EUFA_CACHE_TYPE_OBJ || type === EUFA_CACHE_TYPE_ARR) { 368 | return JSON.parse(Module.UTF8ToString(Module["asm"]["_cache_get_kv_str"](_kbuff))); 369 | } 370 | Module["asm"]["_cache_free"](_kbuff); 371 | }; 372 | 373 | Eufa.Cache.del = function (key) { 374 | var _Eufa$Helper$cache_ma9 = Eufa.Helper.cache_malloc_str(key), 375 | _Eufa$Helper$cache_ma10 = _slicedToArray(_Eufa$Helper$cache_ma9, 2), 376 | _kbuff = _Eufa$Helper$cache_ma10[0], 377 | _ksize = _Eufa$Helper$cache_ma10[1]; 378 | 379 | Module["asm"]["_cache_del_kv"](_kbuff); 380 | Module["asm"]["_cache_free"](_kbuff); 381 | }; 382 | 383 | Eufa.Cache.clear = Module["asm"]["_cache_clear"]; 384 | 385 | // DLib 386 | Eufa.DLib.testcase_kmeans = function () { 387 | return Module.UTF8ToString(Module["asm"]["_testcase_kmeans"]()); 388 | }; 389 | 390 | Eufa.DLib.testcase_dnn = function (pixelDataArray) { 391 | // Allocate memeory 392 | var _buff = Module._malloc(pixelDataArray.length); 393 | // Copy date to memeory 394 | for (var i = 0; i < pixelDataArray.length; i++) { 395 | Module.setValue(_buff + i, pixelDataArray[i], 'i8'); 396 | } 397 | 398 | var result = Module["asm"]["_testcase_dnn_mnist"](_buff); 399 | 400 | if (result > 10) { 401 | result = JSON.parse(Module.UTF8ToString(Module["asm"]["_testcase_dnn_mnist"](_buff))); 402 | console.log(result); 403 | } 404 | // Free up memory 405 | Module._free(_buff); 406 | 407 | return result; 408 | }; 409 | 410 | Eufa.DLib.testcase_dnn_mnist_train = function (folderName) { 411 | if (!folderName) { 412 | console.error("[Eufa] Empty training folders."); 413 | } 414 | 415 | var _Eufa$Helper$malloc_s9 = Eufa.Helper.malloc_str(folderName), 416 | _Eufa$Helper$malloc_s10 = _slicedToArray(_Eufa$Helper$malloc_s9, 2), 417 | _f_buff = _Eufa$Helper$malloc_s10[0], 418 | _f_size = _Eufa$Helper$malloc_s10[1]; 419 | 420 | Module["asm"]["_testcase_dnn_mnist_train"](_f_buff); 421 | Module._free(_f_buff); 422 | }; 423 | 424 | callback && callback(Eufa); 425 | }); 426 | -------------------------------------------------------------------------------- /compiler/es5/eufa-umd-wrapper.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | // Global 7 | var Eufa = {}; 8 | 9 | // Version 10 | var EUFA_VERSION = '1'; 11 | 12 | // Utilities 13 | var fetchWebAssemblyModuleBytes = function fetchWebAssemblyModuleBytes(url) { 14 | var dbVersion = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : EUFA_VERSION; 15 | 16 | var dbName = 'eufa-cache-db'; 17 | var storeName = 'eufa-cache-store'; 18 | 19 | var openDatabase = function openDatabase() { 20 | return new Promise(function (resolve, reject) { 21 | if (!window.indexedDB) { 22 | reject('[Eufa] Failed in opening cache database, not support indexedDB.'); 23 | } 24 | 25 | var request = indexedDB.open(dbName, dbVersion); 26 | request.onerror = function (err) { 27 | reject('[Eufa] Failed in opening cache database.'); 28 | }; 29 | request.onsuccess = function () { 30 | resolve(request.result); 31 | }; 32 | request.onupgradeneeded = function (event) { 33 | var db = request.result; 34 | if (db.objectStoreNames.contains(storeName)) { 35 | console.info('[Eufa] Clearing out cache db, version \'' + event.oldVersion + '\'.'); 36 | db.deleteObjectStore(storeName); 37 | } 38 | console.info('[Eufa] Creating cache db, version \'' + event.newVersion + '\'.'); 39 | db.createObjectStore(storeName); 40 | }; 41 | }); 42 | }; 43 | 44 | var lookupInDatabase = function lookupInDatabase(db) { 45 | return new Promise(function (resolve, reject) { 46 | var store = db.transaction([storeName]).objectStore(storeName); 47 | var request = store.get(url); 48 | request.onerror = function (err) { 49 | reject('[Eufa] Failed in retriving WebAssembly module via \'' + url + '\''); 50 | }; 51 | request.onsuccess = function (event) { 52 | if (request.result) { 53 | console.info('[Eufa] Succeed in reusing WebAssembly module cached in db.'); 54 | resolve(request.result); 55 | } else { 56 | reject('[Eufa] WebAssembly module \'' + url + '\' was not found!'); 57 | } 58 | }; 59 | }); 60 | }; 61 | 62 | var storeInDatabase = function storeInDatabase(db, bytes) { 63 | var store = db.transaction([storeName], 'readwrite').objectStore(storeName); 64 | var request = store.put(bytes, url); 65 | request.onerror = function (err) { 66 | console.error('[Eufa] Failed in storing WebAssembly cache: ' + err + '!'); 67 | }; 68 | request.onsuccess = function (err) { 69 | console.info('[Eufa] Succeed in storing WebAssembly cache.'); 70 | }; 71 | }; 72 | 73 | var fetchAndInstantiate = function fetchAndInstantiate() { 74 | console.info('[Eufa] Retreving WebAssembly module from remote server.'); 75 | return fetch(url).then(function (response) { 76 | return response.arrayBuffer(); 77 | }); 78 | }; 79 | 80 | return openDatabase().then(function (db) { 81 | return lookupInDatabase(db).then(function (bytes) { 82 | return bytes; 83 | }, function (err) { 84 | console.error(err); 85 | return fetchAndInstantiate().then(function (bytes) { 86 | storeInDatabase(db, bytes); 87 | return bytes; 88 | }); 89 | }); 90 | }, function (err) { 91 | console.error(err); 92 | return fetchAndInstantiate().then(function (bytes) { 93 | return bytes; 94 | }); 95 | }); 96 | }; 97 | 98 | // Mount 99 | Eufa.init = function (options, callback) { 100 | // Pre-process 101 | if (!options.wasmStaticDir) { 102 | throw '[Eufa] Initialization option "wasmStaticDir" required!'; 103 | } 104 | options.wasmStaticDir = options.wasmStaticDir.slice(-1) === '/' ? options.wasmStaticDir : options.wasmStaticDir + '/'; 105 | Eufa.options = options; 106 | fetchWebAssemblyModuleBytes(options.wasmStaticDir + (options.wasmCore || 'eufa-module.wasm'), EUFA_VERSION).then(function (bytes) { 107 | var Module = {}; 108 | // Initilization wasm bytes 109 | Module["wasmBinary"] = bytes; 110 | // Initilization memory size (64MB) 111 | Module["TOTAL_MEMORY"] = 67108864; 112 | // [ REPLACEMENT_PLACEHOLDER ] 113 | }); 114 | }; 115 | 116 | exports.default = Eufa; 117 | -------------------------------------------------------------------------------- /compiler/eufa-asyn-worker.js: -------------------------------------------------------------------------------- 1 | let getFileData = (url, chunkSize = 1024 * 1024) => { 2 | var xhr = new XMLHttpRequest(); 3 | xhr.open('HEAD', url, false); 4 | xhr.send(null); 5 | if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); 6 | var datalength = Number(xhr.getResponseHeader("Content-length")); 7 | var header; 8 | var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; 9 | 10 | var chunkSize = 1024 * 1024 * 64; // Chunk size in bytes 11 | 12 | if (!hasByteServing) chunkSize = datalength; 13 | 14 | var from = 0; 15 | var to = chunkSize - 1; 16 | to = Math.min(to, datalength - 1); 17 | 18 | if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!"); 19 | if (to > datalength - 1) throw new Error("only " + datalength + " bytes available! programmer error!"); 20 | 21 | // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available. 22 | var xhr = new XMLHttpRequest(); 23 | xhr.open('GET', url, false); 24 | if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); 25 | 26 | // Some hints to the browser that we want binary data. 27 | if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer'; 28 | if (xhr.overrideMimeType) { 29 | xhr.overrideMimeType('text/plain; charset=x-user-defined'); 30 | } 31 | 32 | xhr.send(null); 33 | if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); 34 | if (xhr.response !== undefined) { 35 | return new Uint8Array(xhr.response || []); 36 | } else { 37 | return intArrayFromString(xhr.responseText || '', true); 38 | } 39 | } 40 | 41 | onmessage = function (event) { 42 | postMessage({ 43 | content: getFileData(event.data.url) 44 | }); 45 | }; 46 | -------------------------------------------------------------------------------- /compiler/eufa-library.js: -------------------------------------------------------------------------------- 1 | mergeInto(LibraryManager.library, { 2 | print_i8_string: (offset, length) => { 3 | let arr = []; 4 | for (let i = 0; i < length; i++) { 5 | arr.push(Module.getValue(offset + i, 'i8')); 6 | } 7 | console.log('[Eufa-wasm-debug]', new TextDecoder().decode(new Uint8Array(arr))); 8 | }, 9 | print_i32_array: (offset, length) => { 10 | let arr = []; 11 | for (let i = 0; i < length; i++) { 12 | arr.push(Module.getValue(offset + 4 * i, 'i32')); 13 | } 14 | console.log('[Eufa-wasm-debug]',arr); 15 | }, 16 | print_i32: int => { 17 | console.log('[Eufa-wasm-debug]',int); 18 | } 19 | }); -------------------------------------------------------------------------------- /compiler/eufa-post-compile.js: -------------------------------------------------------------------------------- 1 | __ATPRERUN__.push(() => { 2 | FS.createPreloadedFile('/', 'mnist_network.mnist.dlib', Eufa.options.wasmStaticDir + 'mnist_network.mnist.dlib', true, true); 3 | }); 4 | // Push callback into execution queue 5 | __ATPOSTRUN__.push(() => { 6 | // Alias 7 | for (let key in Module) { 8 | if (Module.hasOwnProperty(key)) { 9 | Eufa[key] = Module[key]; 10 | } 11 | } 12 | 13 | // Wrapper 14 | Eufa.Math = {}, Eufa.String = {}, Eufa.Encryptor = {}, Eufa.Helper = {}, Eufa.Array = {}, Eufa.Tensorflow = {}, Eufa.Cache = {}, Eufa.DLib = {}; 15 | 16 | // Helper 17 | // Web wrokers for synchronous binary XHRs. 18 | let asyn_reader; 19 | if (typeof(Worker)) { 20 | asyn_reader = new Worker(Eufa.options.wasmStaticDir + (Eufa.options.wasmWorker || 'eufa-asyn-worker.js')); 21 | } 22 | 23 | if (asyn_reader) { 24 | Eufa.Helper.asyncReader = (parent, name, url) => { 25 | var createLazyFile = (parent, name, url, canRead, canWrite, content) => { 26 | function LazyUint8Array() { 27 | this.lengthKnown = false; 28 | this.chunks = []; // Loaded chunks. Index is the chunk number 29 | } 30 | LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) { 31 | if (idx > this.length-1 || idx < 0) { 32 | return undefined; 33 | } 34 | var chunkOffset = idx % this.chunkSize; 35 | var chunkNum = (idx / this.chunkSize)|0; 36 | return this.getter(chunkNum)[chunkOffset]; 37 | } 38 | LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) { 39 | this.getter = getter; 40 | } 41 | LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() { 42 | var chunkSize = 1024 * 1024; 43 | var lazyArray = this; 44 | lazyArray.setDataGetter(function(chunkNum = 0) { 45 | if (typeof(lazyArray.chunks[chunkNum]) === "undefined") { 46 | lazyArray.chunks[chunkNum] = content; 47 | } 48 | if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!"); 49 | return lazyArray.chunks[chunkNum]; 50 | }); 51 | 52 | let datalength = this.getter().length; 53 | chunkSize = datalength; 54 | 55 | this._length = datalength; 56 | this._chunkSize = chunkSize; 57 | this.lengthKnown = true; 58 | } 59 | if (typeof XMLHttpRequest !== 'undefined') { 60 | // if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc'; 61 | var lazyArray = new LazyUint8Array(); 62 | lazyArray.cacheLength(); 63 | var properties = { isDevice: false, contents: lazyArray }; 64 | } else { 65 | var properties = { isDevice: false, url: url }; 66 | } 67 | 68 | var node = FS.createFile(parent, name, properties, canRead, canWrite); 69 | // This is a total hack, but I want to get this lazy file code out of the 70 | // core of MEMFS. If we want to keep this lazy file concept I feel it should 71 | // be its own thin LAZYFS proxying calls to MEMFS. 72 | if (properties.contents) { 73 | node.contents = properties.contents; 74 | } else if (properties.url) { 75 | node.contents = null; 76 | node.url = properties.url; 77 | } 78 | // Add a function that defers querying the file size until it is asked the first time. 79 | Object.defineProperties(node, { 80 | usedBytes: { 81 | get: function() { return this.contents.length; } 82 | } 83 | }); 84 | // override each stream op with one that tries to force load the lazy file first 85 | var stream_ops = {}; 86 | var keys = Object.keys(node.stream_ops); 87 | keys.forEach(function(key) { 88 | var fn = node.stream_ops[key]; 89 | stream_ops[key] = function forceLoadLazyFile() { 90 | if (!FS.forceLoadFile(node)) { 91 | throw new FS.ErrnoError(ERRNO_CODES.EIO); 92 | } 93 | return fn.apply(null, arguments); 94 | }; 95 | }); 96 | // use a custom read function 97 | stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) { 98 | if (!FS.forceLoadFile(node)) { 99 | throw new FS.ErrnoError(ERRNO_CODES.EIO); 100 | } 101 | var contents = stream.node.contents; 102 | if (position >= contents._length) 103 | return 0; 104 | var size = contents._length; 105 | assert(size >= 0); 106 | if (contents.slice) { // normal array 107 | for (var i = 0; i < size; i++) { 108 | buffer[offset + i] = contents[position + i]; 109 | } 110 | } else { 111 | for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR 112 | buffer[offset + i] = contents.get(position + i); 113 | } 114 | } 115 | return size; 116 | }; 117 | node.stream_ops = stream_ops; 118 | return node; 119 | } 120 | asyn_reader.onmessage = event => { 121 | createLazyFile(parent, name, url, true, true, event.data.content); 122 | }; 123 | asyn_reader.postMessage({url: url}); 124 | }; 125 | } 126 | 127 | Eufa.Helper.malloc_str = str => { 128 | // Get length, includes '\0' 129 | var _size = Module.lengthBytesUTF8(str) + 1; 130 | // Allocate memeory 131 | var _buff = Module._malloc(_size); 132 | if (!_buff) { 133 | throw('[Eufa] Unavailable to allocate memory!'); 134 | } 135 | // Copy date to memeory 136 | Module.stringToUTF8(str, _buff, _size); 137 | return [_buff, _size]; 138 | } 139 | 140 | Eufa.Helper.cache_malloc_str = str => { 141 | // Get length, includes '\0' 142 | var _size = Module.lengthBytesUTF8(str) + 1; 143 | // Allocate memeory 144 | var _buff = Module["asm"]["_cache_malloc"](_size); 145 | if (!_buff) { 146 | throw('[Eufa] Unavailable to allocate memory!'); 147 | } 148 | // Copy date to memeory 149 | Module.stringToUTF8(str, _buff, _size); 150 | return [_buff, _size]; 151 | } 152 | 153 | Eufa.Helper.call_str_memeory_method = (method, str, preProcess = false) => { 154 | var [_buff, _size] = Eufa.Helper.malloc_str(str); 155 | // Before process 156 | if (preProcess) { 157 | [_buff, _size] = preProcess(_buff, _size); 158 | } 159 | // Core 160 | var _offset_buff = method(_buff, _size); 161 | // Read back from the same memory 162 | let result = Module.UTF8ToString(_offset_buff); 163 | // Free up memory 164 | Module._free(_buff); 165 | 166 | return result; 167 | } 168 | 169 | Eufa.Helper.call_array_memeory_method = (method, array, reverse = false) => { 170 | var _sizeof_double = Module["asm"]["_sizeof_type_double"]() 171 | var _size = array.length * _sizeof_double; 172 | // Allocate memeory 173 | var _buff = Module._malloc(_size); 174 | // Copy date to memeory 175 | for (var i = 0; i < array.length; i++) { 176 | Module.setValue(_buff + _sizeof_double * i, array[i], 'double'); 177 | } 178 | // Core 179 | var _offset_buff = method(_buff, array.length); 180 | // Read back from the same memorys 181 | var result = []; 182 | if (!reverse) { 183 | for (var i = 0; i < array.length; i++) { 184 | result.push(Module.getValue(_offset_buff + _sizeof_double * i, 'double')); 185 | } 186 | } else { 187 | for (var i = array.length - 1; i >= 0; i--) { 188 | result.push(Module.getValue(_offset_buff + _sizeof_double * i, 'double')); 189 | } 190 | } 191 | 192 | // Free up memory 193 | Module._free(_buff); 194 | 195 | return result; 196 | } 197 | 198 | Eufa.Helper.fetchFile = (fileName, url) => { 199 | let [_f_buff, _f_size] = Eufa.Helper.malloc_str(fileName); 200 | let [_u_buff, _u_size] = Eufa.Helper.malloc_str(url); 201 | Module["asm"]["_fetchFile"](_f_buff, _u_buff); 202 | Module._free(_f_buff); 203 | Module._free(_u_buff); 204 | } 205 | 206 | 207 | // Math 208 | Eufa.Math.i64_add = Module["asm"]["_i64_add"]; 209 | Eufa.Math.f64_add = Module["asm"]["_f64_add"]; 210 | Eufa.Math.i64_minus = Module["asm"]["_i64_minus"]; 211 | Eufa.Math.f64_minus = Module["asm"]["_f64_minus"]; 212 | Eufa.Math.i64_multiply = Module["asm"]["_i64_multiply"]; 213 | Eufa.Math.f64_multiply = Module["asm"]["_f64_multiply"]; 214 | Eufa.Math.i64_divide = Module["asm"]["_i64_divide"]; 215 | Eufa.Math.f64_divide = Module["asm"]["_f64_divide"]; 216 | Eufa.Math.i64_abs = Module["asm"]["_i64_abs"]; 217 | Eufa.Math.f64_abs = Module["asm"]["_f64_abs"]; 218 | Eufa.Math.i64_sqrt = Module["asm"]["_i64_sqrt"]; 219 | Eufa.Math.f64_sqrt = Module["asm"]["_f64_sqrt"]; 220 | 221 | // Tensorflow 222 | Eufa.Tensorflow.tf_version = () => { 223 | var _buff = Module["asm"]["_tf_version"](); 224 | var result = Module.UTF8ToString(_buff); 225 | Module._free(_buff); 226 | return result; 227 | }; 228 | 229 | // String 230 | Eufa.String.capitalize = str => { 231 | return Eufa.Helper.call_str_memeory_method(Module["asm"]["_capitalize"], str); 232 | }; 233 | 234 | // Encryptor 235 | Eufa.Encryptor.base64_encode = str => { 236 | return Eufa.Helper.call_str_memeory_method(Module["asm"]["_base64_encode"], str); 237 | } 238 | 239 | Eufa.Encryptor.base64_decode = str => { 240 | return Eufa.Helper.call_str_memeory_method(Module["asm"]["_base64_decode_ex"], str); 241 | } 242 | 243 | Eufa.Encryptor.md5 = str => { 244 | return Eufa.Helper.call_str_memeory_method(Module["asm"]["_md5"], str, (_buff, _size) => { 245 | return [_buff, _size - 1]; 246 | }); 247 | } 248 | 249 | Eufa.Encryptor.sha1 = str => { 250 | return Eufa.Helper.call_str_memeory_method(Module["asm"]["_sha1"], str, (_buff, _size) => { 251 | return [_buff, _size - 1]; 252 | }); 253 | } 254 | 255 | Eufa.Array.num_sort = array => { 256 | return Eufa.Helper.call_array_memeory_method(Module["asm"]["_num_sort"], array); 257 | } 258 | 259 | Eufa.Array.num_rsort = array => { 260 | return Eufa.Helper.call_array_memeory_method(Module["asm"]["_num_sort"], array, true); 261 | } 262 | 263 | // Cache 264 | const EUFA_CACHE_TYPE_NUM = 1; 265 | const EUFA_CACHE_TYPE_STR = 2; 266 | const EUFA_CACHE_TYPE_OBJ = 3; 267 | const EUFA_CACHE_TYPE_ARR = 4; 268 | const EUFA_CACHE_TYPE_NONE = 0; 269 | Eufa.Cache.set = (key, value) => { 270 | var [_kbuff, _ksize] = Eufa.Helper.cache_malloc_str(key.toString()); 271 | if (Object.prototype.toString.call(value) === '[object Number]') { 272 | console.log('[Eufa] A cache of number set.'); 273 | Module["asm"]["_cache_set_type"](_kbuff, EUFA_CACHE_TYPE_NUM); 274 | Module["asm"]["_cache_set_kv_num"](_kbuff, value); 275 | } 276 | if (Object.prototype.toString.call(value) === '[object String]') { 277 | console.log('[Eufa] A cache of string set.'); 278 | var [_vbuff, _vsize] = Eufa.Helper.cache_malloc_str(value); 279 | Module["asm"]["_cache_set_type"](_kbuff, EUFA_CACHE_TYPE_STR); 280 | Module["asm"]["_cache_set_kv_str"](_kbuff, _vbuff); 281 | } 282 | if (Object.prototype.toString.call(value) === '[object Array]') { 283 | console.log('[Eufa] A cache of array set.'); 284 | var [_vbuff, _vsize] = Eufa.Helper.cache_malloc_str(JSON.stringify(value)); 285 | Module["asm"]["_cache_set_type"](_kbuff, EUFA_CACHE_TYPE_ARR); 286 | Module["asm"]["_cache_set_kv_str"](_kbuff, _vbuff); 287 | } 288 | if (Object.prototype.toString.call(value) === '[object Object]') { 289 | console.log('[Eufa] A cache of object set.'); 290 | var [_vbuff, _vsize] = Eufa.Helper.cache_malloc_str(JSON.stringify(value)); 291 | Module["asm"]["_cache_set_type"](_kbuff, EUFA_CACHE_TYPE_OBJ); 292 | Module["asm"]["_cache_set_kv_str"](_kbuff, _vbuff); 293 | } 294 | } 295 | 296 | Eufa.Cache.get = key => { 297 | var [_kbuff, _ksize] = Eufa.Helper.malloc_str(key); 298 | var type = Module["asm"]["_searchTypeNode"](_kbuff); 299 | 300 | if (type === EUFA_CACHE_TYPE_NONE) { 301 | return null; 302 | } 303 | 304 | if (type === EUFA_CACHE_TYPE_NUM) { 305 | return Module["asm"]["_cache_get_kv_num"](_kbuff); 306 | } 307 | 308 | if (type === EUFA_CACHE_TYPE_STR) { 309 | return Module.UTF8ToString(Module["asm"]["_cache_get_kv_str"](_kbuff)); 310 | } 311 | 312 | if (type === EUFA_CACHE_TYPE_OBJ || type === EUFA_CACHE_TYPE_ARR) { 313 | return JSON.parse(Module.UTF8ToString(Module["asm"]["_cache_get_kv_str"](_kbuff))); 314 | } 315 | Module["asm"]["_cache_free"](_kbuff); 316 | } 317 | 318 | Eufa.Cache.del = key => { 319 | var [_kbuff, _ksize] = Eufa.Helper.cache_malloc_str(key); 320 | Module["asm"]["_cache_del_kv"](_kbuff); 321 | Module["asm"]["_cache_free"](_kbuff); 322 | } 323 | 324 | Eufa.Cache.clear = Module["asm"]["_cache_clear"]; 325 | 326 | // DLib 327 | Eufa.DLib.testcase_kmeans = () => { 328 | return Module.UTF8ToString(Module["asm"]["_testcase_kmeans"]()); 329 | } 330 | 331 | Eufa.DLib.testcase_dnn = (pixelDataArray) => { 332 | // Allocate memeory 333 | var _buff = Module._malloc(pixelDataArray.length); 334 | // Copy date to memeory 335 | for (var i = 0; i < pixelDataArray.length; i++) { 336 | Module.setValue(_buff + i, pixelDataArray[i], 'i8'); 337 | } 338 | 339 | var result = Module["asm"]["_testcase_dnn_mnist"](_buff); 340 | 341 | if (result > 10) { 342 | result = JSON.parse(Module.UTF8ToString(Module["asm"]["_testcase_dnn_mnist"](_buff))); 343 | console.log(result); 344 | } 345 | // Free up memory 346 | Module._free(_buff); 347 | 348 | return result; 349 | } 350 | 351 | Eufa.DLib.testcase_dnn_mnist_train = (folderName) => { 352 | if (!folderName) { 353 | console.error("[Eufa] Empty training folders."); 354 | } 355 | let [_f_buff, _f_size] = Eufa.Helper.malloc_str(folderName); 356 | Module["asm"]["_testcase_dnn_mnist_train"](_f_buff); 357 | Module._free(_f_buff); 358 | } 359 | 360 | callback && callback(Eufa); 361 | }); 362 | -------------------------------------------------------------------------------- /compiler/eufa-umd-wrapper.js: -------------------------------------------------------------------------------- 1 | // Global 2 | let Eufa = {}; 3 | 4 | // Version 5 | const EUFA_VERSION = '1'; 6 | 7 | // Utilities 8 | let fetchWebAssemblyModuleBytes = (url, dbVersion = EUFA_VERSION) => { 9 | const dbName = 'eufa-cache-db'; 10 | const storeName = 'eufa-cache-store'; 11 | 12 | let openDatabase = () => { 13 | return new Promise((resolve, reject) => { 14 | if (!window.indexedDB) { 15 | reject('[Eufa] Failed in opening cache database, not support indexedDB.'); 16 | } 17 | 18 | let request = indexedDB.open(dbName, dbVersion); 19 | request.onerror = err => { 20 | reject('[Eufa] Failed in opening cache database.'); 21 | }; 22 | request.onsuccess = () => { 23 | resolve(request.result) 24 | }; 25 | request.onupgradeneeded = event => { 26 | let db = request.result; 27 | if (db.objectStoreNames.contains(storeName)) { 28 | console.info(`[Eufa] Clearing out cache db, version '${event.oldVersion}'.`); 29 | db.deleteObjectStore(storeName); 30 | } 31 | console.info(`[Eufa] Creating cache db, version '${event.newVersion}'.`); 32 | db.createObjectStore(storeName) 33 | }; 34 | }); 35 | } 36 | 37 | let lookupInDatabase = (db) => { 38 | return new Promise((resolve, reject) => { 39 | let store = db.transaction([storeName]).objectStore(storeName); 40 | let request = store.get(url); 41 | request.onerror = err => { 42 | reject(`[Eufa] Failed in retriving WebAssembly module via '${url}'`); 43 | }; 44 | request.onsuccess = event => { 45 | if (request.result) { 46 | console.info('[Eufa] Succeed in reusing WebAssembly module cached in db.') 47 | resolve(request.result); 48 | } else { 49 | reject(`[Eufa] WebAssembly module '${url}' was not found!`); 50 | } 51 | }; 52 | }); 53 | } 54 | 55 | let storeInDatabase = (db, bytes) => { 56 | let store = db.transaction([storeName], 'readwrite').objectStore(storeName); 57 | let request = store.put(bytes, url); 58 | request.onerror = err => { 59 | console.error(`[Eufa] Failed in storing WebAssembly cache: ${err}!`) 60 | }; 61 | request.onsuccess = err => { 62 | console.info(`[Eufa] Succeed in storing WebAssembly cache.`) 63 | }; 64 | } 65 | 66 | let fetchAndInstantiate = () => { 67 | console.info(`[Eufa] Retreving WebAssembly module from remote server.`) 68 | return fetch(url).then(response => response.arrayBuffer()) 69 | } 70 | 71 | return openDatabase().then(db => { 72 | return lookupInDatabase(db).then(bytes => { 73 | return bytes; 74 | }, err => { 75 | console.error(err); 76 | return fetchAndInstantiate().then(bytes => { 77 | storeInDatabase(db, bytes); 78 | return bytes; 79 | }); 80 | }) 81 | }, err => { 82 | console.error(err); 83 | return fetchAndInstantiate().then(bytes => { 84 | return bytes; 85 | }); 86 | }); 87 | } 88 | 89 | // Mount 90 | Eufa.init = (options, callback) => { 91 | // Pre-process 92 | if (!options.wasmStaticDir) { 93 | throw '[Eufa] Initialization option "wasmStaticDir" required!'; 94 | } 95 | options.wasmStaticDir = options.wasmStaticDir.slice(-1) === '/' ? options.wasmStaticDir : options.wasmStaticDir + '/'; 96 | Eufa.options = options; 97 | fetchWebAssemblyModuleBytes(options.wasmStaticDir + (options.wasmCore || 'eufa-module.wasm'), EUFA_VERSION).then(bytes => { 98 | let Module = {}; 99 | // Initilization wasm bytes 100 | Module["wasmBinary"] = bytes; 101 | // Initilization memory size (64MB) 102 | Module["TOTAL_MEMORY"] = 67108864; 103 | // [ REPLACEMENT_PLACEHOLDER ] 104 | }); 105 | }; 106 | 107 | export default Eufa; 108 | -------------------------------------------------------------------------------- /dist/.gitignore: -------------------------------------------------------------------------------- 1 | *.asm.js 2 | -------------------------------------------------------------------------------- /dist/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/dist/.gitkeep -------------------------------------------------------------------------------- /dist/eufa-asyn-worker.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var getFileData = function getFileData(url) { 4 | var chunkSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1024 * 1024; 5 | 6 | var xhr = new XMLHttpRequest(); 7 | xhr.open('HEAD', url, false); 8 | xhr.send(null); 9 | if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); 10 | var datalength = Number(xhr.getResponseHeader("Content-length")); 11 | var header; 12 | var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; 13 | 14 | var chunkSize = 1024 * 1024 * 64; // Chunk size in bytes 15 | 16 | if (!hasByteServing) chunkSize = datalength; 17 | 18 | var from = 0; 19 | var to = chunkSize - 1; 20 | to = Math.min(to, datalength - 1); 21 | 22 | if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!"); 23 | if (to > datalength - 1) throw new Error("only " + datalength + " bytes available! programmer error!"); 24 | 25 | // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available. 26 | var xhr = new XMLHttpRequest(); 27 | xhr.open('GET', url, false); 28 | if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); 29 | 30 | // Some hints to the browser that we want binary data. 31 | if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer'; 32 | if (xhr.overrideMimeType) { 33 | xhr.overrideMimeType('text/plain; charset=x-user-defined'); 34 | } 35 | 36 | xhr.send(null); 37 | if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); 38 | if (xhr.response !== undefined) { 39 | return new Uint8Array(xhr.response || []); 40 | } else { 41 | return intArrayFromString(xhr.responseText || '', true); 42 | } 43 | }; 44 | 45 | onmessage = function onmessage(event) { 46 | postMessage({ 47 | content: getFileData(event.data.url) 48 | }); 49 | }; 50 | -------------------------------------------------------------------------------- /dist/eufa-module.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/dist/eufa-module.data -------------------------------------------------------------------------------- /dist/eufa-module.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/dist/eufa-module.wasm -------------------------------------------------------------------------------- /dist/eufa-module.wasm.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["src/math.cc","/Users/jason/Desktop/Repo/emsdk/emscripten/1.37.16/system/include/libcxx/math.h","src/string.cc"],"names":[],"mappings":"qpCAOA,qBAIA,qBAIA,qBAIA,qBAIA,qBAIA,qBAIA,qBAIA,qBAIA,sCCkmBA,KD9lBA,cCg3BA,UD52BA,mBAIA,qCE1CA,cAEA,iCACA,uBAOA,UAJA"} -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const gulp = require('gulp'); 3 | const rollup = require('rollup'); 4 | const rollupUglify = require('rollup-plugin-uglify'); 5 | const rollupFilesize = require('rollup-plugin-filesize'); 6 | const gulpReplace = require('gulp-replace'); 7 | const gulpClean = require('gulp-clean'); 8 | const exec = require('child_process').exec; 9 | const program = require('commander'); 10 | 11 | 12 | // Set base dir path; 13 | const basedir = './dist/'; 14 | 15 | 16 | program 17 | .option('-m, --m [value]') 18 | .option('-w, --w [value]') 19 | .parse(process.argv); 20 | 21 | 22 | gulp.task('default', () => { 23 | new Promise(function(resolve, reject) { 24 | fs.readFile(basedir + program.m, 'utf8', (err, data) => { 25 | gulp.src([basedir + program.w]) 26 | .pipe(gulpReplace('// [ REPLACEMENT_PLACEHOLDER ]', data)) 27 | // To fix for node context start 28 | .pipe(gulpReplace(/require\("fs"\)/g, 'null')) 29 | .pipe(gulpReplace(/require\("path"\)/g, 'null')) 30 | // To fix for node context end 31 | .pipe(gulp.dest('./dist/')) 32 | .on('end', resolve); 33 | }); 34 | }).then(() => { 35 | return (async () => { 36 | const bundle = await rollup.rollup({ 37 | entry: basedir + program.w, 38 | plugins: [ 39 | rollupUglify(), 40 | rollupFilesize() 41 | ] 42 | }); 43 | 44 | await bundle.write({ 45 | format: 'umd', 46 | moduleName: 'Eufa', 47 | dest: './dist/eufa-umd.min.js', 48 | sourceMap: true 49 | }); 50 | })(); 51 | }).then(() => { 52 | // Clear files 53 | gulp.src([basedir + program.w], {read: false}) 54 | .pipe(gulpClean()); 55 | }); 56 | }); 57 | 58 | 59 | gulp.task('reset', () => { 60 | return gulp 61 | .src('test/node_modules/eufa', {read: false}) 62 | .pipe(gulpClean({force: true})); 63 | }); 64 | 65 | 66 | gulp.task('test', ['reset'], () => { 67 | return Promise.all([ 68 | new Promise(function(resolve, reject) { 69 | gulp.src('package.json') 70 | .pipe(gulp.dest('test/node_modules/eufa/')) 71 | .on('end', resolve); 72 | }), 73 | new Promise(function(resolve, reject) { 74 | gulp.src('dist/eufa-umd.min.js') 75 | .pipe(gulp.dest('test/node_modules/eufa/dist')) 76 | .on('end', resolve); 77 | }), 78 | new Promise(function(resolve, reject) { 79 | gulp.src('dist/eufa-module.wasm') 80 | .pipe(gulp.dest('test/static')) 81 | .on('end', resolve); 82 | }), 83 | new Promise(function(resolve, reject) { 84 | gulp.src('dist/eufa-asyn-worker.js') 85 | .pipe(gulp.dest('test/static')) 86 | .on('end', resolve); 87 | }), 88 | // Moving models. 89 | new Promise(function(resolve, reject) { 90 | gulp.src('src/dlib/model/mnist_network.mnist.dlib') 91 | .pipe(gulp.dest('test/static')) 92 | .on('end', resolve); 93 | }) 94 | ]).then(() => { 95 | exec('cd test && npm run dev', function (err, stdout, stderr) { 96 | console.log(stdout); 97 | console.error(stderr); 98 | }).stdout.pipe(process.stdout); 99 | }); 100 | }); 101 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eufa", 3 | "version": "0.2.0", 4 | "description": "A high efficient utility functions(encryption, machine learning, etc) library written in webassembly.", 5 | "main": "dist/eufa-umd.min.js", 6 | "files": [ 7 | "dist" 8 | ], 9 | "scripts": { 10 | "test": "gulp test", 11 | "build": "sudo bash ./bin/build.sh", 12 | "benchmark": "sudo node ./benchmark/benchmark.js" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/Becavalier/Eufa.git" 17 | }, 18 | "keywords": [ 19 | "eufa", 20 | "webassembly", 21 | "utility", 22 | "library" 23 | ], 24 | "author": "YHSPY", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/Becavalier/Eufa/issues" 28 | }, 29 | "homepage": "https://github.com/Becavalier/Eufa#readme", 30 | "devDependencies": { 31 | "babel-cli": "^6.24.1", 32 | "babel-preset-es2015": "^6.24.1", 33 | "commander": "^2.11.0", 34 | "gulp": "^3.9.1", 35 | "gulp-clean": "^0.3.2", 36 | "gulp-rename": "^1.2.2", 37 | "gulp-replace": "^0.6.1", 38 | "rollup-plugin-filesize": "^1.4.2", 39 | "rollup-plugin-uglify": "^2.0.1", 40 | "chalk": "^2.0.1", 41 | "chrome-launcher": "^0.3.2", 42 | "chrome-remote-interface": "^0.24.2", 43 | "easy-table": "^1.1.0", 44 | "ora": "^1.3.0", 45 | "rollup": "^0.45.2" 46 | }, 47 | "dependencies": { 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/src/.gitkeep -------------------------------------------------------------------------------- /src/array/array.h: -------------------------------------------------------------------------------- 1 | #ifndef EUFA_ARRAY 2 | #define EUFA_ARRAY 3 | 4 | #include "../global.h" 5 | 6 | extern "C" { 7 | 8 | } 9 | 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/array/sort.cc: -------------------------------------------------------------------------------- 1 | #include "sort.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | void push2_sequence (stack &stack, double left, double right) { 8 | stack.push(right); 9 | stack.push(left); 10 | } 11 | 12 | double* quicksort (double sortArray[], double leftPart, double rightPart) { 13 | stack stack; 14 | push2_sequence(stack, leftPart, rightPart); 15 | int _lp, _rp, _mp; 16 | 17 | while(!stack.empty()) { 18 | double left = stack.top(); stack.pop(); 19 | double right = stack.top(); stack.pop(); 20 | _lp = left; 21 | _rp = right; 22 | _mp = sortArray[(_lp + _rp) / 2]; 23 | 24 | while(_lp < _rp) { 25 | while(sortArray[_lp] < _mp) _lp++; 26 | while(sortArray[_rp] > _mp) _rp--; 27 | 28 | if(_lp <= _rp) { 29 | double tmp = sortArray[_lp]; 30 | sortArray[_lp] = sortArray[_rp]; 31 | sortArray[_rp] = tmp; 32 | _lp++; 33 | _rp--; 34 | } 35 | } 36 | 37 | if(_lp < right) { 38 | push2_sequence(stack, _lp, right); 39 | } 40 | 41 | if(_rp > left) { 42 | push2_sequence(stack, left, _rp); 43 | } 44 | } 45 | 46 | return sortArray; 47 | } 48 | 49 | double* EMSCRIPTEN_KEEPALIVE num_sort (double array[], double length) { 50 | return quicksort (array, 0, length - 1); 51 | } 52 | 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | -------------------------------------------------------------------------------- /src/array/sort.h: -------------------------------------------------------------------------------- 1 | #ifndef EUFA_ARRAY_SORT 2 | #define EUFA_ARRAY_SORT 3 | 4 | #include "array.h" 5 | #include 6 | 7 | using namespace std; 8 | 9 | extern "C" { 10 | 11 | extern double* num_sort (double array[], double length); 12 | 13 | } 14 | 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/build.cc: -------------------------------------------------------------------------------- 1 | #include "global.cc" 2 | #include "math/math.cc" 3 | #include "string/string.cc" 4 | #include "encryptor/md5.cc" 5 | #include "encryptor/sha1.cc" 6 | #include "encryptor/base64.cc" 7 | #include "array/sort.cc" 8 | // #include "tensorflow/tensorflow.cc" 9 | #include "cache/set.cc" 10 | #include "cache/get.cc" 11 | #include "cache/del.cc" 12 | #include "cache/clear.cc" 13 | #include "file/file.cc" 14 | #include "dlib/kmeans.cc" 15 | #include "dlib/dnn.cc" 16 | 17 | int main() { 18 | _INIT_EUFA_CACHE_RUNTIME(); 19 | _INIT_EUFA_FILE_RUNTIME(); 20 | 21 | return 1; 22 | } 23 | -------------------------------------------------------------------------------- /src/cache/cache.h: -------------------------------------------------------------------------------- 1 | #ifndef EUFA_CACHE 2 | #define EUFA_CACHE 3 | 4 | #include "../global.h" 5 | #include "string.h" 6 | 7 | #define EUFA_CACHE_HEAD_LIST_KEY "EUFA_CACHE_HEAD" 8 | #define EUFA_CACHE_HEAD_LIST_VAL "EUFA_CACHE_HEAD_DATA" 9 | #define EUFA_CACHE_TYPE_NUM 1 10 | #define EUFA_CACHE_TYPE_STR 2 11 | 12 | 13 | extern "C" { 14 | 15 | typedef union cacheDataObject { 16 | const char* strData; 17 | double numData; 18 | } cacheDataObject; 19 | 20 | typedef struct cacheDataNode { 21 | const char* key; 22 | cacheDataObject *data; 23 | struct cacheDataNode *next; 24 | struct cacheDataNode *prev; 25 | } cacheDataNode; 26 | 27 | typedef struct cacheTypeNode { 28 | const char* symbol; 29 | /** 30 | 1 - number (int, double) 31 | 2 - string like (char*) 32 | */ 33 | unsigned char type; 34 | struct cacheTypeNode *next; 35 | struct cacheTypeNode *prev; 36 | } cacheTypeNode; 37 | 38 | 39 | // Global doubly linked list 40 | const char* headNodeKey = EUFA_CACHE_HEAD_LIST_KEY; 41 | const char* headNodeVal = EUFA_CACHE_HEAD_LIST_VAL; 42 | 43 | cacheDataObject *headDataObject = (cacheDataObject*) cache_malloc(sizeof(cacheDataObject)); 44 | 45 | cacheDataNode *headNode = (cacheDataNode*) cache_malloc(sizeof(cacheDataNode)); 46 | cacheDataNode *tailNode = headNode; 47 | 48 | cacheTypeNode *headTypeNode = (cacheTypeNode*) cache_malloc(sizeof(cacheTypeNode)); 49 | cacheTypeNode *tailTypeNode = headTypeNode; 50 | 51 | // Init function 52 | void _INIT_EUFA_CACHE_RUNTIME() { 53 | headDataObject->strData = headNodeVal; 54 | headNode->key = headNodeKey; 55 | headNode->data = headDataObject; 56 | headNode->next = NULL; 57 | headNode->prev = NULL; 58 | headTypeNode->symbol = headNodeKey; 59 | headTypeNode->type = EUFA_CACHE_TYPE_STR; 60 | headTypeNode->next = NULL; 61 | headTypeNode->prev = NULL; 62 | } 63 | 64 | // Global methods 65 | void addDataNodeToLinkedList (cacheDataNode* node) { 66 | node->prev = tailNode; 67 | node->next = NULL; 68 | tailNode->next = node; 69 | tailNode = node; 70 | } 71 | 72 | cacheDataNode* searchDataNodeInLinkedList (const char* key) { 73 | cacheDataNode *thisNode = tailNode; 74 | do { 75 | if (strcmp(key, thisNode->key) == 0) { 76 | return thisNode; 77 | } 78 | thisNode = thisNode->prev; 79 | } while(thisNode != NULL); 80 | return NULL; 81 | } 82 | 83 | void delDataNodeInLinkedList (const char* key) { 84 | cacheDataNode *thisNode = tailNode; 85 | do { 86 | if (strcmp(key, thisNode->key) == 0) { 87 | if (thisNode->prev != NULL && thisNode->next != NULL) { 88 | thisNode->prev->next = thisNode->next; 89 | thisNode->next->prev = thisNode->prev; 90 | } else if (thisNode->prev != NULL) { 91 | thisNode->prev->next = NULL; 92 | } else if (thisNode->next != NULL) { 93 | thisNode->next->prev = NULL; 94 | } 95 | 96 | if (thisNode == tailNode) { 97 | tailNode = thisNode->prev; 98 | } 99 | 100 | cache_free(thisNode->data); 101 | cache_free(thisNode); 102 | return; 103 | } 104 | thisNode = thisNode->prev; 105 | } while(thisNode != NULL); 106 | } 107 | 108 | 109 | // Type table related 110 | void addTypeNodeToLinkedList (cacheTypeNode* node) { 111 | node->prev = tailTypeNode; 112 | node->next = NULL; 113 | tailTypeNode->next = node; 114 | tailTypeNode = node; 115 | } 116 | 117 | unsigned char EMSCRIPTEN_KEEPALIVE searchTypeNode (const char* key) { 118 | cacheTypeNode *thisNode = tailTypeNode; 119 | do { 120 | if (strcmp(key, thisNode->symbol) == 0) { 121 | return thisNode->type; 122 | } 123 | thisNode = thisNode->prev; 124 | } while(thisNode != NULL); 125 | return FALSE; 126 | } 127 | 128 | void delTypeNodeInLinkedList (const char* key) { 129 | cacheTypeNode *thisNode = tailTypeNode; 130 | do { 131 | if (strcmp(key, thisNode->symbol) == 0) { 132 | if (thisNode->prev != NULL && thisNode->next != NULL) { 133 | thisNode->prev->next = thisNode->next; 134 | thisNode->next->prev = thisNode->prev; 135 | } else if (thisNode->prev != NULL) { 136 | thisNode->prev->next = NULL; 137 | } else if (thisNode->next != NULL) { 138 | thisNode->next->prev = NULL; 139 | } 140 | 141 | if (thisNode == tailTypeNode) { 142 | tailTypeNode = thisNode->prev; 143 | } 144 | 145 | cache_free(thisNode); 146 | return; 147 | } 148 | thisNode = thisNode->prev; 149 | } while(thisNode != NULL); 150 | } 151 | 152 | // Export functions 153 | extern void cache_set_type (const char* key, const unsigned char type); 154 | extern void cache_set_kv_str (const char* key, const char* value); 155 | extern void cache_set_kv_num (const char* key, double value); 156 | 157 | extern const char* cache_get_kv_str (const char* key); 158 | extern const double cache_get_kv_num (const char* key); 159 | 160 | extern void cache_del_kv (const char* key); 161 | 162 | extern void cache_clear (void); 163 | } 164 | 165 | 166 | #endif 167 | -------------------------------------------------------------------------------- /src/cache/clear.cc: -------------------------------------------------------------------------------- 1 | #include "cache.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | void EMSCRIPTEN_KEEPALIVE cache_clear (void) { 8 | cacheTypeNode *thisNode = tailTypeNode; 9 | cacheTypeNode *prevNode = tailTypeNode->prev; 10 | 11 | do { 12 | prevNode->next = NULL; 13 | free(thisNode); 14 | thisNode = prevNode; 15 | prevNode = prevNode->prev; 16 | } while(prevNode->prev != NULL); 17 | 18 | // Reset pointers 19 | tailNode = headNode; 20 | tailTypeNode = headTypeNode; 21 | } 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | -------------------------------------------------------------------------------- /src/cache/del.cc: -------------------------------------------------------------------------------- 1 | #include "cache.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | void EMSCRIPTEN_KEEPALIVE cache_del_kv (const char* key) { 8 | delDataNodeInLinkedList(key); 9 | delTypeNodeInLinkedList(key); 10 | } 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | -------------------------------------------------------------------------------- /src/cache/freeze.cc: -------------------------------------------------------------------------------- 1 | #include "cache.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | const char* EMSCRIPTEN_KEEPALIVE freeze_proto_snapshot (void) { 8 | 9 | } 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | -------------------------------------------------------------------------------- /src/cache/get.cc: -------------------------------------------------------------------------------- 1 | #include "cache.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | const char* EMSCRIPTEN_KEEPALIVE cache_get_kv_str (const char* key) { 8 | cacheDataNode* dataNode = searchDataNodeInLinkedList(key); 9 | if (dataNode != NULL) { 10 | return dataNode->data->strData; 11 | } else { 12 | return NULL; 13 | } 14 | } 15 | 16 | const double EMSCRIPTEN_KEEPALIVE cache_get_kv_num (const char* key) { 17 | cacheDataNode* dataNode = searchDataNodeInLinkedList(key); 18 | if (dataNode != NULL) { 19 | return dataNode->data->numData; 20 | } else { 21 | return FALSE; 22 | } 23 | } 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | -------------------------------------------------------------------------------- /src/cache/set.cc: -------------------------------------------------------------------------------- 1 | #include "cache.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | void EMSCRIPTEN_KEEPALIVE cache_set_kv_str (const char* key, const char* value) { 8 | cacheDataObject *data = (cacheDataObject*) cache_malloc(sizeof(cacheDataObject)); 9 | cacheDataNode *dataNode = (cacheDataNode*) cache_malloc(sizeof(cacheDataNode)); 10 | // Fill up 11 | data->strData = value; 12 | dataNode->key = key; 13 | dataNode->data = data; 14 | // Immutable 15 | delDataNodeInLinkedList(key); 16 | // Add 17 | addDataNodeToLinkedList(dataNode); 18 | } 19 | 20 | void EMSCRIPTEN_KEEPALIVE cache_set_kv_num (const char* key, double value) { 21 | cacheDataObject *data = (cacheDataObject*) cache_malloc(sizeof(cacheDataObject)); 22 | cacheDataNode *dataNode = (cacheDataNode*) cache_malloc(sizeof(cacheDataNode)); 23 | // Fill up 24 | data->numData = value; 25 | dataNode->key = key; 26 | dataNode->data = data; 27 | // Immutable 28 | delDataNodeInLinkedList(key); 29 | // Add 30 | addDataNodeToLinkedList(dataNode); 31 | } 32 | 33 | void EMSCRIPTEN_KEEPALIVE cache_set_type (const char* key, const unsigned char type) { 34 | cacheTypeNode *typeNode = (cacheTypeNode*) cache_malloc(sizeof(cacheTypeNode)); 35 | // Fill up 36 | typeNode->symbol = key; 37 | typeNode->type = type; 38 | // Immutable 39 | delTypeNodeInLinkedList(key); 40 | // Add 41 | addTypeNodeToLinkedList(typeNode); 42 | } 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | -------------------------------------------------------------------------------- /src/dlib/dlib.h: -------------------------------------------------------------------------------- 1 | #ifndef EUFA_DLIB 2 | #define EUFA_DLIB 3 | 4 | #define NO_MAKEFILE 5 | #define DLIB_NO_GUI_SUPPORT 6 | 7 | #include "../global.h" 8 | 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/dlib/dnn.cc: -------------------------------------------------------------------------------- 1 | #include "dnn.h" 2 | 3 | #define MNIST_PIXEL_WIDTH 28 4 | #define MNIST_PIXEL_HEIGHT 28 5 | #define MNIST_BATCH_COUNT 1 6 | 7 | 8 | 9 | #ifdef MNIST_DEBUG 10 | 11 | const char* EMSCRIPTEN_KEEPALIVE testcase_dnn_mnist(unsigned char pixel[]) { 12 | 13 | #else 14 | 15 | unsigned long EMSCRIPTEN_KEEPALIVE testcase_dnn_mnist(unsigned char pixel[]) { 16 | 17 | #endif 18 | 19 | // MNIST is broken into two parts, a training set of 60000 images and a test set of 20 | // 10000 images. Each image is labeled so that we know what hand written digit is 21 | // depicted. These next statements load the dataset into memory. 22 | std::vector> test_images_rgb; 23 | std::vector> test_images; 24 | 25 | test_images.resize(MNIST_BATCH_COUNT); 26 | test_images_rgb.resize(MNIST_BATCH_COUNT); 27 | 28 | for (size_t k = 0; k < MNIST_BATCH_COUNT; k++) { 29 | test_images[k].set_size(MNIST_PIXEL_WIDTH, MNIST_PIXEL_HEIGHT); 30 | test_images_rgb[k].set_size(MNIST_PIXEL_WIDTH, MNIST_PIXEL_HEIGHT); 31 | 32 | size_t counter = 0; 33 | for (int i = 0; i < MNIST_PIXEL_WIDTH; i++) { 34 | for (int j = 0; j < MNIST_PIXEL_HEIGHT; j++) { 35 | test_images_rgb[k](i, j).red = pixel[counter++]; 36 | test_images_rgb[k](i, j).green = pixel[counter++]; 37 | test_images_rgb[k](i, j).blue = pixel[counter++]; 38 | counter+=1; 39 | } 40 | } 41 | assign_image(test_images[k], test_images_rgb[k]); 42 | } 43 | 44 | 45 | 46 | #ifdef MNIST_DEBUG 47 | 48 | // stringify to json for browser. 49 | StringBuffer s; 50 | Writer writer(s); 51 | writer.StartArray(); 52 | writer.StartArray(); 53 | for (size_t k = 0; k < MNIST_BATCH_COUNT; k++) { 54 | for (int i = 0; i < MNIST_PIXEL_WIDTH; i++) { 55 | for (int j = 0; j < MNIST_PIXEL_HEIGHT; j++) { 56 | writer.Uint(test_images[k](i, j)); 57 | } 58 | } 59 | } 60 | writer.EndArray(); 61 | writer.StartArray(); 62 | for (size_t k = 0; k < MNIST_BATCH_COUNT; k++) { 63 | for (int i = 0; i < MNIST_PIXEL_WIDTH; i++) { 64 | for (int j = 0; j < MNIST_PIXEL_HEIGHT; j++) { 65 | writer.Uint(test_images_rgb[k](i, j).red); 66 | writer.Uint(test_images_rgb[k](i, j).green); 67 | writer.Uint(test_images_rgb[k](i, j).blue); 68 | } 69 | } 70 | } 71 | writer.EndArray(); 72 | writer.StartArray(); 73 | for (int i = 0; i < 4 * MNIST_PIXEL_WIDTH * MNIST_PIXEL_HEIGHT; i++) { 74 | writer.Uint(pixel[i]); 75 | } 76 | writer.EndArray(); 77 | writer.EndArray(); 78 | return s.GetString(); 79 | 80 | #else 81 | 82 | using net_type = loss_multiclass_log< 83 | fc<10, 84 | relu> 89 | >>>>>>>>>>>>; 90 | 91 | 92 | // So with that out of the way, we can make a network instance. 93 | net_type net; 94 | // Now if we later wanted to recall the network from disk we can simply say: 95 | deserialize("/mnist_network.mnist.dlib") >> net; 96 | 97 | // Let's also see if the network can correctly classify the testing images. Since 98 | // MNIST is an easy dataset, we should see at least 99% accuracy. 99 | std::vector predicted_labels = net(test_images); 100 | return predicted_labels[0]; 101 | 102 | #endif 103 | } 104 | 105 | void EMSCRIPTEN_KEEPALIVE testcase_dnn_mnist_train(const char* dir) { 106 | 107 | string folder = dir; 108 | // MNIST is broken into two parts, a training set of 60000 images and a test set of 109 | // 10000 images. Each image is labeled so that we know what hand written digit is 110 | // depicted. These next statements load the dataset into memory. 111 | std::vector> training_images; 112 | std::vector training_labels; 113 | std::vector> testing_images; 114 | std::vector testing_labels; 115 | 116 | emscripten_log(EM_LOG_CONSOLE, "[Eufa] Folder '%s' includes trainning data.", dir); 117 | 118 | load_mnist_dataset(folder, training_images, training_labels, testing_images, testing_labels); 119 | 120 | 121 | // Now let's define the LeNet. Broadly speaking, there are 3 parts to a network 122 | // definition. The loss layer, a bunch of computational layers, and then an input 123 | // layer. You can see these components in the network definition below. 124 | // 125 | // The input layer here says the network expects to be given matrix 126 | // objects as input. In general, you can use any dlib image or matrix type here, or 127 | // even define your own types by creating custom input layers. 128 | // 129 | // Then the middle layers define the computation the network will do to transform the 130 | // input into whatever we want. Here we run the image through multiple convolutions, 131 | // ReLU units, max pooling operations, and then finally a fully connected layer that 132 | // converts the whole thing into just 10 numbers. 133 | // 134 | // Finally, the loss layer defines the relationship between the network outputs, our 10 135 | // numbers, and the labels in our dataset. Since we selected loss_multiclass_log it 136 | // means we want to do multiclass classification with our network. Moreover, the 137 | // number of network outputs (i.e. 10) is the number of possible labels. Whichever 138 | // network output is largest is the predicted label. So for example, if the first 139 | // network output is largest then the predicted digit is 0, if the last network output 140 | // is largest then the predicted digit is 9. 141 | using net_type = loss_multiclass_log< 142 | fc<10, 143 | relu> 148 | >>>>>>>>>>>>; 149 | // This net_type defines the entire network architecture. For example, the block 150 | // relu> means we take the output from the subnetwork, pass it through a 151 | // fully connected layer with 84 outputs, then apply ReLU. Similarly, a block of 152 | // max_pool<2,2,2,2,relu>> means we apply 16 convolutions with a 153 | // 5x5 filter size and 1x1 stride to the output of a subnetwork, then apply ReLU, then 154 | // perform max pooling with a 2x2 window and 2x2 stride. 155 | 156 | emscripten_log(EM_LOG_CONSOLE, "[Eufa] Tranning network defined!"); 157 | 158 | // So with that out of the way, we can make a network instance. 159 | net_type net; 160 | // And then train it using the MNIST data. The code below uses mini-batch stochastic 161 | // gradient descent with an initial learning rate of 0.01 to accomplish this. 162 | emscripten_log(EM_LOG_CONSOLE, "[Eufa] Set trainer!"); 163 | 164 | 165 | // [Not working] maybe due to thread related functions!!!! 166 | dnn_trainer trainer(net); 167 | 168 | emscripten_log(EM_LOG_CONSOLE, "[Eufa] Set learning rate!"); 169 | trainer.set_learning_rate(0.01); 170 | 171 | emscripten_log(EM_LOG_CONSOLE, "[Eufa] Set min learning rate!"); 172 | trainer.set_min_learning_rate(0.00001); 173 | 174 | emscripten_log(EM_LOG_CONSOLE, "[Eufa] Set mini batch size!"); 175 | trainer.set_mini_batch_size(128); 176 | 177 | emscripten_log(EM_LOG_CONSOLE, "[Eufa] Set verbose!"); 178 | trainer.be_verbose(); 179 | // Since DNN training can take a long time, we can ask the trainer to save its state to 180 | // a file named "mnist_sync" every 20 seconds. This way, if we kill this program and 181 | // start it again it will begin where it left off rather than restarting the training 182 | // from scratch. This is because, when the program restarts, this call to 183 | // set_synchronization_file() will automatically reload the settings from mnist_sync if 184 | // the file exists. 185 | emscripten_log(EM_LOG_CONSOLE, "[Eufa] Set sync file!"); 186 | trainer.set_synchronization_file("mnist_sync", std::chrono::seconds(20)); 187 | // Finally, this line begins training. By default, it runs SGD with our specified 188 | // learning rate until the loss stops decreasing. Then it reduces the learning rate by 189 | // a factor of 10 and continues running until the loss stops decreasing again. It will 190 | // keep doing this until the learning rate has dropped below the min learning rate 191 | // defined above or the maximum number of epochs as been executed (defaulted to 10000). 192 | emscripten_log(EM_LOG_CONSOLE, "[Eufa] Start trainning!"); 193 | trainer.train(training_images, training_labels); 194 | 195 | 196 | // Now let's run the training images through the network. This statement runs all the 197 | // images through it and asks the loss layer to convert the network's raw output into 198 | // labels. In our case, these labels are the numbers between 0 and 9. 199 | std::vector predicted_labels = net(training_images); 200 | int num_right = 0; 201 | int num_wrong = 0; 202 | // And then let's see if it classified them correctly. 203 | for (size_t i = 0; i < training_images.size(); ++i) 204 | { 205 | if (predicted_labels[i] == training_labels[i]) 206 | ++num_right; 207 | else 208 | ++num_wrong; 209 | 210 | } 211 | cout << "training num_right: " << num_right << endl; 212 | cout << "training num_wrong: " << num_wrong << endl; 213 | cout << "training accuracy: " << num_right/(double)(num_right+num_wrong) << endl; 214 | 215 | // Let's also see if the network can correctly classify the testing images. Since 216 | // MNIST is an easy dataset, we should see at least 99% accuracy. 217 | predicted_labels = net(testing_images); 218 | num_right = 0; 219 | num_wrong = 0; 220 | for (size_t i = 0; i < testing_images.size(); ++i) 221 | { 222 | if (predicted_labels[i] == testing_labels[i]) 223 | ++num_right; 224 | else 225 | ++num_wrong; 226 | 227 | } 228 | cout << "testing num_right: " << num_right << endl; 229 | cout << "testing num_wrong: " << num_wrong << endl; 230 | cout << "testing accuracy: " << num_right/(double)(num_right+num_wrong) << endl; 231 | 232 | } 233 | 234 | 235 | -------------------------------------------------------------------------------- /src/dlib/dnn.h: -------------------------------------------------------------------------------- 1 | #ifndef EUFA_DLIB_CNN 2 | #define EUFA_DLIB_CNN 3 | 4 | #include "dlib.h" 5 | #include 6 | #include 7 | 8 | 9 | // #define MNIST_DEBUG 10 | 11 | using namespace std; 12 | using namespace dlib; 13 | 14 | extern "C" { 15 | 16 | #ifdef MNIST_DEBUG 17 | 18 | extern const char* testcase_dnn_mnist(unsigned char[]); 19 | 20 | #else 21 | 22 | extern unsigned long testcase_dnn_mnist(unsigned char[]); 23 | 24 | #endif 25 | 26 | extern void testcase_dnn_mnist_train(const char* dir); 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/dlib/kmeans.cc: -------------------------------------------------------------------------------- 1 | #include "kmeans.h" 2 | 3 | 4 | // The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt 5 | /* 6 | This is an example illustrating the use of the kkmeans object 7 | and spectral_cluster() routine from the dlib C++ Library. 8 | 9 | The kkmeans object is an implementation of a kernelized k-means clustering 10 | algorithm. It is implemented by using the kcentroid object to represent 11 | each center found by the usual k-means clustering algorithm. 12 | 13 | So this object allows you to perform non-linear clustering in the same way 14 | a svm classifier finds non-linear decision surfaces. 15 | 16 | This example will make points from 3 classes and perform kernelized k-means 17 | clustering on those points. It will also do the same thing using spectral 18 | clustering. 19 | 20 | The classes are as follows: 21 | - points very close to the origin 22 | - points on the circle of radius 10 around the origin 23 | - points that are on a circle of radius 4 but not around the origin at all 24 | */ 25 | 26 | const char* EMSCRIPTEN_KEEPALIVE testcase_kmeans(void) { 27 | // Here we declare that our samples will be 2 dimensional column vectors. 28 | // (Note that if you don't know the dimensionality of your vectors at compile time 29 | // you can change the 2 to a 0 and then set the size at runtime) 30 | typedef matrix sample_type; 31 | 32 | // Now we are making a typedef for the kind of kernel we want to use. I picked the 33 | // radial basis kernel because it only has one parameter and generally gives good 34 | // results without much fiddling. 35 | typedef radial_basis_kernel kernel_type; 36 | 37 | 38 | // Here we declare an instance of the kcentroid object. It is the object used to 39 | // represent each of the centers used for clustering. The kcentroid has 3 parameters 40 | // you need to set. The first argument to the constructor is the kernel we wish to 41 | // use. The second is a parameter that determines the numerical accuracy with which 42 | // the object will perform part of the learning algorithm. Generally, smaller values 43 | // give better results but cause the algorithm to attempt to use more dictionary vectors 44 | // (and thus run slower and use more memory). The third argument, however, is the 45 | // maximum number of dictionary vectors a kcentroid is allowed to use. So you can use 46 | // it to control the runtime complexity. 47 | kcentroid kc(kernel_type(0.1), 0.0001, 8); 48 | 49 | // Now we make an instance of the kkmeans object and tell it to use kcentroid objects 50 | // that are configured with the parameters from the kc object we defined above. 51 | kkmeans test(kc); 52 | 53 | std::vector samples; 54 | std::vector initial_centers; 55 | 56 | sample_type m; 57 | 58 | dlib::rand rnd; 59 | 60 | // ASA058 the K-Means Problem testcases (http://people.sc.fsu.edu/~jburkardt/f_src/asa058/asa058.html) 61 | static double sample_x[] = {0.532095 ,0.189043 ,0.550977 ,0.003973 ,0.89423 ,0.073072 ,0.64018 ,0.389914 ,0.046918 ,0.820327 ,0.166575 ,0.587999 ,0.184717 ,0.264707 ,0.564959 ,0.986991 ,0.214221 ,0.997171 ,0.233578 ,0.209772 ,0.631619 ,0.441601 ,0.246242 ,0.243191 ,0.129101 ,0.808454 ,0.23591 ,0.841259 ,0.825533 ,0.780973 ,0.492706 ,0.064106 ,0.711451 ,0.532239 ,0.264527 ,0.984485 ,0.890788 ,0.81489 ,0.656357 ,0.161836 ,0.789622 ,0.005299 ,0.751558 ,0.315169 ,0.067572 ,0.144209 ,0.755242 ,0.025839 ,0.009056 ,0.091736 ,0.00012 ,0.599014 ,0.020924 ,0.402961 ,0.536965 ,0.791622 ,0.049268 ,0.321031 ,0.45994 ,0.306635 ,0.290264 ,0.117081 ,0.663268 ,0.25703 ,0.138396 ,0.37325 ,0.792062 ,0.761925 ,0.498106 ,0.079199 ,0.389481 ,0.909555 ,0.78771 ,0.87391 ,0.914291 ,0.126212 ,0.962689 ,0.662097 ,0.514842 ,0.573771 ,0.541641 ,0.880047 ,0.854456 ,0.882323 ,0.083516 ,0.868329 ,0.211671 ,0.169315 ,0.116072 ,0.900911 ,0.889781 ,0.209244 ,0.055621 ,0.787673 ,0.327654 ,0.571657 ,0.519674 ,0.020604 ,0.00635 ,0.414254}; 62 | static double sample_y[] = {0.894141 ,0.613426 ,0.415724 ,0.60576 ,0.666812 ,0.740658 ,0.926186 ,0.553149 ,0.172275 ,0.578957 ,0.597895 ,0.824301 ,0.060804 ,0.661072 ,0.824897 ,0.654621 ,0.611877 ,0.807318 ,0.380796 ,0.585171 ,0.418295 ,0.474479 ,0.196578 ,0.428592 ,0.460463 ,0.240363 ,0.362678 ,0.018226 ,0.867529 ,0.282859 ,0.071775 ,0.024164 ,0.621806 ,0.872561 ,0.947361 ,0.373498 ,0.09006 ,0.765458 ,0.383494 ,0.878997 ,0.367808 ,0.694075 ,0.054149 ,0.989785 ,0.642346 ,0.130059 ,0.723929 ,0.306045 ,0.544864 ,0.031139 ,0.760615 ,0.406906 ,0.067692 ,0.743223 ,0.776167 ,0.4288 ,0.546021 ,0.883358 ,0.049388 ,0.920045 ,0.480864 ,0.709596 ,0.827229 ,0.908703 ,0.712536 ,0.578061 ,0.598336 ,0.679885 ,0.082325 ,0.879007 ,0.161374 ,0.33623 ,0.527877 ,0.282804 ,0.579771 ,0.635836 ,0.412397 ,0.205412 ,0.35217 ,0.571652 ,0.302552 ,0.447681 ,0.455932 ,0.006259 ,0.817145 ,0.54442 ,0.598359 ,0.4421 ,0.753312 ,0.049362 ,0.970528 ,0.783234 ,0.973298 ,0.077573 ,0.267293 ,0.956988 ,0.443726 ,0.472568 ,0.409455 ,0.229849}; 63 | 64 | const long num = 100; 65 | 66 | for (long i = 0; i < num; ++i) { 67 | m(0) = sample_x[i]; 68 | m(1) = sample_y[i]; 69 | 70 | // add this sample to our set of samples we will run k-means 71 | samples.push_back(m); 72 | } 73 | 74 | // tell the kkmeans object we made that we want to run k-means with k set to 5. 75 | // (i.e. we want 5 clusters) 76 | test.set_number_of_centers(5); 77 | 78 | // You need to pick some initial centers for the k-means algorithm. So here 79 | // we will use the dlib::pick_initial_centers() function which tries to find 80 | // n points that are far apart (basically). 81 | pick_initial_centers(5, initial_centers, samples, test.get_kernel()); 82 | 83 | // now run the k-means algorithm on our set of samples. 84 | test.train(samples, initial_centers); 85 | 86 | // stringify to json for browser. 87 | StringBuffer s; 88 | Writer writer(s); 89 | writer.StartArray(); 90 | for (unsigned long i = 0; i < samples.size(); ++i) { 91 | writer.StartArray(); 92 | writer.Int(test(samples[i])); 93 | writer.Double(samples[i](0)); 94 | writer.Double(samples[i](1)); 95 | writer.EndArray(); 96 | } 97 | writer.EndArray(); 98 | return s.GetString(); 99 | 100 | /* 101 | // now loop over all our samples and print out their predicted class. In this example 102 | // all points are correctly identified. 103 | for (unsigned long i = 0; i < samples.size() / 3; ++i) { 104 | emscripten_log(EM_LOG_CONSOLE, "%d", test(samples[i])); 105 | emscripten_log(EM_LOG_CONSOLE, "%d", test(samples[i+num])); 106 | emscripten_log(EM_LOG_CONSOLE, "%d", test(samples[i+2*num])); 107 | } 108 | 109 | // Now print out how many dictionary vectors each center used. Note that 110 | // the maximum number of 8 was reached. If you went back to the kcentroid 111 | // constructor and changed the 8 to some bigger number you would see that these 112 | // numbers would go up. However, 8 is all we need to correctly cluster this dataset. 113 | emscripten_log(EM_LOG_CONSOLE, "num dictionary vectors for center 0: %d", test.get_kcentroid(0).dictionary_size()); 114 | emscripten_log(EM_LOG_CONSOLE, "num dictionary vectors for center 1: %d", test.get_kcentroid(1).dictionary_size()); 115 | emscripten_log(EM_LOG_CONSOLE, "num dictionary vectors for center 2: %d", test.get_kcentroid(2).dictionary_size()); 116 | 117 | 118 | 119 | // Finally, we can also solve the same kind of non-linear clustering problem with 120 | // spectral_cluster(). The output is a vector that indicates which cluster each sample 121 | // belongs to. Just like with kkmeans, it assigns each point to the correct cluster. 122 | std::vector assignments = spectral_cluster(kernel_type(0.1), samples, 3); 123 | // cout << mat(assignments) << endl; 124 | 125 | */ 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/dlib/kmeans.h: -------------------------------------------------------------------------------- 1 | #ifndef EUFA_DLIB_KMEANS 2 | #define EUFA_DLIB_KMEANS 3 | 4 | #include "dlib.h" 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | using namespace dlib; 10 | using namespace rapidjson; 11 | 12 | extern "C" { 13 | 14 | extern const char* testcase_kmeans(void); 15 | 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/dlib/library/source.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/src/dlib/library/source.bc -------------------------------------------------------------------------------- /src/dlib/model/mnist_network.mnist.dlib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/src/dlib/model/mnist_network.mnist.dlib -------------------------------------------------------------------------------- /src/encryptor/base64.cc: -------------------------------------------------------------------------------- 1 | #include "base64.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | /* {{{ base64 related */ 8 | static const char base64_table[] = { 9 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 10 | 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 11 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 12 | 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 13 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0' 14 | }; 15 | 16 | static const char base64_pad = '='; 17 | 18 | static const short base64_reverse_table[256] = { 19 | -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -2, -1, -2, -2, 20 | -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 21 | -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63, 22 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2, 23 | -2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 24 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2, 25 | -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 26 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2, 27 | -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 28 | -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 29 | -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 30 | -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 31 | -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 32 | -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 33 | -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 34 | -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2 35 | }; 36 | 37 | unsigned char* EMSCRIPTEN_KEEPALIVE base64_encode (const unsigned char *str, size_t length) { 38 | const unsigned char *current = str; 39 | unsigned char *p; 40 | unsigned char *result; 41 | 42 | result = (unsigned char*) malloc(((length + 2) / 3) * 4 * sizeof(char)); 43 | p = result; 44 | 45 | while (length > 2) { /* keep going until we have less than 24 bits */ 46 | *p++ = base64_table[current[0] >> 2]; 47 | *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)]; 48 | *p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)]; 49 | *p++ = base64_table[current[2] & 0x3f]; 50 | 51 | current += 3; 52 | length -= 3; /* we just handle 3 octets of data */ 53 | } 54 | 55 | /* now deal with the tail end of things */ 56 | if (length != 0) { 57 | *p++ = base64_table[current[0] >> 2]; 58 | if (length > 1) { 59 | *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)]; 60 | *p++ = base64_table[(current[1] & 0x0f) << 2]; 61 | *p++ = base64_pad; 62 | } else { 63 | *p++ = base64_table[(current[0] & 0x03) << 4]; 64 | *p++ = base64_pad; 65 | *p++ = base64_pad; 66 | } 67 | } 68 | *p = '\0'; 69 | 70 | return result; 71 | } 72 | 73 | unsigned char* EMSCRIPTEN_KEEPALIVE base64_decode_ex (const unsigned char *str, size_t length) { 74 | const unsigned char *current = str; 75 | int ch, i = 0, j = 0, padding = 0; 76 | unsigned char *result; 77 | 78 | result = (unsigned char*) malloc(length); 79 | 80 | /* run through the whole string, converting as we go */ 81 | while (length-- > 0) { 82 | ch = *current++; 83 | if (ch == base64_pad) { 84 | padding++; 85 | continue; 86 | } 87 | 88 | ch = base64_reverse_table[ch]; 89 | if (ch < 0) { 90 | continue; 91 | } 92 | 93 | switch(i % 4) { 94 | case 0: 95 | result[j] = ch << 2; 96 | break; 97 | case 1: 98 | result[j++] |= ch >> 4; 99 | result[j] = (ch & 0x0f) << 4; 100 | break; 101 | case 2: 102 | result[j++] |= ch >>2; 103 | result[j] = (ch & 0x03) << 6; 104 | break; 105 | case 3: 106 | result[j++] |= ch; 107 | break; 108 | } 109 | i++; 110 | } 111 | 112 | result[length] = '\0'; 113 | 114 | return result; 115 | } 116 | /* }}} */ 117 | 118 | #ifdef __cplusplus 119 | } 120 | #endif 121 | -------------------------------------------------------------------------------- /src/encryptor/base64.h: -------------------------------------------------------------------------------- 1 | #ifndef EUFA_ENCRYPTOR_BASE64 2 | #define EUFA_ENCRYPTOR_BASE64 3 | 4 | #include "encryptor.h" 5 | 6 | extern "C" { 7 | 8 | /* 9 | * Expose functions. 10 | */ 11 | extern unsigned char* base64_encode (const unsigned char *str, size_t length); 12 | extern unsigned char* base64_decode_ex (const unsigned char *str, size_t length); 13 | 14 | } 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/encryptor/encryptor.h: -------------------------------------------------------------------------------- 1 | #ifndef EUFA_ENCRYPTOR 2 | #define EUFA_ENCRYPTOR 3 | 4 | #include "../global.h" 5 | 6 | #define EUFA_ZERO(var, size) bzero((var), (size)) 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/encryptor/md5.cc: -------------------------------------------------------------------------------- 1 | #include "md5.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | /* {{{ md5 related */ 8 | char* EMSCRIPTEN_KEEPALIVE md5 (const unsigned char *str, size_t length) { 9 | unsigned char *arg; 10 | unsigned char raw_output = 0; 11 | char* md5str = (char*) malloc(33 * sizeof(char)); 12 | MD5_CTX context; 13 | unsigned char digest[16]; 14 | 15 | md5str[0] = '\0'; 16 | MD5Init(&context); 17 | MD5Update(&context, str, length); 18 | MD5Final(digest, &context); 19 | 20 | make_digest_ex(md5str, digest, 16); 21 | return md5str; 22 | } 23 | 24 | void make_digest_ex (char *md5str, const unsigned char *digest, int len) { 25 | static const char hexits[17] = "0123456789abcdef"; 26 | int i; 27 | 28 | for (i = 0; i < len; i++) { 29 | md5str[i * 2] = hexits[digest[i] >> 4]; 30 | md5str[(i * 2) + 1] = hexits[digest[i] & 0x0F]; 31 | } 32 | md5str[len * 2] = '\0'; 33 | } 34 | 35 | static const unsigned char *md5_body (MD5_CTX *ctx, const unsigned char *data, size_t size) { 36 | const unsigned char *ptr; 37 | uint32_t a, b, c, d; 38 | uint32_t saved_a, saved_b, saved_c, saved_d; 39 | 40 | ptr = data; 41 | 42 | a = ctx->a; 43 | b = ctx->b; 44 | c = ctx->c; 45 | d = ctx->d; 46 | 47 | do { 48 | saved_a = a; 49 | saved_b = b; 50 | saved_c = c; 51 | saved_d = d; 52 | 53 | /* Round 1 */ 54 | STEP(ENCRYPTOR_F, a, b, c, d, SET(0), 0xd76aa478, 7) 55 | STEP(ENCRYPTOR_F, d, a, b, c, SET(1), 0xe8c7b756, 12) 56 | STEP(ENCRYPTOR_F, c, d, a, b, SET(2), 0x242070db, 17) 57 | STEP(ENCRYPTOR_F, b, c, d, a, SET(3), 0xc1bdceee, 22) 58 | STEP(ENCRYPTOR_F, a, b, c, d, SET(4), 0xf57c0faf, 7) 59 | STEP(ENCRYPTOR_F, d, a, b, c, SET(5), 0x4787c62a, 12) 60 | STEP(ENCRYPTOR_F, c, d, a, b, SET(6), 0xa8304613, 17) 61 | STEP(ENCRYPTOR_F, b, c, d, a, SET(7), 0xfd469501, 22) 62 | STEP(ENCRYPTOR_F, a, b, c, d, SET(8), 0x698098d8, 7) 63 | STEP(ENCRYPTOR_F, d, a, b, c, SET(9), 0x8b44f7af, 12) 64 | STEP(ENCRYPTOR_F, c, d, a, b, SET(10), 0xffff5bb1, 17) 65 | STEP(ENCRYPTOR_F, b, c, d, a, SET(11), 0x895cd7be, 22) 66 | STEP(ENCRYPTOR_F, a, b, c, d, SET(12), 0x6b901122, 7) 67 | STEP(ENCRYPTOR_F, d, a, b, c, SET(13), 0xfd987193, 12) 68 | STEP(ENCRYPTOR_F, c, d, a, b, SET(14), 0xa679438e, 17) 69 | STEP(ENCRYPTOR_F, b, c, d, a, SET(15), 0x49b40821, 22) 70 | 71 | /* Round 2 */ 72 | STEP(ENCRYPTOR_G, a, b, c, d, GET(1), 0xf61e2562, 5) 73 | STEP(ENCRYPTOR_G, d, a, b, c, GET(6), 0xc040b340, 9) 74 | STEP(ENCRYPTOR_G, c, d, a, b, GET(11), 0x265e5a51, 14) 75 | STEP(ENCRYPTOR_G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) 76 | STEP(ENCRYPTOR_G, a, b, c, d, GET(5), 0xd62f105d, 5) 77 | STEP(ENCRYPTOR_G, d, a, b, c, GET(10), 0x02441453, 9) 78 | STEP(ENCRYPTOR_G, c, d, a, b, GET(15), 0xd8a1e681, 14) 79 | STEP(ENCRYPTOR_G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) 80 | STEP(ENCRYPTOR_G, a, b, c, d, GET(9), 0x21e1cde6, 5) 81 | STEP(ENCRYPTOR_G, d, a, b, c, GET(14), 0xc33707d6, 9) 82 | STEP(ENCRYPTOR_G, c, d, a, b, GET(3), 0xf4d50d87, 14) 83 | STEP(ENCRYPTOR_G, b, c, d, a, GET(8), 0x455a14ed, 20) 84 | STEP(ENCRYPTOR_G, a, b, c, d, GET(13), 0xa9e3e905, 5) 85 | STEP(ENCRYPTOR_G, d, a, b, c, GET(2), 0xfcefa3f8, 9) 86 | STEP(ENCRYPTOR_G, c, d, a, b, GET(7), 0x676f02d9, 14) 87 | STEP(ENCRYPTOR_G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) 88 | 89 | /* Round 3 */ 90 | STEP(ENCRYPTOR_H, a, b, c, d, GET(5), 0xfffa3942, 4) 91 | STEP(ENCRYPTOR_H, d, a, b, c, GET(8), 0x8771f681, 11) 92 | STEP(ENCRYPTOR_H, c, d, a, b, GET(11), 0x6d9d6122, 16) 93 | STEP(ENCRYPTOR_H, b, c, d, a, GET(14), 0xfde5380c, 23) 94 | STEP(ENCRYPTOR_H, a, b, c, d, GET(1), 0xa4beea44, 4) 95 | STEP(ENCRYPTOR_H, d, a, b, c, GET(4), 0x4bdecfa9, 11) 96 | STEP(ENCRYPTOR_H, c, d, a, b, GET(7), 0xf6bb4b60, 16) 97 | STEP(ENCRYPTOR_H, b, c, d, a, GET(10), 0xbebfbc70, 23) 98 | STEP(ENCRYPTOR_H, a, b, c, d, GET(13), 0x289b7ec6, 4) 99 | STEP(ENCRYPTOR_H, d, a, b, c, GET(0), 0xeaa127fa, 11) 100 | STEP(ENCRYPTOR_H, c, d, a, b, GET(3), 0xd4ef3085, 16) 101 | STEP(ENCRYPTOR_H, b, c, d, a, GET(6), 0x04881d05, 23) 102 | STEP(ENCRYPTOR_H, a, b, c, d, GET(9), 0xd9d4d039, 4) 103 | STEP(ENCRYPTOR_H, d, a, b, c, GET(12), 0xe6db99e5, 11) 104 | STEP(ENCRYPTOR_H, c, d, a, b, GET(15), 0x1fa27cf8, 16) 105 | STEP(ENCRYPTOR_H, b, c, d, a, GET(2), 0xc4ac5665, 23) 106 | 107 | /* Round 4 */ 108 | STEP(ENCRYPTOR_I, a, b, c, d, GET(0), 0xf4292244, 6) 109 | STEP(ENCRYPTOR_I, d, a, b, c, GET(7), 0x432aff97, 10) 110 | STEP(ENCRYPTOR_I, c, d, a, b, GET(14), 0xab9423a7, 15) 111 | STEP(ENCRYPTOR_I, b, c, d, a, GET(5), 0xfc93a039, 21) 112 | STEP(ENCRYPTOR_I, a, b, c, d, GET(12), 0x655b59c3, 6) 113 | STEP(ENCRYPTOR_I, d, a, b, c, GET(3), 0x8f0ccc92, 10) 114 | STEP(ENCRYPTOR_I, c, d, a, b, GET(10), 0xffeff47d, 15) 115 | STEP(ENCRYPTOR_I, b, c, d, a, GET(1), 0x85845dd1, 21) 116 | STEP(ENCRYPTOR_I, a, b, c, d, GET(8), 0x6fa87e4f, 6) 117 | STEP(ENCRYPTOR_I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) 118 | STEP(ENCRYPTOR_I, c, d, a, b, GET(6), 0xa3014314, 15) 119 | STEP(ENCRYPTOR_I, b, c, d, a, GET(13), 0x4e0811a1, 21) 120 | STEP(ENCRYPTOR_I, a, b, c, d, GET(4), 0xf7537e82, 6) 121 | STEP(ENCRYPTOR_I, d, a, b, c, GET(11), 0xbd3af235, 10) 122 | STEP(ENCRYPTOR_I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) 123 | STEP(ENCRYPTOR_I, b, c, d, a, GET(9), 0xeb86d391, 21) 124 | 125 | a += saved_a; 126 | b += saved_b; 127 | c += saved_c; 128 | d += saved_d; 129 | 130 | ptr += 64; 131 | } while (size -= 64); 132 | 133 | ctx->a = a; 134 | ctx->b = b; 135 | ctx->c = c; 136 | ctx->d = d; 137 | 138 | return ptr; 139 | } 140 | 141 | void MD5Init (MD5_CTX *ctx) { 142 | ctx->a = 0x67452301; 143 | ctx->b = 0xefcdab89; 144 | ctx->c = 0x98badcfe; 145 | ctx->d = 0x10325476; 146 | 147 | ctx->lo = 0; 148 | ctx->hi = 0; 149 | } 150 | 151 | void MD5Update (MD5_CTX *ctx, const unsigned char *data, size_t size) { 152 | uint32_t saved_lo; 153 | uint32_t used, free; 154 | 155 | saved_lo = ctx->lo; 156 | if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) { 157 | ctx->hi++; 158 | } 159 | ctx->hi += size >> 29; 160 | 161 | used = saved_lo & 0x3f; 162 | 163 | if (used) { 164 | free = 64 - used; 165 | 166 | if (size < free) { 167 | memcpy(&ctx->buffer[used], data, size); 168 | return; 169 | } 170 | 171 | memcpy(&ctx->buffer[used], data, free); 172 | data = (unsigned char *)data + free; 173 | size -= free; 174 | md5_body(ctx, ctx->buffer, 64); 175 | } 176 | 177 | if (size >= 64) { 178 | data = md5_body(ctx, data, size & ~(size_t)0x3f); 179 | size &= 0x3f; 180 | } 181 | 182 | memcpy(ctx->buffer, data, size); 183 | } 184 | 185 | void MD5Final (unsigned char *result, MD5_CTX *ctx) { 186 | uint32_t used, free; 187 | 188 | used = ctx->lo & 0x3f; 189 | 190 | ctx->buffer[used++] = 0x80; 191 | 192 | free = 64 - used; 193 | 194 | if (free < 8) { 195 | memset(&ctx->buffer[used], 0, free); 196 | md5_body(ctx, ctx->buffer, 64); 197 | used = 0; 198 | free = 64; 199 | } 200 | 201 | memset(&ctx->buffer[used], 0, free - 8); 202 | 203 | ctx->lo <<= 3; 204 | ctx->buffer[56] = ctx->lo; 205 | ctx->buffer[57] = ctx->lo >> 8; 206 | ctx->buffer[58] = ctx->lo >> 16; 207 | ctx->buffer[59] = ctx->lo >> 24; 208 | ctx->buffer[60] = ctx->hi; 209 | ctx->buffer[61] = ctx->hi >> 8; 210 | ctx->buffer[62] = ctx->hi >> 16; 211 | ctx->buffer[63] = ctx->hi >> 24; 212 | 213 | md5_body(ctx, ctx->buffer, 64); 214 | 215 | result[0] = ctx->a; 216 | result[1] = ctx->a >> 8; 217 | result[2] = ctx->a >> 16; 218 | result[3] = ctx->a >> 24; 219 | result[4] = ctx->b; 220 | result[5] = ctx->b >> 8; 221 | result[6] = ctx->b >> 16; 222 | result[7] = ctx->b >> 24; 223 | result[8] = ctx->c; 224 | result[9] = ctx->c >> 8; 225 | result[10] = ctx->c >> 16; 226 | result[11] = ctx->c >> 24; 227 | result[12] = ctx->d; 228 | result[13] = ctx->d >> 8; 229 | result[14] = ctx->d >> 16; 230 | result[15] = ctx->d >> 24; 231 | 232 | EUFA_ZERO(ctx, sizeof(*ctx)); 233 | } 234 | /* }}} */ 235 | 236 | 237 | #ifdef __cplusplus 238 | } 239 | #endif 240 | -------------------------------------------------------------------------------- /src/encryptor/md5.h: -------------------------------------------------------------------------------- 1 | #ifndef EUFA_ENCRYPTOR_MD5 2 | #define EUFA_ENCRYPTOR_MD5 3 | 4 | #include "encryptor.h" 5 | 6 | #define ENCRYPTOR_F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 7 | #define ENCRYPTOR_G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) 8 | #define ENCRYPTOR_H(x, y, z) ((x) ^ (y) ^ (z)) 9 | #define ENCRYPTOR_I(x, y, z) ((y) ^ ((x) | ~(z))) 10 | 11 | #define SET(n) \ 12 | (ctx->block[(n)] = \ 13 | (uint32_t)ptr[(n) * 4] | \ 14 | ((uint32_t)ptr[(n) * 4 + 1] << 8) | \ 15 | ((uint32_t)ptr[(n) * 4 + 2] << 16) | \ 16 | ((uint32_t)ptr[(n) * 4 + 3] << 24)) 17 | #define GET(n) \ 18 | (ctx->block[(n)]) 19 | 20 | /* 21 | * The MD5 transformation for all four rounds. 22 | */ 23 | #define STEP(f, a, b, c, d, x, t, s) \ 24 | (a) += f((b), (c), (d)) + (x) + (t); \ 25 | (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ 26 | (a) += (b); 27 | 28 | 29 | 30 | extern "C" { 31 | 32 | /* 33 | * Expose functions. 34 | */ 35 | extern char* md5 (const unsigned char *str, size_t length); 36 | 37 | typedef struct { 38 | uint32_t lo, hi; 39 | uint32_t a, b, c, d; 40 | unsigned char buffer[64]; 41 | uint32_t block[16]; 42 | } MD5_CTX; 43 | 44 | void MD5Init (MD5_CTX *ctx); 45 | void MD5Update (MD5_CTX *ctx, const unsigned char *data, size_t size); 46 | void MD5Final (unsigned char *result, MD5_CTX *ctx); 47 | 48 | void make_digest_ex (char *md5str, const unsigned char *digest, int len); 49 | 50 | } 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/encryptor/sha1.cc: -------------------------------------------------------------------------------- 1 | #include "sha1.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | /* {{{ sha1 related */ 8 | char* EMSCRIPTEN_KEEPALIVE sha1 (const unsigned char *str, size_t length) { 9 | unsigned char *arg; 10 | unsigned char raw_output = 0; 11 | char* sha1str = (char*) malloc(41 * sizeof(char)); 12 | SHA1_CTX context; 13 | unsigned char digest[20]; 14 | 15 | sha1str[0] = '\0'; 16 | SHA1Init(&context); 17 | SHA1Update(&context, str, length); 18 | SHA1Final(digest, &context); 19 | 20 | make_digest_ex(sha1str, digest, 20); 21 | return sha1str; 22 | } 23 | 24 | void SHA1Init(SHA1_CTX * context) { 25 | context->count[0] = context->count[1] = 0; 26 | /* Load magic initialization constants. */ 27 | context->state[0] = 0x67452301; 28 | context->state[1] = 0xefcdab89; 29 | context->state[2] = 0x98badcfe; 30 | context->state[3] = 0x10325476; 31 | context->state[4] = 0xc3d2e1f0; 32 | } 33 | 34 | 35 | /* 36 | SHA1 block update operation. Continues an SHA1 message-digest 37 | operation, processing another message block, and updating the 38 | context. 39 | */ 40 | void SHA1Update (SHA1_CTX * context, const unsigned char *input, size_t inputLen) { 41 | unsigned int i, index, partLen; 42 | 43 | /* Compute number of bytes mod 64 */ 44 | index = (unsigned int) ((context->count[0] >> 3) & 0x3F); 45 | 46 | /* Update number of bits */ 47 | if ((context->count[0] += ((uint32_t) inputLen << 3)) 48 | < ((uint32_t) inputLen << 3)) 49 | context->count[1]++; 50 | context->count[1] += ((uint32_t) inputLen >> 29); 51 | 52 | partLen = 64 - index; 53 | 54 | /* Transform as many times as possible. */ 55 | if (inputLen >= partLen) { 56 | memcpy 57 | ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen); 58 | SHA1Transform(context->state, context->buffer); 59 | 60 | for (i = partLen; i + 63 < inputLen; i += 64) 61 | SHA1Transform(context->state, &input[i]); 62 | 63 | index = 0; 64 | } else 65 | i = 0; 66 | 67 | /* Buffer remaining input */ 68 | memcpy ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i); 69 | } 70 | 71 | 72 | /* 73 | SHA1 finalization. Ends an SHA1 message-digest operation, writing the 74 | the message digest and zeroizing the context. 75 | */ 76 | void SHA1Final (unsigned char digest[20], SHA1_CTX * context) { 77 | unsigned char bits[8]; 78 | unsigned int index, padLen; 79 | 80 | /* Save number of bits */ 81 | bits[7] = context->count[0] & 0xFF; 82 | bits[6] = (context->count[0] >> 8) & 0xFF; 83 | bits[5] = (context->count[0] >> 16) & 0xFF; 84 | bits[4] = (context->count[0] >> 24) & 0xFF; 85 | bits[3] = context->count[1] & 0xFF; 86 | bits[2] = (context->count[1] >> 8) & 0xFF; 87 | bits[1] = (context->count[1] >> 16) & 0xFF; 88 | bits[0] = (context->count[1] >> 24) & 0xFF; 89 | 90 | /* Pad out to 56 mod 64. */ 91 | index = (unsigned int) ((context->count[0] >> 3) & 0x3f); 92 | padLen = (index < 56) ? (56 - index) : (120 - index); 93 | SHA1Update(context, PADDING, padLen); 94 | 95 | /* Append length (before padding) */ 96 | SHA1Update(context, bits, 8); 97 | 98 | /* Store state in digest */ 99 | SHA1Encode(digest, context->state, 20); 100 | 101 | /* Zeroize sensitive information. 102 | */ 103 | memset((unsigned char*) context, 0, sizeof(*context)); 104 | } 105 | 106 | 107 | /* 108 | * SHA1 basic transformation. Transforms state based on block. 109 | */ 110 | static void SHA1Transform (uint32_t state[5], const unsigned char block[64]) { 111 | uint32_t a = state[0], b = state[1], c = state[2]; 112 | uint32_t d = state[3], e = state[4], x[16], tmp; 113 | 114 | SHA1Decode(x, block, 64); 115 | 116 | /* Round 1 */ 117 | SHA1_FF(a, b, c, d, e, x[0]); /* 1 */ 118 | SHA1_FF(e, a, b, c, d, x[1]); /* 2 */ 119 | SHA1_FF(d, e, a, b, c, x[2]); /* 3 */ 120 | SHA1_FF(c, d, e, a, b, x[3]); /* 4 */ 121 | SHA1_FF(b, c, d, e, a, x[4]); /* 5 */ 122 | SHA1_FF(a, b, c, d, e, x[5]); /* 6 */ 123 | SHA1_FF(e, a, b, c, d, x[6]); /* 7 */ 124 | SHA1_FF(d, e, a, b, c, x[7]); /* 8 */ 125 | SHA1_FF(c, d, e, a, b, x[8]); /* 9 */ 126 | SHA1_FF(b, c, d, e, a, x[9]); /* 10 */ 127 | SHA1_FF(a, b, c, d, e, x[10]); /* 11 */ 128 | SHA1_FF(e, a, b, c, d, x[11]); /* 12 */ 129 | SHA1_FF(d, e, a, b, c, x[12]); /* 13 */ 130 | SHA1_FF(c, d, e, a, b, x[13]); /* 14 */ 131 | SHA1_FF(b, c, d, e, a, x[14]); /* 15 */ 132 | SHA1_FF(a, b, c, d, e, x[15]); /* 16 */ 133 | SHA1_FF(e, a, b, c, d, SHA1_W(16)); /* 17 */ 134 | SHA1_FF(d, e, a, b, c, SHA1_W(17)); /* 18 */ 135 | SHA1_FF(c, d, e, a, b, SHA1_W(18)); /* 19 */ 136 | SHA1_FF(b, c, d, e, a, SHA1_W(19)); /* 20 */ 137 | 138 | /* Round 2 */ 139 | SHA1_GG(a, b, c, d, e, SHA1_W(20)); /* 21 */ 140 | SHA1_GG(e, a, b, c, d, SHA1_W(21)); /* 22 */ 141 | SHA1_GG(d, e, a, b, c, SHA1_W(22)); /* 23 */ 142 | SHA1_GG(c, d, e, a, b, SHA1_W(23)); /* 24 */ 143 | SHA1_GG(b, c, d, e, a, SHA1_W(24)); /* 25 */ 144 | SHA1_GG(a, b, c, d, e, SHA1_W(25)); /* 26 */ 145 | SHA1_GG(e, a, b, c, d, SHA1_W(26)); /* 27 */ 146 | SHA1_GG(d, e, a, b, c, SHA1_W(27)); /* 28 */ 147 | SHA1_GG(c, d, e, a, b, SHA1_W(28)); /* 29 */ 148 | SHA1_GG(b, c, d, e, a, SHA1_W(29)); /* 30 */ 149 | SHA1_GG(a, b, c, d, e, SHA1_W(30)); /* 31 */ 150 | SHA1_GG(e, a, b, c, d, SHA1_W(31)); /* 32 */ 151 | SHA1_GG(d, e, a, b, c, SHA1_W(32)); /* 33 */ 152 | SHA1_GG(c, d, e, a, b, SHA1_W(33)); /* 34 */ 153 | SHA1_GG(b, c, d, e, a, SHA1_W(34)); /* 35 */ 154 | SHA1_GG(a, b, c, d, e, SHA1_W(35)); /* 36 */ 155 | SHA1_GG(e, a, b, c, d, SHA1_W(36)); /* 37 */ 156 | SHA1_GG(d, e, a, b, c, SHA1_W(37)); /* 38 */ 157 | SHA1_GG(c, d, e, a, b, SHA1_W(38)); /* 39 */ 158 | SHA1_GG(b, c, d, e, a, SHA1_W(39)); /* 40 */ 159 | 160 | /* Round 3 */ 161 | SHA1_HH(a, b, c, d, e, SHA1_W(40)); /* 41 */ 162 | SHA1_HH(e, a, b, c, d, SHA1_W(41)); /* 42 */ 163 | SHA1_HH(d, e, a, b, c, SHA1_W(42)); /* 43 */ 164 | SHA1_HH(c, d, e, a, b, SHA1_W(43)); /* 44 */ 165 | SHA1_HH(b, c, d, e, a, SHA1_W(44)); /* 45 */ 166 | SHA1_HH(a, b, c, d, e, SHA1_W(45)); /* 46 */ 167 | SHA1_HH(e, a, b, c, d, SHA1_W(46)); /* 47 */ 168 | SHA1_HH(d, e, a, b, c, SHA1_W(47)); /* 48 */ 169 | SHA1_HH(c, d, e, a, b, SHA1_W(48)); /* 49 */ 170 | SHA1_HH(b, c, d, e, a, SHA1_W(49)); /* 50 */ 171 | SHA1_HH(a, b, c, d, e, SHA1_W(50)); /* 51 */ 172 | SHA1_HH(e, a, b, c, d, SHA1_W(51)); /* 52 */ 173 | SHA1_HH(d, e, a, b, c, SHA1_W(52)); /* 53 */ 174 | SHA1_HH(c, d, e, a, b, SHA1_W(53)); /* 54 */ 175 | SHA1_HH(b, c, d, e, a, SHA1_W(54)); /* 55 */ 176 | SHA1_HH(a, b, c, d, e, SHA1_W(55)); /* 56 */ 177 | SHA1_HH(e, a, b, c, d, SHA1_W(56)); /* 57 */ 178 | SHA1_HH(d, e, a, b, c, SHA1_W(57)); /* 58 */ 179 | SHA1_HH(c, d, e, a, b, SHA1_W(58)); /* 59 */ 180 | SHA1_HH(b, c, d, e, a, SHA1_W(59)); /* 60 */ 181 | 182 | /* Round 4 */ 183 | SHA1_II(a, b, c, d, e, SHA1_W(60)); /* 61 */ 184 | SHA1_II(e, a, b, c, d, SHA1_W(61)); /* 62 */ 185 | SHA1_II(d, e, a, b, c, SHA1_W(62)); /* 63 */ 186 | SHA1_II(c, d, e, a, b, SHA1_W(63)); /* 64 */ 187 | SHA1_II(b, c, d, e, a, SHA1_W(64)); /* 65 */ 188 | SHA1_II(a, b, c, d, e, SHA1_W(65)); /* 66 */ 189 | SHA1_II(e, a, b, c, d, SHA1_W(66)); /* 67 */ 190 | SHA1_II(d, e, a, b, c, SHA1_W(67)); /* 68 */ 191 | SHA1_II(c, d, e, a, b, SHA1_W(68)); /* 69 */ 192 | SHA1_II(b, c, d, e, a, SHA1_W(69)); /* 70 */ 193 | SHA1_II(a, b, c, d, e, SHA1_W(70)); /* 71 */ 194 | SHA1_II(e, a, b, c, d, SHA1_W(71)); /* 72 */ 195 | SHA1_II(d, e, a, b, c, SHA1_W(72)); /* 73 */ 196 | SHA1_II(c, d, e, a, b, SHA1_W(73)); /* 74 */ 197 | SHA1_II(b, c, d, e, a, SHA1_W(74)); /* 75 */ 198 | SHA1_II(a, b, c, d, e, SHA1_W(75)); /* 76 */ 199 | SHA1_II(e, a, b, c, d, SHA1_W(76)); /* 77 */ 200 | SHA1_II(d, e, a, b, c, SHA1_W(77)); /* 78 */ 201 | SHA1_II(c, d, e, a, b, SHA1_W(78)); /* 79 */ 202 | SHA1_II(b, c, d, e, a, SHA1_W(79)); /* 80 */ 203 | 204 | state[0] += a; 205 | state[1] += b; 206 | state[2] += c; 207 | state[3] += d; 208 | state[4] += e; 209 | 210 | /* Zeroize sensitive information. */ 211 | memset((unsigned char*) x, 0, sizeof(x)); 212 | } 213 | 214 | /* 215 | Encodes input (uint32_t) into output (unsigned char). Assumes len is 216 | a multiple of 4. 217 | */ 218 | static void SHA1Encode (unsigned char *output, uint32_t *input, unsigned int len) { 219 | unsigned int i, j; 220 | 221 | for (i = 0, j = 0; j < len; i++, j += 4) { 222 | output[j] = (unsigned char) ((input[i] >> 24) & 0xff); 223 | output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff); 224 | output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff); 225 | output[j + 3] = (unsigned char) (input[i] & 0xff); 226 | } 227 | } 228 | 229 | /* 230 | Decodes input (unsigned char) into output (uint32_t). Assumes len is 231 | a multiple of 4. 232 | */ 233 | static void SHA1Decode (uint32_t *output, const unsigned char *input, unsigned int len){ 234 | unsigned int i, j; 235 | 236 | for (i = 0, j = 0; j < len; i++, j += 4) 237 | output[i] = ((uint32_t) input[j + 3]) | (((uint32_t) input[j + 2]) << 8) | 238 | (((uint32_t) input[j + 1]) << 16) | (((uint32_t) input[j]) << 24); 239 | } 240 | /* }}} */ 241 | 242 | 243 | #ifdef __cplusplus 244 | } 245 | #endif 246 | -------------------------------------------------------------------------------- /src/encryptor/sha1.h: -------------------------------------------------------------------------------- 1 | #ifndef EUFA_ENCRYPTOR_SHA1 2 | #define EUFA_ENCRYPTOR_SHA1 3 | 4 | #include "encryptor.h" 5 | 6 | 7 | extern "C" { 8 | 9 | /* 10 | * Expose functions. 11 | */ 12 | char* sha1 (const unsigned char *str, size_t length); 13 | 14 | typedef struct { 15 | uint32_t state[5]; /* state (ABCD) */ 16 | uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ 17 | unsigned char buffer[64]; /* input buffer */ 18 | } SHA1_CTX; 19 | 20 | void SHA1Init(SHA1_CTX *); 21 | void SHA1Update(SHA1_CTX *, const unsigned char *, size_t); 22 | void SHA1Final(unsigned char[20], SHA1_CTX *); 23 | void make_sha1_digest(char *sha1str, unsigned char *digest); 24 | 25 | static void SHA1Transform(uint32_t[5], const unsigned char[64]); 26 | static void SHA1Encode(unsigned char *, uint32_t *, unsigned int); 27 | static void SHA1Decode(uint32_t *, const unsigned char *, unsigned int); 28 | 29 | static unsigned char PADDING[64] = { 30 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 33 | }; 34 | 35 | /* F, G, H and I are basic SHA1 functions. */ 36 | #define SHA1_F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 37 | #define SHA1_G(x, y, z) ((x) ^ (y) ^ (z)) 38 | #define SHA1_H(x, y, z) (((x) & (y)) | ((z) & ((x) | (y)))) 39 | #define SHA1_I(x, y, z) ((x) ^ (y) ^ (z)) 40 | 41 | /* ROTATE_LEFT rotates x left n bits. */ 42 | #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) 43 | 44 | /* W[i] */ 45 | #define SHA1_W(i) ( tmp=x[(i-3)&15]^x[(i-8)&15]^x[(i-14)&15]^x[i&15], \ 46 | (x[i&15]=ROTATE_LEFT(tmp, 1)) ) 47 | 48 | /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. */ 49 | #define SHA1_FF(a, b, c, d, e, w) { \ 50 | (e) += SHA1_F ((b), (c), (d)) + (w) + (uint32_t)(0x5A827999); \ 51 | (e) += ROTATE_LEFT ((a), 5); \ 52 | (b) = ROTATE_LEFT((b), 30); \ 53 | } 54 | #define SHA1_GG(a, b, c, d, e, w) { \ 55 | (e) += SHA1_G ((b), (c), (d)) + (w) + (uint32_t)(0x6ED9EBA1); \ 56 | (e) += ROTATE_LEFT ((a), 5); \ 57 | (b) = ROTATE_LEFT((b), 30); \ 58 | } 59 | #define SHA1_HH(a, b, c, d, e, w) { \ 60 | (e) += SHA1_H ((b), (c), (d)) + (w) + (uint32_t)(0x8F1BBCDC); \ 61 | (e) += ROTATE_LEFT ((a), 5); \ 62 | (b) = ROTATE_LEFT((b), 30); \ 63 | } 64 | #define SHA1_II(a, b, c, d, e, w) { \ 65 | (e) += SHA1_I ((b), (c), (d)) + (w) + (uint32_t)(0xCA62C1D6); \ 66 | (e) += ROTATE_LEFT ((a), 5); \ 67 | (b) = ROTATE_LEFT((b), 30); \ 68 | } 69 | 70 | } 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/file/file.cc: -------------------------------------------------------------------------------- 1 | #include "file.h" 2 | 3 | 4 | void fetchOnSucceed (const char* fileName) { 5 | emscripten_log(EM_LOG_CONSOLE, "[Eufa] File '%s' loading succeed!", fileName); 6 | } 7 | 8 | void fetchOnFailed (const char* fileName) { 9 | emscripten_log(EM_LOG_ERROR, "[Eufa] File '%s' loading failed!", fileName); 10 | } 11 | 12 | void EMSCRIPTEN_KEEPALIVE fetchFile(const char* fileName, const char* url) { 13 | emscripten_async_wget(url, fileName, &fetchOnSucceed, &fetchOnFailed); 14 | } 15 | 16 | void EMSCRIPTEN_KEEPALIVE fetchFileBatch(const char* jsonFilesData, em_socket_error_callback su, em_socket_error_callback fa) { 17 | 18 | } -------------------------------------------------------------------------------- /src/file/file.h: -------------------------------------------------------------------------------- 1 | #ifndef EUFA_FILE 2 | #define EUFA_FILE 3 | 4 | #include "../global.h" 5 | 6 | // Downloading queue. 7 | typedef map DOWNLOADING_ENTITY; 8 | typedef stack DOWNLOADING_STACK; 9 | 10 | extern "C" { 11 | 12 | // Init function 13 | void _INIT_EUFA_FILE_RUNTIME() { 14 | DOWNLOADING_STACK stack; 15 | } 16 | 17 | extern void fetchFile(const char*, const char*); 18 | extern void fetchFileBatch(const char*, em_str_callback_func, em_str_callback_func); 19 | 20 | } 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/global.cc: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | size_t EMSCRIPTEN_KEEPALIVE sizeof_type_double () { 8 | return sizeof(double); 9 | } 10 | 11 | size_t EMSCRIPTEN_KEEPALIVE sizeof_type_long () { 12 | return sizeof(long); 13 | } 14 | 15 | size_t EMSCRIPTEN_KEEPALIVE sizeof_type_size_t () { 16 | return sizeof(size_t); 17 | } 18 | 19 | void* EMSCRIPTEN_KEEPALIVE cache_malloc (size_t size) { 20 | if (all_cache_used_memory + size > EUFA_CACHE_MAX_MEMORY_SIZE) { 21 | return NULL; 22 | } 23 | void *ptr = malloc(size + PREFIX_SIZE); 24 | *((size_t*)ptr) = size; 25 | update_zmalloc_stat_alloc(size + PREFIX_SIZE); 26 | return (char*)ptr + PREFIX_SIZE; 27 | } 28 | 29 | void EMSCRIPTEN_KEEPALIVE cache_free (void *ptr) { 30 | if (ptr == NULL) { 31 | return; 32 | } 33 | void *realptr = (char*)ptr - PREFIX_SIZE; 34 | size_t oldsize = *((size_t*)realptr); 35 | update_zmalloc_stat_free(oldsize + PREFIX_SIZE); 36 | free(realptr); 37 | } 38 | 39 | size_t EMSCRIPTEN_KEEPALIVE cache_used_memory (void) { 40 | return all_cache_used_memory; 41 | } 42 | 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | -------------------------------------------------------------------------------- /src/global.h: -------------------------------------------------------------------------------- 1 | #ifndef EUFA_GLOBAL 2 | #define EUFA_GLOBAL 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | // DLib 11 | #include 12 | #include 13 | #include 14 | // File 15 | #include 16 | #include 17 | 18 | #define TRUE 1 19 | #define FALSE 0 20 | #define EUFA_CACHE_MAX_MEMORY_SIZE 16777216 21 | #define PREFIX_SIZE sizeof(size_t) 22 | #define update_zmalloc_stat_alloc(__n) do { \ 23 | size_t _n = (__n); \ 24 | if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \ 25 | all_cache_used_memory += (__n); \ 26 | } while(0) 27 | 28 | #define update_zmalloc_stat_free(__n) do { \ 29 | size_t _n = (__n); \ 30 | if (_n&(sizeof(long)-1)) _n += sizeof(long)-(_n&(sizeof(long)-1)); \ 31 | all_cache_used_memory -= (__n); \ 32 | } while(0) 33 | 34 | static size_t all_cache_used_memory = 0; 35 | 36 | extern "C" { 37 | 38 | extern void print_i32 (int number); 39 | extern void print_i8_string (char* offset, int length); 40 | extern void print_i32_array (int* offset, int length); 41 | 42 | /* Environment detect functions */ 43 | extern size_t sizeof_type_double(); 44 | extern size_t sizeof_type_long(); 45 | extern size_t sizeof_type_size_t(); 46 | 47 | /* Memory related functions for cache */ 48 | extern size_t cache_used_memory (void); 49 | extern void* cache_malloc (size_t size); 50 | extern void cache_free (void *ptr); 51 | 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/math/math.cc: -------------------------------------------------------------------------------- 1 | #include "math.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | int EMSCRIPTEN_KEEPALIVE i64_add (int x, int y) { 8 | return x + y; 9 | } 10 | 11 | double EMSCRIPTEN_KEEPALIVE f64_add (double x, double y) { 12 | return x + y; 13 | } 14 | 15 | int EMSCRIPTEN_KEEPALIVE i64_minus (int x, int y) { 16 | return x - y; 17 | } 18 | 19 | double EMSCRIPTEN_KEEPALIVE f64_minus (double x, double y) { 20 | return x - y; 21 | } 22 | 23 | int EMSCRIPTEN_KEEPALIVE i64_multiply (int x, int y) { 24 | return x * y; 25 | } 26 | 27 | double EMSCRIPTEN_KEEPALIVE f64_multiply (double x, double y) { 28 | return x * y; 29 | } 30 | 31 | int EMSCRIPTEN_KEEPALIVE i64_divide (int x, int y) { 32 | return x / y; 33 | } 34 | 35 | double EMSCRIPTEN_KEEPALIVE f64_divide (double x, double y) { 36 | return x / y; 37 | } 38 | 39 | unsigned int EMSCRIPTEN_KEEPALIVE i64_abs (int number) { 40 | return abs(number); 41 | } 42 | 43 | double EMSCRIPTEN_KEEPALIVE f64_abs (double number) { 44 | return abs(number); 45 | } 46 | 47 | unsigned int EMSCRIPTEN_KEEPALIVE i64_sqrt (unsigned int number) { 48 | return sqrt(number); 49 | } 50 | 51 | double EMSCRIPTEN_KEEPALIVE f64_sqrt (double number) { 52 | return sqrtf(number); 53 | } 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | -------------------------------------------------------------------------------- /src/math/math.h: -------------------------------------------------------------------------------- 1 | #ifndef EUFA_MATH 2 | #define EUFA_MATH 3 | 4 | #include "../global.h" 5 | 6 | 7 | extern "C" { 8 | 9 | extern int i64_add (int x, int y); 10 | extern double f64_add (double x, double y); 11 | 12 | extern int i64_minus (int x, int y); 13 | extern double f64_minus (double x, double y); 14 | 15 | extern int i64_multiply (int x, int y); 16 | extern double f64_multiply (double x, double y); 17 | 18 | extern int i64_divide (int x, int y); 19 | extern double f64_divide (double x, double y); 20 | 21 | extern unsigned int i64_abs (int number); 22 | extern double f64_abs (double number); 23 | 24 | extern unsigned int i64_sqrt (unsigned int number); 25 | extern double f64_sqrt (double number); 26 | } 27 | 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/string/string.cc: -------------------------------------------------------------------------------- 1 | #include "string.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | unsigned char* EMSCRIPTEN_KEEPALIVE capitalize (unsigned char *string) { 8 | int i = 0; 9 | while (1) { 10 | char _current_pos = *(string + i); 11 | 12 | if (_current_pos >= 0x61 && _current_pos <= 0x7a) { 13 | *(string + i) = _current_pos - 32; 14 | } 15 | 16 | if (_current_pos == '\0') { 17 | break; 18 | } 19 | 20 | i++; 21 | } 22 | 23 | return string; 24 | } 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | -------------------------------------------------------------------------------- /src/string/string.h: -------------------------------------------------------------------------------- 1 | #ifndef EUFA_STRING 2 | #define EUFA_STRING 3 | 4 | #include "../global.h" 5 | 6 | extern "C" { 7 | extern unsigned char* capitalize (unsigned char *string); 8 | } 9 | 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/tensorflow/bazel/BUILD: -------------------------------------------------------------------------------- 1 | package(default_visibility = ["//visibility:public"]) 2 | 3 | load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar") 4 | 5 | pkg_tar( 6 | name = "ct-libtensorflow", 7 | extension = "tar.gz", 8 | tags = ["manual"], 9 | deps = [ 10 | ":ct-cheaders", 11 | ":ct-clib" 12 | ], 13 | ) 14 | 15 | pkg_tar( 16 | name = "ct-cheaders", 17 | files = ["//tensorflow/c:headers"], 18 | package_dir = "include/tensorflow/c", 19 | tags = ["manual"], 20 | ) 21 | 22 | pkg_tar( 23 | name = "ct-clib", 24 | files = ["//tensorflow:libtensorflow.so"], 25 | package_dir = "lib", 26 | tags = ["manual"], 27 | ) 28 | 29 | 30 | # This is the entry point for --crosstool_top. 31 | # 32 | # The cc_toolchain rule used is found by: 33 | # 34 | # 1. Finding the appropriate toolchain in the CROSSTOOL file based on the --cpu 35 | # and --compiler command line flags (if they exist, otherwise using the 36 | # "default_target_cpu" / "default_toolchain" fields in the CROSSTOOL file) 37 | # 2. Concatenating the "target_cpu" and "compiler" fields of the toolchain in 38 | # use and using that as a key in the map in the "toolchains" attribute 39 | 40 | cc_toolchain_suite( 41 | name = 'toolchain', 42 | toolchains = { 43 | 'darwin|clang': ':cc-compiler-clang-llvm', 44 | }, 45 | ) 46 | 47 | 48 | cc_toolchain( 49 | name = "cc-compiler-clang-llvm", 50 | all_files = ":empty", 51 | compiler_files = ":empty", 52 | cpu = "darwin", 53 | dwp_files = ":empty", 54 | dynamic_runtime_libs = [":empty"], 55 | linker_files = ":empty", 56 | objcopy_files = ":empty", 57 | static_runtime_libs = [":empty"], 58 | strip_files = ":empty", 59 | supports_param_files = 1, 60 | ) 61 | -------------------------------------------------------------------------------- /src/tensorflow/bazel/CROSSTOOL: -------------------------------------------------------------------------------- 1 | major_version: "clang-llvm" 2 | minor_version: "" 3 | 4 | 5 | default_target_cpu: "darwin" 6 | default_toolchain { 7 | cpu: "darwin" 8 | toolchain_identifier: "clang-llvm" 9 | } 10 | 11 | 12 | toolchain { 13 | toolchain_identifier: "clang-llvm" 14 | abi_version: "local" 15 | abi_libc_version: "local" 16 | builtin_sysroot: "" 17 | compiler: "clang" 18 | host_system_name: "local" 19 | needsPic: true 20 | supports_gold_linker: true 21 | supports_incremental_linker: false 22 | supports_fission: false 23 | supports_interface_shared_objects: false 24 | supports_normalizing_ar: false 25 | supports_start_end_lib: true 26 | target_libc: "local" 27 | target_cpu: "darwin" 28 | target_system_name: "local" 29 | cxx_flag: "-std=c++11" 30 | linker_flag: "-lstdc++" 31 | linker_flag: "-lm" 32 | linker_flag: "-fuse-ld=gold" 33 | linker_flag: "-B/home/hbucher/install/bin" 34 | linker_flag: "-B/usr/bin" 35 | linker_flag: "-Wl,--build-id=md5" 36 | linker_flag: "-Wl,--hash-style=gnu" 37 | cxx_builtin_include_directory: "/usr/include/c++/5.4.0" 38 | cxx_builtin_include_directory: "/home/hbucher/install/include/c++/v1" 39 | cxx_builtin_include_directory: "/home/hbucher/install/include/" 40 | cxx_builtin_include_directory: "/usr/include/x86_64-linux-gnu/c++/5.4.0" 41 | cxx_builtin_include_directory: "/usr/include/c++/5.4.0/backward" 42 | cxx_builtin_include_directory: "/usr/local/include" 43 | cxx_builtin_include_directory: "/home/hbucher/install/lib/clang/4.0.0/include" 44 | cxx_builtin_include_directory: "/usr/include/x86_64-linux-gnu" 45 | cxx_builtin_include_directory: "/usr/include" 46 | objcopy_embed_flag: "-I" 47 | objcopy_embed_flag: "binary" 48 | unfiltered_cxx_flag: "-Wno-builtin-macro-redefined" 49 | unfiltered_cxx_flag: "-D__DATE__=\"redacted\"" 50 | unfiltered_cxx_flag: "-D__TIMESTAMP__=\"redacted\"" 51 | unfiltered_cxx_flag: "-D__TIME__=\"redacted\"" 52 | compiler_flag: "-U_FORTIFY_SOURCE" 53 | compiler_flag: "-fstack-protector" 54 | compiler_flag: "-Wall" 55 | compiler_flag: "-B/home/hbucher/install/bin" 56 | compiler_flag: "-B/usr/bin" 57 | compiler_flag: "-fcolor-diagnostics" 58 | compiler_flag: "-fno-omit-frame-pointer" 59 | compiler_flag: "-v" 60 | tool_path {name: "ld" path: "/usr/bin/ld" } 61 | tool_path {name: "cpp" path: "/usr/bin/cpp" } 62 | tool_path {name: "dwp" path: "/usr/bin/dwp" } 63 | tool_path {name: "gcov" path: "/usr/bin/gcov" } 64 | tool_path {name: "nm" path: "/usr/bin/nm" } 65 | tool_path {name: "objcopy" path: "/usr/bin/objcopy" } 66 | tool_path {name: "objdump" path: "/usr/bin/objdump" } 67 | tool_path {name: "strip" path: "/usr/bin/strip" } 68 | tool_path {name: "gcc" path: "/home/hbucher/install/bin/clang" } 69 | tool_path {name: "ar" path: "/usr/bin/ar" } 70 | 71 | compilation_mode_flags { 72 | mode: DBG 73 | compiler_flag: "-g" 74 | } 75 | compilation_mode_flags { 76 | mode: OPT 77 | compiler_flag: "-g0" 78 | compiler_flag: "-O2" 79 | compiler_flag: "-D_FORTIFY_SOURCE=1" 80 | compiler_flag: "-DNDEBUG" 81 | compiler_flag: "-ffunction-sections" 82 | compiler_flag: "-fdata-sections" 83 | linker_flag: "-Wl,--gc-sections" 84 | } 85 | linking_mode_flags { mode: DYNAMIC } 86 | } -------------------------------------------------------------------------------- /src/tensorflow/bazel/README.md: -------------------------------------------------------------------------------- 1 | ## Tensorflow LLVM - Bazel 2 | -------------------------------------------------------------------------------- /src/tensorflow/tensorflow.cc: -------------------------------------------------------------------------------- 1 | #include "tensorflow.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | const char* EMSCRIPTEN_KEEPALIVE tf_version () { 8 | return TF_Version(); 9 | } 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | -------------------------------------------------------------------------------- /src/tensorflow/tensorflow.h: -------------------------------------------------------------------------------- 1 | #ifndef EUFA_TENSORFLOW 2 | #define EUFA_TENSORFLOW 3 | 4 | #include "../global.h" 5 | #include 6 | 7 | extern "C" { 8 | 9 | extern const char* tf_version(); 10 | 11 | } 12 | 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /test/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { 4 | "modules": false, 5 | "targets": { 6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] 7 | } 8 | }], 9 | "stage-2" 10 | ], 11 | "plugins": ["transform-runtime"], 12 | "env": { 13 | "test": { 14 | "presets": ["env", "stage-2"], 15 | "plugins": ["istanbul"] 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /test/.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | -------------------------------------------------------------------------------- /test/.eslintrc.js: -------------------------------------------------------------------------------- 1 | // http://eslint.org/docs/user-guide/configuring 2 | 3 | module.exports = { 4 | root: true, 5 | parser: 'babel-eslint', 6 | parserOptions: { 7 | sourceType: 'module' 8 | }, 9 | env: { 10 | browser: true, 11 | }, 12 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 13 | extends: 'standard', 14 | // required to lint *.vue files 15 | plugins: [ 16 | 'html' 17 | ], 18 | // add your custom rules here 19 | 'rules': { 20 | // allow paren-less arrow functions 21 | 'arrow-parens': 0, 22 | // allow async-await 23 | 'generator-star-spacing': 0, 24 | // allow debugger during development 25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Editor directories and files 9 | .idea 10 | *.suo 11 | *.ntvs* 12 | *.njsproj 13 | *.sln 14 | -------------------------------------------------------------------------------- /test/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | // to edit target browsers: use "browserslist" field in package.json 6 | "autoprefixer": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | # eufa-test 2 | 3 | > Eufa test project. 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | ``` 20 | 21 | For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 22 | -------------------------------------------------------------------------------- /test/build/build.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | process.env.NODE_ENV = 'production' 4 | 5 | var ora = require('ora') 6 | var rm = require('rimraf') 7 | var path = require('path') 8 | var chalk = require('chalk') 9 | var webpack = require('webpack') 10 | var config = require('../config') 11 | var webpackConfig = require('./webpack.prod.conf') 12 | 13 | var spinner = ora('building for production...') 14 | spinner.start() 15 | 16 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 17 | if (err) throw err 18 | webpack(webpackConfig, function (err, stats) { 19 | spinner.stop() 20 | if (err) throw err 21 | process.stdout.write(stats.toString({ 22 | colors: true, 23 | modules: false, 24 | children: false, 25 | chunks: false, 26 | chunkModules: false 27 | }) + '\n\n') 28 | 29 | console.log(chalk.cyan(' Build complete.\n')) 30 | console.log(chalk.yellow( 31 | ' Tip: built files are meant to be served over an HTTP server.\n' + 32 | ' Opening index.html over file:// won\'t work.\n' 33 | )) 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /test/build/check-versions.js: -------------------------------------------------------------------------------- 1 | var chalk = require('chalk') 2 | var semver = require('semver') 3 | var packageConfig = require('../package.json') 4 | var shell = require('shelljs') 5 | function exec (cmd) { 6 | return require('child_process').execSync(cmd).toString().trim() 7 | } 8 | 9 | var versionRequirements = [ 10 | { 11 | name: 'node', 12 | currentVersion: semver.clean(process.version), 13 | versionRequirement: packageConfig.engines.node 14 | }, 15 | ] 16 | 17 | if (shell.which('npm')) { 18 | versionRequirements.push({ 19 | name: 'npm', 20 | currentVersion: exec('npm --version'), 21 | versionRequirement: packageConfig.engines.npm 22 | }) 23 | } 24 | 25 | module.exports = function () { 26 | var warnings = [] 27 | for (var i = 0; i < versionRequirements.length; i++) { 28 | var mod = versionRequirements[i] 29 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 30 | warnings.push(mod.name + ': ' + 31 | chalk.red(mod.currentVersion) + ' should be ' + 32 | chalk.green(mod.versionRequirement) 33 | ) 34 | } 35 | } 36 | 37 | if (warnings.length) { 38 | console.log('') 39 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 40 | console.log() 41 | for (var i = 0; i < warnings.length; i++) { 42 | var warning = warnings[i] 43 | console.log(' ' + warning) 44 | } 45 | console.log() 46 | process.exit(1) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /test/build/dev-client.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | require('eventsource-polyfill') 3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') 4 | 5 | hotClient.subscribe(function (event) { 6 | if (event.action === 'reload') { 7 | window.location.reload() 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /test/build/dev-server.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | var config = require('../config') 4 | if (!process.env.NODE_ENV) { 5 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV) 6 | } 7 | 8 | var opn = require('opn') 9 | var path = require('path') 10 | var express = require('express') 11 | var webpack = require('webpack') 12 | var proxyMiddleware = require('http-proxy-middleware') 13 | var webpackConfig = require('./webpack.dev.conf') 14 | 15 | // default port where dev server listens for incoming traffic 16 | var port = process.env.PORT || config.dev.port 17 | // automatically open browser, if not set will be false 18 | var autoOpenBrowser = !!config.dev.autoOpenBrowser 19 | // Define HTTP proxies to your custom API backend 20 | // https://github.com/chimurai/http-proxy-middleware 21 | var proxyTable = config.dev.proxyTable 22 | 23 | var app = express() 24 | var compiler = webpack(webpackConfig) 25 | 26 | var devMiddleware = require('webpack-dev-middleware')(compiler, { 27 | publicPath: webpackConfig.output.publicPath, 28 | quiet: true 29 | }) 30 | 31 | var hotMiddleware = require('webpack-hot-middleware')(compiler, { 32 | log: () => {}, 33 | heartbeat: 2000 34 | }) 35 | // force page reload when html-webpack-plugin template changes 36 | compiler.plugin('compilation', function (compilation) { 37 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { 38 | hotMiddleware.publish({ action: 'reload' }) 39 | cb() 40 | }) 41 | }) 42 | 43 | // proxy api requests 44 | Object.keys(proxyTable).forEach(function (context) { 45 | var options = proxyTable[context] 46 | if (typeof options === 'string') { 47 | options = { target: options } 48 | } 49 | app.use(proxyMiddleware(options.filter || context, options)) 50 | }) 51 | 52 | // handle fallback for HTML5 history API 53 | app.use(require('connect-history-api-fallback')()) 54 | 55 | // serve webpack bundle output 56 | app.use(devMiddleware) 57 | 58 | // enable hot-reload and state-preserving 59 | // compilation error display 60 | app.use(hotMiddleware) 61 | 62 | // serve pure static assets 63 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) 64 | app.use(staticPath, express.static('./static')) 65 | 66 | var uri = 'http://localhost:' + port 67 | 68 | var _resolve 69 | var readyPromise = new Promise(resolve => { 70 | _resolve = resolve 71 | }) 72 | 73 | console.log('> Starting dev server...') 74 | devMiddleware.waitUntilValid(() => { 75 | console.log('> Listening at ' + uri + '\n') 76 | // when env is testing, don't need open it 77 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { 78 | opn(uri) 79 | } 80 | _resolve() 81 | }) 82 | 83 | var server = app.listen(port) 84 | 85 | module.exports = { 86 | ready: readyPromise, 87 | close: () => { 88 | server.close() 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /test/build/utils.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 4 | 5 | exports.assetsPath = function (_path) { 6 | var assetsSubDirectory = process.env.NODE_ENV === 'production' 7 | ? config.build.assetsSubDirectory 8 | : config.dev.assetsSubDirectory 9 | return path.posix.join(assetsSubDirectory, _path) 10 | } 11 | 12 | exports.cssLoaders = function (options) { 13 | options = options || {} 14 | 15 | var cssLoader = { 16 | loader: 'css-loader', 17 | options: { 18 | minimize: process.env.NODE_ENV === 'production', 19 | sourceMap: options.sourceMap 20 | } 21 | } 22 | 23 | // generate loader string to be used with extract text plugin 24 | function generateLoaders (loader, loaderOptions) { 25 | var loaders = [cssLoader] 26 | if (loader) { 27 | loaders.push({ 28 | loader: loader + '-loader', 29 | options: Object.assign({}, loaderOptions, { 30 | sourceMap: options.sourceMap 31 | }) 32 | }) 33 | } 34 | 35 | // Extract CSS when that option is specified 36 | // (which is the case during production build) 37 | if (options.extract) { 38 | return ExtractTextPlugin.extract({ 39 | use: loaders, 40 | fallback: 'vue-style-loader' 41 | }) 42 | } else { 43 | return ['vue-style-loader'].concat(loaders) 44 | } 45 | } 46 | 47 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 48 | return { 49 | css: generateLoaders(), 50 | postcss: generateLoaders(), 51 | less: generateLoaders('less'), 52 | sass: generateLoaders('sass', { indentedSyntax: true }), 53 | scss: generateLoaders('sass'), 54 | stylus: generateLoaders('stylus'), 55 | styl: generateLoaders('stylus') 56 | } 57 | } 58 | 59 | // Generate loaders for standalone style files (outside of .vue) 60 | exports.styleLoaders = function (options) { 61 | var output = [] 62 | var loaders = exports.cssLoaders(options) 63 | for (var extension in loaders) { 64 | var loader = loaders[extension] 65 | output.push({ 66 | test: new RegExp('\\.' + extension + '$'), 67 | use: loader 68 | }) 69 | } 70 | return output 71 | } 72 | -------------------------------------------------------------------------------- /test/build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | var utils = require('./utils') 2 | var config = require('../config') 3 | var isProduction = process.env.NODE_ENV === 'production' 4 | 5 | module.exports = { 6 | loaders: utils.cssLoaders({ 7 | sourceMap: isProduction 8 | ? config.build.productionSourceMap 9 | : config.dev.cssSourceMap, 10 | extract: isProduction 11 | }), 12 | transformToRequire: { 13 | video: 'src', 14 | source: 'src', 15 | img: 'src', 16 | image: 'xlink:href' 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var utils = require('./utils') 3 | var config = require('../config') 4 | var vueLoaderConfig = require('./vue-loader.conf') 5 | 6 | function resolve (dir) { 7 | return path.join(__dirname, '..', dir) 8 | } 9 | 10 | module.exports = { 11 | entry: { 12 | app: './src/main.js' 13 | }, 14 | output: { 15 | path: config.build.assetsRoot, 16 | filename: '[name].js', 17 | publicPath: process.env.NODE_ENV === 'production' 18 | ? config.build.assetsPublicPath 19 | : config.dev.assetsPublicPath 20 | }, 21 | resolve: { 22 | extensions: ['.js', '.vue', '.json'], 23 | alias: { 24 | 'vue$': 'vue/dist/vue.esm.js', 25 | '@': resolve('src') 26 | } 27 | }, 28 | module: { 29 | rules: [ 30 | { 31 | test: /\.(js|vue)$/, 32 | loader: 'eslint-loader', 33 | enforce: 'pre', 34 | include: [resolve('src'), resolve('test')], 35 | options: { 36 | formatter: require('eslint-friendly-formatter') 37 | } 38 | }, 39 | { 40 | test: /\.vue$/, 41 | loader: 'vue-loader', 42 | options: vueLoaderConfig 43 | }, 44 | { 45 | test: /\.js$/, 46 | loader: 'babel-loader', 47 | include: [resolve('src'), resolve('test')] 48 | }, 49 | { 50 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 51 | loader: 'url-loader', 52 | options: { 53 | limit: 10000, 54 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 55 | } 56 | }, 57 | { 58 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 59 | loader: 'url-loader', 60 | options: { 61 | limit: 10000, 62 | name: utils.assetsPath('media/[name].[hash:7].[ext]') 63 | } 64 | }, 65 | { 66 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 67 | loader: 'url-loader', 68 | options: { 69 | limit: 10000, 70 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 71 | } 72 | } 73 | ] 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /test/build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | var utils = require('./utils') 2 | var webpack = require('webpack') 3 | var config = require('../config') 4 | var merge = require('webpack-merge') 5 | var baseWebpackConfig = require('./webpack.base.conf') 6 | var HtmlWebpackPlugin = require('html-webpack-plugin') 7 | var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 8 | 9 | // add hot-reload related code to entry chunks 10 | Object.keys(baseWebpackConfig.entry).forEach(function (name) { 11 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]) 12 | }) 13 | 14 | module.exports = merge(baseWebpackConfig, { 15 | module: { 16 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) 17 | }, 18 | // cheap-module-eval-source-map is faster for development 19 | devtool: '#cheap-module-eval-source-map', 20 | plugins: [ 21 | new webpack.DefinePlugin({ 22 | 'process.env': config.dev.env 23 | }), 24 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage 25 | new webpack.HotModuleReplacementPlugin(), 26 | new webpack.NoEmitOnErrorsPlugin(), 27 | // https://github.com/ampedandwired/html-webpack-plugin 28 | new HtmlWebpackPlugin({ 29 | filename: 'index.html', 30 | template: 'index.html', 31 | inject: true 32 | }), 33 | new FriendlyErrorsPlugin() 34 | ] 35 | }) 36 | -------------------------------------------------------------------------------- /test/build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var utils = require('./utils') 3 | var webpack = require('webpack') 4 | var config = require('../config') 5 | var merge = require('webpack-merge') 6 | var baseWebpackConfig = require('./webpack.base.conf') 7 | var CopyWebpackPlugin = require('copy-webpack-plugin') 8 | var HtmlWebpackPlugin = require('html-webpack-plugin') 9 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 10 | var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 11 | 12 | var env = config.build.env 13 | 14 | var webpackConfig = merge(baseWebpackConfig, { 15 | module: { 16 | rules: utils.styleLoaders({ 17 | sourceMap: config.build.productionSourceMap, 18 | extract: true 19 | }) 20 | }, 21 | devtool: config.build.productionSourceMap ? '#source-map' : false, 22 | output: { 23 | path: config.build.assetsRoot, 24 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 25 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 26 | }, 27 | plugins: [ 28 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 29 | new webpack.DefinePlugin({ 30 | 'process.env': env 31 | }), 32 | new webpack.optimize.UglifyJsPlugin({ 33 | compress: { 34 | warnings: false 35 | }, 36 | sourceMap: true 37 | }), 38 | // extract css into its own file 39 | new ExtractTextPlugin({ 40 | filename: utils.assetsPath('css/[name].[contenthash].css') 41 | }), 42 | // Compress extracted CSS. We are using this plugin so that possible 43 | // duplicated CSS from different components can be deduped. 44 | new OptimizeCSSPlugin({ 45 | cssProcessorOptions: { 46 | safe: true 47 | } 48 | }), 49 | // generate dist index.html with correct asset hash for caching. 50 | // you can customize output by editing /index.html 51 | // see https://github.com/ampedandwired/html-webpack-plugin 52 | new HtmlWebpackPlugin({ 53 | filename: config.build.index, 54 | template: 'index.html', 55 | inject: true, 56 | minify: { 57 | removeComments: true, 58 | collapseWhitespace: true, 59 | removeAttributeQuotes: true 60 | // more options: 61 | // https://github.com/kangax/html-minifier#options-quick-reference 62 | }, 63 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 64 | chunksSortMode: 'dependency' 65 | }), 66 | // split vendor js into its own file 67 | new webpack.optimize.CommonsChunkPlugin({ 68 | name: 'vendor', 69 | minChunks: function (module, count) { 70 | // any required modules inside node_modules are extracted to vendor 71 | return ( 72 | module.resource && 73 | /\.js$/.test(module.resource) && 74 | module.resource.indexOf( 75 | path.join(__dirname, '../node_modules') 76 | ) === 0 77 | ) 78 | } 79 | }), 80 | // extract webpack runtime and module manifest to its own file in order to 81 | // prevent vendor hash from being updated whenever app bundle is updated 82 | new webpack.optimize.CommonsChunkPlugin({ 83 | name: 'manifest', 84 | chunks: ['vendor'] 85 | }), 86 | // copy custom static assets 87 | new CopyWebpackPlugin([ 88 | { 89 | from: path.resolve(__dirname, '../static'), 90 | to: config.build.assetsSubDirectory, 91 | ignore: ['.*'] 92 | } 93 | ]) 94 | ] 95 | }) 96 | 97 | if (config.build.productionGzip) { 98 | var CompressionWebpackPlugin = require('compression-webpack-plugin') 99 | 100 | webpackConfig.plugins.push( 101 | new CompressionWebpackPlugin({ 102 | asset: '[path].gz[query]', 103 | algorithm: 'gzip', 104 | test: new RegExp( 105 | '\\.(' + 106 | config.build.productionGzipExtensions.join('|') + 107 | ')$' 108 | ), 109 | threshold: 10240, 110 | minRatio: 0.8 111 | }) 112 | ) 113 | } 114 | 115 | if (config.build.bundleAnalyzerReport) { 116 | var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 117 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 118 | } 119 | 120 | module.exports = webpackConfig 121 | -------------------------------------------------------------------------------- /test/config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /test/config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | module.exports = { 5 | build: { 6 | env: require('./prod.env'), 7 | index: path.resolve(__dirname, '../dist/index.html'), 8 | assetsRoot: path.resolve(__dirname, '../dist'), 9 | assetsSubDirectory: 'static', 10 | assetsPublicPath: '/', 11 | productionSourceMap: true, 12 | // Gzip off by default as many popular static hosts such as 13 | // Surge or Netlify already gzip all static assets for you. 14 | // Before setting to `true`, make sure to: 15 | // npm install --save-dev compression-webpack-plugin 16 | productionGzip: false, 17 | productionGzipExtensions: ['js', 'css'], 18 | // Run the build command with an extra argument to 19 | // View the bundle analyzer report after build finishes: 20 | // `npm run build --report` 21 | // Set to `true` or `false` to always turn it on or off 22 | bundleAnalyzerReport: process.env.npm_config_report 23 | }, 24 | dev: { 25 | env: require('./dev.env'), 26 | port: 8080, 27 | autoOpenBrowser: true, 28 | assetsSubDirectory: 'static', 29 | assetsPublicPath: '/', 30 | proxyTable: {}, 31 | // CSS Sourcemaps off by default because relative paths are "buggy" 32 | // with this option, according to the CSS-Loader README 33 | // (https://github.com/webpack/css-loader#sourcemaps) 34 | // In our experience, they generally work as expected, 35 | // just be aware of this issue when enabling this option. 36 | cssSourceMap: false 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | eufa-test 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eufa-test", 3 | "version": "1.0.0", 4 | "description": "Eufa test project.", 5 | "author": "YHSPY", 6 | "private": true, 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "start": "node build/dev-server.js", 10 | "build": "node build/build.js", 11 | "lint": "eslint --ext .js,.vue src" 12 | }, 13 | "dependencies": { 14 | "echarts": "^3.7.0", 15 | "vue": "^2.3.3" 16 | }, 17 | "devDependencies": { 18 | "autoprefixer": "^7.1.2", 19 | "babel-core": "^6.22.1", 20 | "babel-eslint": "^7.1.1", 21 | "babel-loader": "^7.1.1", 22 | "babel-plugin-transform-runtime": "^6.22.0", 23 | "babel-preset-env": "^1.3.2", 24 | "babel-preset-stage-2": "^6.22.0", 25 | "babel-register": "^6.22.0", 26 | "chalk": "^2.0.1", 27 | "connect-history-api-fallback": "^1.3.0", 28 | "copy-webpack-plugin": "^4.0.1", 29 | "css-loader": "^0.28.0", 30 | "cssnano": "^3.10.0", 31 | "eslint": "^3.19.0", 32 | "eslint-config-standard": "^6.2.1", 33 | "eslint-friendly-formatter": "^3.0.0", 34 | "eslint-loader": "^1.7.1", 35 | "eslint-plugin-html": "^3.0.0", 36 | "eslint-plugin-promise": "^3.4.0", 37 | "eslint-plugin-standard": "^2.0.1", 38 | "eventsource-polyfill": "^0.9.6", 39 | "express": "^4.14.1", 40 | "extract-text-webpack-plugin": "^2.0.0", 41 | "file-loader": "^0.11.1", 42 | "friendly-errors-webpack-plugin": "^1.1.3", 43 | "html-webpack-plugin": "^2.28.0", 44 | "http-proxy-middleware": "^0.17.3", 45 | "opn": "^5.1.0", 46 | "optimize-css-assets-webpack-plugin": "^2.0.0", 47 | "ora": "^1.2.0", 48 | "rimraf": "^2.6.0", 49 | "semver": "^5.3.0", 50 | "shelljs": "^0.7.6", 51 | "url-loader": "^0.5.8", 52 | "vue-loader": "^12.1.0", 53 | "vue-style-loader": "^3.0.1", 54 | "vue-template-compiler": "^2.3.3", 55 | "webpack": "^2.6.1", 56 | "webpack-bundle-analyzer": "^2.2.1", 57 | "webpack-dev-middleware": "^1.10.0", 58 | "webpack-hot-middleware": "^2.18.0", 59 | "webpack-merge": "^4.1.0" 60 | }, 61 | "engines": { 62 | "node": ">= 4.0.0", 63 | "npm": ">= 3.0.0" 64 | }, 65 | "browserslist": [ 66 | "> 1%", 67 | "last 2 versions", 68 | "not ie <= 8" 69 | ] 70 | } 71 | -------------------------------------------------------------------------------- /test/src/App.vue: -------------------------------------------------------------------------------- 1 | 179 | 180 | 389 | 390 | 415 | -------------------------------------------------------------------------------- /test/src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import App from './App' 5 | 6 | Vue.config.productionTip = false 7 | 8 | /* eslint-disable no-new */ 9 | new Vue({ 10 | el: '#app', 11 | template: '', 12 | components: { App } 13 | }) 14 | -------------------------------------------------------------------------------- /test/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/test/static/.gitkeep -------------------------------------------------------------------------------- /test/static/eufa-asyn-worker.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var getFileData = function getFileData(url) { 4 | var chunkSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1024 * 1024; 5 | 6 | var xhr = new XMLHttpRequest(); 7 | xhr.open('HEAD', url, false); 8 | xhr.send(null); 9 | if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); 10 | var datalength = Number(xhr.getResponseHeader("Content-length")); 11 | var header; 12 | var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes"; 13 | 14 | var chunkSize = 1024 * 1024 * 64; // Chunk size in bytes 15 | 16 | if (!hasByteServing) chunkSize = datalength; 17 | 18 | var from = 0; 19 | var to = chunkSize - 1; 20 | to = Math.min(to, datalength - 1); 21 | 22 | if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!"); 23 | if (to > datalength - 1) throw new Error("only " + datalength + " bytes available! programmer error!"); 24 | 25 | // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available. 26 | var xhr = new XMLHttpRequest(); 27 | xhr.open('GET', url, false); 28 | if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to); 29 | 30 | // Some hints to the browser that we want binary data. 31 | if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer'; 32 | if (xhr.overrideMimeType) { 33 | xhr.overrideMimeType('text/plain; charset=x-user-defined'); 34 | } 35 | 36 | xhr.send(null); 37 | if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status); 38 | if (xhr.response !== undefined) { 39 | return new Uint8Array(xhr.response || []); 40 | } else { 41 | return intArrayFromString(xhr.responseText || '', true); 42 | } 43 | }; 44 | 45 | onmessage = function onmessage(event) { 46 | postMessage({ 47 | content: getFileData(event.data.url) 48 | }); 49 | }; 50 | -------------------------------------------------------------------------------- /test/static/eufa-module.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/test/static/eufa-module.wasm -------------------------------------------------------------------------------- /test/static/mnist/t10k-images-idx3-ubyte.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/test/static/mnist/t10k-images-idx3-ubyte.dat -------------------------------------------------------------------------------- /test/static/mnist/t10k-labels-idx1-ubyte.dat: -------------------------------------------------------------------------------- 1 | '                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             -------------------------------------------------------------------------------- /test/static/mnist/train-images-idx3-ubyte.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/test/static/mnist/train-images-idx3-ubyte.dat -------------------------------------------------------------------------------- /test/static/mnist/train-labels-idx1-ubyte.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/test/static/mnist/train-labels-idx1-ubyte.dat -------------------------------------------------------------------------------- /test/static/mnist_network.mnist.dlib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/test/static/mnist_network.mnist.dlib -------------------------------------------------------------------------------- /test/static/testcases/mnist_test_1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/test/static/testcases/mnist_test_1.bmp -------------------------------------------------------------------------------- /test/static/testcases/mnist_test_3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/test/static/testcases/mnist_test_3.bmp -------------------------------------------------------------------------------- /test/static/testcases/mnist_test_4.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/test/static/testcases/mnist_test_4.bmp -------------------------------------------------------------------------------- /test/static/testcases/mnist_test_6.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Becavalier/Eufa/ed4fad479b00e870a4c4f7269fc65887e29fa6d2/test/static/testcases/mnist_test_6.bmp -------------------------------------------------------------------------------- /tools/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | dist/ 3 | *.egg-info/ -------------------------------------------------------------------------------- /tools/decode_sections.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import argparse 4 | import sys 5 | 6 | 7 | def decode_sections(file): 8 | try: 9 | with open(file, 'rb') as raw: 10 | raw = raw.read() 11 | except IOError as exc: 12 | print("[Eufa-tools] Can't open input wasm module file: " + str(exc), file=sys.stderr) 13 | return 14 | 15 | 16 | def __main__(): 17 | parser = argparse.ArgumentParser() 18 | parser.add_argument('--module', type=str, help='The path of module file which need to be analyzed.') 19 | FLAGS, unparsed = parser.parse_known_args() 20 | 21 | if FLAGS.module is not None: 22 | decode_sections(FLAGS.module) 23 | 24 | if __name__ == '__main__': 25 | __main__() 26 | 27 | -------------------------------------------------------------------------------- /tools/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf8 -*- 3 | 4 | from setuptools import setup 5 | 6 | setup( 7 | name='eufa-tools', 8 | version='0.1', 9 | packages=['.'], 10 | url='https://github.com/Becavalier/Eufa/tools', 11 | keywords=['wasm', 'webassembly', 'eufa'], 12 | license='MIT', 13 | author='YHSPY', 14 | author_email='yhorg@hotmail.com', 15 | description='A high efficient utility functions library written in webassembly with profiling tools.', 16 | install_requires=[ 17 | 'setuptools', 18 | ], 19 | entry_points={ 20 | 'console_scripts': [ 21 | 'eufa_ds = decode_sections:__main__' 22 | ] 23 | } 24 | ) 25 | --------------------------------------------------------------------------------