home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.mactech.com 2010
/
ftp.mactech.com.tar
/
ftp.mactech.com
/
challenge
/
12.09-Sep96
/
Testcode96.09R1.sit.hqx
/
Testcode96.09R1
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-08-20
|
8KB
|
312 lines
void JavaMiniVM(
void *constant_pool, /* pointer to cp_info array */
void *fields, /* pointer to field_info array */
void *methods, /* pointer to method_info array */
void *classFile, /* pointer to class file */
long methodToExecute, /* index of method to start executing */
void *heapSpace, /* preallocated storage for your use */
void *returnStack /* stack where return values are stored */
);
#define printConst 0
#define kFileName1 "Swarm.class"
#define kTargetClass1 "myRun"
#define kResult1 21111L
#define kFileName2 "FibApp.class"
#define kTargetClass2 "Fib"
#define kResult2 102334155L
#define kFileName3 "HelloWorld.class"
#define kTargetClass3 "myHello"
#define kResult3 "Hello, World!"
#define kFileName4 "MiscByteCodes.class"
#define kTargetClass4 "myTest"
#define kResult4 115
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define READLONG(n,x) n=*(unsigned long *)x; x+=sizeof(long);
#define READSHORT(n,x) n=*(unsigned short *)x; x+=sizeof(short);
#define READBYTE(n,x) n=*(unsigned char *)x; x+=sizeof(unsigned char);
void **pConstant;
short *constantLength;
static unsigned char *ProcessAttribute(unsigned char *p,long j)
{
unsigned short attribute_name,opcodeByte;
unsigned long attribute_length;
char *attr;
long k,i;
short length,max_stack,max_locals,byteLength;
long code_length;
READSHORT(attribute_name,p);
READLONG(attribute_length,p);
length = constantLength[attribute_name];
attr = 3 + (char *)pConstant[attribute_name]; /* +3 skips tag and length */
if (0 == strncmp("SourceFile",attr,length)) {
;
} else if (0 == strncmp("ConstantValue",attr,length)) {
;
} else if (0 == strncmp("Code",attr,length)) {
READSHORT(max_stack,p);
READSHORT(max_locals,p);
READLONG(code_length,p);
p += attribute_length-8;
return p;
} else if (0 == strncmp("Exceptions",attr,length)) {
;
} else if (0 == strncmp("LineNumberTable",attr,length)) {
;
} else if (0 == strncmp("LocalVariableTable",attr,length)) {
;
} else {
;
}
p += attribute_length;
return p;
}
static void DoReadClass(char *fileName, char *targetClass,
void **p_constant_pool, /* pointer to cp_info array */
void **p_fields, /* pointer to field_info array */
void **p_methods, /* pointer to method_info array */
void **p_classFile, /* pointer to class file */
long *p_methodToExecute /* index of method to start executing */
)
{
FILE *inFile;
unsigned char *p,*buf;
unsigned long magic, numBytes;
unsigned long bytes,high_bytes,low_bytes;
unsigned short minor_version,major_version,constant_pool_count;
unsigned short name_index,class_index,name_and_type_index,string_index;
unsigned short signature_index;
unsigned short length;
unsigned short access_flags,this_class,super_class,interfaces_count,interfaces;
unsigned short fields_count,attribute_count,attribute_name;
unsigned short methods_count,attributes_count;
void *constant_pool,*fields,*methods,*classFile;
long methodToExecute;
unsigned long attribute_length;
unsigned char tag;
fpos_t pos;
int err;
long i,j,k;
inFile = fopen(fileName,"rb");
if (inFile == nil) DebugStr("\p fopen err");
err = fseek(inFile,0L,SEEK_END);
if (err != 0) DebugStr("\p fseek err");
err = fgetpos(inFile,&pos);
if (err != 0) DebugStr("\p fgetpos err");
buf = (unsigned char *)NewPtr(pos._Off);
if (buf == nil) DebugStr("\p NewPtr err");
fseek(inFile,0L,SEEK_SET);
numBytes = fread(buf,1,pos._Off,inFile);
p = buf;
/* Header */
classFile = p;
READLONG(magic,p);
READSHORT(minor_version,p);
READSHORT(major_version,p);
/* Constant pool */
READSHORT(constant_pool_count,p);
pConstant = (void **)NewPtrClear(constant_pool_count * sizeof(Ptr));
constantLength = (short *)NewPtrClear(constant_pool_count * sizeof(short));
constant_pool = p;
for (i=1; i<constant_pool_count; ++i) {
pConstant[i] = p; READBYTE(tag,p);
switch (tag) {
case 7: /*Constant_Class*/
READSHORT(name_index,p);
break;
case 9: /*Fieldref*/
case 10: /*Methodref*/
case 11: /*InterfaceMethodref*/
READSHORT(class_index,p);
READSHORT(name_and_type_index,p);
break;
case 8: /*Constant_Class*/
READSHORT(string_index,p);
break;
case 3: /*Integer*/
case 4: /*Float*/
READLONG(bytes,p);
break;
case 5: /*long*/
case 6: /*double*/
READLONG(high_bytes,p);
READLONG(low_bytes,p);
++i; // 8 byte constants take 2 slots in constant pool
break;
case 12: /*NameAndType*/
case 13: /*??*/
READSHORT(name_index,p);
READSHORT(signature_index,p);
break;
case 1: /*Utf8*/
case 2: /*Unicode*/
READSHORT(length,p);
constantLength[i] = length;
p += length;
break;
default:
p -=1 ;
break;
}
}
READSHORT(access_flags,p);
READSHORT(this_class,p);
READSHORT(super_class,p);
READSHORT(interfaces_count,p);
for (i=0; i<interfaces_count; ++i) {
READSHORT(interfaces,p);
}
READSHORT(fields_count,p);
fields = p;
for (i=0; i<fields_count; ++i) {
READSHORT(access_flags,p);
READSHORT(name_index,p);
READSHORT(signature_index,p);
READSHORT(attribute_count,p);
for (j=0; j<attribute_count; ++j) {
p = ProcessAttribute(p,j);
}
}
READSHORT(methods_count,p);
methods = p;
for (i=0; i<methods_count; ++i) {
char *theMethodName;
READSHORT(access_flags,p);
READSHORT(name_index,p);
READSHORT(signature_index,p);
READSHORT(attribute_count,p);
theMethodName = 3 + (char *)pConstant[name_index]; /* +3 skips tag and length */
if (0 == strncmp(targetClass,theMethodName,constantLength[name_index])) {
methodToExecute = i;
}
for (j=0; j<attribute_count; ++j) {
p = ProcessAttribute(p,j);
}
}
READSHORT(attributes_count,p);
for (j=0; j<attributes_count; ++j) {
p = ProcessAttribute(p,j);
}
*p_constant_pool = constant_pool;
*p_fields = fields;
*p_methods = methods;
*p_classFile = classFile;
*p_methodToExecute = methodToExecute;
}
//
// Initialize everything for the program, make sure we can run
//
static void Initialize(void)
{
WindowPtr mainPtr;
long i;
/* Initialize all the needed managers. */
InitGraf(&qd.thePort);
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs(nil);
InitCursor();
GetDateTime((unsigned long*) &qd.randSeed);
}
#define RUNCASE(n) \
if (nil != heapSpace) DisposePtr(heapSpace); \
if (nil != returnStack) DisposePtr(returnStack); \
if (nil != classFile) DisposePtr(classFile); \
heapSpace = NewPtrClear(10*1024L*1024); \
returnStack = NewPtrClear(1024); \
methodToExecute = -1; \
DoReadClass(kFileName##n,kTargetClass##n,&constant_pool,&fields,&methods,&classFile,&methodToExecute); \
JavaMiniVM(constant_pool,fields,methods,classFile,methodToExecute,heapSpace,returnStack); \
void main(void)
{
void *constant_pool=nil; /* pointer to cp_info array */
void *fields=nil; /* pointer to field_info array */
void *methods=nil; /* pointer to method_info array */
void *classFile=nil; /* pointer to class file */
long methodToExecute=0; /* index of method to start executing */
void *heapSpace=nil;
void *returnStack=nil;
long result;
char *resultP;
char *s;
short len;
Initialize();
// Case 1
RUNCASE(1)
result = *(long *)returnStack;
if (result == kResult1)
printf("Correct result %ld returned.\n",result);
else
printf("Inorrect result %ld returned, expected %ld.\n",result,kResult1);
printf("\n\n");
// Case 2
RUNCASE(2)
result = *(long *)returnStack;
if (result == kResult2)
printf("Correct result %ld returned.\n",result);
else
printf("Inorrect result %ld returned, expected %ld.\n",result,kResult2);
printf("\n\n");
// Case 3
RUNCASE(3)
// If I understand areturn correctly, the stack has a pointer to a CONSTANT_Utf8 object
resultP = *(char **)returnStack;
len = *(short *)resultP;
s = (char *)(2+resultP);
if ( (len == strlen(kResult3)) && (0 != strncmp(kResult3,s,len) ) )
printf("Correct result \"%s\" returned.\n",s);
else
printf("Inorrect result \"%s\" returned, expected \"%s\".\n",s,kResult3);
printf("\n\n");
// Case 4
RUNCASE(4)
result = *(long *)returnStack;
if (result == kResult4)
printf("Correct result %ld returned.\n",result);
else
printf("Inorrect result %ld returned, expected %ld.\n",result,kResult4);
printf("\n\n");
}