Skip to content
This repository was archived by the owner on Feb 21, 2018. It is now read-only.
This repository was archived by the owner on Feb 21, 2018. It is now read-only.

Native modules API: the FFI approach #10

@orangemocha

Description

@orangemocha

The current API for native modules exposes the entire v8 API to native module developers. Even if NAN is used to insulate module code from the v8 API changes, it doesn't do anything to shield it from changes in the Node ABI, which in turn would require recompiling the module.

I think that an FFI-based approach has the potential of providing what's needed to implement the vast majority of native modules out there. The idea is to be able to marshal only basic types back and forth between JavaScript and C/C++. Since those types can hopefully be defined in standard terms, and they don't expose any engine-specific features or implementation details, the interface can stay consistent across engine versions and even across multiple engines. Native modules would have to be rewritten to expose their functionality through this marshaling layer, and they wouldn't have access to the v8 constructs. Note that arbitrary JavaScript objects would probably not be supported across the interface, because they risk exposing engine-specific implementation details. Instead, native modules following this model will likely need a JavaScript portion, to map the JavaScript-style API defined by the module to calls into the native portion that use only simple types.

I am hypothesizing that the vast majority of modules could be rewritten using this approach and that the only ones that couldn't are the ones that are designed to expose engine specific features (e.g. v8-profiler). Those will naturally need to continue to support specific engines, and be exposed to changes in the engine.

There is a widespread perception in the community that an FFI solution would be too slow to be of general use. I think the cause of this perception might be that the node-ffi module is known to introduce a lot of overhead. I haven't had a chance to study the node-ffi implementation, but I am guessing that it is using a reflection-based approach to do the marshaling, which may be the cause of the overhead. A template-based approach was suggested by @geoffkizer at nodejs/nan#349 (comment) which showed that the overhead can be very small. My experience with other platforms that use this approach (i.e. .NET) also leads me to believe that the overhead can be reasonable and that the approach should be feasible.

I am raising this issue so that at least we don't dismiss this possibility. It would be useful for this group to prove or disprove whether this can be an effective solution.

One of the open questions in my mind would be how to support the array/buffer type in a portable and performant way.

/cc @robpaveza (Chakra)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions