Purescript native FFI in pieces; don’t use operator [] on data constructors.

I haven’t seen great documentation for purescript-native, which is a shame. It’s not very efficient, but I see it as a way to lay down template code that provably satisfies desirable properties without being too much of a pain to interface with. Because the result is very vanilla C++11, you can do a lot of neat things with the resulting code.

PureScript-native builds data constructors using the Data tag, meaning that the raw pointer in the PureScript::any object is a pointer to a C style array of any (generally 16 bytes each). You should use any::get<N>(val) to access them. Specifically don’t use the [] operator, which you should use if the PureScript::any represents a proper array in PureScript. The code in PureScript.hh is a bit confusing.

On first blush, operator[] uses a cast operator to return an array view of the any:

any::operator const array&() const {
return *static_cast<const array*>(extractPointer(PS_IF_DEBUG(Tag::Array)));
}

Note that this specifies Tag::Array, which will break nicely if you have a nice runtime environment, and are building debug. (You should totally only use this code in supported build configurations and not do wacky exotic things).

I read this code after trying it and was like “hmm I don’t see a using std; anywhere. That’s because, confusingly:

template <size_t N>
using data = std::array<const any, N>;
using array = std::deque<any WITH_ALLOCATOR(any)>;

So data is really std::array because it’s actually fixed sized, and array is really std::deque, so it can have reasonably efficient push and pop operations on both ends like javascript’s array is likely to have in a good implementation.

This public service announcement brought to you by the number #GP and the letter segmentation fault (core dumped)