Print this page
XXX doco cleanup
XXX first cut of crosscall


 203 `ap`.  Allocate and populate a C object, stuff it into `*opp`, and return
 204 `v8plus_void()`.  If you need to throw an exception you can do so by
 205 returning `v8plus_error()` or one of its wrappers, or by setting
 206 `_v8plus_errno` using one of those functions and then returning an nvlist
 207 with an `err` member representing a decorated exception.
 208 
 209 ### void v8plus_c_dtor_f(void *op)
 210 
 211 Free the C object `op` and anything else associated with it.  Your object is
 212 going away.  This function may be empty if the constructor did not allocate
 213 any memory (i.e., `op` is not a pointer to dynamically allocated memory).
 214 
 215 ### nvlist_t *v8plus_c_method_f(void *op, const nvlist_t *ap)
 216 
 217 When the JavaScript method is called in the context of your object, the
 218 corresponding C function is invoked.  `op` is the C object associated with
 219 the JavaScript object, and `ap` is the encoded list of arguments to the
 220 function.  Return an encoded object with a `res` member, or use one of the
 221 error/exception patterns.
 222 
 223 ### nvlist_t *v8plus_c_static_method_f(nvlist_t *ap)
 224 
 225 In addition to methods on the native objects returned by your constructor,
 226 you can also provide a set of functions on the native binding object itself.
 227 This may be useful for providing bindings to libraries for which no object
 228 representation makes sense, or that have functions that operate outside the
 229 context of any particular object.  Your arguments are once again encoded in
 230 `ap`, and your return values are an object containing `res` or an error.
 231 
 232 ### Argument Handling
 233 
 234 When JavaScript objects cross the boundary from C++ to C, they are converted
 235 from v8 C++ objects into C nvlists.  This means that they are effectively
 236 passed by value, unlike in JavaScript or in native addons written in C++.
 237 The arguments to the JavaScript function are treated as an array and
 238 marshalled into a single nvlist whose properties are named "0", "1", and so
 239 on.  Each such property is encoded as follows:
 240 
 241 - numbers and Number objects (regardless of size): double
 242 - strings and String objects: UTF-8 encoded C string
 243 - booleans and Boolean objects: boolean_value


 607                 my_context_t *cp = malloc(sizeof (my_context_t));
 608                 ...
 609                 if (v8plus_args(ap, 0, V8PLUS_TYPE_JSFUNC, &cb,
 610                     V8PLUS_TYPE_NONE) != 0) {
 611                         free(cp);
 612                         return (NULL);
 613                 }
 614 
 615                 v8plus_jsfunc_hold(cb);
 616                 cp->mc_callback = cb;
 617                 v8plus_defer(op, cp, async_worker, async_completion);
 618 
 619                 return (v8plus_void());
 620         }
 621 
 622 This mechanism uses `uv_queue_work()` and as such will tie up one of the
 623 worker threads in the pool for as long as `async_worker` is running.
 624 
 625 The other asynchronous mechanism is the Node.js `EventEmitter` model.  This
 626 model requires some assistance from JavaScript code, because v8+ native
 627 objects no not inherit from `EventEmitter`.  To make this work, you will
 628 need to create a JavaScript object (the object your consumers actually use)
 629 that inherits from `EventEmitter`, hang your native object off this object,
 630 and populate the native object with an appropriate method that will cause
 631 the JavaScript object to emit events when the native object invokes that
 632 method.  A simple example might look like this:
 633 
 634         var util = require('util');
 635         var binding = require('./native_binding');
 636         var events = require('events');
 637 
 638         function
 639         MyObjectWrapper()
 640         {
 641                 var self = this;
 642 
 643                 events.EventEmitter.call(this);
 644                 this._native = binding._create.apply(this,
 645                     Array.prototype.slice.call(arguments));
 646                 this._native._emit = function () {
 647                         var args = Array.prototype.slice.call(arguments);




 203 `ap`.  Allocate and populate a C object, stuff it into `*opp`, and return
 204 `v8plus_void()`.  If you need to throw an exception you can do so by
 205 returning `v8plus_error()` or one of its wrappers, or by setting
 206 `_v8plus_errno` using one of those functions and then returning an nvlist
 207 with an `err` member representing a decorated exception.
 208 
 209 ### void v8plus_c_dtor_f(void *op)
 210 
 211 Free the C object `op` and anything else associated with it.  Your object is
 212 going away.  This function may be empty if the constructor did not allocate
 213 any memory (i.e., `op` is not a pointer to dynamically allocated memory).
 214 
 215 ### nvlist_t *v8plus_c_method_f(void *op, const nvlist_t *ap)
 216 
 217 When the JavaScript method is called in the context of your object, the
 218 corresponding C function is invoked.  `op` is the C object associated with
 219 the JavaScript object, and `ap` is the encoded list of arguments to the
 220 function.  Return an encoded object with a `res` member, or use one of the
 221 error/exception patterns.
 222 
 223 ### nvlist_t *v8plus_c_static_method_f(const nvlist_t *ap)
 224 
 225 In addition to methods on the native objects returned by your constructor,
 226 you can also provide a set of functions on the native binding object itself.
 227 This may be useful for providing bindings to libraries for which no object
 228 representation makes sense, or that have functions that operate outside the
 229 context of any particular object.  Your arguments are once again encoded in
 230 `ap`, and your return values are an object containing `res` or an error.
 231 
 232 ### Argument Handling
 233 
 234 When JavaScript objects cross the boundary from C++ to C, they are converted
 235 from v8 C++ objects into C nvlists.  This means that they are effectively
 236 passed by value, unlike in JavaScript or in native addons written in C++.
 237 The arguments to the JavaScript function are treated as an array and
 238 marshalled into a single nvlist whose properties are named "0", "1", and so
 239 on.  Each such property is encoded as follows:
 240 
 241 - numbers and Number objects (regardless of size): double
 242 - strings and String objects: UTF-8 encoded C string
 243 - booleans and Boolean objects: boolean_value


 607                 my_context_t *cp = malloc(sizeof (my_context_t));
 608                 ...
 609                 if (v8plus_args(ap, 0, V8PLUS_TYPE_JSFUNC, &cb,
 610                     V8PLUS_TYPE_NONE) != 0) {
 611                         free(cp);
 612                         return (NULL);
 613                 }
 614 
 615                 v8plus_jsfunc_hold(cb);
 616                 cp->mc_callback = cb;
 617                 v8plus_defer(op, cp, async_worker, async_completion);
 618 
 619                 return (v8plus_void());
 620         }
 621 
 622 This mechanism uses `uv_queue_work()` and as such will tie up one of the
 623 worker threads in the pool for as long as `async_worker` is running.
 624 
 625 The other asynchronous mechanism is the Node.js `EventEmitter` model.  This
 626 model requires some assistance from JavaScript code, because v8+ native
 627 objects do not inherit from `EventEmitter`.  To make this work, you will
 628 need to create a JavaScript object (the object your consumers actually use)
 629 that inherits from `EventEmitter`, hang your native object off this object,
 630 and populate the native object with an appropriate method that will cause
 631 the JavaScript object to emit events when the native object invokes that
 632 method.  A simple example might look like this:
 633 
 634         var util = require('util');
 635         var binding = require('./native_binding');
 636         var events = require('events');
 637 
 638         function
 639         MyObjectWrapper()
 640         {
 641                 var self = this;
 642 
 643                 events.EventEmitter.call(this);
 644                 this._native = binding._create.apply(this,
 645                     Array.prototype.slice.call(arguments));
 646                 this._native._emit = function () {
 647                         var args = Array.prototype.slice.call(arguments);