Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 89 additions & 5 deletions src/unix/web/matoya-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ const MTY = {
glObj: {},
fds: {},
fdIndex: 0,
jspi: typeof WebAssembly !== 'undefined' &&
typeof WebAssembly.Suspending === 'function' &&
typeof WebAssembly.promising === 'function',
promising: {},
};


Expand All @@ -36,6 +40,50 @@ function mty_dup_c(buf) {
return ptr;
}

// Wraps the calling function to allow a Promise to be returned (if needed).
// Fallback to a direct call if JSPI is not supported or the export cannot be wrapped.
async function mty_call_export(name, ...args) {
const fn = MTY.exports[name];

if (!fn)
throw new Error('Missing export: ' + name);

if (!MTY.jspi)
return fn(...args);

if (!MTY.promising[name]) {
try {
MTY.promising[name] = WebAssembly.promising(fn);

} catch (e) {
console.warn('JSPI export wrap failed for', name, e);
MTY.jspi = false;
return fn(...args);
}
}

return await MTY.promising[name](...args);
}

async function mty_web_run_and_yield_async(iter, opaque) {
MTY.exports.mty_app_set_keys();

const cfunc = mty_cfunc(iter);

await new Promise(resolve => {
const step = () => {
if (cfunc(opaque)) {
setTimeout(step, 0);

} else {
resolve();
}
};

step();
});
}


// window.localStorage

Expand Down Expand Up @@ -313,7 +361,28 @@ function mty_mutex_unlock(mutex, index, notify) {
}

const MTY_AUDIO_API = {
MTY_AudioCreate: function (format, minBuffer, maxBuffer, deviceID, fallback) {
MTY_AudioCreate: function (formatPtr, minBuffer, maxBuffer, deviceID, fallback) {
if (formatPtr === null || formatPtr === undefined)
return 0;

let format;
if (typeof formatPtr === 'number') {
const memoryBuffer = new DataView(MTY_MEMORY.buffer);
format = {
channels: memoryBuffer.getUint32(formatPtr, true),
sampleRate: memoryBuffer.getUint32(formatPtr + 4, true),
};

} else if (typeof formatPtr === 'object') {
format = {
channels: formatPtr.channels,
sampleRate: formatPtr.sampleRate,
};

} else {
throw new Error('Invalid formatPtr type');
}

MTY.audio = {
sampleRate: format.sampleRate,
minBuffer,
Expand Down Expand Up @@ -804,7 +873,10 @@ const MTY_WEB_API = {
MTY.app = app;
mty_update_window(app, MTY.initWindowInfo);
},

// Fallback in case the browser does not support JSPI.
web_run_and_yield: function (iter, opaque) {
console.warn('JSPI not supported. Fallback to old behavior. This may cause issues with blocking calls.');
MTY.exports.mty_app_set_keys();

const step = () => {
Expand All @@ -813,7 +885,9 @@ const MTY_WEB_API = {
};

setTimeout(step, 0);
throw 'MTY_RunAndYield halted execution';
// Throw exception to ensure execution does not halt when this function finishes.
// NOTE: This will end up blocking the caller indefinitely.
throw 'run_and_yield halted execution';
},
};

Expand Down Expand Up @@ -1090,6 +1164,15 @@ async function mty_instantiate_wasm(wasmBuf, userEnv) {
},
}

if (MTY.jspi) {
try {
imports.env.web_run_and_yield = new WebAssembly.Suspending(mty_web_run_and_yield_async);
} catch (e) {
console.warn('JSPI import setup failed, falling back to sync imports', e);
MTY.jspi = false;
}
}

// Add userEnv to imports, run on the main thread
for (let x = 0; x < userEnv.length; x++) {
const key = userEnv[x];
Expand Down Expand Up @@ -1145,17 +1228,18 @@ onmessage = async (ev) => {
try {
// Additional thread
if (msg.startArg) {
MTY.exports.wasi_thread_start(msg.threadId, msg.startArg);
await mty_call_export('wasi_thread_start', msg.threadId, msg.startArg);

// Main thread
} else {
MTY.exports._start();
await mty_call_export('_start');
}

close();

} catch (e) {
if (e.toString().search('MTY_RunAndYield') == -1)
// Ignore known exception that we throw to continue thread execution
if (e.toString().search('run_and_yield halted execution') == -1)
console.error(e);
}
break;
Expand Down
2 changes: 1 addition & 1 deletion src/unix/web/matoya.js
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ function mty_set_rgba_cursor(buf, width, height, hot_x, hot_y) {
if (buf) {
if (!MTY.ccanvas) {
MTY.ccanvas = document.createElement('canvas');
MTY.cctx = MTY.ccanvas.getContext('2d');
MTY.cctx = MTY.ccanvas.getContext('2d', {"willReadFrequently": true});
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolve warning we were receiving with the cursor.

}

MTY.ccanvas.width = width;
Expand Down