V8: Passing object from JavaScript to uv_work function
v8
Solution
The code in `SendMessageWorker` is not executed on the JavaScript - what `uv_queue_work` does is execute your `SendMessageWorker` in a separate thread, so it can let the node.js code run as well, and when it's ready, `SendMessageWorkerComplete` is executed back on the JavaScript thread.
So you can't use JavaScript variables in SendMessageWorker - if you really need to, you'd have to convert them to e.g. C++ string before calling `uv_queue_work`.
Problem
OK, I have a function in C++ that I need to call from JavaScript, and one of the parameters is a JavaScript object. The JavaScript looks like this: ``` var message = { fieldA: 42, fieldB: "moo" }; myObj.send(message, function (err) { console.log("Result: " + err); }); ``` In the send() routine I need to call a native function in another C library that may block. All functions in this library may block so I've been using uv_queue_work extensively. This routine is the first time I've hit an issue and it is because of the JavaScript object. The C++ code looks like this: ``` struct SendMessageRequest { Persistent<Object> message; Persistent<Function> callback; int result; }; Handle<Value> MyObj::Send(const Arguments& args) { HandleScope scope; // Parameter checking done but not included here Local<Object> message = Local<Object>::Cast(args[0]); Local<Function> callback = Local<Function>::Cast(args[1]); // Send data to worker thread SendMessageRequest* request = new SendMessageRequest; request->message = Persistent<Object>::New(message); request->callback = Persistent<Function>::New(callback); uv_work_t* req = new uv_work_t(); req->data = request; uv_queue_work(uv_default_loop(), req, SendMessageWorker, SendMessageWorkerComplete); return scope.Close(Undefined()); } ``` This is all fine, the problem comes when I try to access request->message in the SendMessageWorker function. ``` void SendMessageWorker(uv_work_t* req) { SendMessageRequest* request = (SendMessageRequest*)req->data; Local<Array> names = request->message->GetPropertyNames(); // CRASH ``` It seems that calling methods off of request->message causes an Access Violation on a really small address (probably a NULL pointer reference somewhere in V8/node). So using request->message directly must be wrong. I know to access the callback function I need to do this: ``` request->callback->Call(Context::GetCurrent()->Global(), 1, argv); ``` Do I need to use Context::GetCurrent()->Global() in order to access methods off of the Object class that is wrapped by the Persistent template? If so how do I do that?