-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use as as Dynlink-like extension mechanism #2
Comments
After experimenting a bit, I can partially answer my own questions:
|
Actually, going through a module that isn't the main module ( |
This is quite similar to what MDX does, especially with the |
Interesting, I didn't know that. In any case, I've already removed the dependency on the toplevel bits so I can start testing in vanilla 4.13. The overall changes are fairly small (export Globals, Symbols and Address, add a function for adding symbols, and move some code around, so that Using the above fork, I find the address of symbols using the following code: extern void* camlPlugin_api;
extern void* camlInit;
CAMLprim value caml_find_external_symbols(value unit) {
CAMLparam1 (unit);
CAMLlocal1(res);
res = caml_alloc(2, 0);
Field(res, 0) = caml_copy_nativeint((intnat)&camlPlugin_api);
Field(res, 1) = caml_copy_nativeint((intnat)&camlInit);
CAMLreturn(res);
} And then add to symbols and run plugins as follows: external find_external_symbols : unit -> Jit.Address.t array = "caml_find_external_symbols"
let () =
Clflags.native_code := true;
let symbols =
Array.map2 (fun name addr -> name, addr)
[|
"camlPlugin_api";
"camlInit";
|]
(find_external_symbols ())
in
Jit.Globals.symbols :=
Jit.Symbols.union !Jit.Globals.symbols (Jit.Symbols.of_seq (Array.to_seq symbols));
let run_ml phrase_name source_file =
Jit.with_jit_x86 (fun () ->
let output_prefix = Filename.remove_extension source_file in
let start_from = Clflags.Compiler_pass.Parsing in
Optcompile.implementation ~backend ~start_from ~source_file ~output_prefix
) phrase_name (ref None) |
I'm working on an OCaml program that can be extended with scripts written in OCaml, however the existing Dynlink mechanism (and higher-level approaches like
ocaml_plugin
) is too heavyweight and doesn't work in statically compiled programs. I've had a similar implementation in mind (link with the OCaml compiler, generate assembly, assemble it using a custom x86 assembler in memory and make it executable in the running process using mmap/mprotect). I'm curious if this project could be extended to handle this, in particular:From what I can tell this is technically possible (the old native toplevel already uses Dynlink, and
jit_run
in this repository is similar to the native dynlink code in OCaml), although I might be missing some difficulties, especially around changes to the OCaml compiler. If there's anything you need, I'd gladly contribute.The text was updated successfully, but these errors were encountered: