Windows Support

7 views
Skip to first unread message

Anton Yemelyanov

unread,
Apr 8, 2012, 5:35:14 PM4/8/12
to v8-juice-js-dev
Stephan,

What I am about to write applies to v8-juice and from what I see to cvv8, although we are not using cvv8 yet (since we based ourselves on v8-juice over a year ago and haven't had opportunity to convert to cvv8).  This, actually, applies to any type of template library.

v8-juice in it's current form doesn't support windows shared libraries (DLLs).  The problem resides in the fact that in windows, all symbols in libraries are private by default (whereas in unix they are public. although i seem to have seen ability to control that in the latest versions of gcc).

In v8-juice a number of core variables (such as OneOfUs, SubclassGetNatives, SubclassGetJSObjects) are created "on-the-fly" by declaring template functions and then returning static variables from these functions.

Unfortunately, in windows, when two DLLs reference the same class/header a private instance of each static variable within a function gets created in each DLL.  Thus passing an object from one DLL to another does not work because while it will be created in DLL1, in DLL2 it is not present in a type check array (OneOfUs), consequently failing validation.

The way I have made this work is by forcing all our classes to contain V8_JUICE_DECLARE_CLASS macro, which instantiates OneOfUs, SubclassGetNatives, SubclassGetJSObjects as static members of the wrapped class and modified v8-juice to refer to the wrapped class when obtaining a reference to these arrays.

Unfortunately, I don't think there is a better way to do this because it is not known from which DLL the class originates and the arrays in question must follow import/export declarations of the wrapped class.  We can't even wrap the derived class from a template because the arrays in question must be static.

Furthermore, this circumvents ability to wrap an existing class without modifying it. In order to wrap existing classes, we had to derive custom classes and apply this methodology to them...

...

I would like to gather thoughts on the matter.  I think Windows support is imperative... and while it breaks the cleanliness of the framework, the ability to have modular structure (i.e. plugins) is imperative...  

Unless we can devise a way to create a central map of maps that catalogs all classes wrapped by v8-juice/cvv8 (it may be possible to create a central resolver that would map wrapped classes to map of structures using RTTI)... we should seriously consider reworking the entire library to facilitate this using the above described method...

Anton

Stephan Beal

unread,
Apr 8, 2012, 5:58:47 PM4/8/12
to v8-juic...@googlegroups.com
On Sun, Apr 8, 2012 at 11:35 PM, Anton Yemelyanov <anton.ye...@gmail.com> wrote:
I would like to gather thoughts on the matter.  I think Windows support is imperative... and while it breaks the cleanliness of the framework, the ability to have modular structure (i.e. plugins) is imperative...  

i agree with you, and understand the problem, but unfortunately don't have a nice solution for it. Coincidentally, i read today a bit about C++11's extern templates, which sound like they are a solution to exactly this problem. But that doesn't help most people just yet. i've experimented with a couple solutions in the past but never found one which wouldn't suffer from this problem.

i once had an idea involving storing the cross-DLL data in (void const *-to-void *) map which would be exposed in the API via a non-template interface, so that DLLs would have no choice but to just (void*) as opposed to (T*) for their storage. But i never got around to actually trying it out, and don't know if that approach would work. It's been so long since i've touched that code, i can't say much about how it works.

Unless we can devise a way to create a central map of maps that catalogs all classes wrapped by v8-juice/cvv8 (it may be possible to create a central resolver that would map wrapped classes to map of structures using RTTI)... we should seriously consider reworking the entire library to facilitate this using the above described method...

While i agree a whole new mechanism would be ideal, i'm not personally up for revamping the juice code (but volunteers are welcome as long as it doesn't mean i have to rewrite all of the existing plugins). However... there's no reason we cannot add a completely new class-binding mechanism to it which uses a mechanism which doesn't have this problem. Juice itself is not tied to any specific class-binding mechanism - the ones provided with it simply represent my own evolution through the class-binding process. All of the plugins have an intimate relationship with the current class wrappers (several of them were written just to demonstrate the wrappers), and i don't want to have to go fix that older code by breaking the existing class wrapping mechanisms. But i'm all for adding another one.

AFAIK, the plugin mechanism itself is not the problem, per se, but:

a) i don't know for 100% sure that the plugin code works on Windows (???)
b) the problem is more the multiple-instantiation of template-created static bits when used across DLLs. If we can work around that then the world will be round again.

:-?

--
----- stephan beal
http://wanderinghorse.net/home/stephan/

Anton Yemelyanov

unread,
Apr 8, 2012, 9:55:05 PM4/8/12
to v8-juic...@googlegroups.com
One thing just occurred to me.  The "type resolver" (i.e. object containing OneOfUs types of maps) doesn't have to be present within the wrapper class nor within the wrapped class.  It would be a completely external class that has to be manually instantiated by the user.

The wrapper class can contain a pointer to such resolver.  If pointer is not present (NULL), wrapper can use internal mechanisms as done in the current implementation.  However, if resolver has been set, then the resolver is used.

This way current functionality can remain untouched, but one can come from the side and supply the resolver, which would address this problem.

The only requirement of such approach is that the wrapper (ClassBinder in v8-juice) is made global and follows import/export declarations of the class that it wraps.

... I unfortunately don't have time to contribute until mid summer.:(  Maybe sometime toward mid summer I will look into switching v8-juice to cvv8 and as this pass try to implement this.

Anton
Reply all
Reply to author
Forward
0 new messages