From 6ea95660579df74791994bec75a901eb4e4b8b07 Mon Sep 17 00:00:00 2001 From: kingloud Date: Fri, 5 May 2017 15:52:11 -0700 Subject: [PATCH 1/5] initial convert, wip - needs error handles --- binding.gyp | 1 + libdtrace.cc | 485 ++++++++++++++++++++++++++------------------------- package.json | 3 +- 3 files changed, 249 insertions(+), 240 deletions(-) diff --git a/binding.gyp b/binding.gyp index 5bc1524..831731f 100644 --- a/binding.gyp +++ b/binding.gyp @@ -7,6 +7,7 @@ 'sources': [ 'libdtrace.cc' ], + "include_dirs" : [" -#include +#include +#include + #include #include -#include #include #include #include @@ -65,68 +65,109 @@ DTRACE_LLQUANTIZE_NSTEPSHIFT) #endif + +using namespace Nan; using namespace v8; using std::string; using std::vector; -class DTraceConsumer : node::ObjectWrap { + + +class DTraceConsumer : public Nan::ObjectWrap { public: - static void Initialize(Handle target); + + static NAN_MODULE_INIT(Init) + { + + + v8::Local dtc = Nan::New(New); + + dtc->SetClassName(Nan::New("Consumer").ToLocalChecked()); + dtc->InstanceTemplate()->SetInternalFieldCount(1); + + + Nan::SetPrototypeMethod(dtc, "strcompile", DTraceConsumer::Strcompile); + Nan::SetPrototypeMethod(dtc, "version", DTraceConsumer::Version); + Nan::SetPrototypeMethod(dtc, "setopt", DTraceConsumer::Setopt); + + + Nan::SetPrototypeMethod(dtc, "go", DTraceConsumer::Go); + Nan::SetPrototypeMethod(dtc, "consume", DTraceConsumer::Consume); + Nan::SetPrototypeMethod(dtc, "aggwalk", DTraceConsumer::Aggwalk); + Nan::SetPrototypeMethod(dtc, "aggclear", DTraceConsumer::Aggclear); + Nan::SetPrototypeMethod(dtc, "aggmin", DTraceConsumer::Aggmin); + Nan::SetPrototypeMethod(dtc, "aggmax", DTraceConsumer::Aggmax); + Nan::SetPrototypeMethod(dtc, "stop", DTraceConsumer::Stop); + + constructor().Reset(Nan::GetFunction(dtc).ToLocalChecked()); + Nan::Set(target, Nan::New("Consumer").ToLocalChecked(), + Nan::GetFunction(dtc).ToLocalChecked()); + } + protected: DTraceConsumer(); ~DTraceConsumer(); Handle error(const char *fmt, ...); - Handle badarg(const char *msg); +// Handle badarg(const char *msg); boolean_t valid(const dtrace_recdesc_t *); const char *action(const dtrace_recdesc_t *, char *, int); - Local record(const dtrace_recdesc_t *, caddr_t); - Local probedesc(const dtrace_probedesc_t *); + v8::Local record(const dtrace_recdesc_t *, caddr_t); + v8::Local probedesc(const dtrace_probedesc_t *); - Local *ranges_cached(dtrace_aggvarid_t); - Local *ranges_cache(dtrace_aggvarid_t, Local *); - Local *ranges_quantize(dtrace_aggvarid_t); - Local *ranges_lquantize(dtrace_aggvarid_t, uint64_t); - Local *ranges_llquantize(dtrace_aggvarid_t, uint64_t, int); + v8::Local *ranges_cached(dtrace_aggvarid_t); + v8::Local *ranges_cache(dtrace_aggvarid_t, Local *); + v8::Local *ranges_quantize(dtrace_aggvarid_t); + v8::Local *ranges_lquantize(dtrace_aggvarid_t, uint64_t); + v8::Local *ranges_llquantize(dtrace_aggvarid_t, uint64_t, int); static int consume(const dtrace_probedata_t *data, const dtrace_recdesc_t *rec, void *arg); static int aggwalk(const dtrace_aggdata_t *agg, void *arg); static int bufhandler(const dtrace_bufdata_t *bufdata, void *arg); - static Handle New(const Arguments& args); - static Handle Consume(const Arguments& args); - static Handle Aggclear(const Arguments& args); - static Handle Aggwalk(const Arguments& args); - static Handle Aggmin(const Arguments& args); - static Handle Aggmax(const Arguments& args); - static Handle Strcompile(const Arguments& args); - static Handle Setopt(const Arguments& args); - static Handle Go(const Arguments& args); - static Handle Stop(const Arguments& args); - static Handle Version(const Arguments& args); + static NAN_METHOD(New); + static NAN_METHOD(Consume); + static NAN_METHOD(Aggclear); + static NAN_METHOD(Aggwalk); + static NAN_METHOD(Aggmin); + static NAN_METHOD(Aggmax); + static NAN_METHOD(Strcompile); + static NAN_METHOD(Setopt); + static NAN_METHOD(Go); + static NAN_METHOD(Stop); + static NAN_METHOD(Version); private: dtrace_hdl_t *dtc_handle; - static Persistent dtc_templ; - const Arguments *dtc_args; + + static Nan::Persistent dtc_templ; + const Nan::FunctionCallbackInfo *dtc_args; Local dtc_callback; Handle dtc_error; Local *dtc_ranges; dtrace_aggvarid_t dtc_ranges_varid; + + + static inline Nan::Persistent & constructor() { + static Nan::Persistent my_constructor; + return my_constructor; + } + }; -Persistent DTraceConsumer::dtc_templ; -DTraceConsumer::DTraceConsumer() : node::ObjectWrap() +// Persistent DTraceConsumer::dtc_templ; + +DTraceConsumer::DTraceConsumer() : Nan::ObjectWrap() { int err; dtrace_hdl_t *dtp; if ((dtc_handle = dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) - throw (dtrace_errmsg(NULL, err)); - + Nan::ThrowError(Nan::New(dtrace_errmsg(NULL, err)).ToLocalChecked()); + /* * Set our buffer size and aggregation buffer size to the de facto * standard of 4M. @@ -148,52 +189,22 @@ DTraceConsumer::~DTraceConsumer() dtrace_close(dtc_handle); } -void -DTraceConsumer::Initialize(Handle target) -{ - HandleScope scope; - Local dtc = - FunctionTemplate::New(DTraceConsumer::New); - - dtc_templ = Persistent::New(dtc); - dtc_templ->InstanceTemplate()->SetInternalFieldCount(1); - dtc_templ->SetClassName(String::NewSymbol("Consumer")); - - NODE_SET_PROTOTYPE_METHOD(dtc_templ, "strcompile", - DTraceConsumer::Strcompile); - NODE_SET_PROTOTYPE_METHOD(dtc_templ, "setopt", DTraceConsumer::Setopt); - NODE_SET_PROTOTYPE_METHOD(dtc_templ, "go", DTraceConsumer::Go); - NODE_SET_PROTOTYPE_METHOD(dtc_templ, "consume", - DTraceConsumer::Consume); - NODE_SET_PROTOTYPE_METHOD(dtc_templ, "aggwalk", - DTraceConsumer::Aggwalk); - NODE_SET_PROTOTYPE_METHOD(dtc_templ, "aggclear", - DTraceConsumer::Aggclear); - NODE_SET_PROTOTYPE_METHOD(dtc_templ, "aggmin", DTraceConsumer::Aggmin); - NODE_SET_PROTOTYPE_METHOD(dtc_templ, "aggmax", DTraceConsumer::Aggmax); - NODE_SET_PROTOTYPE_METHOD(dtc_templ, "stop", DTraceConsumer::Stop); - NODE_SET_PROTOTYPE_METHOD(dtc_templ, "version", - DTraceConsumer::Version); - - target->Set(String::NewSymbol("Consumer"), dtc_templ->GetFunction()); -} -Handle -DTraceConsumer::New(const Arguments& args) -{ - HandleScope scope; +NAN_METHOD (DTraceConsumer::New) { DTraceConsumer *dtc; try { dtc = new DTraceConsumer(); + dtc->Wrap(info.This()); + info.GetReturnValue().Set(info.This()); + } catch (char const *msg) { - return (ThrowException(Exception::Error(String::New(msg)))); + Nan::ThrowError(Nan::New(msg).ToLocalChecked()); + // return (ThrowException(Exception::Error(String::New(msg)))); // how to throw errors now? } +} - dtc->Wrap(args.Holder()); - return (args.This()); -} const char * DTraceConsumer::action(const dtrace_recdesc_t *rec, char *buf, int size) @@ -266,14 +277,14 @@ DTraceConsumer::error(const char *fmt, ...) buf[strlen(buf) - 1] = '\0'; } - return (ThrowException(Exception::Error(String::New(err)))); + // return (ThrowException(Nan::Error(Nan::New(err)))); } -Handle -DTraceConsumer::badarg(const char *msg) -{ - return (ThrowException(Exception::TypeError(String::New(msg)))); -} +// Handle +// DTraceConsumer::badarg(const char *msg) +// { +// return (ThrowException(Exception::TypeError(String::New(msg)))); +// } boolean_t DTraceConsumer::valid(const dtrace_recdesc_t *rec) @@ -294,26 +305,26 @@ DTraceConsumer::valid(const dtrace_recdesc_t *rec) } } -Local +v8::Local DTraceConsumer::record(const dtrace_recdesc_t *rec, caddr_t addr) { switch (rec->dtrd_action) { case DTRACEACT_DIFEXPR: switch (rec->dtrd_size) { case sizeof (uint64_t): - return (Number::New(*((int64_t *)addr))); + return (Nan::New(*((int64_t *)addr))); case sizeof (uint32_t): - return (Integer::New(*((int32_t *)addr))); + return (Nan::New(*((int32_t *)addr))); case sizeof (uint16_t): - return (Integer::New(*((uint16_t *)addr))); + return (Nan::New(*((uint16_t *)addr))); case sizeof (uint8_t): - return (Integer::New(*((uint8_t *)addr))); + return (Nan::New(*((uint8_t *)addr))); default: - return (String::New((const char *)addr)); + return Nan::New((const char *)addr).ToLocalChecked(); } case DTRACEACT_SYM: @@ -343,7 +354,7 @@ DTraceConsumer::record(const dtrace_recdesc_t *rec, caddr_t addr) * tick -- or "" if there is none. */ if ((tick = strchr(buf, '`')) == NULL) - return (String::New("")); + return Nan::New("").ToLocalChecked(); *tick = '\0'; } else if (rec->dtrd_action == DTRACEACT_SYM || @@ -356,112 +367,111 @@ DTraceConsumer::record(const dtrace_recdesc_t *rec, caddr_t addr) if ((plus = strrchr(buf, '+')) != NULL) *plus = '\0'; } - - return (String::New(buf)); + return (Nan::New(buf).ToLocalChecked()); } assert(B_FALSE); - return (Integer::New(-1)); + + return Nan::New(-1); } -Handle -DTraceConsumer::Strcompile(const Arguments& args) -{ - DTraceConsumer *dtc = ObjectWrap::Unwrap(args.Holder()); +NAN_METHOD (DTraceConsumer::Strcompile) { + + DTraceConsumer *dtc = Nan::ObjectWrap::Unwrap(info.Holder()); dtrace_hdl_t *dtp = dtc->dtc_handle; dtrace_prog_t *dp; - dtrace_proginfo_t info; + dtrace_proginfo_t dinfo; - if (args.Length() < 1 || !args[0]->IsString()) - return (dtc->badarg("expected program")); + if (info.Length() < 1 || !info[0]->IsString()){ + // return (dtc->badarg("expected program")); + } - String::Utf8Value program(args[0]->ToString()); + String::Utf8Value program(info[0]->ToString()); if ((dp = dtrace_program_strcompile(dtp, *program, DTRACE_PROBESPEC_NAME, 0, 0, NULL)) == NULL) { - return (dtc->error("couldn't compile '%s': %s\n", *program, - dtrace_errmsg(dtp, dtrace_errno(dtp)))); + // return (dtc->error("couldn't compile '%s': %s\n", *program, + // dtrace_errmsg(dtp, dtrace_errno(dtp)))); } - if (dtrace_program_exec(dtp, dp, &info) == -1) { - return (dtc->error("couldn't execute '%s': %s\n", *program, - dtrace_errmsg(dtp, dtrace_errno(dtp)))); + if (dtrace_program_exec(dtp, dp, &dinfo) == -1) { + // return (dtc->error("couldn't execute '%s': %s\n", *program, + // dtrace_errmsg(dtp, dtrace_errno(dtp)))); } - return (Undefined()); + info.GetReturnValue().Set(Undefined()); } -Handle -DTraceConsumer::Setopt(const Arguments& args) -{ - DTraceConsumer *dtc = ObjectWrap::Unwrap(args.Holder()); + +NAN_METHOD (DTraceConsumer::Setopt) { + DTraceConsumer *dtc = Nan::ObjectWrap::Unwrap(info.Holder()); dtrace_hdl_t *dtp = dtc->dtc_handle; - dtrace_prog_t *dp; - dtrace_proginfo_t info; + // dtrace_prog_t *dp; + // dtrace_proginfo_t dinfo; int rval; - if (args.Length() < 1 || !args[0]->IsString()) - return (dtc->badarg("expected an option to set")); + if (info.Length() < 1 || !info[0]->IsString()){ + // return (dtc->badarg("expected an option to set")); + return; + } - String::Utf8Value option(args[0]->ToString()); + String::Utf8Value option(info[0]->ToString()); - if (args.Length() >= 2) { - if (args[1]->IsArray()) - return (dtc->badarg("option value can't be an array")); + if (info.Length() >= 2) { + if (info[1]->IsArray()){ + // return (dtc->badarg("option value can't be an array")); + } - if (args[1]->IsObject()) - return (dtc->badarg("option value can't be an object")); + if (info[1]->IsObject()){ + // return (dtc->badarg("option value can't be an object")); + } - String::Utf8Value optval(args[1]->ToString()); + String::Utf8Value optval(info[1]->ToString()); rval = dtrace_setopt(dtp, *option, *optval); } else { rval = dtrace_setopt(dtp, *option, NULL); } if (rval != 0) { - return (dtc->error("couldn't set option '%s': %s\n", *option, - dtrace_errmsg(dtp, dtrace_errno(dtp)))); + // return (dtc->error("couldn't set option '%s': %s\n", *option, + // dtrace_errmsg(dtp, dtrace_errno(dtp)))); } - return (Undefined()); + info.GetReturnValue().Set(Undefined()); } -Handle -DTraceConsumer::Go(const Arguments& args) -{ - DTraceConsumer *dtc = ObjectWrap::Unwrap(args.Holder()); +NAN_METHOD (DTraceConsumer::Go) { + DTraceConsumer *dtc = Nan::ObjectWrap::Unwrap(info.Holder()); dtrace_hdl_t *dtp = dtc->dtc_handle; if (dtrace_go(dtp) == -1) { - return (dtc->error("couldn't enable tracing: %s\n", - dtrace_errmsg(dtp, dtrace_errno(dtp)))); + // return (dtc->error("couldn't enable tracing: %s\n", + // dtrace_errmsg(dtp, dtrace_errno(dtp)))); } - return (Undefined()); + info.GetReturnValue().Set(Undefined()); } -Handle -DTraceConsumer::Stop(const Arguments& args) -{ - DTraceConsumer *dtc = ObjectWrap::Unwrap(args.Holder()); +NAN_METHOD (DTraceConsumer::Stop) { + + DTraceConsumer *dtc = Nan::ObjectWrap::Unwrap(info.Holder()); dtrace_hdl_t *dtp = dtc->dtc_handle; - if (dtrace_stop(dtp) == -1) { - return (dtc->error("couldn't disable tracing: %s\n", - dtrace_errmsg(dtp, dtrace_errno(dtp)))); + if (dtrace_stop(dtp) == -1) { // what do I return + // return (dtc->error("couldn't disable tracing: %s\n", + // dtrace_errmsg(dtp, dtrace_errno(dtp)))); } - - return (Undefined()); + info.GetReturnValue().Set(Undefined()); } -Local +v8::Local DTraceConsumer::probedesc(const dtrace_probedesc_t *pd) { - Local probe = Object::New(); - probe->Set(String::New("provider"), String::New(pd->dtpd_provider)); - probe->Set(String::New("module"), String::New(pd->dtpd_mod)); - probe->Set(String::New("function"), String::New(pd->dtpd_func)); - probe->Set(String::New("name"), String::New(pd->dtpd_name)); + v8::Local probe = Nan::New(); + Nan::Set(probe, Nan::New("provider").ToLocalChecked(),Nan::New(pd->dtpd_provider).ToLocalChecked()); + Nan::Set(probe, Nan::New("module").ToLocalChecked(),Nan::New(pd->dtpd_mod).ToLocalChecked()); + Nan::Set(probe, Nan::New("function").ToLocalChecked(),Nan::New(pd->dtpd_func).ToLocalChecked()); + Nan::Set(probe, Nan::New("name").ToLocalChecked(),Nan::New(pd->dtpd_name).ToLocalChecked()); return (probe); } @@ -476,9 +486,10 @@ DTraceConsumer::bufhandler(const dtrace_bufdata_t *bufdata, void *arg) if (rec == NULL || rec->dtrd_action != DTRACEACT_PRINTF) return (DTRACE_HANDLE_OK); - Local probe = dtc->probedesc(data->dtpda_pdesc); - Local record = Object::New(); - record->Set(String::New("data"), String::New(bufdata->dtbda_buffered)); + v8::Local probe = dtc->probedesc(data->dtpda_pdesc); + v8::Local record = Nan::New(); + + Nan::Set(record, Nan::New("data").ToLocalChecked(),Nan::New(bufdata->dtbda_buffered).ToLocalChecked()); Local argv[2] = { probe, record }; dtc->dtc_callback->Call(dtc->dtc_args->This(), 2, argv); @@ -494,11 +505,11 @@ DTraceConsumer::consume(const dtrace_probedata_t *data, dtrace_probedesc_t *pd = data->dtpda_pdesc; Local datum; - Local probe = dtc->probedesc(data->dtpda_pdesc); + v8::Local probe = dtc->probedesc(data->dtpda_pdesc); if (rec == NULL) { - Local argv[1] = { probe }; - dtc->dtc_callback->Call(dtc->dtc_args->This(), 1, argv); + Local info[1] = { probe }; + dtc->dtc_callback->Call(dtc->dtc_args->This(), 1, info); return (DTRACE_CONSUME_NEXT); } @@ -519,35 +530,37 @@ DTraceConsumer::consume(const dtrace_probedata_t *data, return (DTRACE_CONSUME_ABORT); } - Local record = Object::New(); - record->Set(String::New("data"), dtc->record(rec, data->dtpda_data)); - Local argv[2] = { probe, record }; + v8::Local record = Nan::New(); + Nan::Set(record, Nan::New("data").ToLocalChecked(), dtc->record(rec, data->dtpda_data)); - dtc->dtc_callback->Call(dtc->dtc_args->This(), 2, argv); + Local info[2] = { probe, record }; + + dtc->dtc_callback->Call(dtc->dtc_args->This(), 2, info); return (DTRACE_CONSUME_THIS); } -Handle -DTraceConsumer::Consume(const Arguments& args) -{ - DTraceConsumer *dtc = ObjectWrap::Unwrap(args.Holder()); +NAN_METHOD (DTraceConsumer::Consume) { + DTraceConsumer *dtc = Nan::ObjectWrap::Unwrap(info.Holder()); dtrace_hdl_t *dtp = dtc->dtc_handle; dtrace_workstatus_t status; - if (!args[0]->IsFunction()) - return (dtc->badarg("expected function as argument")); + if (!info[0]->IsFunction()){ + // return (dtc->badarg("expected function as argument")); + // Nan::ThrowError() + } - dtc->dtc_callback = Local::Cast(args[0]); - dtc->dtc_args = &args; + dtc->dtc_callback = Local::Cast(info[0]); + dtc->dtc_args = &info; dtc->dtc_error = Null(); status = dtrace_work(dtp, NULL, NULL, DTraceConsumer::consume, dtc); - if (status == -1 && !dtc->dtc_error->IsNull()) - return (dtc->dtc_error); + if (status == -1 && !dtc->dtc_error->IsNull()){ + // return (dtc->dtc_error); + } - return (Undefined()); + info.GetReturnValue().Set(Undefined()); } /* @@ -557,7 +570,7 @@ DTraceConsumer::Consume(const Arguments& args) * may see significant degradations in performance. (If this is a common * case, this cache should clearly be expanded.) */ -Local * +v8::Local * DTraceConsumer::ranges_cached(dtrace_aggvarid_t varid) { if (varid == dtc_ranges_varid) @@ -566,7 +579,7 @@ DTraceConsumer::ranges_cached(dtrace_aggvarid_t varid) return (NULL); } -Local * +v8::Local * DTraceConsumer::ranges_cache(dtrace_aggvarid_t varid, Local *ranges) { if (dtc_ranges != NULL) @@ -578,11 +591,11 @@ DTraceConsumer::ranges_cache(dtrace_aggvarid_t varid, Local *ranges) return (ranges); } -Local * +v8::Local * DTraceConsumer::ranges_quantize(dtrace_aggvarid_t varid) { int64_t min, max; - Local *ranges; + v8::Local *ranges; int i; if ((ranges = ranges_cached(varid)) != NULL) @@ -590,10 +603,10 @@ DTraceConsumer::ranges_quantize(dtrace_aggvarid_t varid) ranges = new Local[DTRACE_QUANTIZE_NBUCKETS]; - for (i = 0; i < DTRACE_QUANTIZE_NBUCKETS; i++) { - ranges[i] = Array::New(2); + for (i = 0; i < (int)DTRACE_QUANTIZE_NBUCKETS; i++) { + ranges[i] = Nan::New(2); - if (i < DTRACE_QUANTIZE_ZEROBUCKET) { + if (i < (int)DTRACE_QUANTIZE_ZEROBUCKET) { /* * If we're less than the zero bucket, our range * extends from negative infinity through to the @@ -606,24 +619,24 @@ DTraceConsumer::ranges_quantize(dtrace_aggvarid_t varid) min = max = 0; } else { min = DTRACE_QUANTIZE_BUCKETVAL(i); - max = i < DTRACE_QUANTIZE_NBUCKETS - 1 ? + max = i < (int)DTRACE_QUANTIZE_NBUCKETS - 1 ? DTRACE_QUANTIZE_BUCKETVAL(i + 1) - 1 : INT64_MAX; } - ranges[i]->Set(0, Number::New(min)); - ranges[i]->Set(1, Number::New(max)); + ranges[i]->Set(0, Nan::New(min)); + ranges[i]->Set(1, Nan::New(max)); } return (ranges_cache(varid, ranges)); } -Local * +v8::Local * DTraceConsumer::ranges_lquantize(dtrace_aggvarid_t varid, const uint64_t arg) { int64_t min, max; - Local *ranges; + v8::Local *ranges; int32_t base; uint16_t step, levels; int i; @@ -638,19 +651,19 @@ DTraceConsumer::ranges_lquantize(dtrace_aggvarid_t varid, ranges = new Local[levels + 2]; for (i = 0; i <= levels + 1; i++) { - ranges[i] = Array::New(2); + ranges[i] = Nan::New(2); min = i == 0 ? INT64_MIN : base + ((i - 1) * step); max = i > levels ? INT64_MAX : base + (i * step) - 1; - ranges[i]->Set(0, Number::New(min)); - ranges[i]->Set(1, Number::New(max)); + ranges[i]->Set(0, Nan::New(min)); + ranges[i]->Set(1, Nan::New(max)); } return (ranges_cache(varid, ranges)); } -Local * +v8::Local * DTraceConsumer::ranges_llquantize(dtrace_aggvarid_t varid, const uint64_t arg, int nbuckets) { @@ -667,23 +680,23 @@ DTraceConsumer::ranges_llquantize(dtrace_aggvarid_t varid, high = DTRACE_LLQUANTIZE_HIGH(arg); nsteps = DTRACE_LLQUANTIZE_NSTEP(arg); - ranges = new Local[nbuckets]; + ranges = new v8::Local[nbuckets]; for (order = 0; order < low; order++) value *= factor; - ranges[bucket] = Array::New(2); - ranges[bucket]->Set(0, Number::New(0)); - ranges[bucket]->Set(1, Number::New(value - 1)); + ranges[bucket] = Nan::New(2); + ranges[bucket]->Set(0, Nan::New(0)); + ranges[bucket]->Set(1, Nan::New(value - 1)); bucket++; next = value * factor; step = next > nsteps ? next / nsteps : 1; while (order <= high) { - ranges[bucket] = Array::New(2); - ranges[bucket]->Set(0, Number::New(value)); - ranges[bucket]->Set(1, Number::New(value + step - 1)); + ranges[bucket] = Nan::New(2); + ranges[bucket]->Set(0, Nan::New(value)); + ranges[bucket]->Set(1, Nan::New(value + step - 1)); bucket++; if ((value += step) != next) @@ -694,9 +707,9 @@ DTraceConsumer::ranges_llquantize(dtrace_aggvarid_t varid, order++; } - ranges[bucket] = Array::New(2); - ranges[bucket]->Set(0, Number::New(value)); - ranges[bucket]->Set(1, Number::New(INT64_MAX)); + ranges[bucket] = Nan::New(2); + ranges[bucket]->Set(0, Nan::New(value)); + ranges[bucket]->Set(1, Nan::New(INT64_MAX)); assert(bucket + 1 == nbuckets); @@ -709,7 +722,8 @@ DTraceConsumer::aggwalk(const dtrace_aggdata_t *agg, void *arg) DTraceConsumer *dtc = (DTraceConsumer *)arg; const dtrace_aggdesc_t *aggdesc = agg->dtada_desc; const dtrace_recdesc_t *aggrec; - Local id = Integer::New(aggdesc->dtagd_varid), val; + Local val; + Local id = Nan::New(aggdesc->dtagd_varid); Local key; char errbuf[256]; int i; @@ -719,7 +733,7 @@ DTraceConsumer::aggwalk(const dtrace_aggdata_t *agg, void *arg) * if we have fewer than two records, something is deeply wrong. */ assert(aggdesc->dtagd_nrecs >= 2); - key = Array::New(aggdesc->dtagd_nrecs - 2); + key = Nan::New(aggdesc->dtagd_nrecs - 2); for (i = 1; i < aggdesc->dtagd_nrecs - 1; i++) { const dtrace_recdesc_t *rec = &aggdesc->dtagd_rec[i]; @@ -747,7 +761,7 @@ DTraceConsumer::aggwalk(const dtrace_aggdata_t *agg, void *arg) caddr_t addr = agg->dtada_data + aggrec->dtrd_offset; assert(aggrec->dtrd_size == sizeof (uint64_t)); - val = Number::New(*((int64_t *)addr)); + val = Nan::New(*((int64_t *)addr)); break; } @@ -756,12 +770,12 @@ DTraceConsumer::aggwalk(const dtrace_aggdata_t *agg, void *arg) aggrec->dtrd_offset); assert(aggrec->dtrd_size == sizeof (uint64_t) * 2); - val = Number::New(data[1] / (double)data[0]); + val = Nan::New(data[1] / (double)data[0]); break; } case DTRACEAGG_QUANTIZE: { - Local quantize = Array::New(); + Local quantize = Nan::New(); const int64_t *data = (int64_t *)(agg->dtada_data + aggrec->dtrd_offset); Local *ranges, datum; @@ -769,13 +783,13 @@ DTraceConsumer::aggwalk(const dtrace_aggdata_t *agg, void *arg) ranges = dtc->ranges_quantize(aggdesc->dtagd_varid); - for (i = 0; i < DTRACE_QUANTIZE_NBUCKETS; i++) { + for (i = 0; i < (int)DTRACE_QUANTIZE_NBUCKETS; i++) { if (!data[i]) continue; - datum = Array::New(2); + datum = Nan::New(2); datum->Set(0, ranges[i]); - datum->Set(1, Number::New(data[i])); + datum->Set(1, Nan::New(data[i])); quantize->Set(j++, datum); } @@ -786,7 +800,7 @@ DTraceConsumer::aggwalk(const dtrace_aggdata_t *agg, void *arg) case DTRACEAGG_LQUANTIZE: case DTRACEAGG_LLQUANTIZE: { - Local lquantize = Array::New(); + Local lquantize = Nan::New(); const int64_t *data = (int64_t *)(agg->dtada_data + aggrec->dtrd_offset); Local *ranges, datum; @@ -803,9 +817,9 @@ DTraceConsumer::aggwalk(const dtrace_aggdata_t *agg, void *arg) if (!data[i]) continue; - datum = Array::New(2); + datum = Nan::New(2); datum->Set(0, ranges[i]); - datum->Set(1, Number::New(data[i])); + datum->Set(1, Nan::New(data[i])); lquantize->Set(j++, datum); } @@ -827,45 +841,43 @@ DTraceConsumer::aggwalk(const dtrace_aggdata_t *agg, void *arg) return (DTRACE_AGGWALK_REMOVE); } -Handle -DTraceConsumer::Aggclear(const Arguments& args) -{ - HandleScope scope; - DTraceConsumer *dtc = ObjectWrap::Unwrap(args.Holder()); +NAN_METHOD (DTraceConsumer::Aggclear) { + + DTraceConsumer *dtc = Nan::ObjectWrap::Unwrap(info.Holder()); dtrace_hdl_t *dtp = dtc->dtc_handle; if (dtrace_status(dtp) == -1) { - return (dtc->error("couldn't get status: %s\n", - dtrace_errmsg(dtp, dtrace_errno(dtp)))); + // return (dtc->error("couldn't get status: %s\n", + // dtrace_errmsg(dtp, dtrace_errno(dtp)))); } dtrace_aggregate_clear(dtp); - return (Undefined()); + info.GetReturnValue().Set(Undefined()); } -Handle -DTraceConsumer::Aggwalk(const Arguments& args) -{ - HandleScope scope; - DTraceConsumer *dtc = ObjectWrap::Unwrap(args.Holder()); + +NAN_METHOD (DTraceConsumer::Aggwalk) { + + DTraceConsumer *dtc = Nan::ObjectWrap::Unwrap(info.Holder()); dtrace_hdl_t *dtp = dtc->dtc_handle; int rval; - if (!args[0]->IsFunction()) - return (dtc->badarg("expected function as argument")); + if (!info[0]->IsFunction()){ + // return (dtc->badarg("expected function as argument")); + } - dtc->dtc_callback = Local::Cast(args[0]); - dtc->dtc_args = &args; + dtc->dtc_callback = Local::Cast(info[0]); + dtc->dtc_args = &info; dtc->dtc_error = Null(); if (dtrace_status(dtp) == -1) { - return (dtc->error("couldn't get status: %s\n", - dtrace_errmsg(dtp, dtrace_errno(dtp)))); + // return (dtc->error("couldn't get status: %s\n", + // dtrace_errmsg(dtp, dtrace_errno(dtp)))); } if (dtrace_aggregate_snap(dtp) == -1) { - return (dtc->error("couldn't snap aggregate: %s\n", - dtrace_errmsg(dtp, dtrace_errno(dtp)))); + // return (dtc->error("couldn't snap aggregate: %s\n", + // dtrace_errmsg(dtp, dtrace_errno(dtp)))); } rval = dtrace_aggregate_walk(dtp, DTraceConsumer::aggwalk, dtc); @@ -878,38 +890,33 @@ DTraceConsumer::Aggwalk(const Arguments& args) dtc->ranges_cache(DTRACE_AGGVARIDNONE, NULL); if (rval == -1) { - if (!dtc->dtc_error->IsNull()) - return (dtc->dtc_error); + if (!dtc->dtc_error->IsNull()){ + // return (dtc->dtc_error); + } - return (dtc->error("couldn't walk aggregate: %s\n", - dtrace_errmsg(dtp, dtrace_errno(dtp)))); + // return (dtc->error("couldn't walk aggregate: %s\n", + // dtrace_errmsg(dtp, dtrace_errno(dtp)))); } - return (Undefined()); + info.GetReturnValue().Set(Undefined()); } -Handle -DTraceConsumer::Aggmin(const Arguments& args) -{ - return (Number::New(INT64_MIN)); +NAN_METHOD (DTraceConsumer::Aggmin) { + info.GetReturnValue().Set(Nan::New(INT64_MIN)); } -Handle -DTraceConsumer::Aggmax(const Arguments& args) -{ - return (Number::New(INT64_MAX)); +NAN_METHOD (DTraceConsumer::Aggmax) { + info.GetReturnValue().Set(Nan::New(INT64_MAX)); } -Handle -DTraceConsumer::Version(const Arguments& args) -{ - return (String::New(_dtrace_version)); +NAN_METHOD (DTraceConsumer::Version) { + info.GetReturnValue().Set(Nan::New(_dtrace_version).ToLocalChecked()); } -extern "C" void -init (Handle target) -{ - DTraceConsumer::Initialize(target); -} +// extern "C" void +// init (Handle target) +// { +// DTraceConsumer::Initialize(target); +// } -NODE_MODULE(dtrace, init); +NODE_MODULE(dtrace, DTraceConsumer::Init); diff --git a/package.json b/package.json index 9724af4..29c4485 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "engines": { "node": ">=0.8" }, "main": "./index.js", "dependencies": { - "bindings": "1.0.0" + "bindings": "1.0.0", + "nan": "^2.6.2" } } From d8e915bea41ca19884b633b8ee9dc7e40ca8f2c5 Mon Sep 17 00:00:00 2001 From: kingloud Date: Mon, 8 May 2017 12:25:05 -0700 Subject: [PATCH 2/5] update persist template --- libdtrace.cc | 65 ++++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/libdtrace.cc b/libdtrace.cc index bb5f632..06e935e 100644 --- a/libdtrace.cc +++ b/libdtrace.cc @@ -80,6 +80,7 @@ class DTraceConsumer : public Nan::ObjectWrap { { + v8::Local dtc = Nan::New(New); dtc->SetClassName(Nan::New("Consumer").ToLocalChecked()); @@ -99,7 +100,8 @@ class DTraceConsumer : public Nan::ObjectWrap { Nan::SetPrototypeMethod(dtc, "aggmax", DTraceConsumer::Aggmax); Nan::SetPrototypeMethod(dtc, "stop", DTraceConsumer::Stop); - constructor().Reset(Nan::GetFunction(dtc).ToLocalChecked()); + dtc_templ.Reset(dtc); + Nan::Set(target, Nan::New("Consumer").ToLocalChecked(), Nan::GetFunction(dtc).ToLocalChecked()); } @@ -110,7 +112,7 @@ class DTraceConsumer : public Nan::ObjectWrap { ~DTraceConsumer(); Handle error(const char *fmt, ...); -// Handle badarg(const char *msg); + Handle badarg(const char *msg); boolean_t valid(const dtrace_recdesc_t *); const char *action(const dtrace_recdesc_t *, char *, int); v8::Local record(const dtrace_recdesc_t *, caddr_t); @@ -158,27 +160,28 @@ class DTraceConsumer : public Nan::ObjectWrap { }; -// Persistent DTraceConsumer::dtc_templ; +Nan::Persistent DTraceConsumer::dtc_templ; DTraceConsumer::DTraceConsumer() : Nan::ObjectWrap() { int err; dtrace_hdl_t *dtp; - if ((dtc_handle = dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) + if ((dtc_handle = dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL){ Nan::ThrowError(Nan::New(dtrace_errmsg(NULL, err)).ToLocalChecked()); - - /* - * Set our buffer size and aggregation buffer size to the de facto - * standard of 4M. - */ - (void) dtrace_setopt(dtp, "bufsize", "4m"); - (void) dtrace_setopt(dtp, "aggsize", "4m"); + }else{ + /* + * Set our buffer size and aggregation buffer size to the de facto + * standard of 4M. + */ + (void) dtrace_setopt(dtp, "bufsize", "4m"); + (void) dtrace_setopt(dtp, "aggsize", "4m"); - if (dtrace_handle_buffered(dtp, DTraceConsumer::bufhandler, this) == -1) - throw (dtrace_errmsg(dtp, dtrace_errno(dtp))); + if (dtrace_handle_buffered(dtp, DTraceConsumer::bufhandler, this) == -1) + throw (dtrace_errmsg(dtp, dtrace_errno(dtp))); - dtc_ranges = NULL; + dtc_ranges = NULL; + } }; DTraceConsumer::~DTraceConsumer() @@ -192,7 +195,6 @@ DTraceConsumer::~DTraceConsumer() NAN_METHOD (DTraceConsumer::New) { DTraceConsumer *dtc; - try { dtc = new DTraceConsumer(); dtc->Wrap(info.This()); @@ -200,7 +202,6 @@ NAN_METHOD (DTraceConsumer::New) { } catch (char const *msg) { Nan::ThrowError(Nan::New(msg).ToLocalChecked()); - // return (ThrowException(Exception::Error(String::New(msg)))); // how to throw errors now? } } @@ -276,15 +277,15 @@ DTraceConsumer::error(const char *fmt, ...) } else { buf[strlen(buf) - 1] = '\0'; } - - // return (ThrowException(Nan::Error(Nan::New(err)))); + + Nan::ThrowError(Nan::New(err).ToLocalChecked()); } -// Handle -// DTraceConsumer::badarg(const char *msg) -// { -// return (ThrowException(Exception::TypeError(String::New(msg)))); -// } +Handle +DTraceConsumer::badarg(const char *msg) +{ + Nan::ThrowTypeError(Nan::New(msg).ToLocalChecked()); +} boolean_t DTraceConsumer::valid(const dtrace_recdesc_t *rec) @@ -399,7 +400,7 @@ NAN_METHOD (DTraceConsumer::Strcompile) { // dtrace_errmsg(dtp, dtrace_errno(dtp)))); } - info.GetReturnValue().Set(Undefined()); + info.GetReturnValue().Set(Nan::Undefined()); } @@ -437,7 +438,7 @@ NAN_METHOD (DTraceConsumer::Setopt) { // dtrace_errmsg(dtp, dtrace_errno(dtp)))); } - info.GetReturnValue().Set(Undefined()); + info.GetReturnValue().Set(Nan::Undefined()); } NAN_METHOD (DTraceConsumer::Go) { @@ -449,7 +450,7 @@ NAN_METHOD (DTraceConsumer::Go) { // dtrace_errmsg(dtp, dtrace_errno(dtp)))); } - info.GetReturnValue().Set(Undefined()); + info.GetReturnValue().Set(Nan::Undefined()); } NAN_METHOD (DTraceConsumer::Stop) { @@ -461,7 +462,7 @@ NAN_METHOD (DTraceConsumer::Stop) { // return (dtc->error("couldn't disable tracing: %s\n", // dtrace_errmsg(dtp, dtrace_errno(dtp)))); } - info.GetReturnValue().Set(Undefined()); + info.GetReturnValue().Set(Nan::Undefined()); } v8::Local @@ -552,7 +553,7 @@ NAN_METHOD (DTraceConsumer::Consume) { dtc->dtc_callback = Local::Cast(info[0]); dtc->dtc_args = &info; - dtc->dtc_error = Null(); + dtc->dtc_error = Nan::Null(); status = dtrace_work(dtp, NULL, NULL, DTraceConsumer::consume, dtc); @@ -560,7 +561,7 @@ NAN_METHOD (DTraceConsumer::Consume) { // return (dtc->dtc_error); } - info.GetReturnValue().Set(Undefined()); + info.GetReturnValue().Set(Nan::Undefined()); } /* @@ -852,7 +853,7 @@ NAN_METHOD (DTraceConsumer::Aggclear) { } dtrace_aggregate_clear(dtp); - info.GetReturnValue().Set(Undefined()); + info.GetReturnValue().Set(Nan::Undefined()); } @@ -868,7 +869,7 @@ NAN_METHOD (DTraceConsumer::Aggwalk) { dtc->dtc_callback = Local::Cast(info[0]); dtc->dtc_args = &info; - dtc->dtc_error = Null(); + dtc->dtc_error = Nan::Null(); if (dtrace_status(dtp) == -1) { // return (dtc->error("couldn't get status: %s\n", @@ -898,7 +899,7 @@ NAN_METHOD (DTraceConsumer::Aggwalk) { // dtrace_errmsg(dtp, dtrace_errno(dtp)))); } - info.GetReturnValue().Set(Undefined()); + info.GetReturnValue().Set(Nan::Undefined()); } NAN_METHOD (DTraceConsumer::Aggmin) { From 02fdf18005df3d4a796618f4399b89ef029f6cd2 Mon Sep 17 00:00:00 2001 From: kingloud Date: Mon, 8 May 2017 15:22:28 -0700 Subject: [PATCH 3/5] taking a stab at returning error types --- libdtrace.cc | 207 ++++++++++++++++++++++++--------------------------- 1 file changed, 99 insertions(+), 108 deletions(-) diff --git a/libdtrace.cc b/libdtrace.cc index 06e935e..edb639a 100644 --- a/libdtrace.cc +++ b/libdtrace.cc @@ -111,8 +111,8 @@ class DTraceConsumer : public Nan::ObjectWrap { DTraceConsumer(); ~DTraceConsumer(); - Handle error(const char *fmt, ...); - Handle badarg(const char *msg); + v8::Local error(const char *fmt, ...); + v8::Local badarg(const char *msg); boolean_t valid(const dtrace_recdesc_t *); const char *action(const dtrace_recdesc_t *, char *, int); v8::Local record(const dtrace_recdesc_t *, caddr_t); @@ -257,7 +257,7 @@ DTraceConsumer::action(const dtrace_recdesc_t *rec, char *buf, int size) return (buf); } -Handle +v8::Local DTraceConsumer::error(const char *fmt, ...) { char buf[1024], buf2[1024]; @@ -278,13 +278,13 @@ DTraceConsumer::error(const char *fmt, ...) buf[strlen(buf) - 1] = '\0'; } - Nan::ThrowError(Nan::New(err).ToLocalChecked()); + return Nan::Error(err); } -Handle +v8::Local DTraceConsumer::badarg(const char *msg) { - Nan::ThrowTypeError(Nan::New(msg).ToLocalChecked()); + return Nan::TypeError(msg); } boolean_t @@ -384,23 +384,22 @@ NAN_METHOD (DTraceConsumer::Strcompile) { dtrace_proginfo_t dinfo; if (info.Length() < 1 || !info[0]->IsString()){ - // return (dtc->badarg("expected program")); - } - - String::Utf8Value program(info[0]->ToString()); - - if ((dp = dtrace_program_strcompile(dtp, *program, - DTRACE_PROBESPEC_NAME, 0, 0, NULL)) == NULL) { - // return (dtc->error("couldn't compile '%s': %s\n", *program, - // dtrace_errmsg(dtp, dtrace_errno(dtp)))); - } + Nan::ThrowError(dtc->badarg("expected program")); + }else{ - if (dtrace_program_exec(dtp, dp, &dinfo) == -1) { - // return (dtc->error("couldn't execute '%s': %s\n", *program, - // dtrace_errmsg(dtp, dtrace_errno(dtp)))); + String::Utf8Value program(info[0]->ToString()); + + if ((dp = dtrace_program_strcompile(dtp, *program, + DTRACE_PROBESPEC_NAME, 0, 0, NULL)) == NULL) { + Nan::ThrowError(dtc->error("couldn't compile '%s': %s\n", *program, + dtrace_errmsg(dtp, dtrace_errno(dtp)))); + } else if (dtrace_program_exec(dtp, dp, &dinfo) == -1) { + Nan::ThrowError(dtc->error("couldn't execute '%s': %s\n", *program, + dtrace_errmsg(dtp, dtrace_errno(dtp)))); + }else{ + info.GetReturnValue().Set(Nan::Undefined()); + } } - - info.GetReturnValue().Set(Nan::Undefined()); } @@ -412,45 +411,43 @@ NAN_METHOD (DTraceConsumer::Setopt) { int rval; if (info.Length() < 1 || !info[0]->IsString()){ - // return (dtc->badarg("expected an option to set")); - return; - } - - String::Utf8Value option(info[0]->ToString()); - - if (info.Length() >= 2) { - if (info[1]->IsArray()){ - // return (dtc->badarg("option value can't be an array")); + Nan::ThrowError(dtc->badarg("expected an option to set")); + }else{ + String::Utf8Value option(info[0]->ToString()); + + if (info.Length() >= 2) { + if (info[1]->IsArray()){ + Nan::ThrowError(dtc->badarg("option value can't be an array")); + }else if (info[1]->IsObject()){ + Nan::ThrowError(dtc->badarg("option value can't be an object")); + }else{ + String::Utf8Value optval(info[1]->ToString()); + rval = dtrace_setopt(dtp, *option, *optval); + } + } else { + rval = dtrace_setopt(dtp, *option, NULL); } - if (info[1]->IsObject()){ - // return (dtc->badarg("option value can't be an object")); + if (rval != 0) { + Nan::ThrowError(dtc->error("couldn't set option '%s': %s\n", *option, + dtrace_errmsg(dtp, dtrace_errno(dtp)))); + }else{ + info.GetReturnValue().Set(Nan::Undefined()); } - - String::Utf8Value optval(info[1]->ToString()); - rval = dtrace_setopt(dtp, *option, *optval); - } else { - rval = dtrace_setopt(dtp, *option, NULL); - } - - if (rval != 0) { - // return (dtc->error("couldn't set option '%s': %s\n", *option, - // dtrace_errmsg(dtp, dtrace_errno(dtp)))); } - - info.GetReturnValue().Set(Nan::Undefined()); } NAN_METHOD (DTraceConsumer::Go) { DTraceConsumer *dtc = Nan::ObjectWrap::Unwrap(info.Holder()); dtrace_hdl_t *dtp = dtc->dtc_handle; - if (dtrace_go(dtp) == -1) { - // return (dtc->error("couldn't enable tracing: %s\n", - // dtrace_errmsg(dtp, dtrace_errno(dtp)))); + if (dtrace_go(dtp) == -1){ + Nan::ThrowError(dtc->error("couldn't enable tracing: %s\n", + dtrace_errmsg(dtp, dtrace_errno(dtp)))); + }else{ + info.GetReturnValue().Set(Nan::Undefined()); } - - info.GetReturnValue().Set(Nan::Undefined()); + } NAN_METHOD (DTraceConsumer::Stop) { @@ -458,11 +455,13 @@ NAN_METHOD (DTraceConsumer::Stop) { DTraceConsumer *dtc = Nan::ObjectWrap::Unwrap(info.Holder()); dtrace_hdl_t *dtp = dtc->dtc_handle; - if (dtrace_stop(dtp) == -1) { // what do I return - // return (dtc->error("couldn't disable tracing: %s\n", - // dtrace_errmsg(dtp, dtrace_errno(dtp)))); + if (dtrace_stop(dtp) == -1) { + Nan::ThrowError(dtc->error("couldn't disable tracing: %s\n", + dtrace_errmsg(dtp, dtrace_errno(dtp)))); + }else{ + info.GetReturnValue().Set(Nan::Undefined()); } - info.GetReturnValue().Set(Nan::Undefined()); + } v8::Local @@ -547,21 +546,20 @@ NAN_METHOD (DTraceConsumer::Consume) { dtrace_workstatus_t status; if (!info[0]->IsFunction()){ - // return (dtc->badarg("expected function as argument")); - // Nan::ThrowError() - } - - dtc->dtc_callback = Local::Cast(info[0]); - dtc->dtc_args = &info; - dtc->dtc_error = Nan::Null(); + Nan::ThrowError(dtc->badarg("expected function as argument")); + }else{ + dtc->dtc_callback = Local::Cast(info[0]); + dtc->dtc_args = &info; + dtc->dtc_error = Nan::Null(); - status = dtrace_work(dtp, NULL, NULL, DTraceConsumer::consume, dtc); + status = dtrace_work(dtp, NULL, NULL, DTraceConsumer::consume, dtc); - if (status == -1 && !dtc->dtc_error->IsNull()){ - // return (dtc->dtc_error); + if (status == -1 && !dtc->dtc_error->IsNull()){ + Nan::ThrowError(dtc->dtc_error); + }else{ + info.GetReturnValue().Set(Nan::Undefined()); + } } - - info.GetReturnValue().Set(Nan::Undefined()); } /* @@ -848,12 +846,12 @@ NAN_METHOD (DTraceConsumer::Aggclear) { dtrace_hdl_t *dtp = dtc->dtc_handle; if (dtrace_status(dtp) == -1) { - // return (dtc->error("couldn't get status: %s\n", - // dtrace_errmsg(dtp, dtrace_errno(dtp)))); - } - - dtrace_aggregate_clear(dtp); - info.GetReturnValue().Set(Nan::Undefined()); + Nan::ThrowError(dtc->error("couldn't get status: %s\n", + dtrace_errmsg(dtp, dtrace_errno(dtp)))); + }else{ + dtrace_aggregate_clear(dtp); + info.GetReturnValue().Set(Nan::Undefined()); + } } @@ -864,42 +862,41 @@ NAN_METHOD (DTraceConsumer::Aggwalk) { int rval; if (!info[0]->IsFunction()){ - // return (dtc->badarg("expected function as argument")); - } - - dtc->dtc_callback = Local::Cast(info[0]); - dtc->dtc_args = &info; - dtc->dtc_error = Nan::Null(); - - if (dtrace_status(dtp) == -1) { - // return (dtc->error("couldn't get status: %s\n", - // dtrace_errmsg(dtp, dtrace_errno(dtp)))); - } - - if (dtrace_aggregate_snap(dtp) == -1) { - // return (dtc->error("couldn't snap aggregate: %s\n", - // dtrace_errmsg(dtp, dtrace_errno(dtp)))); - } + Nan::ThrowError(dtc->badarg("expected function as argument")); + }else{ - rval = dtrace_aggregate_walk(dtp, DTraceConsumer::aggwalk, dtc); + dtc->dtc_callback = Local::Cast(info[0]); + dtc->dtc_args = &info; + dtc->dtc_error = Nan::Null(); - /* - * Flush the ranges cache; the ranges will go out of scope when the - * destructor for our HandleScope is called, and we cannot be left - * holding references. - */ - dtc->ranges_cache(DTRACE_AGGVARIDNONE, NULL); + if (dtrace_status(dtp) == -1) { + Nan::ThrowError(dtc->error("couldn't get status: %s\n", + dtrace_errmsg(dtp, dtrace_errno(dtp)))); + }else if (dtrace_aggregate_snap(dtp) == -1) { + Nan::ThrowError(dtc->error("couldn't snap aggregate: %s\n", + dtrace_errmsg(dtp, dtrace_errno(dtp)))); + }else{ + rval = dtrace_aggregate_walk(dtp, DTraceConsumer::aggwalk, dtc); - if (rval == -1) { - if (!dtc->dtc_error->IsNull()){ - // return (dtc->dtc_error); + /* + * Flush the ranges cache; the ranges will go out of scope when the + * destructor for our HandleScope is called, and we cannot be left + * holding references. + */ + dtc->ranges_cache(DTRACE_AGGVARIDNONE, NULL); + + if (rval == -1) { + if (!dtc->dtc_error->IsNull()){ + Nan::ThrowError(dtc->dtc_error); + } + + Nan::ThrowError(dtc->error("couldn't walk aggregate: %s\n", + dtrace_errmsg(dtp, dtrace_errno(dtp)))); + }else{ + info.GetReturnValue().Set(Nan::Undefined()); + } } - - // return (dtc->error("couldn't walk aggregate: %s\n", - // dtrace_errmsg(dtp, dtrace_errno(dtp)))); } - - info.GetReturnValue().Set(Nan::Undefined()); } NAN_METHOD (DTraceConsumer::Aggmin) { @@ -914,10 +911,4 @@ NAN_METHOD (DTraceConsumer::Version) { info.GetReturnValue().Set(Nan::New(_dtrace_version).ToLocalChecked()); } -// extern "C" void -// init (Handle target) -// { -// DTraceConsumer::Initialize(target); -// } - NODE_MODULE(dtrace, DTraceConsumer::Init); From 6b2c6f820d562c5fa5c565b1d7ad5c3aed270b05 Mon Sep 17 00:00:00 2001 From: kingloud Date: Mon, 8 May 2017 16:27:29 -0700 Subject: [PATCH 4/5] missed one --- libdtrace.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libdtrace.cc b/libdtrace.cc index edb639a..3684657 100644 --- a/libdtrace.cc +++ b/libdtrace.cc @@ -147,7 +147,7 @@ class DTraceConsumer : public Nan::ObjectWrap { static Nan::Persistent dtc_templ; const Nan::FunctionCallbackInfo *dtc_args; Local dtc_callback; - Handle dtc_error; + v8::Local dtc_error; Local *dtc_ranges; dtrace_aggvarid_t dtc_ranges_varid; From e2769770e1e921750ec929a5e6d6b6303be41fb8 Mon Sep 17 00:00:00 2001 From: Anton Whalley Date: Fri, 22 Sep 2017 12:34:36 +0100 Subject: [PATCH 5/5] FreeBSD support --- binding.gyp | 19 ++++++++++++++++--- libdtrace.cc | 6 +++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/binding.gyp b/binding.gyp index 831731f..c509743 100644 --- a/binding.gyp +++ b/binding.gyp @@ -6,9 +6,22 @@ 'ldflags': ['-ldtrace'], 'sources': [ 'libdtrace.cc' - ], - "include_dirs" : [" #include #include - /* * Sadly, libelf refuses to compile if _FILE_OFFSET_BITS has been manually * jacked to 64 on a 32-bit compile. In this case, we just manually set it @@ -25,7 +24,6 @@ #undef _FILE_OFFSET_BITS #define _FILE_OFFSET_BITS 32 #endif - #include /* @@ -71,7 +69,9 @@ using namespace v8; using std::string; using std::vector; - +#if __FreeBSD__ +typedef enum { B_FALSE, B_TRUE } boolean_t; +#endif class DTraceConsumer : public Nan::ObjectWrap { public: