-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[experiments/rust/wasm] Add a WASM test page.
As soon as `esbuild` supports `new URL(…, import.meta.url)` (evanw/esbuild#795), I want to include a tiny bit of Rust WASM in the published library to see how much of the ecosystem can handle it.
- Loading branch information
Showing
13 changed files
with
712 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 2 additions & 0 deletions
2
src/sites/experiments.cubing.net/cubing.js/rust/wasm/.htaccess
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Dreamhost 🤨 | ||
AddType application/wasm .wasm |
47 changes: 47 additions & 0 deletions
47
src/sites/experiments.cubing.net/cubing.js/rust/wasm/hello_wasm.d.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* tslint:disable */ | ||
/* eslint-disable */ | ||
/** | ||
*/ | ||
export function greet(): void; | ||
/** | ||
*/ | ||
export function internal_init(): void; | ||
/** | ||
* @param {string} alg_str | ||
* @returns {string} | ||
*/ | ||
export function invert_alg(alg_str: string): string; | ||
|
||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; | ||
|
||
export interface InitOutput { | ||
readonly memory: WebAssembly.Memory; | ||
readonly invert_alg: (a: number, b: number, c: number) => void; | ||
readonly greet: () => void; | ||
readonly internal_init: () => void; | ||
readonly __wbindgen_add_to_stack_pointer: (a: number) => number; | ||
readonly __wbindgen_malloc: (a: number) => number; | ||
readonly __wbindgen_realloc: (a: number, b: number, c: number) => number; | ||
readonly __wbindgen_free: (a: number, b: number) => void; | ||
} | ||
|
||
export type SyncInitInput = BufferSource | WebAssembly.Module; | ||
/** | ||
* Instantiates the given `module`, which can either be bytes or | ||
* a precompiled `WebAssembly.Module`. | ||
* | ||
* @param {SyncInitInput} module | ||
* | ||
* @returns {InitOutput} | ||
*/ | ||
export function initSync(module: SyncInitInput): InitOutput; | ||
|
||
/** | ||
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and | ||
* for everything else, calls `WebAssembly.instantiate` directly. | ||
* | ||
* @param {InitInput | Promise<InitInput>} module_or_path | ||
* | ||
* @returns {Promise<InitOutput>} | ||
*/ | ||
export default function init (module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>; |
273 changes: 273 additions & 0 deletions
273
src/sites/experiments.cubing.net/cubing.js/rust/wasm/hello_wasm.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,273 @@ | ||
// Mangled so that bundlers don't try to inline the source. | ||
const node_fs_promises_mangled = "node:-fs/pr-omises"; | ||
const node_fs_promises_unmangled = () => node_fs_promises_mangled.replace(/-/g, ""); | ||
|
||
let wasm; | ||
|
||
const cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); | ||
|
||
cachedTextDecoder.decode(); | ||
|
||
let cachedUint8Memory0 = null; | ||
|
||
function getUint8Memory0() { | ||
if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) { | ||
cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); | ||
} | ||
return cachedUint8Memory0; | ||
} | ||
|
||
function getStringFromWasm0(ptr, len) { | ||
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); | ||
} | ||
|
||
const heap = new Array(128).fill(undefined); | ||
|
||
heap.push(undefined, null, true, false); | ||
|
||
let heap_next = heap.length; | ||
|
||
function addHeapObject(obj) { | ||
if (heap_next === heap.length) heap.push(heap.length + 1); | ||
const idx = heap_next; | ||
heap_next = heap[idx]; | ||
|
||
heap[idx] = obj; | ||
return idx; | ||
} | ||
|
||
function getObject(idx) { return heap[idx]; } | ||
|
||
function dropObject(idx) { | ||
if (idx < 132) return; | ||
heap[idx] = heap_next; | ||
heap_next = idx; | ||
} | ||
|
||
function takeObject(idx) { | ||
const ret = getObject(idx); | ||
dropObject(idx); | ||
return ret; | ||
} | ||
/** | ||
*/ | ||
export function greet() { | ||
wasm.greet(); | ||
} | ||
|
||
/** | ||
*/ | ||
export function internal_init() { | ||
wasm.internal_init(); | ||
} | ||
|
||
let WASM_VECTOR_LEN = 0; | ||
|
||
const cachedTextEncoder = new TextEncoder('utf-8'); | ||
|
||
const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' | ||
? function (arg, view) { | ||
return cachedTextEncoder.encodeInto(arg, view); | ||
} | ||
: function (arg, view) { | ||
const buf = cachedTextEncoder.encode(arg); | ||
view.set(buf); | ||
return { | ||
read: arg.length, | ||
written: buf.length | ||
}; | ||
}); | ||
|
||
function passStringToWasm0(arg, malloc, realloc) { | ||
|
||
if (realloc === undefined) { | ||
const buf = cachedTextEncoder.encode(arg); | ||
const ptr = malloc(buf.length); | ||
getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf); | ||
WASM_VECTOR_LEN = buf.length; | ||
return ptr; | ||
} | ||
|
||
let len = arg.length; | ||
let ptr = malloc(len); | ||
|
||
const mem = getUint8Memory0(); | ||
|
||
let offset = 0; | ||
|
||
for (; offset < len; offset++) { | ||
const code = arg.charCodeAt(offset); | ||
if (code > 0x7F) break; | ||
mem[ptr + offset] = code; | ||
} | ||
|
||
if (offset !== len) { | ||
if (offset !== 0) { | ||
arg = arg.slice(offset); | ||
} | ||
ptr = realloc(ptr, len, len = offset + arg.length * 3); | ||
const view = getUint8Memory0().subarray(ptr + offset, ptr + len); | ||
const ret = encodeString(arg, view); | ||
|
||
offset += ret.written; | ||
} | ||
|
||
WASM_VECTOR_LEN = offset; | ||
return ptr; | ||
} | ||
|
||
let cachedInt32Memory0 = null; | ||
|
||
function getInt32Memory0() { | ||
if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) { | ||
cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); | ||
} | ||
return cachedInt32Memory0; | ||
} | ||
/** | ||
* @param {string} alg_str | ||
* @returns {string} | ||
*/ | ||
export function invert_alg(alg_str) { | ||
try { | ||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); | ||
const ptr0 = passStringToWasm0(alg_str, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); | ||
const len0 = WASM_VECTOR_LEN; | ||
wasm.invert_alg(retptr, ptr0, len0); | ||
var r0 = getInt32Memory0()[retptr / 4 + 0]; | ||
var r1 = getInt32Memory0()[retptr / 4 + 1]; | ||
var r2 = getInt32Memory0()[retptr / 4 + 2]; | ||
var r3 = getInt32Memory0()[retptr / 4 + 3]; | ||
var ptr1 = r0; | ||
var len1 = r1; | ||
if (r3) { | ||
ptr1 = 0; len1 = 0; | ||
throw takeObject(r2); | ||
} | ||
return getStringFromWasm0(ptr1, len1); | ||
} finally { | ||
wasm.__wbindgen_add_to_stack_pointer(16); | ||
wasm.__wbindgen_free(ptr1, len1); | ||
} | ||
} | ||
|
||
async function load(module, imports) { | ||
if (typeof Response === 'function' && module instanceof Response) { | ||
if (typeof WebAssembly.instantiateStreaming === 'function') { | ||
try { | ||
return await WebAssembly.instantiateStreaming(module, imports); | ||
|
||
} catch (e) { | ||
if (module.headers.get('Content-Type') != 'application/wasm') { | ||
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); | ||
|
||
} else { | ||
throw e; | ||
} | ||
} | ||
} | ||
|
||
const bytes = await module.arrayBuffer(); | ||
return await WebAssembly.instantiate(bytes, imports); | ||
|
||
} else { | ||
const instance = await WebAssembly.instantiate(module, imports); | ||
|
||
if (instance instanceof WebAssembly.Instance) { | ||
return { instance, module }; | ||
|
||
} else { | ||
return instance; | ||
} | ||
} | ||
} | ||
|
||
function getImports() { | ||
const imports = {}; | ||
imports.wbg = {}; | ||
imports.wbg.__wbg_alert_8755b7883b6ce0ef = function(arg0, arg1) { | ||
alert(getStringFromWasm0(arg0, arg1)); | ||
}; | ||
imports.wbg.__wbindgen_string_new = function(arg0, arg1) { | ||
const ret = getStringFromWasm0(arg0, arg1); | ||
return addHeapObject(ret); | ||
}; | ||
imports.wbg.__wbg_new_abda76e883ba8a5f = function() { | ||
const ret = new Error(); | ||
return addHeapObject(ret); | ||
}; | ||
imports.wbg.__wbg_stack_658279fe44541cf6 = function(arg0, arg1) { | ||
const ret = getObject(arg1).stack; | ||
const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); | ||
const len0 = WASM_VECTOR_LEN; | ||
getInt32Memory0()[arg0 / 4 + 1] = len0; | ||
getInt32Memory0()[arg0 / 4 + 0] = ptr0; | ||
}; | ||
imports.wbg.__wbg_error_f851667af71bcfc6 = function(arg0, arg1) { | ||
try { | ||
console.error(getStringFromWasm0(arg0, arg1)); | ||
} finally { | ||
wasm.__wbindgen_free(arg0, arg1); | ||
} | ||
}; | ||
imports.wbg.__wbindgen_object_drop_ref = function(arg0) { | ||
takeObject(arg0); | ||
}; | ||
|
||
return imports; | ||
} | ||
|
||
function initMemory(imports, maybe_memory) { | ||
|
||
} | ||
|
||
function finalizeInit(instance, module) { | ||
wasm = instance.exports; | ||
init.__wbindgen_wasm_module = module; | ||
cachedInt32Memory0 = null; | ||
cachedUint8Memory0 = null; | ||
|
||
|
||
return wasm; | ||
} | ||
|
||
function initSync(module) { | ||
const imports = getImports(); | ||
|
||
initMemory(imports); | ||
|
||
if (!(module instanceof WebAssembly.Module)) { | ||
module = new WebAssembly.Module(module); | ||
} | ||
|
||
const instance = new WebAssembly.Instance(module, imports); | ||
|
||
return finalizeInit(instance, module); | ||
} | ||
|
||
async function init(input) { | ||
if (typeof input === 'undefined') { | ||
input = new URL('hello_wasm_bg.wasm', import.meta.url); | ||
} | ||
const imports = getImports(); | ||
|
||
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) { | ||
try { | ||
input = await fetch(input); | ||
} catch (e) { | ||
if (!(e instanceof TypeError)) { | ||
throw e; | ||
} | ||
input = await (await import(node_fs_promises_unmangled())).readFile(input); | ||
} | ||
} | ||
|
||
initMemory(imports); | ||
|
||
const { instance, module } = await load(await input, imports); | ||
|
||
return finalizeInit(instance, module); | ||
} | ||
|
||
export { initSync } | ||
export default init; |
Oops, something went wrong.