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
/
support.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-28
|
5KB
|
286 lines
/*
* support.c
* Native language 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>, February 1996.
*/
#include "config.h"
#include <assert.h>
#include <stdarg.h>
#include <string.h>
#if defined(HAVE_MALLOC_H)
#include <malloc.h>
#endif
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
#if defined(HAVE_SYS_TIME_H)
#include <sys/time.h>
#endif
#include "gtypes.h"
#include "access.h"
#include "object.h"
#include "constants.h"
#include "baseClasses.h"
#include "classMethod.h"
#include "lookup.h"
#include "errors.h"
#include "exception.h"
#include "slots.h"
#include "external.h"
#include "machine.h"
#include "support.h"
#include "md.h"
#define MAXEXCEPTIONLEN 200
#define CONSTRUCTOR_NAME "<init>"
#define ERROR_SIGNATURE "(Ljava/lang/String;)V"
/* Anchor point for user defined properties */
userProperty* userProperties;
/*
* Convert an Java String to a C string.
*/
char*
javaString2CString(stringClass* js, char* cs, int len)
{
if (len == 0) {
return (0);
}
len--;
if (len > js->count) {
len = js->count;
}
strncpy(cs, STRING_OBJ2DATA(js->value) + js->offset, len);
cs[len] = 0;
return (cs);
}
/*
* Convert a C string into a Java String.
*/
stringClass*
makeJavaString(char* cs, int len)
{
return (getString(STRING_DATA2BASE(addStringLen(cs, len))));
}
/*
* Convert a C string into a Java char array.
*/
object*
makeJavaCharArray(char* cs, int len)
{
return (STRING_DATA2OBJECT(addStringLen(cs, len)));
}
/*
* Call a Java method from native code.
*/
long
do_execute_java_method(void* ee, object* obj, char* method_name, char* signature, methods* mb, int isStaticCall, ...)
{
char* sig;
int args;
va_list argptr;
if (mb == 0 || mb->ncode == 0) {
mb = findMethod(obj->dtable->class, addStringPair(method_name, signature));
if (mb == 0) {
throwException(NoSuchMethodError);
}
}
/* Calculate number of arguments */
sig = signature;
args = sizeofSig(&sig);
/* Make the call */
va_start(argptr, isStaticCall);
CALL_KAFFE_FUNCTION_VARARGS(mb, obj, args, argptr);
va_end(argptr);
return (0);
}
/*
* Call a Java static method on a class from native code.
*/
long
do_execute_java_class_method(char* cname, char* method_name, char* signature, ...)
{
char* sig;
int args;
va_list argptr;
classes* class;
methods* mb;
/* Convert "." to "/" */
classname2pathname(cname, cname);
class = lookupClass(addString(cname));
assert(class != 0);
mb = findMethod(class, addStringPair(method_name, signature));
if (mb == 0) {
throwException(NoSuchMethodError);
}
/* Calculate number of arguments */
sig = signature;
args = sizeofSig(&sig);
/* Make the call */
va_start(argptr, signature);
CALL_KAFFE_FUNCTION_VARARGS(mb, 0, args, argptr);
va_end(argptr);
return (0);
}
/*
* Allocate and object and execute the constructor.
*/
object*
execute_java_constructor(void* ee, char* cname, classes* cc, char* signature, ...)
{
int args;
object* obj;
char* sig;
va_list argptr;
methods* mb;
char buf[MAXEXCEPTIONLEN];
if (cc == 0) {
/* Convert "." to "/" */
classname2pathname(cname, buf);
cc = lookupClass(addString(buf));
assert(cc != 0);
}
mb = findMethod(cc, addStringPair(CONSTRUCTOR_NAME, signature));
if (mb == 0) {
throwException(NoSuchMethodError);
}
obj = alloc_object(cc, false);
assert(obj != 0);
/* Calculate number of arguments */
sig = signature;
args = sizeofSig(&sig);
/* Make the call */
va_start(argptr, signature);
CALL_KAFFE_FUNCTION_VARARGS(mb, obj, args, argptr);
va_end(argptr);
return (obj);
}
/*
* Signal an error by creating the object and throwing the exception.
*/
void
SignalError(void* ee, char* cname, char* str)
{
object* obj;
obj = execute_java_constructor(ee, cname, 0, ERROR_SIGNATURE, makeJavaString(str, strlen(str)));
throwException(obj);
}
/*
* Convert a class name to a path name.
*/
void
classname2pathname(char* from, char* to)
{
int i;
/* Convert any '.' in name to '/' */
for (i = 0; from[i] != 0; i++) {
if (from[i] == '.') {
to[i] = '/';
}
else {
to[i] = from[i];
}
}
to[i] = 0;
}
/*
* Return current time in milliseconds.
*/
jlong
currentTime(void)
{
jlong tme;
#if !defined(HAVE_NATIVE_INT64)
tme.jl = 0;
tme.jh = 0;
#elif defined(HAVE_GETTIMEOFDAY)
struct timeval tm;
gettimeofday(&tm, 0);
tme = (((jlong)tm.tv_sec * (jlong)1000) + ((jlong)tm.tv_usec / (jlong)1000));
#else
tme = 0;
#endif
return (tme);
}
/*
* Set a property to a value.
*/
void
setProperty(void* properties, char* key, char* value)
{
do_execute_java_method(0, properties, "put",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
0, false,
makeJavaString(key, strlen(key)),
makeJavaString(value, strlen(value)));
}
/*
* Allocate a new object of the given class name.
*/
object*
AllocObject(char* classname)
{
classes* class;
class = lookupClass(classname);
assert(class != 0);
return (alloc_object(class, false));
}
/*
* Allocate a new array of a given size and type.
*/
object*
AllocArray(int sz, int type)
{
return (alloc_array(sz, type));
}
/*
* Allocate a new array of the given size and class name.
*/
object*
AllocObjectArray(int sz, char* classname)
{
return (alloc_objectarray(sz, classname));
}