diff --git a/src/nodeutil.h b/src/nodeutil.h new file mode 100644 index 0000000..d8b9a6f --- /dev/null +++ b/src/nodeutil.h @@ -0,0 +1,59 @@ +#pragma once + +#define BUILDING_NODE_EXTENSION +#include +#include +#include + +/* ****************************************************** + * exception utilities + */ +#define THROW_TYPE_ERROR(str) \ + ThrowException(Exception::TypeError(String::New(str))) + +/* ****************************************************** + * Argument utilities. + */ +#define ARG_EXT(I, VAR) \ + if (args.Length() <= (I) || !args[I]->IsExternal()) \ + return ThrowException(Exception::TypeError( \ + String::New("Argument " #I " must be an external"))); \ + Local VAR = Local::Cast(args[I]); + +/** + * ARG_STR(0, src); + * + * see http://blog.64p.org/entry/2012/09/02/101609 + */ +#define ARG_STR(I, VAR) \ + if (args.Length() <= (I)) \ + return ThrowException(Exception::TypeError( \ + String::New("Argument " #I " must be a string"))); \ + String::Utf8Value VAR(args[I]->ToString()); + +#define ARG_OBJ(I, VAR) \ + if (args.Length() <= (I) || !args[I]->IsObject()) \ + return ThrowException(Exception::TypeError( \ + String::New("Argument " #I " must be a object"))); \ + Local VAR = Local::Cast(args[I]); + +#define ARG_INT(I, VAR) \ + if (args.Length() <= (I) || !args[I]->IsInt32()) \ + return ThrowException(Exception::TypeError( \ + String::New("Argument " #I " must be an integer"))); \ + int32_t VAR = args[I]->Int32Value(); + +#define ARG_BUF(I, VAR) \ + if (args.Length() <= (I) || !Buffer::HasInstance(args[I])) \ + return ThrowException(Exception::TypeError( \ + String::New("Argument " #I " must be an Buffer"))); \ + void * VAR = Buffer::Data(args[I]->ToObject()); + +/* ****************************************************** + * Class construction utilities + */ +#define SET_ENUM_VALUE(target, _value) \ + target->Set(String::NewSymbol(#_value), \ + Integer::New(_value), \ + static_cast(ReadOnly|DontDelete)) + diff --git a/src/perl_bindings.cc b/src/perl_bindings.cc index 76c7a87..70c812c 100644 --- a/src/perl_bindings.cc +++ b/src/perl_bindings.cc @@ -1,7 +1,5 @@ -#define BUILDING_NODE_EXTENSION +#include "nodeutil.h" - -#include #include #include #include @@ -24,27 +22,8 @@ using namespace v8; using namespace node; #define INTERPRETER_NAME "node-perl-simple" -#define THR_TYPE_ERROR(str) \ - ThrowException(Exception::TypeError(String::New(str))) -#define REQ_EXT_ARG(I, VAR) \ -if (args.Length() <= (I) || !args[I]->IsExternal()) \ -return ThrowException(Exception::TypeError( \ -String::New("Argument " #I " must be an external"))); \ -Local VAR = Local::Cast(args[I]); -#define REQ_STR_ARG(I, VAR) \ -if (args.Length() <= (I) || !args[I]->IsString()) \ -return ThrowException(Exception::TypeError( \ -String::New("Argument " #I " must be a string"))); \ -String::Utf8Value VAR(args[I]->ToString()); - -#define REQ_OBJ_ARG(I, VAR) \ -if (args.Length() <= (I) || !args[I]->IsObject()) \ -return ThrowException(Exception::TypeError( \ -String::New("Argument " #I " must be a object"))); \ -Local VAR = Local::Cast(args[I]); // TODO: pass the NodePerlObject to perl5 world. -// TODO: blessed() function class PerlFoo { protected: @@ -84,7 +63,7 @@ class PerlFoo { SV* js2perl(Handle val) const; Handle CallMethod2(const Arguments& args, bool in_list_context) { - REQ_STR_ARG(0, method); + ARG_STR(0, method); return this->CallMethod2(NULL, *method, 1, args, in_list_context); } Handle CallMethod2(SV * self, const char *method, int offset, const Arguments& args, bool in_list_context) { @@ -194,9 +173,9 @@ class NodePerlMethod: ObjectWrap, PerlFoo { if (!args.IsConstructCall()) return args.Callee()->NewInstance(); - REQ_EXT_ARG(0, jssv); - REQ_EXT_ARG(1, jsmyp); - REQ_STR_ARG(2, jsname); + ARG_EXT(0, jssv); + ARG_EXT(1, jsmyp); + ARG_STR(2, jsname); SV* sv = static_cast(jssv->Value()); PerlInterpreter* myp = static_cast(jsmyp->Value()); (new NodePerlMethod(sv, *jsname, myp))->Wrap(args.Holder()); @@ -242,7 +221,7 @@ class NodePerlObject: protected ObjectWrap, protected PerlFoo { HandleScope scope; if (info.This()->InternalFieldCount() < 1 || info.Data().IsEmpty()) { - return THR_TYPE_ERROR("SetNamedProperty intercepted " + return THROW_TYPE_ERROR("SetNamedProperty intercepted " "by non-Proxy object"); } @@ -301,8 +280,8 @@ class NodePerlObject: protected ObjectWrap, protected PerlFoo { if (!args.IsConstructCall()) return args.Callee()->NewInstance(); - REQ_EXT_ARG(0, jssv); - REQ_EXT_ARG(1, jsmyp); + ARG_EXT(0, jssv); + ARG_EXT(1, jsmyp); SV* sv = static_cast(jssv->Value()); PerlInterpreter* myp = static_cast(jsmyp->Value()); (new NodePerlObject(sv, myp))->Wrap(args.Holder()); @@ -376,7 +355,7 @@ class NodePerl: ObjectWrap, PerlFoo { static Handle blessed(const Arguments& args) { HandleScope scope; - REQ_OBJ_ARG(0, jsobj); + ARG_OBJ(0, jsobj); if (NodePerlObject::constructor_template->HasInstance(jsobj)) { return scope.Close(NodePerlObject::blessed(jsobj)); @@ -557,8 +536,6 @@ static Handle InitPerl(const Arguments& args) { } extern "C" void init(Handle target) { - HandleScope scope; - { Handle t = FunctionTemplate::New(InitPerl); target->Set(String::New("InitPerl"), t->GetFunction());