Search code examples
javascriptc++node.jsnode-webkit

node-webkit crashes when I create an ArrayBuffer inside c++ add-on


I am writing a node-webkit c++ add-on, it crashes every time I try to create an ArrayBuffer. The following code is a minimal crash example.

#include <node.h>
#include <v8.h>
#include <cstring>

using namespace v8;

Handle<Value> createVector(const Arguments& args) {
  HandleScope scope;
  Handle<ArrayBuffer> a = ArrayBuffer::New(12);
  return scope.Close(a);
}

void init(Handle<Object> exports) {
  exports->Set(String::NewSymbol("createVector"),
      FunctionTemplate::New(createVector)->GetFunction());
}

NODE_MODULE(vectortest, init)

Every time I call the createVector() method node-webkit crashes on Windows 8. I call it from the console using the following javascript code:

var m=require('vectortest');
m.createVector();

I tried it on node-webkit 0.7.2 and 0.7.5. Any suggestion?


Solution

  • So I solved my problem using the workaround below.

    Handle<Object> createBuffer(void *data, size_t size) {
        if (size == 0)
            throw "Zero sized data";
        Handle<Value> abv = Context::GetCurrent()->Global()->Get(String::NewSymbol("ArrayBuffer"));
        Handle<Value> argv[] = { Integer::NewFromUnsigned(size) };
        Handle<Object> arrbuf = Handle<Function>::Cast(abv)->NewInstance(1, argv);
        void *buffer = arrbuf->GetPointerFromInternalField(0);
        memcpy(buffer, data, size);
    
        Handle<Value> ui8av = Context::GetCurrent()->Global()->Get(String::NewSymbol("Uint8Array"));
        argv[0] = arrbuf;
        Handle<Object> result = Handle<Function>::Cast(ui8av)->NewInstance(1, argv);
        return result;
    }
    

    Obviously in the v8 namespace.
    It seems that node, and in consequence node-webkit, re-implements the ArrayBuffer, TypedArray, Uint8Array and so on in node/src/v8_typed_array.cc. They are totally different from the ones in v8.h and they haven't an header file to include.
    Initially I had in my javascript code something like this:

    var buffer = ... // call function that in the end call createBuffer
    var data = new Uint8Array(buffer);
    

    and createBuffer was returning the arrbuf ArrayBuffer but I had problems doing that: data length was always 0. Instead, by creating the Uint8Array in c++ code the behavior is right, I don't know why.