#include #include using namespace v8; #define ARRAY String::NewSymbol("array") #define BOOLEAN String::NewSymbol("boolean") #define BOOLEAN_OBJECT String::NewSymbol("boolean_object") #define DATE String::NewSymbol("date") #define FUNCTION String::NewSymbol("function") #define NUMBER String::NewSymbol("number") #define NUMBER_OBJECT String::NewSymbol("number_object") #define REGEXP String::NewSymbol("regexp") #define STRING String::NewSymbol("string") #define STRING_OBJECT String::NewSymbol("string_object") #define OBJECT String::NewSymbol("object") #define UNDEFINED String::NewSymbol("undefined") #define NULL_TYPE String::NewSymbol("null") #define PRIMITIVE String::NewSymbol("primitive") Handle v8type_of(const Arguments& args){ HandleScope scope; if(args.Length() < 1){ ThrowException(Exception::TypeError(String::New("v8type.of function requires at least 1 argument"))); return scope.Close(Undefined()); } if(args[0]->IsArray()){ return scope.Close(ARRAY); } else if(args[0]->IsBoolean()){ return scope.Close(BOOLEAN); } else if(args[0]->IsBooleanObject()){ return scope.Close(BOOLEAN_OBJECT); } else if(args[0]->IsDate()){ return scope.Close(DATE); } else if(args[0]->IsFunction()){ return scope.Close(FUNCTION); } else if(args[0]->IsNumber()){ return scope.Close(NUMBER); } else if(args[0]->IsNumberObject()){ return scope.Close(NUMBER_OBJECT); } else if(args[0]->IsString()){ return scope.Close(STRING); } else if(args[0]->IsStringObject()){ return scope.Close(STRING_OBJECT); } else if(args[0]->IsRegExp()){ return scope.Close(REGEXP); } else if(args[0]->IsUndefined()){ return scope.Close(UNDEFINED); } else if(args[0]->IsNull()){ return scope.Close(NULL_TYPE); } else if(args[0]->IsObject()){ return scope.Close(OBJECT); } return scope.Close(Undefined()); } Handle v8type_is(const Arguments& args){ HandleScope scope; if(args.Length() < 2){ ThrowException(Exception::TypeError(String::New("v8type.is function requires at least 2 arguments"))); return scope.Close(Undefined()); } if(!args[1]->IsString()){ ThrowException(Exception::TypeError(String::New("v8type.is second argument must be a string"))); return scope.Close(Undefined()); } Handle context = Context::New(); Context::Scope context_scope(context); Handle arguments[] = { args[0] }; Handle type = FunctionTemplate::New(v8type_of)->GetFunction()->Call(context->Global(), 1, arguments); return scope.Close(Boolean::New(args[1] == type)); } Handle v8type_instance(const Arguments& args){ HandleScope scope; if(args.Length() < 2){ ThrowException(Exception::TypeError(String::New("v8type.instance function requires at least 2 arguments"))); return scope.Close(Undefined()); } if(!args[1]->IsString()){ ThrowException(Exception::TypeError(String::New("v8type.instance second argument must be a string"))); return scope.Close(Undefined()); } Handle context = Context::New(); Context::Scope context_scope(context); Handle arguments[] = { args[0] }; Handle type = FunctionTemplate::New(v8type_of)->GetFunction()->Call(context->Global(), 1, arguments); if(args[1] == type){ return scope.Close(Boolean::New(true)); } if(args[1]->ToString() == OBJECT){ if(type == ARRAY or type == FUNCTION or type == DATE or type == REGEXP or type == STRING_OBJECT or type == BOOLEAN_OBJECT or type == NUMBER_OBJECT){ return scope.Close(Boolean::New(true)); } } else if(args[1]->ToString() == PRIMITIVE){ if(type == NUMBER or type == BOOLEAN or type == STRING){ return scope.Close(Boolean::New(true)); } } else if(args[1]->ToString() == NUMBER and type == NUMBER_OBJECT){ return scope.Close(Boolean::New(true)); } else if(args[1]->ToString() == STRING and type == STRING_OBJECT){ return scope.Close(Boolean::New(true)); } else if(args[1]->ToString() == BOOLEAN and type == BOOLEAN_OBJECT){ return scope.Close(Boolean::New(true)); } return scope.Close(Boolean::New(false)); } void init_constants(Handle target){ target->Set(String::NewSymbol("ARRAY"), ARRAY); target->Set(String::NewSymbol("BOOLEAN"), BOOLEAN); target->Set(String::NewSymbol("BOOLEAN_OBJECT"), BOOLEAN_OBJECT); target->Set(String::NewSymbol("DATE"), DATE); target->Set(String::NewSymbol("FUNCTION"), FUNCTION); target->Set(String::NewSymbol("NUMBER"), NUMBER); target->Set(String::NewSymbol("NUMBER_OBJECT"), NUMBER_OBJECT); target->Set(String::NewSymbol("REGEXP"), REGEXP); target->Set(String::NewSymbol("STRING"), STRING); target->Set(String::NewSymbol("STRING_OBJECT"), STRING_OBJECT); target->Set(String::NewSymbol("OBJECT"), OBJECT); target->Set(String::NewSymbol("UNDEFINED"), UNDEFINED); target->Set(String::NewSymbol("NULL"), NULL_TYPE); target->Set(String::NewSymbol("PRIMITIVE"), PRIMITIVE); } void init_v8type_of(Handle target){ target->Set(String::NewSymbol("of"), FunctionTemplate::New(v8type_of)->GetFunction()); } void init_v8type_is(Handle target){ target->Set(String::NewSymbol("is"), FunctionTemplate::New(v8type_is)->GetFunction()); } void init_v8type_instance(Handle target){ target->Set(String::NewSymbol("instance"), FunctionTemplate::New(v8type_instance)->GetFunction()); } void init(Handle target){ init_constants(target); init_v8type_of(target); init_v8type_is(target); init_v8type_instance(target); } NODE_MODULE(v8type, init);