📄 jsj_javaobject.c
字号:
JSJPropertyInfo prop_info; JSBool result; /* printf("In JavaObject_setProperty\n"); */ /* Get the Java per-thread environment pointer for this JSContext */ jsj_env = jsj_EnterJava(cx, &jEnv); if (!jEnv) return JS_FALSE; prop_info.wantProp = JS_FALSE; if (!lookup_member_by_id(cx, jEnv, obj, &java_wrapper, id, &member_descriptor, NULL, &proto_chain, &prop_info)) { jsj_ExitJava(jsj_env); return JS_FALSE; } /* Could be assignment to magic JS __proto__ property rather than a Java field */ if (!member_descriptor) { if (proto_chain && (prop_info.attributes & JSPROP_SHARED)) { JS_SetProperty(cx, proto_chain, prop_info.name, vp); } else { JS_IdToValue(cx, id, &idval); if (!JSVAL_IS_STRING(idval)) goto no_such_field; member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval)); if (strcmp(member_name, "__proto__")) goto no_such_field; if (!JSVAL_IS_OBJECT(*vp)) { JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_BAD_PROTO_ASSIGNMENT); jsj_ExitJava(jsj_env); return JS_FALSE; } JS_SetPrototype(cx, obj, JSVAL_TO_OBJECT(*vp)); } jsj_ExitJava(jsj_env); return JS_TRUE; } /* Check for the case where there is a method with the given name, but no field with that name */ if (!member_descriptor->field) goto no_such_field; /* Silently fail if field value is final (immutable), as required by ECMA spec */ if (member_descriptor->field->modifiers & ACC_FINAL) { jsj_ExitJava(jsj_env); return JS_TRUE; } java_obj = java_wrapper->java_obj; if (jaApplet && (*jEnv)->IsInstanceOf(jEnv, java_obj, jaApplet)) { jsj_JSIsCallingApplet = JS_TRUE; } result = jsj_SetJavaFieldValue(cx, jEnv, member_descriptor->field, java_obj, *vp); jsj_ExitJava(jsj_env); return result;no_such_field: JS_IdToValue(cx, id, &idval); member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval)); class_descriptor = java_wrapper->class_descriptor; JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_NO_NAME_IN_CLASS, member_name, class_descriptor->name); jsj_ExitJava(jsj_env); return JS_FALSE;}JS_STATIC_DLL_CALLBACK(JSBool)JavaObject_lookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, JSProperty **propp){ JNIEnv *jEnv; JSErrorReporter old_reporter; jsval dummy_val; JSObject *proto_chain; JSJPropertyInfo prop_info; JSJavaThreadState *jsj_env; /* printf("In JavaObject_lookupProperty()\n"); */ /* Get the Java per-thread environment pointer for this JSContext */ jsj_env = jsj_EnterJava(cx, &jEnv); if (!jEnv) return JS_FALSE; old_reporter = JS_SetErrorReporter(cx, NULL); prop_info.wantProp = JS_TRUE; if (lookup_member_by_id(cx, jEnv, obj, NULL, id, NULL, &dummy_val, &proto_chain, &prop_info)) { /* signify that the property is in the prototype chain or the object itself. */ if (proto_chain) { *objp = proto_chain; *propp = prop_info.prop; } else { *objp = obj; *propp = (JSProperty*)1; } } else { *objp = NULL; *propp = NULL; } JS_SetErrorReporter(cx, old_reporter); jsj_ExitJava(jsj_env); return JS_TRUE;}JS_STATIC_DLL_CALLBACK(JSBool)JavaObject_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, JSPropertyOp getter, JSPropertyOp setter, uintN attrs, JSProperty **propp){ JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_JOBJECT_PROP_DEFINE); return JS_FALSE;}JS_STATIC_DLL_CALLBACK(JSBool)JavaObject_getAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, uintN *attrsp){ /* We don't maintain JS property attributes for Java class members */ *attrsp = JSPROP_PERMANENT|JSPROP_ENUMERATE; return JS_TRUE;}JS_STATIC_DLL_CALLBACK(JSBool)JavaObject_setAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, uintN *attrsp){ /* We don't maintain JS property attributes for Java class members */ if (*attrsp != (JSPROP_PERMANENT|JSPROP_ENUMERATE)) { JS_ASSERT(0); return JS_FALSE; } /* Silently ignore all setAttribute attempts */ return JS_TRUE;}JS_STATIC_DLL_CALLBACK(JSBool)JavaObject_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_JOBJECT_PROP_DELETE); return JS_FALSE; } else { /* Attempts to delete permanent properties are silently ignored by ECMAScript. */ return JS_TRUE; }}JS_STATIC_DLL_CALLBACK(JSBool)JavaObject_defaultValue(JSContext *cx, JSObject *obj, JSType type, jsval *vp){ /* printf("In JavaObject_defaultValue()\n"); */ return JavaObject_convert(cx, obj, type, vp);}JS_STATIC_DLL_CALLBACK(JSBool)JavaObject_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, jsval *statep, jsid *idp){ JavaObjectWrapper *java_wrapper; JavaMemberDescriptor *member_descriptor; JavaClassDescriptor *class_descriptor; JNIEnv *jEnv; JSJavaThreadState *jsj_env; java_wrapper = JS_GetPrivate(cx, obj); /* Check for prototype object */ if (!java_wrapper) { *statep = JSVAL_NULL; if (idp) *idp = INT_TO_JSVAL(0); return JS_TRUE; } class_descriptor = java_wrapper->class_descriptor; 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_GetClassInstanceMembers(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)JavaObject_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_JOBJECT_PROP_WATCH); return JS_FALSE; case JSACC_IMPORT: JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, JSJMSG_JOBJECT_PROP_EXPORT); return JS_FALSE; default: return JS_TRUE; }}#define JSJ_SLOT_COUNT (JSSLOT_PRIVATE+1)JSObjectMap * JS_DLL_CALLBACKjsj_wrapper_newObjectMap(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp, JSObject *obj){ JSObjectMap * map; map = (JSObjectMap *) JS_malloc(cx, sizeof(JSObjectMap)); if (map) { map->nrefs = nrefs; map->ops = ops; map->nslots = JSJ_SLOT_COUNT; map->freeslot = JSJ_SLOT_COUNT; } return map;}void JS_DLL_CALLBACKjsj_wrapper_destroyObjectMap(JSContext *cx, JSObjectMap *map){ JS_free(cx, map);}jsval JS_DLL_CALLBACKjsj_wrapper_getRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot){ JS_ASSERT(slot < JSJ_SLOT_COUNT); JS_ASSERT(obj->slots); JS_ASSERT(obj->map->nslots == JSJ_SLOT_COUNT); JS_ASSERT(obj->map->freeslot == JSJ_SLOT_COUNT); return obj->slots[slot];}JSBool JS_DLL_CALLBACKjsj_wrapper_setRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot, jsval v){ JS_ASSERT(slot < JSJ_SLOT_COUNT); JS_ASSERT(obj->slots); JS_ASSERT(obj->map->nslots == JSJ_SLOT_COUNT); JS_ASSERT(obj->map->freeslot == JSJ_SLOT_COUNT); obj->slots[slot] = v; return JS_TRUE;}JSObjectOps JavaObject_ops = { /* Mandatory non-null function pointer members. */ jsj_wrapper_newObjectMap, /* newObjectMap */ jsj_wrapper_destroyObjectMap, /* destroyObjectMap */ JavaObject_lookupProperty, JavaObject_defineProperty, JavaObject_getPropertyById, /* getProperty */ JavaObject_setPropertyById, /* setProperty */ JavaObject_getAttributes, JavaObject_setAttributes, JavaObject_deleteProperty, JavaObject_defaultValue, JavaObject_newEnumerate, JavaObject_checkAccess, /* Optionally non-null members start here. */ NULL, /* thisObject */ NULL, /* dropProperty */ NULL, /* call */ NULL, /* construct */ NULL, /* xdrObject */ NULL, /* hasInstance */ NULL, /* setProto */ NULL, /* setParent */ NULL, /* mark */ NULL, /* clear */ jsj_wrapper_getRequiredSlot, /* getRequiredSlot */ jsj_wrapper_setRequiredSlot /* setRequiredSlot */};JS_STATIC_DLL_CALLBACK(JSObjectOps *)JavaObject_getObjectOps(JSContext *cx, JSClass *clazz){ return &JavaObject_ops;}JSClass JavaObject_class = { "JavaObject", JSCLASS_HAS_PRIVATE, NULL, NULL, NULL, NULL, NULL, NULL, JavaObject_convert, JavaObject_finalize, /* Optionally non-null members start here. */ JavaObject_getObjectOps, NULL, /* checkAccess */ NULL, /* call */ NULL, /* construct */ NULL, /* xdrObject */ NULL, /* hasInstance */ NULL, /* mark */ 0, /* spare */};extern JS_IMPORT_DATA(JSObjectOps) js_ObjectOps;JSBooljsj_init_JavaObject(JSContext *cx, JSObject *global_obj){ return JS_InitClass(cx, global_obj, 0, &JavaObject_class, 0, 0, 0, 0, 0, 0) != 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -