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

📄 gcj-glue.c

📁 java virtual machince kaffe
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * gcj-glue.c * * Copyright (c) 1996, 1997, 1998, 1999 *      Transvirtual Technologies, Inc.  All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. * * Written by Godmar Back <gback@cs.utah.edu> */#include "config.h"#include "debug.h"#include "config-mem.h"#include "classMethod.h"#include "errors.h"#include "access.h"#include "lookup.h"#include "baseClasses.h"#include "stringSupport.h"#include "gcj.h"#include "jit3/machine.h"#include "object.h"#if defined(HAVE_GCJ_SUPPORT) && defined(JIT3) && defined(TRANSLATOR)/* * GCJ code wants to create an object.   */Hjava_lang_Object *kenvCreateObject(struct Hjava_lang_Class *clazz, int size){	/* !? --- I think that may be i386 specific -- XXX optimize me */	assert(((CLASS_FSIZE(clazz)+3)&~3) == size); 	return (newObject(clazz));}/* Given a const char * type name as a class name, create a * pathname.  I.e., makes a utf8const "[Ljava/lang/String;" from * [Ljava.lang.String */static Utf8Const *makePathUtf8FromClassChar(const char *name){	int n;	char buf[256], *b = buf;	Utf8Const *utf8;	n = strlen(name);	if (n > sizeof(buf) - 1) {		b = KMALLOC(n + 1);	}	classname2pathname(name, b);	utf8 = utf8ConstNew(b, n);	if (b != buf) {		KFREE(b);	}	return (utf8);}/* * cname is a qualified class name, like * [[I or Ljava.lang.String; or LHelloWorld; or [[[Ljava.lang.Object; * or a qualified path name where there's a slash instead of the dot */Hjava_lang_Class *kenvFindClass(char *cname, errorInfo *einfo){	char buf[1024];			/* XXX */	Utf8Const *name;	Hjava_lang_Class *class;	/* XXX handle classloaders -- but how? */        if (cname[0] == '[') {		/* loadArray does want the "L...;" */		name = makePathUtf8FromClassChar(cname);                class = loadArray(name, 0, einfo);        } else {		/* loadClass doesn't want the "L...;" */		if (*cname == 'L') {			strcpy(buf, cname+1);			assert(buf[strlen(buf) - 1] == ';');			buf[strlen(buf) - 1] = '\0';		} else {			/* else could be a primitive class such as "long" */			strcpy(buf, cname);		}		name = makePathUtf8FromClassChar(buf);                class = loadClass(name, 0, einfo);        }	utf8ConstRelease(name);DBG(GCJ, dprintf(__FUNCTION__": `%s' --> @%p\n", cname, class); )	return (class);}void kenvPostClassNotFound(const char *utf8name, errorInfo *einfo){	postNoClassDefFoundError(einfo, utf8name);}voidkenvProcessClass(struct Hjava_lang_Class *class){	errorInfo info;DBG(GCJ, dprintf("processing kaffe class for %s@%p from st=%d to %d...\n",  	CLASS_CNAME(class), class, class->state, CSTATE_COMPLETE);    )	if (processClass(class, CSTATE_COMPLETE, &info) == false) {		throwError(&info);	}}/* * Create a kaffe class from the gcj info */Hjava_lang_Class*kenvMakeClass(neutralClassInfo *info, errorInfo *einfo){	int n;	classEntry *centry;	Hjava_lang_Class *class = newClass();DBG(GCJ, dprintf("making kaffe class for %s@%p vtab=%p gcj=%p...\n",  	info->name, class, info->vtable, info->gcjClass);)		if (class == 0) {		goto oom;	}	class->name = makePathUtf8FromClassChar(info->name);	/* We must take care to not free some of these fields when unloading 	 * fully or partially loaded gcj classes (if that'll ever be supported) 	 * because they may still point in gcj-produced static data.	 */	/* We assume the same vtable layout here: first a pointer to the	 * class, then a zero, then the vtable	 */	class->dtable = info->vtable;	/* write kaffe class in vtable.class field in gcj space if class has	 * a dtable --- interfaces don't have one.	 */	if (class->dtable) {		class->dtable->class = class;	}	class->gcjPeer = info->gcjClass;	class->accflags = info->accflags;	class->msize = info->vTableCount;	class->superclass = info->superclass;	/* either null or pointer to						   other gcj class */	if (info->methodCount > 0) {		Kaffe_set_class_methods(class->methods,					gc_malloc(sizeof(Method) * info->methodCount, 						  GC_ALLOC_METHOD));		if (Kaffe_get_class_methods(class) == NULL) {			goto oom;		}	}	if (info->fieldCount > 0) {		class->fields = gc_malloc(sizeof(Field) * info->fieldCount, 					   GC_ALLOC_FIELD);		if (class->fields == 0) {			goto oom;		}	}	/* 	 * I copy those such that resolveInterfaces can proceed the same	 * way it does for for kaffe classes.	 */	class->interface_len = info->interfaceCount;	n = info->interfaceCount * sizeof(struct Hjava_lang_Class**);	if (n > 0) {		class->interfaces = (Hjava_lang_Class**)KMALLOC(n);		memcpy(class->interfaces, info->interfaces, n);	}	class->state = CSTATE_PRELOADED;	if (class->superclass == 0 && CLASS_IS_INTERFACE(class)) {			/* gcj sets superclass to zero for interfaces, but we 		 * set it to ObjectClass.		 */		class->superclass = ObjectClass;	}	SET_CLASS_GCJ(class);	/* XXX: find a better place to do this:	 * If we're invoked via loadClass, the caller will anchor us after	 * we return.  This gc_add_ref call is only necessary if we're	 * resolving a class referenced from gcj code via its address, 	 * bypassing the usual name-based lookup path.   XXX	 */	if (!gc_add_ref(class)) {		goto oom;	}	/* make sure this class is registered with the class pool 	 * Same caveat as for call to gc_add_ref above applies.	 */        centry = lookupClassEntry(class->name, 0, einfo);        if (centry == 0) {                return (0);        }	class->centry = centry;        centry->class = class;	return (class);oom:	postOutOfMemory(einfo);	return (0);}/* * Build a Kaffe Method* struct from a GCJ method description * * NB:  It ain't pretty, and it duplicates a lot of code from  * classMethod.c:addMethod() */boolkenvMakeMethod(neutralMethodInfo* info, Hjava_lang_Class *c, errorInfo *einfo){	Utf8Const *signature;	static 	char buf[1024];        Method *mt = &(Kaffe_get_class_methods(c)[CLASS_NMETHODS(c)]);	mt->name = utf8ConstFromString(info->name);	classname2pathname(info->signature, buf);	signature = utf8ConstFromString(buf);        METHOD_PSIG(mt) = parseSignature(signature, einfo);	utf8ConstRelease(signature);        if (METHOD_PSIG(mt) == NULL) {DBG(GCJ, 			dprintf("could not parse signature %s.%s ...\n", 			info->name, info->signature);     )                return (false);        }        mt->class = c;        mt->accflags = info->accflags;        mt->c.bcode.code = 0;        mt->stacksz = 0;        mt->localsz = 0;        mt->exception_table = 0;	if (*info->idx == -1) {		mt->idx = -1;	} else {		int supermsize;		/* avoid accessing superclass when mt->class == ObjectClass */		if (c == ObjectClass) {			supermsize = 0;		} else {			supermsize = c->superclass->msize;		}		assert(c == ObjectClass || c->superclass != 0);		/* assign a new method index unless this method was inherited */		if (c->superclass != 0 		    && getInheritedMethodIndex(c->superclass, mt) == false) 		{			mt->idx = supermsize + (*info->idx)++;		}	}	mt->ncode = info->ncode;	/* Interfaces and abstract class don't have a vtable in gcj, but 	 * their methods have non-zero indices.  METHOD_NATIVECODE accesses	 * a location within the dtable if idx != 0.	 *	 * XXX: Fix this whole "METHOD_NATIVECODE" mess and come up with	 * a more viable abstraction instead.	 */	if (!CLASS_IS_INTERFACE(mt->class) && !CLASS_IS_ABSTRACT(mt->class)) {		METHOD_NATIVECODE(mt) = mt->ncode;	}        /* Mark constructors as such */        if (utf8ConstEqual (mt->name, constructor_name)) {                mt->kFlags |= KFLAG_CONSTRUCTOR;        }	/* Assumption 1: gcj always sets the 0x4000 ACC_TRANSLATED flag, 	 * even in abstract methods.	 */	assert(mt->accflags & KFLAG_TRANSLATED);	/*	 * We clear ACC_TRANSLATED flags for methods with no code, such as	 * abstract methods.	 */	if (info->ncode == 0 || (info->accflags & ACC_NATIVE)) {		mt->kFlags &= ~KFLAG_TRANSLATED;	}        CLASS_NMETHODS(c)++;DBG(GCJ, 	dprintf("making kaffe method %s.%s @%p idx=%d m->ncode=%p...\n", 	    mt->name->data, METHOD_SIGD(mt), 	    mt, mt->idx, mt->ncode);    )        return (true);}/*  * Create a kaffe Field structure from GCJ field description * * compare addField in classMethod.c  */boolkenvMakeField(neutralFieldInfo* info, Hjava_lang_Class *c, errorInfo *einfo){	Field *fld;	Hjava_lang_Class *ftype;	/* static fields start from the bottom, instance fields from the top */        if (info->flags & ACC_STATIC) {                fld = &CLASS_FIELDS(c)[CLASS_NSFIELDS(c)];        } else {                fld = &CLASS_FIELDS(c)[info->idx + CLASS_NSFIELDS(c)];        }        fld->accflags = info->flags;	fld->name = utf8ConstFromString(info->name);	/* For now, that's true.  However, see	 * http://sourceware.cygnus.com/ml/java-discuss/1999-q4/msg00379.html	 * http://sourceware.cygnus.com/ml/java-discuss/1999-q4/msg00380.html	 * for how things may change.	 */	assert(!(fld->accflags & FIELD_CONSTANT_VALUE));	/* The resolved flags have the same meaning as in Kaffe---note that	 * gcj only resolves types if it can do so at link/compile time.  	 * Array types, for instance, are stored as unresolved field refs.	 */	if ((fld->accflags & FIELD_UNRESOLVED_FLAG) == 0) {		/* can't use kenvFindClassByAddress2 here cause we must avoid		 * attempts to process this class---especially if the		 * field points to a type that is the type of its enclosing		 * object.		 */		ftype = gcjFindClassByAddress(info->type, einfo);		if (!ftype) {			char *name;			name = gcjFindUnresolvedClassByAddress(info->type); 			if (name) {				ftype = kenvFindClass(name, einfo);

⌨️ 快捷键说明

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