#include "dtrace_provider.h" #include namespace node { using namespace v8; DTraceProbe::DTraceProbe() : Nan::ObjectWrap() { argc = 0; probedef = NULL; } DTraceProbe::~DTraceProbe() { for (size_t i = 0; i < argc; i++) delete(this->arguments[i]); usdt_probe_release(probedef); } Nan::Persistent DTraceProbe::constructor_template; void DTraceProbe::Initialize(v8::Local target) { Nan::HandleScope scope; Local t = Nan::New(DTraceProbe::New); t->InstanceTemplate()->SetInternalFieldCount(1); t->SetClassName(Nan::New("DTraceProbe").ToLocalChecked()); constructor_template.Reset(t); Nan::SetPrototypeMethod(t, "fire", DTraceProbe::Fire); target->Set(Nan::New("DTraceProbe").ToLocalChecked(), t->GetFunction()); } NAN_METHOD(DTraceProbe::New) { Nan::HandleScope scope; DTraceProbe *probe = new DTraceProbe(); probe->Wrap(info.This()); info.GetReturnValue().Set(info.This()); } NAN_METHOD(DTraceProbe::Fire) { Nan::HandleScope scope; if (!info[0]->IsFunction()) { Nan::ThrowTypeError("Must give probe value callback as first argument"); return; } DTraceProbe *pd = Nan::ObjectWrap::Unwrap(info.Holder()); info.GetReturnValue().Set(pd->_fire(info, 0)); } v8::Local DTraceProbe::_fire(Nan::NAN_METHOD_ARGS_TYPE argsinfo, size_t fnidx) { Nan::HandleScope scope; if (usdt_is_enabled(this->probedef->probe) == 0) { return Nan::Undefined(); } // invoke fire callback Nan::TryCatch try_catch; size_t cblen = argsinfo.Length() - fnidx - 1; Local *cbargs = new Local[cblen]; for (size_t i = 0; i < cblen; i++) { cbargs[i] = argsinfo[i + fnidx + 1]; } Local cb = Local::Cast(argsinfo[fnidx]); Local probe_args = cb->Call(this->handle(), cblen, cbargs); delete [] cbargs; // exception in args callback? if (try_catch.HasCaught()) { Nan::FatalException(try_catch); return Nan::Undefined(); } // check return if (!probe_args->IsArray()) { return Nan::Undefined(); } Local a = Local::Cast(probe_args); void *argv[USDT_ARG_MAX]; // convert each argument value for (size_t i = 0; i < argc; i++) { argv[i] = this->arguments[i]->ArgumentValue(a->Get(i)); } // finally fire the probe usdt_fire_probe(this->probedef->probe, argc, argv); // free argument values for (size_t i = 0; i < argc; i++) { this->arguments[i]->FreeArgument(argv[i]); } return Nan::True(); } } // namespace node