Skip to content

Instantly share code, notes, and snippets.

@alexcrichton
Created December 20, 2017 03:21
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