// ---------------------------------------------------------------------------- // Project : K7 - Standard Library for V8 // ----------------------------------------------------------------------------- // Author : Sebastien Pierre // and modified by tokuhirom // ---------------------------------------------------------------------------- // Creation date : 27-Sep-2008 // Last modification : 27-Sep-2008 // ---------------------------------------------------------------------------- #ifndef __K7_MACROS__ #define __K7_MACROS__ #include #include #include /** * These macros are just shorthand to creat V8/JavaScript values that can be * passed to the V8 API or returned to the JavaScript environment */ #define JS_str(s) v8::String::New(s) #define JS_int(s) v8::Integer::New(s) #define JS_undefined v8::Undefined() #define JSOBJ_set(target,slot,value) target->Set(JS_str(slot),value) #define V8_FT(f) v8::FunctionTemplate::New(f) /** * This set of macro make it easy to declare a function that can be exported to * the JavaScript environment. * See the 'posix.cpp' module for examples. */ #define FUNCTION(f) static v8::Handle f(const v8::Arguments& args) { v8::HandleScope handlescope; #define FUNCTION_C(f) static v8::Handle f(const v8::Arguments& args) { #ifdef _MSC_VER # define __func__ __FUNCTION__ #endif #define ARG_COUNT(c) do { \ if (args.Length() != c) { \ std::ostringstream __k7_e; \ __k7_e << "Exception: argument error." << __func__ << " expects " << c << " args."; \ return ThrowException(String::New(__k7_e.str().c_str())); \ } \ } while(0) #define ARG_BETWEEN(min, max) do { \ if (args.Length() < min || args.Length() > max) { \ std::ostringstream __k7_e; \ __k7_e << "Exception: argument error." << __func__ << " expects between " << min << " and " << max << " args."; \ return ThrowException(String::New(__k7_e.str().c_str())); \ } \ } while(0) #define ARG_int(n,c) int32_t n=(int32_t)(args[c]->Int32Value()) #define ARG_int32 ARG_int #define ARG_uint(n,c) uint32_t n=args[c]->Uint32Value() #define ARG_str(v,i) v8::String::Utf8Value v(args[i]) #define ARG_obj(v,i) v8::Local v=args[i]->ToObject(); #define ARG_bool(v,i) bool v=args[(i)]->BooleanValue(); #define ARG_array(name, c) \ if (!args[(c)]->IsArray()) { \ std::ostringstream __k7_e; \ __k7_e << "Exception: argument error." << __func__ << " expects array for argument " << c << "."; \ return ThrowException(String::New(__k7_e.str().c_str())); \ } \ Handle name = Handle::Cast(args[(c)]) #define END return v8::ThrowException(v8::String::New("Don't reach here... this function doesn't return value.")); } /** * This set of macros allow you to declare a new object type, usually because * you want to set internal data in this object. * See the 'posix.cpp' module for examples. */ #define OBJECT(name,fields,...) \ v8::Handle name(__VA_ARGS__) { \ v8::HandleScope handle_scope;\ v8::Handle fun_template = v8::FunctionTemplate::New();\ v8::Handle obj_template = fun_template->InstanceTemplate();\ obj_template->SetInternalFieldCount(fields);\ v8::Handle self = obj_template->NewInstance(); #define INTERNAL(i,value) \ self->SetInternalField(i, v8::External::New((void*)value)); #define SET_INTERNAL(i, val) \ args.This()->SetInternalField(i, v8::External::New((void*)val)); #define EXTERNAL(type,name,object,index) \ type name = (type) (v8::Local::Cast(object->GetInternalField(index))->Value()); /** * These macros allow to declare a module initialization function and register * FUNCTIONs in this module. */ #define INIT(name,moduleName) \ extern "C" v8::Handle name(v8::Handle global) {\ HandleScope handle_scope; \ Handle module = EnsureModule(global,moduleName); #define ENVIRONMENT void SetupEnvironment (v8::Handle global) { \ #define IMPORT(function) extern "C" v8::Handle function(v8::Handle global); #define LOAD(function) function(global); // my class create macros #define CLASS_WITH_CONSTRUCTOR(constructor) \ v8::Handle __k7_ft = v8::FunctionTemplate::New(constructor); \ Handle __k7_ot = __k7_ft->InstanceTemplate(); #define CLASS() v8::Handle __k7_ft = v8::FunctionTemplate::New(); \ Handle __k7_ot = __k7_ft->InstanceTemplate(); #define BIND_CS(s,v) __k7_ft->Set(JS_str(s), JS_str(v)); #define BIND_CI(s,v) __k7_ft->Set(JS_str(s), JS_int(v)); #define BIND_CM(s,v) __k7_ft->Set(JS_str(s), v8::FunctionTemplate::New(v)->GetFunction()); #define BIND_IM(s,v) __k7_ot->Set(JS_str(s), v8::FunctionTemplate::New(v)->GetFunction()); #define INTERNALCOUNT(i) __k7_ot->SetInternalFieldCount(i) #define EXPORT_CLASS(name) __k7_ft->SetClassName(String::New(name)); target->Set( String::New(name), __k7_ft->GetFunction(), PropertyAttribute(ReadOnly | DontDelete) ); #define MODULE() V8EXTINIT_FUNC Handle instantiate() { Handle target = Object::New(); #define ENDMODULE return target; } #define SUBMODULE(funcname) void funcname(Handle target) { #define ENDSUBMODULE } #define OBJECT_TEMPLATE __k7_ot #endif // EOF - vim: ts=4 sw=4 noet