Subj : helper macros for accessing the jsapi To : netscape.public.mozilla.jseng From : stefan noll Date : Mon Aug 01 2005 02:38 am hi, some time ago i wrote some helper macros for accessing the jsapi. perhaps there are usefull for somebody: header file: > #ifdef LINUX > #define XP_UNIX > #endif > > #ifdef WIN32 > #define XP_WIN > #endif > > #include "jsapi.h" > > extern int32 Jsval_AsInt(JSContext *cx, jsval v); > > extern jsdouble Jsval_AsDouble(JSContext *cx, jsval v); > > #define JSVAL_AS_STRING(x) JS_GetStringBytes(JS_ValueToString(cx,x)) > #define JSVAL_AS_INT(x) Jsval_AsInt(cx,x) > #define JSVAL_AS_DOUBLE(x) Jsval_AsDouble(cx,x) > > /* JS Class Functions */ > #define DEFINE_JSCLASS \ > static JSBool JSGetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);\ > static JSBool JSSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);\ > static JSBool JSConstructor(JSContext *cx, JSObject *obj, uintN argc, \ > jsval *argv, jsval *rval);\ > static void JSDestructor(JSContext *cx, JSObject *obj);\ > static JSObject *JSInit(JSContext *cx, JSObject *obj, JSObject *proto);\ > static JSObject *JSInitGlobal(JSContext *cx, JSObject *obj, const char* Name=0); \ > \ > static JSClass JsClass;\ > static JSPropertySpec JsProperties[];\ > static JSFunctionSpec JsMethods[]; > > > > > #define IMPLEMENT_JSINIT(c) IMPLEMENT_JSINIT_ARGS(c, 0); > > > > > #define IMPLEMENT_JSINIT_ARGS(c,args)\ > JSObject *c::JSInit(JSContext *cx, JSObject *obj, JSObject *proto)\ > {\ > JSObject *newObj = JS_InitClass(cx, obj, proto, &JsClass, \ > c::JSConstructor, args,\ > NULL, c::JsMethods,\ > NULL, NULL);\ > JS_DefineProperties(cx, newObj, c::JsProperties);\ > return newObj;\ > }\ > JSObject *c::JSInitGlobal(JSContext *cx, JSObject *obj, const char* Name) \ > { \ > if(!Name) Name = #c; \ > JSObject *ClassObject;\ > ClassObject = JS_DefineObject(cx, obj, Name, &JsClass, NULL, 0);\ > if(!ClassObject) { fprintf(stderr, "klassenobjekt nicht initialisiert"); return NULL; }\ > if(!JS_DefineFunctions(cx, ClassObject, c::JsMethods)) { fprintf(stderr, "funktionen nicht initialisiert"); return NULL; }\ > if(!JS_DefineProperties(cx, ClassObject, c::JsProperties)) { fprintf(stderr, "eigenschaften nicht initialisiert"); return NULL; }\ > return ClassObject ; \ > } > > #define IMPLEMENT_JSDESTRUCTOR(c)\ > void c::JSDestructor(JSContext *cx, JSObject *obj)\ > {\ > c* pThis = (c*)JS_GetPrivate(cx, obj);\ > if(pThis) delete pThis;\ > pThis = NULL;\ > } > > #define IMPLEMENT_JSCONSTRUCTOR(c)\ > JSBool c::JSConstructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)\ > {\ > c* pThis = new c();\ > JS_SetPrivate(cx, obj, (void*)pThis);\ > return JS_TRUE;\ > } > > > #define IMPLEMENT_JSCONSTRUCTOR_ARGS1(c,arg1)\ > JSBool c::JSConstructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)\ > {\ > c* pThis = new c(arg1);\ > JS_SetPrivate(cx, obj, (void*)pThis);\ > return JS_TRUE;\ > } > > #define IMPLEMENT_JSCONSTRUCTOR_ARGS2(c,arg1,arg2)\ > JSBool c::JSConstructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)\ > {\ > c* pThis = new c(arg1,arg2);\ > JS_SetPrivate(cx, obj, (void*)pThis);\ > return JS_TRUE;\ > } > > > > #define IMPLEMENT_JSCLASS(c) \ > JSClass c::JsClass = \ > {\ > #c, JSCLASS_HAS_PRIVATE,\ > JS_PropertyStub, JS_PropertyStub,\ > c::JSGetProperty, c::JSSetProperty,\ > JS_EnumerateStub, JS_ResolveStub, \ > JS_ConvertStub, c::JSDestructor\ > }; > > #define DEFINE_PROPERTIES(c) JSPropertySpec c::JsProperties[] = > #define DEFINE_OBJECTMETHODS(c) JSFunctionSpec c::JsMethods[] = > > #define DEFINE_METHOD(f, nArgs) { #f, f, nArgs, 0, 0 }, > > #define DEFINE_END { 0 } > > #define METHOD_DEKLARATION(f) static JSBool f##(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); > > #define METHOD_IMPLEMENTATION(c, f) \ > JSBool c::f(JSContext *cx, JSObject *obj, uintN argc, \ > jsval *argv, jsval *value)\ > {\ > c* pThis = (c*)JS_GetPrivate(cx, obj); \ > const char* FuncName = #f;\ > { > > > #define IMPLEMENT_GET_PROPERTIES(c)\ > JSBool c::JSGetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *value)\ > {\ > if (!JSVAL_IS_INT(id)) return JS_TRUE;\ > c* pThis = (c*)JS_GetPrivate(cx, obj);\ > switch(JSVAL_TO_INT(id))\ > { > > #define IMPLEMENT_SET_PROPERTIES(c)\ > JSBool c::JSSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *value)\ > {\ > if (!JSVAL_IS_INT(id)) return JS_TRUE;\ > c* pThis = (c*)JS_GetPrivate(cx, obj);\ > switch(JSVAL_TO_INT(id))\ > { > > > #define END_IMPLEMENT } return JS_TRUE; } > > > #define PROPERTY(p) case p: { > #define ENDPROPERTY } break; > > #define RETURN_VALUE_INT(v) *value = INT_TO_JSVAL(v); > #define RETURN_VALUE_DOUBLE(v) JS_NewDoubleValue(cx,v, value); > > > #define CHECKARGSCOUNT(nArgs)\ > if(argc != nArgs)\ > {\ > JS_ReportError(cx, "%s needs exactly %i aguments", FuncName, nArgs);\ > return false;\ > } source implementation: > > int32 Jsval_AsInt(JSContext *cx, jsval v) > { > int32 Value=0; > JS_ValueToInt32(cx, v, &Value); > return Value; > } > > jsdouble Jsval_AsDouble(JSContext *cx, jsval v) > { > jsdouble Value=0; > JS_ValueToNumber(cx, v, &Value); > return Value; > } example: > #include "JsHelper.h" > > class DoSomething > { > public: > DoSomething(int Arg1, int Arg2); > virtual ~Schalter(); > DEFINE_JSCLASS; > METHOD_DEKLARATION(Save); > void setstate(int state); int getstate(); > protected: > int m_nAdress; > }; > IMPLEMENT_JSINIT_ARGS(DoSomething,2); > IMPLEMENT_JSCONSTRUCTOR_ARGS2(DoSomething, JSVAL_AS_INT(argv[0]), JSVAL_AS_INT(argv[1])); > > IMPLEMENT_JSCLASS(DoSomething) > IMPLEMENT_JSDESTRUCTOR(DoSomething); > > > DEFINE_OBJECTMETHODS(DoSomething) > { > DEFINE_METHOD(Save, 0) > DEFINE_END > }; > > DEFINE_PROPERTIES(DoSomething) > { > { "state", 1, JSPROP_ENUMERATE }, > DEFINE_END > }; > > IMPLEMENT_SET_PROPERTIES(DoSomething) > PROPERTY(1) > pThis->setstate(JSVAL_AS_INT(*value)); > ENDPROPERTY > > END_IMPLEMENT; > > > IMPLEMENT_GET_PROPERTIES(DoSomething) > PROPERTY(1) > RETURN_VALUE_INT(pThis->getstate()); > ENDPROPERTY > END_IMPLEMENT; > METHOD_IMPLEMENTATION(DoSomething, Save) > { > pThis->save(); > return JS_TRUE; > } > END_IMPLEMENT; please send me a short message if you use parts of it, you'll get more examples and updates :-) sincerely, stefan noll .