diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-11-22 15:34:30 +0100 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-11-22 15:42:12 +0100 |
| commit | a4d6defa1722d52bf0f5bb2f3abf1443c4b6509c (patch) | |
| tree | fc6bda84afeca68fe84d2e56119db107e2c509f1 /src/talks/wasm/examples/4-primes-sieve | |
| parent | e855546ab1df31131b906d6cabed91409daf922d (diff) | |
| download | sebastiano.tronto.net-a4d6defa1722d52bf0f5bb2f3abf1443c4b6509c.tar.gz sebastiano.tronto.net-a4d6defa1722d52bf0f5bb2f3abf1443c4b6509c.zip | |
Added talk
Diffstat (limited to 'src/talks/wasm/examples/4-primes-sieve')
| -rw-r--r-- | src/talks/wasm/examples/4-primes-sieve/index.html.raw | 18 | ||||
| -rw-r--r-- | src/talks/wasm/examples/4-primes-sieve/mime.txt | 1 | ||||
| -rw-r--r-- | src/talks/wasm/examples/4-primes-sieve/primes.c | 23 | ||||
| -rw-r--r-- | src/talks/wasm/examples/4-primes-sieve/primes.mjs | 2 | ||||
| -rwxr-xr-x | src/talks/wasm/examples/4-primes-sieve/primes.wasm | bin | 0 -> 7203 bytes | |||
| -rw-r--r-- | src/talks/wasm/examples/4-primes-sieve/script.js | 38 |
6 files changed, 82 insertions, 0 deletions
diff --git a/src/talks/wasm/examples/4-primes-sieve/index.html.raw b/src/talks/wasm/examples/4-primes-sieve/index.html.raw new file mode 100644 index 0000000..48e84e0 --- /dev/null +++ b/src/talks/wasm/examples/4-primes-sieve/index.html.raw | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | <!doctype html> | ||
| 2 | <html lang="en-US"> | ||
| 3 | <head> | ||
| 4 | <meta charset="utf-8" /> | ||
| 5 | <meta name="viewport" content="width=device-width" /> | ||
| 6 | <title>Count prime numbers (sieve)</title> | ||
| 7 | <script src="./script.js" type="module" defer></script> | ||
| 8 | </head> | ||
| 9 | |||
| 10 | <body> | ||
| 11 | <input id="input" /> | ||
| 12 | <button id="wasmButton">Count with WASM</button> | ||
| 13 | <button id="jsButton">Count with JS</button> | ||
| 14 | <br /> | ||
| 15 | <p id="resultText"></p> | ||
| 16 | </body> | ||
| 17 | |||
| 18 | </html> | ||
diff --git a/src/talks/wasm/examples/4-primes-sieve/mime.txt b/src/talks/wasm/examples/4-primes-sieve/mime.txt new file mode 100644 index 0000000..6a9a425 --- /dev/null +++ b/src/talks/wasm/examples/4-primes-sieve/mime.txt | |||
| @@ -0,0 +1 @@ | |||
| text/javascript mjs | |||
diff --git a/src/talks/wasm/examples/4-primes-sieve/primes.c b/src/talks/wasm/examples/4-primes-sieve/primes.c new file mode 100644 index 0000000..3f86864 --- /dev/null +++ b/src/talks/wasm/examples/4-primes-sieve/primes.c | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | #include <stdlib.h> | ||
| 2 | #include <string.h> | ||
| 3 | |||
| 4 | int count(int n) { | ||
| 5 | if (n < 2) | ||
| 6 | return 0; | ||
| 7 | |||
| 8 | /* Prepare sieve array */ | ||
| 9 | char *notprime = malloc(n+2); | ||
| 10 | memset(notprime, 0, n+2); | ||
| 11 | |||
| 12 | int count = 0; | ||
| 13 | for (int i = 2; i < n; i++) { | ||
| 14 | count += 1 - notprime[i]; | ||
| 15 | for (int j = 2*i; j < n; j += i) | ||
| 16 | notprime[j] = 1; | ||
| 17 | } | ||
| 18 | |||
| 19 | /* Manual memory management is fun :D */ | ||
| 20 | free(notprime); | ||
| 21 | |||
| 22 | return count; | ||
| 23 | } | ||
diff --git a/src/talks/wasm/examples/4-primes-sieve/primes.mjs b/src/talks/wasm/examples/4-primes-sieve/primes.mjs new file mode 100644 index 0000000..952cdb5 --- /dev/null +++ b/src/talks/wasm/examples/4-primes-sieve/primes.mjs | |||
| @@ -0,0 +1,2 @@ | |||
| 1 | async function Primes(moduleArg={}){var moduleRtn;var Module=moduleArg;var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof WorkerGlobalScope!="undefined";var ENVIRONMENT_IS_NODE=typeof process=="object"&&process.versions?.node&&process.type!="renderer";if(ENVIRONMENT_IS_NODE){const{createRequire}=await import("module");var require=createRequire(import.meta.url)}var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var _scriptName=import.meta.url;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("fs");if(_scriptName.startsWith("file:")){scriptDirectory=require("path").dirname(require("url").fileURLToPath(_scriptName))+"/"}readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){try{scriptDirectory=new URL(".",_scriptName).href}catch{}{if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=async url=>{if(isFileURI(url)){return new Promise((resolve,reject)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){resolve(xhr.response);return}reject(xhr.status)};xhr.onerror=reject;xhr.send(null)})}var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var out=console.log.bind(console);var err=console.error.bind(console);var wasmBinary;var ABORT=false;var isFileURI=filename=>filename.startsWith("file://");var readyPromiseResolve,readyPromiseReject;var wasmMemory;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;var HEAP64,HEAPU64;var runtimeInitialized=false;function updateMemoryViews(){var b=wasmMemory.buffer;HEAP8=new Int8Array(b);HEAP16=new Int16Array(b);HEAPU8=new Uint8Array(b);HEAPU16=new Uint16Array(b);HEAP32=new Int32Array(b);HEAPU32=new Uint32Array(b);HEAPF32=new Float32Array(b);HEAPF64=new Float64Array(b);HEAP64=new BigInt64Array(b);HEAPU64=new BigUint64Array(b)}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(onPreRuns)}function initRuntime(){runtimeInitialized=true;wasmExports["c"]()}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(onPostRuns)}var runDependencies=0;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;Module["monitorRunDependencies"]?.(runDependencies)}function removeRunDependency(id){runDependencies--;Module["monitorRunDependencies"]?.(runDependencies);if(runDependencies==0){if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";err(what);ABORT=true;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject?.(e);throw e}var wasmBinaryFile;function findWasmBinary(){if(Module["locateFile"]){return locateFile("primes.wasm")}return new URL("primes.wasm",import.meta.url).href}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}async function getWasmBinary(binaryFile){if(!wasmBinary){try{var response=await readAsync(binaryFile);return new Uint8Array(response)}catch{}}return getBinarySync(binaryFile)}async function instantiateArrayBuffer(binaryFile,imports){try{var binary=await getWasmBinary(binaryFile);var instance=await WebAssembly.instantiate(binary,imports);return instance}catch(reason){err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)}}async function instantiateAsync(binary,binaryFile,imports){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE){try{var response=fetch(binaryFile,{credentials:"same-origin"});var instantiationResult=await WebAssembly.instantiateStreaming(response,imports);return instantiationResult}catch(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation")}}return instantiateArrayBuffer(binaryFile,imports)}function getWasmImports(){return{a:wasmImports}}async function createWasm(){function receiveInstance(instance,module){wasmExports=instance.exports;wasmMemory=wasmExports["b"];updateMemoryViews();assignWasmExports(wasmExports);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){return receiveInstance(result["instance"])}var info=getWasmImports();if(Module["instantiateWasm"]){return new Promise((resolve,reject)=>{Module["instantiateWasm"](info,(mod,inst)=>{resolve(receiveInstance(mod,inst))})})}wasmBinaryFile??=findWasmBinary();var result=await instantiateAsync(wasmBinary,wasmBinaryFile,info);var exports=receiveInstantiationResult(result);return exports}class ExitStatus{name="ExitStatus";constructor(status){this.message=`Program terminated with exit(${status})`;this.status=status}}var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var onPostRuns=[];var addOnPostRun=cb=>onPostRuns.push(cb);var onPreRuns=[];var addOnPreRun=cb=>onPreRuns.push(cb);var noExitRuntime=true;var abortOnCannotGrowMemory=requestedSize=>{abort("OOM")};var _emscripten_resize_heap=requestedSize=>{var oldSize=HEAPU8.length;requestedSize>>>=0;abortOnCannotGrowMemory(requestedSize)};{if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(Module["print"])out=Module["print"];if(Module["printErr"])err=Module["printErr"];if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"]}var _count;function assignWasmExports(wasmExports){Module["_count"]=_count=wasmExports["d"]}var wasmImports={a:_emscripten_resize_heap};var wasmExports=await createWasm();function run(){if(runDependencies>0){dependenciesFulfilled=run;return}preRun();if(runDependencies>0){dependenciesFulfilled=run;return}function doRun(){Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve?.(Module);Module["onRuntimeInitialized"]?.();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(()=>{setTimeout(()=>Module["setStatus"](""),1);doRun()},1)}else{doRun()}}function preInit(){if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].shift()()}}}preInit();run();if(runtimeInitialized){moduleRtn=Module}else{moduleRtn=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject})} | ||
| 2 | ;return moduleRtn}export default Primes; | ||
diff --git a/src/talks/wasm/examples/4-primes-sieve/primes.wasm b/src/talks/wasm/examples/4-primes-sieve/primes.wasm new file mode 100755 index 0000000..b5a5d99 --- /dev/null +++ b/src/talks/wasm/examples/4-primes-sieve/primes.wasm | |||
| Binary files differ | |||
diff --git a/src/talks/wasm/examples/4-primes-sieve/script.js b/src/talks/wasm/examples/4-primes-sieve/script.js new file mode 100644 index 0000000..8041e5b --- /dev/null +++ b/src/talks/wasm/examples/4-primes-sieve/script.js | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | import Primes from "./primes.mjs"; | ||
| 2 | |||
| 3 | var primes = await Primes(); | ||
| 4 | |||
| 5 | var input = document.getElementById("input"); | ||
| 6 | var wasm_button = document.getElementById("wasmButton"); | ||
| 7 | var js_button = document.getElementById("jsButton"); | ||
| 8 | var resultText = document.getElementById("resultText"); | ||
| 9 | |||
| 10 | var count_wasm = (n) => primes._count(n); | ||
| 11 | |||
| 12 | var count_js = (n) => { | ||
| 13 | if (n < 2) | ||
| 14 | return 0; | ||
| 15 | |||
| 16 | var notprime = new Uint8Array(n+2); | ||
| 17 | |||
| 18 | var count = 0; | ||
| 19 | for (var i = 2; i < n; i++) { | ||
| 20 | count += 1 - notprime[i]; | ||
| 21 | for (var j = 2*i; j < n; j += i) | ||
| 22 | notprime[j] = 1; | ||
| 23 | } | ||
| 24 | |||
| 25 | return count; | ||
| 26 | } | ||
| 27 | |||
| 28 | var timerun = (count, tag) => { | ||
| 29 | var n = Number(input.value); | ||
| 30 | var msg = "Counting primes less than " + n + " with " + tag; | ||
| 31 | console.time(msg); | ||
| 32 | var c = count(n); | ||
| 33 | console.timeEnd(msg); | ||
| 34 | resultText.innerText = "There are " + c + " primes less than " + n; | ||
| 35 | } | ||
| 36 | |||
| 37 | wasm_button.addEventListener("click", () => timerun(count_wasm, "WASM")); | ||
| 38 | js_button.addEventListener("click", () => timerun(count_js, "JS")); | ||
