⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsj_javaclass.c

📁 caffeine-monkey java实现的js模拟引擎
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** *//* This file is part of the Java-vendor-neutral implementation of LiveConnect * * It contains the native code implementation of JS's JavaClass class. * * A JavaClass is JavaScript's representation of a Java class. * Its parent JS object is always a JavaPackage object.  A JavaClass is not an * exact reflection of Java's corresponding java.lang.Class object.  Rather, * the properties of a JavaClass are the static methods and properties of the * corresponding Java class. * * Note that there is no runtime equivalent to the JavaClass class in Java. * (Although there are instances of java.lang.String and there are static * methods of java.lang.String that can be invoked, there's no such thing as * a first-class object that can be referenced simply as "java.lang.String".) */#include <stdlib.h>#include <string.h>#include "jsj_private.h"        /* LiveConnect internals */#include "jscntxt.h"            /* for error reporting */JS_STATIC_DLL_CALLBACK(JSBool)JavaClass_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp){    char *name;    JSString *str;    JavaClassDescriptor *class_descriptor;        class_descriptor = JS_GetPrivate(cx, obj);    if (!class_descriptor)        return JS_FALSE;    switch(type) {    case JSTYPE_STRING:        /* Convert '/' to '.' so that it looks like Java language syntax. */        if (!class_descriptor->name)            break;        name = JS_smprintf("[JavaClass %s]", class_descriptor->name);        if (!name) {            JS_ReportOutOfMemory(cx);            return JS_FALSE;        }        str = JS_NewString(cx, name, strlen(name));        if (!str) {            free(name);            /* It's not necessary to call JS_ReportOutOfMemory(), as               JS_NewString() will do so on failure. */            return JS_FALSE;        }        *vp = STRING_TO_JSVAL(str);        return JS_TRUE;    default:      break;    }    return JS_TRUE;}static JSBoollookup_static_member_by_id(JSContext *cx, JNIEnv *jEnv, JSObject *obj,                           JavaClassDescriptor **class_descriptorp,                           jsid id, JavaMemberDescriptor **memberp){    jsval idval;    JavaMemberDescriptor *member_descriptor;    const char *member_name;    JavaClassDescriptor *class_descriptor;    class_descriptor = JS_GetPrivate(cx, obj);    if (!class_descriptor) {        *class_descriptorp = NULL;        *memberp = NULL;        return JS_TRUE;    }        if (class_descriptorp)        *class_descriptorp = class_descriptor;        member_descriptor = jsj_LookupJavaStaticMemberDescriptorById(cx, jEnv, class_descriptor, id);    if (!member_descriptor) {        JS_IdToValue(cx, id, &idval);        if (!JSVAL_IS_STRING(idval)) {            JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,                                             JSJMSG_BAD_JCLASS_EXPR);            return JS_FALSE;        }        member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));                /*         * See if the property looks like the explicit resolution of an         * overloaded method, e.g. "max(double,double)".         */        member_descriptor =            jsj_ResolveExplicitMethod(cx, jEnv, class_descriptor, id, JS_TRUE);        if (member_descriptor)            goto done;        /* Why do we have to do this ? */        if (!strcmp(member_name, "prototype")) {            *memberp = NULL;            return JS_TRUE;        }        JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,                         JSJMSG_MISSING_NAME,                       class_descriptor->name, member_name);        return JS_FALSE;    }done:    if (memberp)        *memberp = member_descriptor;    return JS_TRUE;}JS_STATIC_DLL_CALLBACK(JSBool)JavaClass_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp){    jsval idval;    jclass java_class;    const char *member_name;    JavaClassDescriptor *class_descriptor;    JavaMemberDescriptor *member_descriptor;    JNIEnv *jEnv;    JSJavaThreadState *jsj_env;    JSBool result;    /* printf("In JavaClass_getProperty\n"); */        /* Get the Java per-thread environment pointer for this JSContext */    jsj_env = jsj_EnterJava(cx, &jEnv);    if (!jEnv)        return JS_FALSE;    if (!lookup_static_member_by_id(cx, jEnv, obj, &class_descriptor, id, &member_descriptor)) {	jsj_ExitJava(jsj_env);        return JS_FALSE;    }    if (!member_descriptor) {        *vp = JSVAL_VOID;	jsj_ExitJava(jsj_env);        return JS_TRUE;    }    java_class = class_descriptor->java_class;    if (member_descriptor->field) {        if (!member_descriptor->methods) {            result = jsj_GetJavaFieldValue(cx, jEnv, member_descriptor->field, java_class, vp);	    jsj_ExitJava(jsj_env);	    return result;        } else {            JS_ASSERT(0);        }    } else {        JSFunction *function;                /* TODO - eliminate JSFUN_BOUND_METHOD */        if (member_descriptor->methods->is_alias) {            /* If this is an explicit resolution of an overloaded method,               use the fully-qualified method name as the name of the               resulting JS function, i.e. "myMethod(int,long)" */            JS_IdToValue(cx, id, &idval);            member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));        } else {            /* Either not explicit resolution of overloaded method or               explicit resolution was unnecessary because method was               not overloaded. */            member_name = member_descriptor->name;        }        function = JS_NewFunction(cx, jsj_JavaStaticMethodWrapper, 0,                                  JSFUN_BOUND_METHOD, obj, member_name);        if (!function) {	    jsj_ExitJava(jsj_env);            return JS_FALSE;	}        *vp = OBJECT_TO_JSVAL(JS_GetFunctionObject(function));    }    jsj_ExitJava(jsj_env);    return JS_TRUE;}JS_STATIC_DLL_CALLBACK(JSBool)JavaClass_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp){    jclass java_class;    const char *member_name;    JavaClassDescriptor *class_descriptor;    JavaMemberDescriptor *member_descriptor;    jsval idval;    JNIEnv *jEnv;    JSJavaThreadState *jsj_env;    JSBool result;    /* printf("In JavaClass_setProperty\n"); */    /* Get the Java per-thread environment pointer for this JSContext */    jsj_env = jsj_EnterJava(cx, &jEnv);    if (!jEnv)        return JS_FALSE;        if (!lookup_static_member_by_id(cx, jEnv, obj, &class_descriptor, id, &member_descriptor)) {	jsj_ExitJava(jsj_env);        return JS_FALSE;    }    /* 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_class = class_descriptor->java_class;    result = jsj_SetJavaFieldValue(cx, jEnv, member_descriptor->field, java_class, *vp);    jsj_ExitJava(jsj_env);    return result;no_such_field:    JS_IdToValue(cx, id, &idval);    member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));    JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,                    JSJMSG_MISSING_STATIC,                   member_name, class_descriptor->name);    jsj_ExitJava(jsj_env);    return JS_FALSE;}/* * Free the private native data associated with the JavaPackage object. */JS_STATIC_DLL_CALLBACK(void)JavaClass_finalize(JSContext *cx, JSObject *obj){    JNIEnv *jEnv;    JSJavaThreadState *jsj_env;    JavaClassDescriptor *class_descriptor = JS_GetPrivate(cx, obj);    if (!class_descriptor)        return;        /* Get the Java per-thread environment pointer for this JSContext */    jsj_env = jsj_EnterJava(cx, &jEnv);    if (!jEnv)        return;    /* printf("Finalizing %s\n", class_descriptor->name); */    jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor);    jsj_ExitJava(jsj_env);}JS_STATIC_DLL_CALLBACK(JSBool)JavaClass_lookupProperty(JSContext *cx, JSObject *obj, jsid id,                         JSObject **objp, JSProperty **propp){    JNIEnv *jEnv;    JSErrorReporter old_reporter;    JSJavaThreadState *jsj_env;    /* printf("In JavaClass_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);    if (lookup_static_member_by_id(cx, jEnv, obj, NULL, id, NULL)) {        *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)JavaClass_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,                         JSPropertyOp getter, JSPropertyOp setter,                         uintN attrs, JSProperty **propp){    JavaClassDescriptor *class_descriptor;        class_descriptor = JS_GetPrivate(cx, obj);    /* Check for prototype JavaClass object */    if (!class_descriptor)	return JS_TRUE;    JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,                          JSJMSG_JCLASS_PROP_DEFINE);    return JS_FALSE;}JS_STATIC_DLL_CALLBACK(JSBool)JavaClass_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_FALSE;}JS_STATIC_DLL_CALLBACK(JSBool)JavaClass_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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -