I found that the Foreign Class is actually a subclass of HeapObject and
the only difference is that it has some extra size to store a pointer
inside.
So, Can I use a Foreign instance to store a pointer from some C function
and pass it back and forth from/to JS?
From the code of SetPointerInInternalField I see that's what V8 does if
the pointer cannot be encoded as a SMI. But for the purpose of *just*
sending pointers back and forth, creating an object with an internal
field that ends up having another object on it that actually stores the
address seems overkill, if a Foreign object is a valid JS object, I'd
use that directly.
On Fri, Oct 5, 2012 at 7:04 PM, Pablo Sole <pablo.s...@gmail.com> wrote:
> I found that the Foreign Class is actually a subclass of HeapObject and
> the only difference is that it has some extra size to store a pointer
> inside.
> So, Can I use a Foreign instance to store a pointer from some C function
> and pass it back and forth from/to JS?
Have you looked at External::Wrap (and Unwrap)? It returns an
v8::Value than can be passed through the embedding api. It states
(literally) "The Wrap function V8 will return the most optimal Value
object wrapping the C++ void*. "
> From the code of SetPointerInInternalField I see that's what V8 does if
> the pointer cannot be encoded as a SMI. But for the purpose of *just*
> sending pointers back and forth, creating an object with an internal
> field that ends up having another object on it that actually stores the
> address seems overkill, if a Foreign object is a valid JS object, I'd
> use that directly.
A Foreign object is *not* a JavaScript object it is intended to be used
only internally. Furthermore, v8's GC needs to distinguish the objects
under its control from the external ones, so we can't simply put any void*
into an internal field. Currently this part of the API is in a poor and
slightly broken state and there have been some discusssions how to fix it.
The probable future API looks like this:
* A SetAlignedPointerInInternalField/GetAlignedPointerFromInternalField
will be added, allowing highly efficient stores/loads of 2-byte-aligned
void* to/from internal fields.
* External will be changed back again to provide a real JavaScript
object, namely one with a hidden field containing a Foreign. This way *any*
void* can be wrapped and stored/loaded via
SetInternalField/GetInternalField and IsExternal will work again.
Wrap, Unwrap, SetPointerInInternalField and GetPointerFromInternalField
will probably be deprecated and die in some not-to-far future.
Having an efficient store/load of pointers over an Object would be very
handy indeed, in the meantime I'm using the storage space of a
HeapNumber object to store my pointers as you suggested some time ago (I
didn't check that a Foreign was related to an External before asking).
I suppose that hacking a new "Opaque" type that behaves like a
HeapNumber object from the GC perspective but without any of the number
methods should be doable and very useful for embedders. The whole idea,
after all, is to have an opaque pointer (from a V8 perspective) inside
JS, so I don't need any "services" from V8, just store it and please
don't consider it a pointer that should be handled in any way.
> A Foreign object is *not* a JavaScript object it is intended to be
> used only internally. Furthermore, v8's GC needs to distinguish the
> objects under its control from the external ones, so we can't simply
> put any void* into an internal field. Currently this part of the API
> is in a poor and slightly broken state and there have been some
> discusssions how to fix it. The probable future API looks like this:
> * A
> SetAlignedPointerInInternalField/GetAlignedPointerFromInternalField
> will be added, allowing highly efficient stores/loads of
> 2-byte-aligned void* to/from internal fields.
> * External will be changed back again to provide a real JavaScript
> object, namely one with a hidden field containing a Foreign. This way
> *any* void* can be wrapped and stored/loaded via
> SetInternalField/GetInternalField and IsExternal will work again.
> Wrap, Unwrap, SetPointerInInternalField and
> GetPointerFromInternalField will probably be deprecated and die in
> some not-to-far future.
> -- > v8-users mailing list
> v8-users@googlegroups.com
> http://groups.google.com/group/v8-users