home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
kaffe-0.5p4-src.tgz
/
tar.out
/
contrib
/
kaffe
/
kaffevm
/
soft.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-28
|
8KB
|
477 lines
/*
* soft.c
* Soft instruction support.
*
* Copyright (c) 1996 Systems Architecture Research Centre,
* City University, London, UK.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* Written by Tim Wilkinson <tim@sarc.city.ac.uk>, May 1996.
*/
#define MDBG(s)
#define ADBG(s)
#define CDBG(s)
#if MDBG(1) - 1 == 0
#undef CDBG
#define CDBG(s) s
#endif
#include "config.h"
#include <stdio.h>
#include <assert.h>
#include <math.h>
#include <stdarg.h>
#include "gtypes.h"
#include "bytecode.h"
#include "slots.h"
#include "soft.h"
#include "access.h"
#include "object.h"
#include "constants.h"
#include "classMethod.h"
#include "lookup.h"
#include "errors.h"
#include "exception.h"
#include "locks.h"
#if defined(HAVE_REMAINDER)
#elif defined(HAVE_FMOD)
#define remainder fmod
#else
#error "Need some form of remainder"
#endif
#if !defined(HAVE_REMAINDERF)
#define remainderf(a, b) (float)remainder((double)a, (double)b)
#endif
/* If we dont' have isinf() assume nothing is */
#if !defined(HAVE_ISINF)
#define isinf(x) 0
#endif
/* If we don't have isnan() assume nothing is */
#if !defined(HAVE_ISNAN)
#define isnan(x) 0
#endif
static jint instanceof(classes*, classes*);
/*
* soft_new
*/
void*
soft_new(classes* c)
{
object* obj;
obj = alloc_object(c, false);
ADBG( printf("New object of type %s (%d,%x)\n", c->name, c->fsize, obj);
fflush(stdout); )
return (obj);
}
/*
* soft_newarray
*/
void*
soft_newarray(jint type, jint size)
{
object* obj;
if (size < 0) {
throwException(NegativeArraySizeException);
}
obj = alloc_array(size, type);
ADBG( printf("New object of %d type (%d,%x)\n", type, size, obj);
fflush(stdout); )
return (obj);
}
/*
* soft_anewarray.
*/
void*
soft_anewarray(classes* c, jint size)
{
object* obj;
if (size < 0) {
throwException(NegativeArraySizeException);
}
obj = alloc_objectarray(size, c->sig);
ADBG( printf("New object array of type %s (%d,%x)\n", c->name, size, obj);
fflush(stdout); )
return (obj);
}
/*
* soft_multianewarray.
*/
#define MAXDIMS 16
#if defined(INTERPRETER)
void*
soft_multianewarray(classes* class, jint dims, slots* args)
{
int arraydims[MAXDIMS];
object* obj;
jint arg;
int i;
assert(dims < MAXDIMS);
/* Extract the dimensions into an array */
for (i = 0; i < dims; i++) {
arg = args[i].v.tint;
if (arg < 0) {
throwException(NegativeArraySizeException);
}
arraydims[i] = arg;
}
arraydims[i] = 0;
/* Mmm, okay now build the array using the wonders of recursion */
obj = alloc_multiarray(arraydims, class->name);
/* Return the base object */
return (obj);
}
#endif
#if defined(TRANSLATOR)
void*
soft_multianewarray(classes* class, jint dims, ...)
{
va_list ap;
int arraydims[MAXDIMS];
int i;
jint arg;
object* obj;
assert(dims < MAXDIMS);
/* Extract the dimensions into an array */
va_start(ap, dims);
for (i = 0; i < dims; i++) {
arg = va_arg(ap, jint);
if (arg < 0) {
throwException(NegativeArraySizeException);
}
arraydims[i] = arg;
}
arraydims[i] = 0;
va_end(ap);
/* Mmm, okay now build the array using the wonders of recursion */
obj = alloc_multiarray(arraydims, class->name);
/* Return the base object */
return (obj);
}
#endif
/*
* soft_monitorenter.
*/
void
soft_monitorenter(object* o)
{
lockMutex(o);
}
/*
* soft_monitorexit.
*/
void
soft_monitorexit(object* o)
{
unlockMutex(o);
}
/*
* soft_lookupmethod.
* (Note. dispatchTable could be methodTable - it doesn't matter)
*/
void*
soft_lookupmethod(dispatchTable* tab, strpair* pair)
{
classes* cls;
methods* meth;
void* func;
cls = tab->class;
meth = findMethod(cls, pair);
if (meth == 0) {
throwException(NoSuchMethodError);
}
#if defined(TRANSLATOR)
func = meth->ncode;
#elif defined(INTERPRETER)
func = (void*)meth;
#else
abort();
#endif
CDBG( printf("Calling %s:%s%s @ 0x%x\n",
cls->name, pair->s1, pair->s2, func);
fflush(stdout); )
#if MDBG(1) - 1 == -1
/* Fill in dispatchTable and methodTable cache */
cls->mtable->m[pair->hash % MAXMETHOD].tag = pair;
cls->mtable->m[pair->hash % MAXMETHOD].method = func;
cls->dtable->m[meth->idx].method = func;
#endif
return (func);
}
/*
* soft_checkcast.
*/
void
soft_checkcast(classes* c, object* o)
{
classes* oc;
/* Null can be cast to anything */
if (o == 0) {
return;
}
/* If object is instance of class, return */
if (soft_instanceof(c, o)) {
return;
}
/* Otherwise throw exception */
throwException(ClassCastException);
}
/*
* soft_instanceof.
*/
jint
soft_instanceof(classes* c, object* o)
{
/* Null object are never instances of anything */
if (o == 0) {
return (0);
}
return (instanceof(c, o->dtable->class));
}
static
jint
instanceof(classes* c, classes* oc)
{
int i;
if (oc == c) {
return (1);
}
if (oc == 0) {
return (0);
}
if (instanceof(c, oc->superclass)) {
return (1);
}
for (i = 0; i < oc->interface_len; i++) {
if (instanceof(c, oc->interfaces[i])) {
return (1);
}
}
return (0);
}
/*
* soft_athrow.
*/
void
soft_athrow(object* o)
{
throwExternalException(o);
}
/*
* soft_badarrayindex.
*/
void
soft_badarrayindex(void)
{
throwException(ArrayIndexOutOfBoundsException);
}
/*
* soft_dcmpg
*/
jint
soft_dcmpg(jdouble v1, jdouble v2)
{
jint ret;
if ((!isinf(v1) && isnan(v1)) || (!isinf(v2) && isnan(v2))) {
ret = 1;
}
else if (v1 > v2) {
ret = 1;
}
else if (v1 == v2) {
ret = 0;
}
else {
ret = -1;
}
return (ret);
}
/*
* soft_dcmpl
*/
jint
soft_dcmpl(jdouble v1, jdouble v2)
{
jint ret;
if ((!isinf(v1) && isnan(v1)) || (!isinf(v2) && isnan(v2))) {
ret = -1;
}
else if (v1 > v2) {
ret = 1;
}
else if (v1 == v2) {
ret = 0;
}
else {
ret = -1;
}
return (ret);
}
/*
* soft_fcmpg
*/
jint
soft_fcmpg(jfloat v1, jfloat v2)
{
jint ret;
if ((!isinf(v1) && isnan(v1)) || (!isinf(v2) && isnan(v2))) {
ret = 1;
}
else if (v1 > v2) {
ret = 1;
}
else if (v1 == v2) {
ret = 0;
}
else {
ret = -1;
}
return (ret);
}
/*
* soft_fcmpg
*/
jint
soft_fcmpl(jfloat v1, jfloat v2)
{
jint ret;
if ((!isinf(v1) && isnan(v1)) || (!isinf(v2) && isnan(v2))) {
ret = -1;
}
else if (v1 > v2) {
ret = 1;
}
else if (v1 == v2) {
ret = 0;
}
else {
ret = -1;
}
return (ret);
}
#if defined(TRANSLATOR)
jlong
soft_lmul(jlong v1, jlong v2)
{
return (v1 * v2);
}
jlong
soft_ldiv(jlong v1, jlong v2)
{
return (v1 / v2);
}
jlong
soft_lrem(jlong v1, jlong v2)
{
return (v1 % v2);
}
jfloat
soft_frem(jfloat v1, jfloat v2)
{
return (remainderf(v1, v2));
}
jdouble
soft_freml(jdouble v1, jdouble v2)
{
return (remainder(v1, v2));
}
jlong
soft_lshll(jlong v1, jint v2)
{
return (v1 << (v2 & 63));
}
jlong
soft_ashrl(jlong v1, jint v2)
{
return (v1 >> (v2 & 63));
}
jlong
soft_lshrl(jlong v1, jint v2)
{
return (((uint64)v1) >> (v2 & 63));
}
jint
soft_lcmp(jlong v1, jlong v2)
{
jlong lcc = v2 - v1;
if (lcc < 0) {
return (-1);
}
else if (lcc > 0) {
return (1);
}
else {
return (0);
}
}
#endif