📄 jsj_javaclass.c
字号:
JS_STATIC_DLL_CALLBACK(JSBool)JavaClass_deleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp){ JSVersion version = JS_GetVersion(cx); *vp = JSVAL_FALSE; if (!JSVERSION_IS_ECMA(version)) { JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_JCLASS_PROP_DELETE); return JS_FALSE; } else { /* Attempts to delete permanent properties are silently ignored by ECMAScript. */ return JS_TRUE; }}JS_STATIC_DLL_CALLBACK(JSBool)JavaClass_defaultValue(JSContext *cx, JSObject *obj, JSType type, jsval *vp){ /* printf("In JavaClass_defaultValue()\n"); */ return JavaClass_convert(cx, obj, JSTYPE_STRING, vp);}JS_STATIC_DLL_CALLBACK(JSBool)JavaClass_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, jsval *statep, jsid *idp){ JavaMemberDescriptor *member_descriptor; JavaClassDescriptor *class_descriptor; JNIEnv *jEnv; JSJavaThreadState *jsj_env; class_descriptor = JS_GetPrivate(cx, obj); /* Check for prototype JavaClass object */ if (!class_descriptor) { *statep = JSVAL_NULL; if (idp) *idp = INT_TO_JSVAL(0); return JS_TRUE; } switch(enum_op) { case JSENUMERATE_INIT: /* Get the Java per-thread environment pointer for this JSContext */ jsj_env = jsj_EnterJava(cx, &jEnv); if (!jEnv) return JS_FALSE; member_descriptor = jsj_GetClassStaticMembers(cx, jEnv, class_descriptor); *statep = PRIVATE_TO_JSVAL(member_descriptor); if (idp) *idp = INT_TO_JSVAL(class_descriptor->num_instance_members); jsj_ExitJava(jsj_env); return JS_TRUE; case JSENUMERATE_NEXT: member_descriptor = JSVAL_TO_PRIVATE(*statep); if (member_descriptor) { /* Don't enumerate explicit-signature methods, i.e. enumerate toValue, but not toValue(int), toValue(double), etc. */ while (member_descriptor->methods && member_descriptor->methods->is_alias) { member_descriptor = member_descriptor->next; if (!member_descriptor) { *statep = JSVAL_NULL; return JS_TRUE; } } *idp = member_descriptor->id; *statep = PRIVATE_TO_JSVAL(member_descriptor->next); return JS_TRUE; } /* Fall through ... */ case JSENUMERATE_DESTROY: *statep = JSVAL_NULL; return JS_TRUE; default: JS_ASSERT(0); return JS_FALSE; }}JS_STATIC_DLL_CALLBACK(JSBool)JavaClass_checkAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, jsval *vp, uintN *attrsp){ switch (mode) { case JSACC_WATCH: JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_JCLASS_PROP_WATCH); return JS_FALSE; case JSACC_IMPORT: JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_JCLASS_PROP_EXPORT); return JS_FALSE; default: return JS_TRUE; }}/* * Implement the JavaScript instanceof operator for JavaClass objects by using * the equivalent Java instanceof operation. */JS_STATIC_DLL_CALLBACK(JSBool)JavaClass_hasInstance(JSContext *cx, JSObject *obj, jsval candidate_jsval, JSBool *has_instancep){ JavaClassDescriptor *class_descriptor; JavaObjectWrapper *java_wrapper; JSClass *js_class; JSBool has_instance; JSObject *candidate_obj; jclass java_class; jobject java_obj; JNIEnv *jEnv; JSJavaThreadState *jsj_env; has_instance = JS_FALSE; class_descriptor = JS_GetPrivate(cx, obj); if (!class_descriptor) { JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_BAD_OP_JCLASS); return JS_FALSE; } /* * Make sure that the thing to the left of the instanceof operator is a * Java object. */ if (!JSVAL_IS_OBJECT(candidate_jsval)) goto done; candidate_obj = JSVAL_TO_OBJECT(candidate_jsval);#ifdef JS_THREADSAFE js_class = JS_GetClass(cx, candidate_obj);#else js_class = JS_GetClass(candidate_obj);#endif if ((js_class != &JavaObject_class) && (js_class != &JavaArray_class)) goto done; java_class = class_descriptor->java_class; java_wrapper = JS_GetPrivate(cx, candidate_obj); if (!java_wrapper) { JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_BAD_OP_PROTO); return JS_FALSE; } java_obj = java_wrapper->java_obj; /* Get JNI pointer */ jsj_env = jsj_EnterJava(cx, &jEnv); has_instance = (*jEnv)->IsInstanceOf(jEnv, java_obj, java_class); jsj_ExitJava(jsj_env);done: *has_instancep = has_instance; return JS_TRUE;}JSObjectOps JavaClass_ops = { /* Mandatory non-null function pointer members. */ jsj_wrapper_newObjectMap, /* newObjectMap */ jsj_wrapper_destroyObjectMap, /* destroyObjectMap */ JavaClass_lookupProperty, JavaClass_defineProperty, JavaClass_getPropertyById, /* getProperty */ JavaClass_setPropertyById, /* setProperty */ JavaClass_getAttributes, JavaClass_setAttributes, JavaClass_deleteProperty, JavaClass_defaultValue, JavaClass_newEnumerate, JavaClass_checkAccess, /* Optionally non-null members start here. */ NULL, /* thisObject */ NULL, /* dropProperty */ jsj_JavaConstructorWrapper, /* call */ jsj_JavaConstructorWrapper, /* construct */ NULL, /* xdrObject */ JavaClass_hasInstance, /* hasInstance */ NULL, /* setProto */ NULL, /* setParent */ NULL, /* mark */ NULL, /* clear */ jsj_wrapper_getRequiredSlot, /* getRequiredSlot */ jsj_wrapper_setRequiredSlot /* setRequiredSlot */};JS_STATIC_DLL_CALLBACK(JSObjectOps *)JavaClass_getObjectOps(JSContext *cx, JSClass *clazz){ return &JavaClass_ops;}JSClass JavaClass_class = { "JavaClass", JSCLASS_HAS_PRIVATE, NULL, NULL, NULL, NULL, NULL, NULL, JavaClass_convert, JavaClass_finalize, /* Optionally non-null members start here. */ JavaClass_getObjectOps, NULL, NULL, NULL, NULL, NULL, NULL, 0,};static JSObject *jsj_new_JavaClass(JSContext *cx, JNIEnv *jEnv, JSObject* parent_obj, JavaClassDescriptor *class_descriptor){ JSObject *JavaClass_obj; JavaClass_obj = JS_NewObject(cx, &JavaClass_class, 0, parent_obj); if (!JavaClass_obj) return NULL; JS_SetPrivate(cx, JavaClass_obj, (void *)class_descriptor);#ifdef DEBUG /* printf("JavaClass \'%s\' created\n", class_descriptor->name); */#endif return JavaClass_obj;}JSObject *jsj_define_JavaClass(JSContext *cx, JNIEnv *jEnv, JSObject* parent_obj, const char *simple_class_name, jclass java_class){ JavaClassDescriptor *class_descriptor; JSObject *JavaClass_obj; class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class); if (!class_descriptor) return NULL; JavaClass_obj = jsj_new_JavaClass(cx, jEnv, parent_obj, class_descriptor); if (!JavaClass_obj) return NULL; if (!JS_DefineProperty(cx, parent_obj, simple_class_name, OBJECT_TO_JSVAL(JavaClass_obj), 0, 0, JSPROP_PERMANENT|JSPROP_READONLY|JSPROP_ENUMERATE)) return NULL; return JavaClass_obj;}/* * The getClass() native JS method is defined as a property of the global * object. Given a JavaObject it returns the corresponding JavaClass. This * is useful for accessing static methods and fields. * * js> getClass(new java.lang.String("foo")) * [JavaClass java.lang.String] */JS_STATIC_DLL_CALLBACK(JSBool)getClass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSObject *obj_arg, *JavaClass_obj; JavaObjectWrapper *java_wrapper; JavaClassDescriptor *class_descriptor; JNIEnv *jEnv; JSJavaThreadState *jsj_env; if (argc != 1 || !JSVAL_IS_OBJECT(argv[0]) || !(obj_arg = JSVAL_TO_OBJECT(argv[0])) || (!JS_InstanceOf(cx, obj_arg, &JavaObject_class, 0) && !JS_InstanceOf(cx, obj_arg, &JavaArray_class, 0))) { JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_NEED_JOBJECT_ARG); return JS_FALSE; } java_wrapper = JS_GetPrivate(cx, obj_arg); if (!java_wrapper) { JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_PROTO_GETCLASS); return JS_FALSE; } jsj_env = jsj_EnterJava(cx, &jEnv); if (!jEnv) return JS_FALSE; class_descriptor = java_wrapper->class_descriptor; JavaClass_obj = jsj_new_JavaClass(cx, jEnv, NULL, class_descriptor); if (!JavaClass_obj) { jsj_ExitJava(jsj_env); return JS_FALSE; } *rval = OBJECT_TO_JSVAL(JavaClass_obj); jsj_ExitJava(jsj_env); return JS_TRUE;}JS_STATIC_DLL_CALLBACK(JSBool)JavaClass_construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSObject *obj_arg, *JavaClass_obj; JavaObjectWrapper *java_wrapper; JavaClassDescriptor *class_descriptor; JNIEnv *jEnv; JSJavaThreadState *jsj_env; if (argc != 1 || !JSVAL_IS_OBJECT(argv[0]) || !(obj_arg = JSVAL_TO_OBJECT(argv[0])) || !JS_InstanceOf(cx, obj_arg, &JavaObject_class, 0) || ((java_wrapper = JS_GetPrivate(cx, obj_arg)) == NULL)) { JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_NEED_JCLASS_ARG); return JS_FALSE; } jsj_env = jsj_EnterJava(cx, &jEnv); if (!jEnv) return JS_FALSE; class_descriptor = java_wrapper->class_descriptor; if (!(*jEnv)->IsSameObject(jEnv, class_descriptor->java_class, jlClass)) { JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_NEED_JCLASS_ARG); jsj_ExitJava(jsj_env); return JS_FALSE; } class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_wrapper->java_obj); JavaClass_obj = jsj_new_JavaClass(cx, jEnv, NULL, class_descriptor); if (!JavaClass_obj) { jsj_ExitJava(jsj_env); return JS_FALSE; } *rval = OBJECT_TO_JSVAL(JavaClass_obj); jsj_ExitJava(jsj_env); return JS_TRUE;}extern JS_IMPORT_DATA(JSObjectOps) js_ObjectOps;JSBooljsj_init_JavaClass(JSContext *cx, JSObject *global_obj){ /* Define JavaClass class */ if (!JS_InitClass(cx, global_obj, 0, &JavaClass_class, JavaClass_construct, 0, 0, 0, 0, 0)) return JS_FALSE; if (!JS_DefineFunction(cx, global_obj, "getClass", getClass, 0, JSPROP_READONLY)) return JS_FALSE; return jsj_InitJavaClassReflectionsTable();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -