111 lines
2.9 KiB
C++
111 lines
2.9 KiB
C++
#include "dtrace_provider.h"
|
|
#include <nan.h>
|
|
|
|
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<FunctionTemplate> DTraceProbe::constructor_template;
|
|
|
|
void DTraceProbe::Initialize(v8::Local<Object> target) {
|
|
Nan::HandleScope scope;
|
|
|
|
Local<FunctionTemplate> t = Nan::New<FunctionTemplate>(DTraceProbe::New);
|
|
t->InstanceTemplate()->SetInternalFieldCount(2);
|
|
t->SetClassName(Nan::New<String>("DTraceProbe").ToLocalChecked());
|
|
constructor_template.Reset(t);
|
|
|
|
Nan::SetPrototypeMethod(t, "fire", DTraceProbe::Fire);
|
|
|
|
target->Set(Nan::New<String>("DTraceProbe").ToLocalChecked(), Nan::GetFunction(t).ToLocalChecked());
|
|
}
|
|
|
|
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<DTraceProbe>(info.Holder());
|
|
info.GetReturnValue().Set(pd->_fire(info, 0));
|
|
}
|
|
|
|
v8::Local<Value> 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<Value> *cbargs = new Local<Value>[cblen];
|
|
|
|
for (size_t i = 0; i < cblen; i++) {
|
|
cbargs[i] = argsinfo[i + fnidx + 1];
|
|
}
|
|
|
|
Local<Function> cb = Local<Function>::Cast(argsinfo[fnidx]);
|
|
Nan::MaybeLocal<Value> maybe = Nan::Call(cb, this->handle(), cblen, cbargs);
|
|
if (maybe.IsEmpty()) {
|
|
Nan::ThrowTypeError("Failed to invoke fire callback");
|
|
return Nan::Undefined();
|
|
}
|
|
Local<Value> probe_args = maybe.ToLocalChecked();
|
|
|
|
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<Array> a = Local<Array>::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
|