Skip to content

Commit

Permalink
feat: runtime - change directory structure
Browse files Browse the repository at this point in the history
  • Loading branch information
winetree94 committed Jul 30, 2024
1 parent af16049 commit 8c6e1b8
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 115 deletions.
4 changes: 2 additions & 2 deletions packages/browser-runtime/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ slave.ioctl(

xterm.loadAddon(master);

const worker = new Worker(new URL('./worker.ts', import.meta.url), {
const worker = new Worker(new URL('./workers/worker.ts', import.meta.url), {
type: 'module',
});

Expand All @@ -63,7 +63,7 @@ switch (networkMode) {
image.wasmName,
image.chunkCount,
networkMode,
new Worker(new URL('./stack-worker.ts', import.meta.url), {
new Worker(new URL('./workers/stack-worker.ts', import.meta.url), {
type: 'module',
}),
location.origin + '/wasms/c2w-net-proxy.wasm',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
import { Fd, WASI, wasi as wasiOrigin } from '@bjorn3/browser_wasi_shim';
import { Fd, WASI, wasi } from '@bjorn3/browser_wasi_shim';
import {
appendData,
errStatus,
Expand All @@ -13,7 +13,7 @@ import {
streamStatus,
wasiHackSocket,
} from './worker-util';
import { Event, EventType, Subscription } from './wasi-util';
import { WASIEvent, WASIEventType, WASISubscription } from './wasi-util';

onmessage = async (msg: MessageEvent) => {
console.log('init');
Expand Down Expand Up @@ -42,22 +42,22 @@ onmessage = async (msg: MessageEvent) => {
'--debug',
];
const env: string[] = [];
const wasi = new WASI(args, env, fds);
wasiHack(wasi, certfd, 5);
wasiHackSocket(wasi, listenfd, 5);
const wasiInstance = new WASI(args, env, fds);
wasiHack(wasiInstance, certfd, 5);
wasiHackSocket(wasiInstance, listenfd, 5);

const wasm = await fetch(getImagename(), { credentials: 'same-origin' }).then(
(res) => res.arrayBuffer(),
);

WebAssembly.instantiate(wasm, {
wasi_snapshot_preview1: wasi.wasiImport,
env: envHack(wasi),
wasi_snapshot_preview1: wasiInstance.wasiImport,
env: envHack(wasiInstance),
}).then((inst) => {
/**
* @todo type missmatching
*/
wasi.start(
wasiInstance.start(
inst.instance as {
exports: { memory: WebAssembly.Memory; _start: () => unknown };
},
Expand All @@ -68,37 +68,33 @@ onmessage = async (msg: MessageEvent) => {
// definition from wasi-libc https://github.com/WebAssembly/wasi-libc/blob/wasi-sdk-19/expected/wasm32-wasi/predefined-macros.txt
const ERRNO_INVAL = 28;

function wasiHack(wasi: WASI, certfd: number, connfd: number) {
function wasiHack(wasiInstance: WASI, certfd: number, connfd: number) {
let certbuf = new Uint8Array(0);
const _fd_close = wasi.wasiImport.fd_close;
wasi.wasiImport.fd_close = (fd) => {
const _fd_close = wasiInstance.wasiImport.fd_close;
wasiInstance.wasiImport.fd_close = (fd) => {
if (fd == certfd) {
sendCert(certbuf);
return 0;
}
return _fd_close.apply(wasi.wasiImport, [fd]);
return _fd_close.apply(wasiInstance.wasiImport, [fd]);
};
const _fd_fdstat_get = wasi.wasiImport.fd_fdstat_get;
wasi.wasiImport.fd_fdstat_get = (fd, fdstat_ptr) => {
const _fd_fdstat_get = wasiInstance.wasiImport.fd_fdstat_get;
wasiInstance.wasiImport.fd_fdstat_get = (fd, fdstat_ptr) => {
if (fd == certfd) {
return 0;
}
return _fd_fdstat_get.apply(wasi.wasiImport, [fd, fdstat_ptr]);
return _fd_fdstat_get.apply(wasiInstance.wasiImport, [fd, fdstat_ptr]);
};
wasi.wasiImport.fd_fdstat_set_flags = () => {
wasiInstance.wasiImport.fd_fdstat_set_flags = () => {
// TODO
return 0;
};
const _fd_write = wasi.wasiImport.fd_write;
wasi.wasiImport.fd_write = (fd, iovs_ptr, iovs_len, nwritten_ptr) => {
const _fd_write = wasiInstance.wasiImport.fd_write;
wasiInstance.wasiImport.fd_write = (fd, iovs_ptr, iovs_len, nwritten_ptr) => {
if (fd == 1 || fd == 2 || fd == certfd) {
const buffer = new DataView(wasi.inst.exports.memory.buffer);
const buffer8 = new Uint8Array(wasi.inst.exports.memory.buffer);
const iovecs = wasiOrigin.Ciovec.read_bytes_array(
buffer,
iovs_ptr,
iovs_len,
);
const buffer = new DataView(wasiInstance.inst.exports.memory.buffer);
const buffer8 = new Uint8Array(wasiInstance.inst.exports.memory.buffer);
const iovecs = wasi.Ciovec.read_bytes_array(buffer, iovs_ptr, iovs_len);
let wtotal = 0;
for (let i = 0; i < iovecs.length; i++) {
const iovec = iovecs[i];
Expand All @@ -116,14 +112,14 @@ function wasiHack(wasi: WASI, certfd: number, connfd: number) {
return 0;
}
console.log('fd_write: unknown fd ' + fd);
return _fd_write.apply(wasi.wasiImport, [
return _fd_write.apply(wasiInstance.wasiImport, [
fd,
iovs_ptr,
iovs_len,
nwritten_ptr,
]);
};
wasi.wasiImport.poll_oneoff = (
wasiInstance.wasiImport.poll_oneoff = (
in_ptr,
out_ptr,
nsubscriptions,
Expand All @@ -132,8 +128,12 @@ function wasiHack(wasi: WASI, certfd: number, connfd: number) {
if (nsubscriptions == 0) {
return ERRNO_INVAL;
}
const buffer = new DataView(wasi.inst.exports.memory.buffer);
const in_ = Subscription.read_bytes_array(buffer, in_ptr, nsubscriptions);
const buffer = new DataView(wasiInstance.inst.exports.memory.buffer);
const in_ = WASISubscription.read_bytes_array(
buffer,
in_ptr,
nsubscriptions,
);
let isReadPollStdin = false;
let isReadPollConn = false;
let isClockPoll = false;
Expand Down Expand Up @@ -176,29 +176,29 @@ function wasiHack(wasi: WASI, certfd: number, connfd: number) {
if (sockreadable == errStatus) {
return ERRNO_INVAL;
} else if (sockreadable == true) {
const event = new Event();
const event = new WASIEvent();
event.userdata = pollSubConn?.userdata;
event.error = 0;
event.type = new EventType('fd_read');
event.type = new WASIEventType('fd_read');
events.push(event);
}
}
if (isClockPoll) {
const event = new Event();
const event = new WASIEvent();
event.userdata = clockSub?.userdata;
event.error = 0;
event.type = new EventType('clock');
event.type = new WASIEventType('clock');
events.push(event);
}
}
const len = events.length;
Event.write_bytes_array(buffer, out_ptr, events);
WASIEvent.write_bytes_array(buffer, out_ptr, events);
buffer.setUint32(nevents_ptr, len, true);
return 0;
};
}

function envHack(wasi: WASI) {
function envHack(wasiInstance: WASI) {
return {
http_send: function (
addressP: number,
Expand All @@ -207,13 +207,17 @@ function envHack(wasi: WASI) {
reqlen: number,
idP: number,
) {
const buffer = new DataView(wasi.inst.exports.memory.buffer);
const buffer = new DataView(wasiInstance.inst.exports.memory.buffer);
const address = new Uint8Array(
wasi.inst.exports.memory.buffer,
wasiInstance.inst.exports.memory.buffer,
addressP,
addresslen,
);
const req = new Uint8Array(wasi.inst.exports.memory.buffer, reqP, reqlen);
const req = new Uint8Array(
wasiInstance.inst.exports.memory.buffer,
reqP,
reqlen,
);
streamCtrl[0] = 0;
postMessage({
type: 'http_send',
Expand All @@ -235,9 +239,9 @@ function envHack(wasi: WASI) {
nwrittenP: number,
isEOF: number,
) {
const buffer = new DataView(wasi.inst.exports.memory.buffer);
const buffer = new DataView(wasiInstance.inst.exports.memory.buffer);
const body = new Uint8Array(
wasi.inst.exports.memory.buffer,
wasiInstance.inst.exports.memory.buffer,
bodyP,
bodylen,
);
Expand All @@ -256,7 +260,7 @@ function envHack(wasi: WASI) {
return 0;
},
http_isreadable: function (id: number, isOKP: number) {
const buffer = new DataView(wasi.inst.exports.memory.buffer);
const buffer = new DataView(wasiInstance.inst.exports.memory.buffer);
streamCtrl[0] = 0;
postMessage({ type: 'http_isreadable', id: id });
Atomics.wait(streamCtrl, 0, 0);
Expand All @@ -277,8 +281,8 @@ function envHack(wasi: WASI) {
respsizeP: number,
isEOFP: number,
) {
const buffer = new DataView(wasi.inst.exports.memory.buffer);
const buffer8 = new Uint8Array(wasi.inst.exports.memory.buffer);
const buffer = new DataView(wasiInstance.inst.exports.memory.buffer);
const buffer8 = new Uint8Array(wasiInstance.inst.exports.memory.buffer);

streamCtrl[0] = 0;
postMessage({ type: 'http_recv', id: id, len: bufsize });
Expand All @@ -304,8 +308,8 @@ function envHack(wasi: WASI) {
bodysizeP: number,
isEOFP: number,
) {
const buffer = new DataView(wasi.inst.exports.memory.buffer);
const buffer8 = new Uint8Array(wasi.inst.exports.memory.buffer);
const buffer = new DataView(wasiInstance.inst.exports.memory.buffer);
const buffer8 = new Uint8Array(wasiInstance.inst.exports.memory.buffer);

streamCtrl[0] = 0;
postMessage({ type: 'http_readbody', id: id, len: bufsize });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { wasi } from '@bjorn3/browser_wasi_shim';
//
////////////////////////////////////////////////////////////

export class EventType {
export class WASIEventType {
/*:: variant: "clock" | "fd_read" | "fd_write"*/
variant: 'clock' | 'fd_read' | 'fd_write';

Expand All @@ -18,11 +18,11 @@ export class EventType {
static from_u8(data: number) /*: EventType*/ {
switch (data) {
case wasi.EVENTTYPE_CLOCK:
return new EventType('clock');
return new WASIEventType('clock');
case wasi.EVENTTYPE_FD_READ:
return new EventType('fd_read');
return new WASIEventType('fd_read');
case wasi.EVENTTYPE_FD_WRITE:
return new EventType('fd_write');
return new WASIEventType('fd_write');
default:
throw 'Invalid event type ' + String(data);
}
Expand All @@ -42,14 +42,14 @@ export class EventType {
}
}

export class Event {
export class WASIEvent {
/*:: userdata: UserData*/
/*:: error: number*/
/*:: type: EventType*/
/*:: fd_readwrite: EventFdReadWrite | null*/
userdata?: bigint;
error?: number;
type?: EventType;
type?: WASIEventType;
// fd_readwrite: EventFdReadWrite | null;

write_bytes(view: DataView, ptr: number) {
Expand All @@ -62,48 +62,52 @@ export class Event {
// }
}

static write_bytes_array(view: DataView, ptr: number, events: Array<Event>) {
static write_bytes_array(
view: DataView,
ptr: number,
events: Array<WASIEvent>,
) {
for (let i = 0; i < events.length; i++) {
events[i].write_bytes(view, ptr + 32 * i);
}
}
}

export class SubscriptionClock {
export class WASISubscriptionClock {
timeout?: number;

static read_bytes(view: DataView, ptr: number): SubscriptionClock {
const self = new SubscriptionClock();
static read_bytes(view: DataView, ptr: number): WASISubscriptionClock {
const self = new WASISubscriptionClock();
self.timeout = Number(view.getBigUint64(ptr + 8, true));
return self;
}
}

export class SubscriptionFdReadWrite {
export class WASISubscriptionFdReadWrite {
/*:: fd: number*/
fd?: number;

static read_bytes(view: DataView, ptr: number): SubscriptionFdReadWrite {
const self = new SubscriptionFdReadWrite();
static read_bytes(view: DataView, ptr: number): WASISubscriptionFdReadWrite {
const self = new WASISubscriptionFdReadWrite();
self.fd = view.getUint32(ptr, true);
return self;
}
}

export class SubscriptionU {
tag?: EventType;
data?: SubscriptionClock | SubscriptionFdReadWrite;
export class WASISubscriptionU {
tag?: WASIEventType;
data?: WASISubscriptionClock | WASISubscriptionFdReadWrite;

static read_bytes(view: DataView, ptr: number): SubscriptionU {
const self = new SubscriptionU();
self.tag = EventType.from_u8(view.getUint8(ptr));
static read_bytes(view: DataView, ptr: number): WASISubscriptionU {
const self = new WASISubscriptionU();
self.tag = WASIEventType.from_u8(view.getUint8(ptr));
switch (self.tag.variant) {
case 'clock':
self.data = SubscriptionClock.read_bytes(view, ptr + 8);
self.data = WASISubscriptionClock.read_bytes(view, ptr + 8);
break;
case 'fd_read':
case 'fd_write':
self.data = SubscriptionFdReadWrite.read_bytes(view, ptr + 8);
self.data = WASISubscriptionFdReadWrite.read_bytes(view, ptr + 8);
break;
default:
throw 'unreachable';
Expand All @@ -112,25 +116,25 @@ export class SubscriptionU {
}
}

export class Subscription {
export class WASISubscription {
userdata?: bigint;
u?: SubscriptionU;
u?: WASISubscriptionU;

static read_bytes(view: DataView, ptr: number): Subscription {
const subscription = new Subscription();
static read_bytes(view: DataView, ptr: number): WASISubscription {
const subscription = new WASISubscription();
subscription.userdata = view.getBigUint64(ptr, true);
subscription.u = SubscriptionU.read_bytes(view, ptr + 8);
subscription.u = WASISubscriptionU.read_bytes(view, ptr + 8);
return subscription;
}

static read_bytes_array(
view: DataView,
ptr: number,
len: number,
): Array<Subscription> {
): Array<WASISubscription> {
const subscriptions = [];
for (let i = 0; i < len; i++) {
subscriptions.push(Subscription.read_bytes(view, ptr + 48 * i));
subscriptions.push(WASISubscription.read_bytes(view, ptr + 48 * i));
}
return subscriptions;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
PreopenDirectory,
wasi as wasiOrigin,
} from '@bjorn3/browser_wasi_shim';
import { NetworkMode } from './types';
import { NetworkMode } from '../types';

export let streamCtrl: Int32Array;
export let streamStatus: Int32Array;
Expand Down
Loading

0 comments on commit 8c6e1b8

Please sign in to comment.