Created
December 20, 2017 03:21
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
let wasm_exports: WasmExports; | |
let memory: WebAssembly.Memory; | |
function passStringToWasm(arg: string): [number, number] { | |
if (typeof(arg) !== 'string') | |
throw new Error('expected a string argument'); | |
const buf = new TextEncoder('utf-8').encode(arg); | |
const len = buf.length; | |
const ptr = wasm_exports.__wbindgen_malloc(len); | |
let array = new Uint8Array(memory.buffer); | |
array.set(buf, ptr); | |
return [ptr, len]; | |
} | |
function getStringFromWasm(ptr: number, len: number): string { | |
const mem = new Uint8Array(memory.buffer); | |
const slice = mem.slice(ptr, ptr + len); | |
const ret = new TextDecoder('utf-8').decode(slice); | |
return ret; | |
} | |
const token = Symbol('foo'); | |
function _checkToken(sym: Symbol): void { | |
if (token !== sym) | |
throw new Error('cannot invoke `new` directly'); | |
} | |
function _assertNum(n: number): void { | |
if (typeof(n) !== 'number') | |
throw new Error('expected a number argument'); | |
} | |
function _assertClass(instance: any, klass: any) { | |
if (!(instance instanceof klass)) | |
throw new Error(`expected instance of ${klass.name}`); | |
return instance.__wasmPtr; | |
} | |
let slab: ({ obj: any, cnt: number } | number)[] = []; | |
let slab_next: number = 0; | |
function addHeapObject(obj: any): number { | |
if (slab_next == slab.length) { | |
slab.push(slab.length + 1); | |
} | |
const idx = slab_next; | |
const next = slab[idx]; | |
if (typeof(next) !== 'number') | |
throw new Error('corrupt slab'); | |
slab_next = next; | |
slab[idx] = { obj, cnt: 1 }; | |
return idx << 1; | |
} | |
let stack: any[] = []; | |
function getObject(idx: number): any { | |
if ((idx & 1) === 1) { | |
return stack[idx >> 1]; | |
} else { | |
const val = slab[idx >> 1]; | |
if (typeof(val) === 'number') | |
throw new Error('corrupt slab'); | |
return val.obj; | |
} | |
} | |
export class Foo { | |
constructor(public __wasmPtr: number, sym: Symbol) { | |
_checkToken(sym); | |
} | |
free(): void { | |
const ptr = this.__wasmPtr; | |
this.__wasmPtr = 0; | |
wasm_exports.__wbindgen_foo_free(ptr); | |
} | |
static new(): Foo { | |
const ret = wasm_exports.foo_new(); | |
return new Foo(ret, token); | |
} | |
add(arg0: number): number { | |
_assertNum(arg0); | |
const ret = wasm_exports.foo_add(this.__wasmPtr, arg0); | |
return ret; | |
} | |
add_other(arg0: Bar): void { | |
const ptr0 = _assertClass(arg0, Bar); | |
const ret = wasm_exports.foo_add_other(this.__wasmPtr, ptr0); | |
return ret; | |
} | |
consume_other(arg0: Bar): void { | |
const ptr0 = _assertClass(arg0, Bar); | |
arg0.__wasmPtr = 0; | |
const ret = wasm_exports.foo_consume_other(this.__wasmPtr, ptr0); | |
return ret; | |
} | |
} | |
export class Bar { | |
constructor(public __wasmPtr: number, sym: Symbol) { | |
_checkToken(sym); | |
} | |
free(): void { | |
const ptr = this.__wasmPtr; | |
this.__wasmPtr = 0; | |
wasm_exports.__wbindgen_bar_free(ptr); | |
} | |
static from_str(arg0: string, arg1: any): Bar { | |
const [ptr0, len0] = passStringToWasm(arg0); | |
const idx1 = addHeapObject(arg1); | |
try { | |
const ret = wasm_exports.bar_from_str(ptr0, len0, idx1); | |
return new Bar(ret, token); | |
} finally { | |
wasm_exports.__wbindgen_free(ptr0, len0); | |
} | |
} | |
reset(arg0: string): void { | |
const [ptr0, len0] = passStringToWasm(arg0); | |
try { | |
const ret = wasm_exports.bar_reset(this.__wasmPtr, ptr0, len0); | |
return ret; | |
} finally { | |
wasm_exports.__wbindgen_free(ptr0, len0); | |
} | |
} | |
} | |
function dropRef(idx: number): void { | |
if ((idx & 1) == 1) | |
throw new Error('cannot drop ref of stack objects'); | |
// Decrement our refcount, but if it's still larger than one | |
// keep going | |
let obj = slab[idx >> 1]; | |
if (typeof(obj) === 'number') | |
throw new Error('corrupt slab'); | |
obj.cnt -= 1; | |
if (obj.cnt > 0) | |
return; | |
// If we hit 0 then free up our space in the slab | |
slab[idx >> 1] = slab_next; | |
slab_next = idx >> 1; | |
} | |
interface WasmImportsTop { | |
env: WasmImports, | |
} | |
interface WasmImports { | |
__wasm_bindgen_object_drop_ref(arg0: number): void; | |
bar_on_reset(arg0: number, arg1: number, arg2: number): void; | |
} | |
interface WasmExports { | |
__wbindgen_malloc(arg0: number): number; | |
__wbindgen_free(arg0: number, arg1: number): void; | |
__wbindgen_boxed_str_len(arg0: number): number; | |
__wbindgen_boxed_str_ptr(arg0: number): number; | |
__wbindgen_boxed_str_free(arg0: number): void; | |
concat(arg0: number, arg1: number, arg2: number, arg3: number): number; | |
foo_new(): number; | |
foo_add(arg0: number, arg1: number): number; | |
foo_add_other(arg0: number, arg1: number): void; | |
foo_consume_other(arg0: number, arg1: number): void; | |
__wbindgen_foo_free(arg0: number): void; | |
bar_from_str(arg0: number, arg1: number, arg2: number): number; | |
bar_reset(arg0: number, arg1: number, arg2: number): void; | |
__wbindgen_bar_free(arg0: number): void; | |
rust_eh_personality(): void; | |
__ashlti3(arg0: number, arg1: number, arg2: number, arg3: number): void; | |
__ashrti3(arg0: number, arg1: number, arg2: number, arg3: number): void; | |
__lshrti3(arg0: number, arg1: number, arg2: number, arg3: number): void; | |
__ashldi3(arg0: number, arg1: number): number; | |
__ashrdi3(arg0: number, arg1: number): number; | |
__lshrdi3(arg0: number, arg1: number): number; | |
__multi3(arg0: number, arg1: number, arg2: number, arg3: number, arg4: number): void; | |
__muloti4(arg0: number, arg1: number, arg2: number, arg3: number, arg4: number, arg5: number): void; | |
__muldi3(arg0: number, arg1: number): number; | |
__mulosi4(arg0: number, arg1: number, arg2: number): number; | |
__mulodi4(arg0: number, arg1: number, arg2: number): number; | |
__floatsisf(arg0: number): number; | |
__floatsidf(arg0: number): number; | |
__floatdidf(arg0: number): number; | |
__floattisf(arg0: number, arg1: number): number; | |
__floattidf(arg0: number, arg1: number): number; | |
__floatunsisf(arg0: number): number; | |
__floatunsidf(arg0: number): number; | |
__floatundidf(arg0: number): number; | |
__floatuntisf(arg0: number, arg1: number): number; | |
__floatuntidf(arg0: number, arg1: number): number; | |
__fixsfsi(arg0: number): number; | |
__fixsfdi(arg0: number): number; | |
__fixsfti(arg0: number, arg1: number): void; | |
__fixdfsi(arg0: number): number; | |
__fixdfdi(arg0: number): number; | |
__fixdfti(arg0: number, arg1: number): void; | |
__fixunssfsi(arg0: number): number; | |
__fixunssfdi(arg0: number): number; | |
__fixunssfti(arg0: number, arg1: number): void; | |
__fixunsdfsi(arg0: number): number; | |
__fixunsdfdi(arg0: number): number; | |
__fixunsdfti(arg0: number, arg1: number): void; | |
__mulsf3(arg0: number, arg1: number): number; | |
__muldf3(arg0: number, arg1: number): number; | |
__udivmodti4(arg0: number, arg1: number, arg2: number, arg3: number, arg4: number, arg5: number): void; | |
__udivsi3(arg0: number, arg1: number): number; | |
__umodsi3(arg0: number, arg1: number): number; | |
__udivmodsi4(arg0: number, arg1: number, arg2: number): number; | |
__udivdi3(arg0: number, arg1: number): number; | |
__udivmoddi4(arg0: number, arg1: number, arg2: number): number; | |
__umoddi3(arg0: number, arg1: number): number; | |
__udivti3(arg0: number, arg1: number, arg2: number, arg3: number, arg4: number): void; | |
__umodti3(arg0: number, arg1: number, arg2: number, arg3: number, arg4: number): void; | |
memcpy(arg0: number, arg1: number, arg2: number): number; | |
memmove(arg0: number, arg1: number, arg2: number): number; | |
memset(arg0: number, arg1: number, arg2: number): number; | |
memcmp(arg0: number, arg1: number, arg2: number): number; | |
__powisf2(arg0: number, arg1: number): number; | |
__powidf2(arg0: number, arg1: number): number; | |
__addsf3(arg0: number, arg1: number): number; | |
__adddf3(arg0: number, arg1: number): number; | |
__subsf3(arg0: number, arg1: number): number; | |
__subdf3(arg0: number, arg1: number): number; | |
__divsf3(arg0: number, arg1: number): number; | |
__divdf3(arg0: number, arg1: number): number; | |
__divsi3(arg0: number, arg1: number): number; | |
__divdi3(arg0: number, arg1: number): number; | |
__divti3(arg0: number, arg1: number, arg2: number, arg3: number, arg4: number): void; | |
__modsi3(arg0: number, arg1: number): number; | |
__moddi3(arg0: number, arg1: number): number; | |
__modti3(arg0: number, arg1: number, arg2: number, arg3: number, arg4: number): void; | |
__divmodsi4(arg0: number, arg1: number, arg2: number): number; | |
__divmoddi4(arg0: number, arg1: number, arg2: number): number; | |
} | |
export interface Imports { | |
bar_on_reset(arg0: string, arg1: any): void | |
} | |
export interface Exports { | |
module: WebAssembly.Module; | |
instance: WebAssembly.Module; | |
concat(arg0: string, arg1: string): string; | |
Foo: typeof Foo; | |
Bar: typeof Bar; | |
} | |
function xform(obj: WebAssembly.ResultObject): Exports { | |
let { module, instance } = obj; | |
let { exports } = instance; | |
memory = exports.memory; | |
wasm_exports = exports; | |
return { | |
module, | |
instance, | |
concat: function concat(arg0: string, arg1: string): string { | |
const [ptr0, len0] = passStringToWasm(arg0); | |
const [ptr1, len1] = passStringToWasm(arg1); | |
try { | |
const ret = wasm_exports.concat(ptr0, len0, ptr1, len1); | |
const ptr = wasm_exports.__wbindgen_boxed_str_ptr(ret); | |
const len = wasm_exports.__wbindgen_boxed_str_len(ret); | |
const realRet = getStringFromWasm(ptr, len); | |
wasm_exports.__wbindgen_boxed_str_free(ret); | |
return realRet; | |
} finally { | |
wasm_exports.__wbindgen_free(ptr0, len0); | |
wasm_exports.__wbindgen_free(ptr1, len1); | |
} | |
}, | |
Foo: Foo, | |
Bar: Bar, | |
}; | |
} | |
export function instantiate(bytes: any, imports: Imports): Promise<Exports> { | |
let wasm_imports: WasmImportsTop = { | |
env: { | |
bar_on_reset:function bar_on_reset_shim(ptr0: number, len0: number, arg1: number): void { | |
return imports.bar_on_reset(getStringFromWasm(ptr0, len0), getObject(arg1)); | |
}, | |
__wasm_bindgen_object_drop_ref: dropRef, | |
}, | |
}; | |
return WebAssembly.instantiate(bytes, wasm_imports).then(xform); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment