Fix native access errors
This commit is contained in:
parent
738272f2d4
commit
3e2d088848
|
|
@ -107,7 +107,6 @@ async function instantiate(url: string) {
|
||||||
initial: 32,
|
initial: 32,
|
||||||
});
|
});
|
||||||
const table = new WebAssembly.Table({ initial: 16, element: 'anyfunc' });
|
const table = new WebAssembly.Table({ initial: 16, element: 'anyfunc' });
|
||||||
let data = new DataView(memory.buffer);
|
|
||||||
const decoder = new TextDecoder();
|
const decoder = new TextDecoder();
|
||||||
let buf = '';
|
let buf = '';
|
||||||
let errBuf = '';
|
let errBuf = '';
|
||||||
|
|
@ -115,12 +114,14 @@ async function instantiate(url: string) {
|
||||||
env: { memory, __indirect_function_table: table },
|
env: { memory, __indirect_function_table: table },
|
||||||
wasi_snapshot_preview1: new Proxy({
|
wasi_snapshot_preview1: new Proxy({
|
||||||
random_get: (ptr: number, length: number) => {
|
random_get: (ptr: number, length: number) => {
|
||||||
|
const data = new DataView(memory.buffer);
|
||||||
for (let i = 0; i < length; i++) {
|
for (let i = 0; i < length; i++) {
|
||||||
data.setUint8(ptr + i, Math.random() * 256);
|
data.setUint8(ptr + i, Math.random() * 256);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fd_write: (fd: number, iovsPtr: number, iovsLength: number, bytesWrittenPtr: number) => {
|
fd_write: (fd: number, iovsPtr: number, iovsLength: number, bytesWrittenPtr: number) => {
|
||||||
const iovs = new Uint32Array(memory.buffer, iovsPtr, iovsLength * 2);
|
const iovs = new Uint32Array(memory.buffer, iovsPtr, iovsLength * 2);
|
||||||
|
const data = new DataView(memory.buffer);
|
||||||
if (fd === 1 || fd === 2) {
|
if (fd === 1 || fd === 2) {
|
||||||
let text = "";
|
let text = "";
|
||||||
let totalBytesWritten = 0;
|
let totalBytesWritten = 0;
|
||||||
|
|
@ -159,7 +160,7 @@ async function instantiate(url: string) {
|
||||||
...instance.exports,
|
...instance.exports,
|
||||||
memory,
|
memory,
|
||||||
table,
|
table,
|
||||||
get data() { return data; },
|
get data() { return new DataView(memory.buffer); },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ interface WasmModule {
|
||||||
frame?: () => void;
|
frame?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createWasmCanvas(module: WasmModule, width: number, height: number) {
|
export function createWasmCanvas(module: WasmModule, width: number = 0, height: number = 0) {
|
||||||
const pointer = module.init?.(width, height);
|
const pointer = module.init?.(width, height);
|
||||||
|
|
||||||
if (pointer) {
|
if (pointer) {
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,26 @@
|
||||||
import { createCanvas, loadImageData } from "@common/display/canvas";
|
import { createWasmCanvas } from "@common/display/canvas";
|
||||||
import life from "./life.c";
|
import life from "./life.c";
|
||||||
|
import { gameLoop } from "@common/game";
|
||||||
|
|
||||||
let context: CanvasRenderingContext2D | null;
|
export default gameLoop(
|
||||||
let imageData: ImageData;
|
() => {
|
||||||
|
const canvas = createWasmCanvas(life);
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
export default function main() {
|
if (!ctx) {
|
||||||
const imageDataPtr = life.initField();
|
throw new Error("Failed to create canvas context");
|
||||||
imageData = loadImageData(life.data, imageDataPtr);
|
}
|
||||||
|
|
||||||
const canvas = createCanvas(imageData.width, imageData.height);
|
return {
|
||||||
context = canvas.getContext('2d');
|
canvas, ctx,
|
||||||
|
sum: 0, count: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
(dt, state) => {
|
||||||
|
state.sum += dt * 1000;
|
||||||
|
state.count++;
|
||||||
|
|
||||||
console.log(life, imageData);
|
state.ctx.clearRect(0, 0, 35, 15);
|
||||||
|
state.ctx.fillText(`${(state.sum / state.count).toFixed(1)} ms`, 2, 10);
|
||||||
requestAnimationFrame(loop);
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
let sum = 0;
|
|
||||||
let count = 0;
|
|
||||||
|
|
||||||
async function loop() {
|
|
||||||
const start = performance.now();
|
|
||||||
|
|
||||||
life.step();
|
|
||||||
|
|
||||||
context?.putImageData(imageData, 0, 0);
|
|
||||||
context?.clearRect(0, 0, 35, 15);
|
|
||||||
|
|
||||||
const end = performance.now();
|
|
||||||
|
|
||||||
sum += end - start;
|
|
||||||
count++;
|
|
||||||
|
|
||||||
context?.fillText(`${(sum / count).toFixed(1)} ms`, 2, 10);
|
|
||||||
requestAnimationFrame(loop);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ static image_data_t image_data;
|
||||||
|
|
||||||
static int count_neighbours(int x, int y);
|
static int count_neighbours(int x, int y);
|
||||||
|
|
||||||
EXPORT(step) void step(void) {
|
EXPORT(frame) void frame(void) {
|
||||||
for (int y = 0; y < HEIGHT; y++) {
|
for (int y = 0; y < HEIGHT; y++) {
|
||||||
for (int x = 0; x < WIDTH; x++) {
|
for (int x = 0; x < WIDTH; x++) {
|
||||||
int count = count_neighbours(x, y);
|
int count = count_neighbours(x, y);
|
||||||
|
|
@ -59,7 +59,7 @@ static int count_neighbours(int x, int y) {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT(initField) image_data_t* init_field(void) {
|
EXPORT(init) image_data_t* init(void) {
|
||||||
field = malloc(WIDTH * HEIGHT);
|
field = malloc(WIDTH * HEIGHT);
|
||||||
next_field = malloc(WIDTH * HEIGHT);
|
next_field = malloc(WIDTH * HEIGHT);
|
||||||
image_data = image_create(WIDTH, HEIGHT);
|
image_data = image_create(WIDTH, HEIGHT);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <iostream>
|
|
||||||
#include <format>
|
#include <format>
|
||||||
|
#include <iostream>
|
||||||
#include <js.h>
|
#include <js.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -78,8 +78,8 @@ constexpr bit bit::nor(const bit& a, const bit& b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t awoo() {
|
uint64_t awoo() {
|
||||||
bit a {1, "a"};
|
bit a{1, "a"};
|
||||||
bit b {1, "b"};
|
bit b{1, "b"};
|
||||||
|
|
||||||
auto [sum, carry] = a + b;
|
auto [sum, carry] = a + b;
|
||||||
|
|
||||||
|
|
@ -91,4 +91,4 @@ uint64_t awoo() {
|
||||||
EXPORT(play) void play() {
|
EXPORT(play) void play() {
|
||||||
auto awoo = std::format("{2} {1}{0}!\n", 23, "C++", "Hello");
|
auto awoo = std::format("{2} {1}{0}!\n", 23, "C++", "Hello");
|
||||||
std::puts(awoo.c_str());
|
std::puts(awoo.c_str());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,110 +0,0 @@
|
||||||
|
|
||||||
import { createCanvas, getPixelInt, setPixel } from '@common/display/canvas';
|
|
||||||
import { gameLoop } from '@common/game';
|
|
||||||
import Input from '@common/input';
|
|
||||||
|
|
||||||
const sandWidth = 128;
|
|
||||||
|
|
||||||
const setup = () => {
|
|
||||||
const canvas = createCanvas(window.innerWidth >> 2, window.innerHeight >> 2);
|
|
||||||
const ctx = canvas.getContext('2d');
|
|
||||||
if (!ctx) {
|
|
||||||
throw new Error('Failed to get canvas context');
|
|
||||||
}
|
|
||||||
document.body.style.backgroundColor = '#eee';
|
|
||||||
|
|
||||||
const imageData = initData();
|
|
||||||
|
|
||||||
return {
|
|
||||||
canvas,
|
|
||||||
ctx,
|
|
||||||
imageData,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const initData = () => {
|
|
||||||
const imageData = new ImageData(sandWidth, sandWidth);
|
|
||||||
|
|
||||||
for (let x = 0; x < imageData.width; x++) {
|
|
||||||
for (let y = 0; y < imageData.height; y++) {
|
|
||||||
const index = (y * imageData.width + x) * 4;
|
|
||||||
imageData.data[index + 0] = Math.random() < 0.3 ? 255 : 0;
|
|
||||||
imageData.data[index + 1] = Math.random() < 0.3 ? 255 : 0;
|
|
||||||
imageData.data[index + 2] = Math.random() < 0.3 ? 255 : 0;
|
|
||||||
imageData.data[index + 3] = 255;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return imageData;
|
|
||||||
}
|
|
||||||
|
|
||||||
const emptyColor = 0x000000FF;
|
|
||||||
const isEmpty = (pixel: number) => (pixel >> 8) === 0;
|
|
||||||
|
|
||||||
type State = ReturnType<typeof setup>;
|
|
||||||
|
|
||||||
const frame = async (dt: number, state: State): Promise<State> => {
|
|
||||||
const { canvas, ctx } = state;
|
|
||||||
|
|
||||||
if (Input.isPressed(Input.KeyCode.SPACE)) {
|
|
||||||
state.imageData = initData();
|
|
||||||
}
|
|
||||||
|
|
||||||
const imageData = state.imageData;
|
|
||||||
|
|
||||||
for (let y = imageData.height - 2; y >= 0; y--) {
|
|
||||||
const direction = Math.random() < 0.5 ? 1 : -1;
|
|
||||||
let startX, endX;
|
|
||||||
if (direction > 0) {
|
|
||||||
startX = 0;
|
|
||||||
endX = imageData.width;
|
|
||||||
} else {
|
|
||||||
startX = imageData.width - 1;
|
|
||||||
endX = -1;
|
|
||||||
}
|
|
||||||
for (let x = startX; x != endX; x += direction) {
|
|
||||||
const pixel = getPixelInt(imageData, x, y);
|
|
||||||
if (isEmpty(pixel)) continue;
|
|
||||||
|
|
||||||
const pixelBelow = getPixelInt(imageData, x, y + 1);
|
|
||||||
if (isEmpty(pixelBelow)) {
|
|
||||||
setPixel(imageData, x, y, emptyColor);
|
|
||||||
setPixel(imageData, x, y + 1, pixel);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let leftEmpty = false;
|
|
||||||
let rightEmpty = false;
|
|
||||||
|
|
||||||
if (x > 0) {
|
|
||||||
const pixelLeft = getPixelInt(imageData, x - 1, y + 1);
|
|
||||||
leftEmpty = isEmpty(pixelLeft);
|
|
||||||
}
|
|
||||||
if (x < imageData.width - 1) {
|
|
||||||
const pixelRight = getPixelInt(imageData, x + 1, y + 1);
|
|
||||||
rightEmpty = isEmpty(pixelRight);
|
|
||||||
}
|
|
||||||
|
|
||||||
const selector = Math.random() < 0.5;
|
|
||||||
const selectedLeft = (leftEmpty && rightEmpty && selector) || (leftEmpty && !rightEmpty);
|
|
||||||
const selectedRight = (leftEmpty && rightEmpty && !selector) || (!leftEmpty && rightEmpty);
|
|
||||||
|
|
||||||
if (selectedLeft) {
|
|
||||||
setPixel(imageData, x, y, emptyColor);
|
|
||||||
setPixel(imageData, x - 1, y + 1, pixel);
|
|
||||||
} else if (selectedRight) {
|
|
||||||
setPixel(imageData, x, y, emptyColor);
|
|
||||||
setPixel(imageData, x + 1, y + 1, pixel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
ctx.putImageData(imageData, (canvas.width - sandWidth) / 2, (canvas.height - sandWidth) / 2);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default gameLoop(setup, frame);
|
|
||||||
Loading…
Reference in New Issue