Extending V8 via native modules/addons

117 views
Skip to first unread message

Vangelis Ts.

unread,
Sep 20, 2017, 10:21:21 AM9/20/17
to v8-users
Hello,

I have written a C++ library and I would like to make it work like a Node.js addon (see https://nodejs.org/api/addons.html#addons_c_addons), but for V8.

However, I am not sure what is the best way to do that. Some thoughts/limitations are:

1. I would prefer to connect it directly with V8, without any extra interfaces (like nbind, for example) or Node.js.
2. Compiling the library to JavaScript (e.g. using Emscripten) is not an option.
3. Ideally, I would like to be able to load it in any instance of V8, such as in Chrome, (maybe via the "require(…)" keyword, like a Node.js addon?), so embedding the library with V8 and shipping it as an executable would not be a neat choice. I also guess that this diminishes the option to compile the library as a builtin V8 library function.

I would really appreciate any suggestions you might have. 🙂

― Vangelis

Vangelis Ts.

unread,
Sep 20, 2017, 12:12:52 PM9/20/17
to v8-users
Related, follow-up question:

I've been wondering whether I could prepare a Context with all the object and function templates of my library, save it in a binary file (like V8 does with the startup snapshot) and then load it on demand, in order to gain access to my library's code in the currently executing context. Is that even possible?

P.S.: I am sorry for asking many, possibly vague, questions. This is my first experience with V8 and I haven't been able to find a right and accurate solution yet, although I've read the V8 wiki on GitHub.

― Vangelis

Zac Hansen

unread,
Sep 20, 2017, 3:31:45 PM9/20/17
to v8-users
There's no way to compile native code that can connect to any version of v8 - first of all v8 spans platforms where the code wouldn't even make sense.  Second of all, there are ABI concerns across versions.  Lastly, there's no way to simply connect arbitrary data to v8 that's linked in to another program.

At least, as far as I know.

Vangelis Ts.

unread,
Sep 21, 2017, 5:38:08 PM9/21/17
to v8-users
Thank you for your answer, Zac. 🙂

I see that Node.js uses libuv to dynamically load native addons and link them with V8 on runtime. I was hoping that V8 alone provided this kind of functionality. However, a native Node.js addon seems like the next best option, so that's what I'm going to try next.

Fabio Kaminski

unread,
Sep 29, 2017, 2:08:53 PM9/29/17
to v8-users
> I've been wondering whether I could prepare a Context with all the object and function templates of my library, save it in a binary file (like V8 does with the startup snapshot) and then load it on demand, in order to gain access to my library's code in the currently executing context. Is that even possible?

You can create a snapshot with native code.. the problem is that you will need to change the v8 source, so you will end up with a fork of v8, and will have to 
manuallly change it every time you want to sync with upstream.

See the code the v8 itself generates for methods in javascript

See the src/builtin dir for implementations.. 

Note the differences in wrapping:

TF_BUILTIN -> Uses the TurboFan backend directly, and you are basically writing a portable assembly
in C++ code, that TurboFan will translate to machine code according to the host machine

Also the trick there is to use 'CodeStubAssembler' which will give you access to the TurboFan frontend

For instance in builtins-array-gen.cc the 'ArrayBuiltinCodeStubAssembler' class used in TF_BUILTIN(builtin_method, ArrayBuiltinCodeStubAssembler)
inherits from 'CodeStubAssembler'

Then you have 'BUILTIN(builtin_method)' which is implemented in C++

Once you create your methods you will need to change 'src/builtins/builtins-definitions.h'
and add a reference to the created methods there with 'CPP(Method)' for C++ code or 'TFS(Method) / TFJ(Method)' for 
methods created using the turbofan frontend.

Once you create your builtins, and add it to definitions, you will need to change src/bootstrap.cc
and add them to the references and possibly to the runtime global object if you want..

Note that if you do that, anywhere you use this custom v8 of yours this custom runtime will be available...

Thats the only way im aware, that you can embed native code in the snapshot

Vangelis Ts.

unread,
Oct 21, 2017, 5:56:57 AM10/21/17
to v8-users
Hi Fabio,

Thank you very much for your complete reply! It has helped me a lot. 😊
Reply all
Reply to author
Forward
0 new messages