diff --git a/index.html b/index.html index 70a71c5..63c6b52 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ - + diff --git a/common.js b/src/js/common.js similarity index 100% rename from common.js rename to src/js/common.js diff --git a/common.ts b/src/js/common.ts similarity index 100% rename from common.ts rename to src/js/common.ts diff --git a/draw.js b/src/js/draw.js similarity index 100% rename from draw.js rename to src/js/draw.js diff --git a/draw.ts b/src/js/draw.ts similarity index 100% rename from draw.ts rename to src/js/draw.ts diff --git a/graphics.js b/src/js/graphics.js similarity index 100% rename from graphics.js rename to src/js/graphics.js diff --git a/graphics.ts b/src/js/graphics.ts similarity index 100% rename from graphics.ts rename to src/js/graphics.ts diff --git a/script.js b/src/js/script.js similarity index 95% rename from script.js rename to src/js/script.js index e33ddf1..c3bb755 100644 --- a/script.js +++ b/src/js/script.js @@ -1,6 +1,7 @@ import { initializeContext, Vec2 } from "./common.js"; import { Graphics, fullscreenCanvas } from "./graphics.js"; import * as drawing from "./draw.js"; +import * as wasm from "./wasm.js"; const vertexShader = `#version 300 es in vec2 a_position; @@ -48,7 +49,7 @@ function draw(gfx, dt, pos, velocity) { } pos.add(velocity.multNew(dt)); } -(() => { +(async () => { const canvasId = "game"; const ctx = initializeContext(canvasId); if (ctx === null) @@ -74,4 +75,5 @@ function draw(gfx, dt, pos, velocity) { prevTimestamp = timestamp; window.requestAnimationFrame(frame); }); + let env = await wasm.loadWasmModule("./src/wasm/module.wasm"); })(); diff --git a/script.ts b/src/js/script.ts similarity index 95% rename from script.ts rename to src/js/script.ts index 7b8251a..9da7de3 100644 --- a/script.ts +++ b/src/js/script.ts @@ -1,6 +1,7 @@ import { initializeContext, Vec2 } from "./common.js"; import { Graphics, fullscreenCanvas } from "./graphics.js"; import * as drawing from "./draw.js"; +import * as wasm from "./wasm.js"; const vertexShader = `#version 300 es @@ -61,7 +62,7 @@ function draw(gfx: Graphics, dt: number, pos: Vec2, velocity: Vec2) { pos.add(velocity.multNew(dt)); } -(() => { +(async () => { const canvasId = "game"; const ctx = initializeContext(canvasId); if (ctx === null) return; @@ -95,4 +96,6 @@ function draw(gfx: Graphics, dt: number, pos: Vec2, velocity: Vec2) { prevTimestamp = timestamp; window.requestAnimationFrame(frame); }); + + let env: any = await wasm.loadWasmModule("./src/wasm/module.wasm"); })(); diff --git a/src/js/wasm.js b/src/js/wasm.js new file mode 100644 index 0000000..7a90e74 --- /dev/null +++ b/src/js/wasm.js @@ -0,0 +1,63 @@ +class WASMGLvalue { + ptr; + size; + constructor(ptr, size) { + this.ptr = ptr; + this.size = size; + } +} +async function loadWasmModule(path) { + let wasm = await WebAssembly.instantiateStreaming(fetch(path)); + const memSize = new Int32Array(wasm.instance.exports.memory.buffer, wasm.instance.exports.WASMGLmemory.value + 4, 1)[0]; + let memInt = new Int32Array(wasm.instance.exports.memory.buffer, wasm.instance.exports.WASMGLmemory.value, memSize); + let memFloat = new Float32Array(wasm.instance.exports.memory.buffer, wasm.instance.exports.WASMGLmemory.value, memSize); + wasm.instance.exports.WASMGLmain(); + const data = [ + 1.5, + 2.5, + 3.5, + 4.5, + 5.5, + 6.5, + 7.5, + 8.5, + ]; + let ptr = sendDataFloat(memFloat, data); + wasm.instance.exports.calc(ptr, data.length); + for (let i = 0; i < data.length; ++i) { + console.log(memFloat[ptr + i]); + } + return wasm.instance.exports; +} +function alloc(mem, size) { + const head = mem[2]; + mem[2] += size; + return head; +} +function allocFloat(mem, size) { + const head = mem[2]; + mem[2] += size; + return head; +} +function setstr(mem, ptr, size, str) { + for (let i = 0; i < size; i++) { + mem[ptr] = str.charCodeAt(i); + ++ptr; + } +} +function sendData(mem, data) { + let ptr = alloc(mem, data.length); + data.forEach((v, i) => { + mem[ptr + i] = v; + }); + return ptr; +} +function sendDataFloat(mem, data) { + let ptr = allocFloat(mem, data.length); + data.forEach((v, i) => { + mem[ptr + i] = v; + console.log(mem[ptr + i]); + }); + return ptr; +} +export { loadWasmModule, alloc, setstr }; diff --git a/src/js/wasm.ts b/src/js/wasm.ts new file mode 100644 index 0000000..f4b2e7a --- /dev/null +++ b/src/js/wasm.ts @@ -0,0 +1,97 @@ +class WASMGLvalue { + ptr: number; + size: number; + + constructor(ptr: number, size: number) { + this.ptr = ptr; + this.size = size; + } +} + +async function loadWasmModule(path: string): Promise { + let wasm: any = await WebAssembly.instantiateStreaming(fetch(path)); + + const memSize = new Int32Array( + wasm.instance.exports.memory.buffer, + wasm.instance.exports.WASMGLmemory.value + 4, + 1 + )[0]; + + let memInt = new Int32Array( + wasm.instance.exports.memory.buffer, + wasm.instance.exports.WASMGLmemory.value, + memSize + ); + + let memFloat = new Float32Array( + wasm.instance.exports.memory.buffer, + wasm.instance.exports.WASMGLmemory.value, + memSize + ); + + wasm.instance.exports.WASMGLmain(); + + const data = [ + 1.5, + 2.5, + 3.5, + 4.5, + 5.5, + 6.5, + 7.5, + 8.5, + ]; + + let ptr = sendDataFloat(memFloat, data); + wasm.instance.exports.calc(ptr, data.length); + + for (let i = 0; i < data.length; ++i) { + console.log(memFloat[ptr + i]); + } + + return wasm.instance.exports; +} + +function alloc(mem: Int32Array, size: number): number { + const head = mem[2]; + mem[2] += size; + + return head; +} + +function allocFloat(mem: Float32Array, size: number): number { + const head = mem[2]; + mem[2] += size; + + return head; +} + +function setstr(mem: Int32Array, ptr: number, size: number, str: string) { + for (let i = 0; i < size; i++) { + mem[ptr] = str.charCodeAt(i); + ++ptr; + } +} + +function sendData(mem: Int32Array, data: number[]): number { + let ptr = alloc(mem, data.length); + + data.forEach((v, i) => { + mem[ptr + i] = v; + }); + + return ptr; +} + +function sendDataFloat(mem: Float32Array, data: number[]): number { + let ptr = allocFloat(mem, data.length); + + data.forEach((v, i) => { + mem[ptr + i] = v; + console.log(mem[ptr + i]); + }); + + return ptr; +} + +export { loadWasmModule, alloc, setstr } diff --git a/src/wasm/build.sh b/src/wasm/build.sh new file mode 100755 index 0000000..e0b7f2e --- /dev/null +++ b/src/wasm/build.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +set -xe + +CC="clang" + +CLIBS="" +CFLAGS="--target=wasm32 -flto -Wl,--lto-O3 -nostdlib -Wl,--no-entry -Wl,--export-all" + +$CC $CFLAGS -o module.wasm *.c $CLIBS diff --git a/src/wasm/index.html b/src/wasm/index.html new file mode 100644 index 0000000..31716d2 --- /dev/null +++ b/src/wasm/index.html @@ -0,0 +1,12 @@ + + + + + aaa + + + + + + + diff --git a/src/wasm/main.c b/src/wasm/main.c new file mode 100644 index 0000000..94a50d0 --- /dev/null +++ b/src/wasm/main.c @@ -0,0 +1,19 @@ +#include "wasmgl.h" + +int WASMGLmemory[WASMGLmemory_size] = { + [MEM_SIZE] = WASMGLmemory_size, + [MEM_HEAD] = MEM_ELEM_COUNT, + 0, +}; + +void calc(WASMGLvalue(0)) +{ + for (int i = 0; i < size_0; ++i) + WASMGLmemory[ptr_0 + i] = ((float) WASMGLmemory[ptr_0 + i]) * 2.0; +} + +int main(void) +{ + + return 0; +} diff --git a/src/wasm/module.wasm b/src/wasm/module.wasm new file mode 100755 index 0000000..a05c526 Binary files /dev/null and b/src/wasm/module.wasm differ diff --git a/src/wasm/test.js b/src/wasm/test.js new file mode 100644 index 0000000..4d14b65 --- /dev/null +++ b/src/wasm/test.js @@ -0,0 +1,34 @@ +(async () => { + let instance = await WebAssembly.instantiateStreaming(fetch("module.wasm")); + const memSize = new Int32Array( + instance.instance.exports.memory.buffer, + instance.instance.exports.WASMGLmemory.value + 4, + 1 + )[0] + + let mem = new Int32Array( + instance.instance.exports.memory.buffer, + instance.instance.exports.WASMGLmemory.value, + memSize + ); + + let ptr = alloc(mem, 4); + setstr(mem, ptr, 4, "game"); + + console.log(String.fromCharCode(instance.instance.exports.initialize(ptr, 4))); +})(); + +function alloc(mem, size) { + const head = mem[2]; + console.log(head); + mem[2] += size; + + return head; +} + +function setstr(mem, ptr, size, str) { + for (let i = 0; i < size; i++) { + mem[ptr] = str.charCodeAt(i); + ++ptr; + } +} diff --git a/src/wasm/wasmgl.c b/src/wasm/wasmgl.c new file mode 100644 index 0000000..2a383de --- /dev/null +++ b/src/wasm/wasmgl.c @@ -0,0 +1,22 @@ +#include "wasmgl.h" + +WASMGLptr WASMGLmalloc(int * mem, WASMGLsize size) +{ + WASMGLptr ptr = mem[MEM_HEAD]; + mem[MEM_HEAD] += size; + + return ptr; +} + +void WASMGLset(int * mem, WASMGLptr ptr, int value) +{ + mem[ptr] = value; +} + +void WASMGLsetstr(int * mem, WASMGLptr ptr, const char * cstr, WASMGLsize size) +{ + for (int i = 0; i < size; ++i) + { + WASMGLset(mem, ptr + i, cstr[i]); + } +} diff --git a/src/wasm/wasmgl.h b/src/wasm/wasmgl.h new file mode 100644 index 0000000..35f8c66 --- /dev/null +++ b/src/wasm/wasmgl.h @@ -0,0 +1,23 @@ +#ifndef WASMGL_H_ +#define WASMGL_H_ + +#define main WASMGLmain + +#define WASMGLmemory_size (1024 * 1024) + +typedef enum { + MEM_NULL = 0, + MEM_SIZE = 1, + MEM_HEAD, + MEM_ELEM_COUNT, +} WASMGLmemory_layout; + +typedef unsigned int WASMGLptr; +typedef unsigned int WASMGLsize; + +#define WASMGLvalue(n) WASMGLptr ptr_##n, WASMGLsize size_##n + +WASMGLptr WASMGLmalloc(int * mem, WASMGLsize size); +void WASMGLset(int * mem, WASMGLptr ptr, int value); +void WASMGLsetstr(int * mem, WASMGLptr ptr, const char * cstr, WASMGLsize size); +#endif // WASMGL_H_