2021-08-06 17:28:10 -04:00
|
|
|
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
((window) => {
|
|
|
|
const core = window.Deno.core;
|
2021-08-24 09:09:00 -04:00
|
|
|
const __bootstrap = window.__bootstrap;
|
2021-10-05 18:27:05 -04:00
|
|
|
const {
|
|
|
|
ArrayBuffer,
|
|
|
|
} = window.__bootstrap.primordials;
|
2021-08-06 17:28:10 -04:00
|
|
|
class DynamicLibrary {
|
|
|
|
#rid;
|
|
|
|
symbols = {};
|
|
|
|
|
|
|
|
constructor(path, symbols) {
|
|
|
|
this.#rid = core.opSync("op_ffi_load", { path, symbols });
|
|
|
|
|
|
|
|
for (const symbol in symbols) {
|
2021-10-05 18:27:05 -04:00
|
|
|
const isNonBlocking = symbols[symbol].nonblocking;
|
|
|
|
|
|
|
|
this.symbols[symbol] = (...args) => {
|
|
|
|
const parameters = [];
|
|
|
|
const buffers = [];
|
|
|
|
|
|
|
|
for (const arg of args) {
|
|
|
|
if (
|
|
|
|
arg?.buffer instanceof ArrayBuffer &&
|
|
|
|
arg.byteLength !== undefined
|
|
|
|
) {
|
|
|
|
parameters.push(buffers.length);
|
|
|
|
buffers.push(arg);
|
|
|
|
} else {
|
|
|
|
parameters.push(arg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isNonBlocking) {
|
|
|
|
return core.opAsync("op_ffi_call_nonblocking", {
|
|
|
|
rid: this.#rid,
|
|
|
|
symbol,
|
|
|
|
parameters,
|
|
|
|
buffers,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
return core.opSync("op_ffi_call", {
|
2021-10-05 08:50:00 -04:00
|
|
|
rid: this.#rid,
|
|
|
|
symbol,
|
|
|
|
parameters,
|
2021-10-05 18:27:05 -04:00
|
|
|
buffers,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
2021-08-06 17:28:10 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
close() {
|
|
|
|
core.close(this.#rid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function dlopen(path, symbols) {
|
2021-08-24 09:09:00 -04:00
|
|
|
// URL support is progressively enhanced by util in `runtime/js`.
|
|
|
|
const pathFromURL = __bootstrap.util.pathFromURL ?? ((p) => p);
|
|
|
|
return new DynamicLibrary(pathFromURL(path), symbols);
|
2021-08-06 17:28:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
window.__bootstrap.ffi = { dlopen };
|
|
|
|
})(this);
|