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);
|