Repository navigation
Conversation
|
I might need some help with adding the |
|
It's about 90% there at this point just need to fix some bugs, and figure out what to do with the new dependencies I added. Major TODOs still left:
|
1619c3e to
e8ad99b
Compare
|
Mostly finished at this point. Ended up dropping This poses some problems for cross platform mainly that the built artifact name varies from platform to platform. I didn't want to introduce any magic I.E. I also might need some help figuring out the current issue on appveyor or finding a simpler way to build my test binding plugin. I'm currently waiting on my changes to |
f6fe31e to
d30c877
Compare
|
This is an awesome patch. Amazing work. Adding a native bindings API needs to be considered very carefully. It has impacts on security (all bets are off when you execute some random native code), performance, and usability (the GYP situation in Node is one of my largest blunders). I am not ready to commit to importing .so files via the module system. For one thing, this breaks browser compatibility; not such a big deal itself. It introduces need for There's also the question of how these I propose having a Line 53 in 856c442 I think making these changes will reduce the surface area of this proposal and allow us to land something basic before committing to defining how everything works upfront. I suggest renaming --allow-native-bindings to --allow-dlopen. |
|
Great feedback. I needed to get out of my one track mindset a little here. Since I already decided that direct cargo import is a little too complicated for this one, I don't really see any reason it has to be a dylib that loads typescript instead of the other way around. export interface DynamicLibFn {
dispatchSync(
data: Uint8Array,
zeroCopy: undefined | ArrayBufferView,
): Uint8Array;
dispatchAsync(
data: Uint8Array,
zeroCopy: undefined | ArrayBufferView,
): Promise<Uint8Array>;
}
// A loaded dynamic lib function.
// Loaded functions will need to loaded and addressed by unique identifiers
// for performance, since loading a function from a library for every call
// would likely be the limiting factor for many use cases.
/** @internal */
class DynamicLibFnImpl implements DynamicLibFn {
private readonly dlFnId: number;
constructor(dlId: number, name: string) {
this.dlFnId = loadDlFn(dlId, name);
}
dispatchSync(
data: Uint8Array,
zeroCopy: undefined | ArrayBufferView,
): Uint8Array {
// Like the prior Deno.nativeBindings.sendSync
return callDlFnSync(this.dlFnId, data, zeroCopy);
}
async dispatchAsync(
data: Uint8Array,
zeroCopy: undefined | ArrayBufferView,
): Promise<Uint8Array> {
// Like the prior Deno.nativeBindings.sendSync but async
return callDlFnAsync(this.dlFnId, data, zeroCopy);
}
}
export interface DynamicLib {
loadFn(name: string): DynamicLibFn;
}
// A loaded dynamic lib.
// Dynamic libraries need to remain loaded into memory on the rust side
// ,and then be addressed by their unique identifier to avoid loading
// the same library multiple times.
export class DynamicLibImpl implements DynamicLib {
// unique resource identifier for the loaded dynamic lib rust side
private readonly dlId: number;
private readonly fnMap: Map<string, DynamicLibFn> = new Map();
constructor(private readonly libraryPath: string) {
// call some op to load the library and get a resource identifier
this.dlId = loadDl(libraryPath);
}
loadFn(name: string): DynamicLibFn {
// call some op to load the fn from this library and get resource identifier
const cachedFn = this.fnMap.get(name);
if (cachedFn) {
return cachedFn;
} else {
const dlFn = new DynamicLibFnImpl(this.dlId, name);
this.fnMap.set(name, dlFn);
return dlFn;
}
}
}The implementation for the test plugin/binding being something like this const { platformFilename, DynamicLibary } = Deno.dlopen;
const dLib = new DynamicLibary("target/release/" + platformFilename("test_binding_lib"));
const testOpFn = dLib.loadFn("test_op");
export interface TestOptions {
name: string;
}
export interface TestResponse {
data: Uint8Array;
}
const textEncoder = new TextEncoder();
function encodeTestOp(args: TestOptions): Uint8Array {
return textEncoder.encode(JSON.stringify(args));
}
const textDecoder = new TextDecoder();
function decodeTestOp(data: Uint8Array): any {
return textDecoder.decode(data);
}
export const testOp = (args: TestOptions): any => {
return decodeTestOp(
testOpFn.dispatchSync(
encodeTestOp(args),
),
);
} |
|
@ry I made some major simplifications, and removed the import functionality PTAL. |
16ea973 to
1003661
Compare
| - ./tools/test_format.py | ||
| - ./tools/build.py -C target/release | ||
| - DENO_BUILD_MODE=release ./tools/test.py | ||
| - cargo build -p test_plugin --release --locked |
There was a problem hiding this comment.
I don't like that this breaks my usual ./tools/build.py && ./tools/test.py
Let me see if I can whip up a BUILD.gn to do this...
There was a problem hiding this comment.
I've added the BUILD.gn file... it's a bit hacky but ./tools/build.py && ./tools/test.py -p 034 works.
|
|
||
| const plugin = openPlugin( | ||
| env().DENO_BUILD_PATH + "/" + pluginFilename("test_plugin") | ||
| env().DENO_BUILD_PATH + "/rust_crates/" + pluginFilename("test_plugin") |
There was a problem hiding this comment.
It is, but it works. Any idea what is up with the appveyor build?
There was a problem hiding this comment.
tools/build.py --release works fine on windows, but tools/build.py doesn't for some reason.
|
This patch resolves the issue with windows, but it wouldn't really be a debug build anymore It seems like we need to add a arg to the linker via deno/build_extra/rust/rust.gni Lines 247 to 252 in 1b48d67 |
1961a12 to
4d3862f
Compare
|
In further testing I discovered that asyncs don't work correctly. |
|
@ry I don't think so. Also I forgot to mention that patch is for |
That works |
|
Update: I very much want to land this patch, but I think we need a bit more reorganization in core ops first. In particular I'd like to add |
|
Native plugins are still something we're actively working towards, but this PR is very out of date - so I'm closing it. We'll refer back to it for dlopen bindings. |
See denoland/std#475 for WIP example usage.