// Date: 09/02/02
// Name: Vijay P. Chauhan
// Supervisor: Dr. Arthur Norman
// "Jlisp to JVM Compiler" - Part II Project
// Fns4.java
// Amended 26/02/02 to accomodate for ClassDescription4.java
// see ClassFileTest4 for more info about the methods for making a class
// Each built-in function is created wrapped in a class
// that is derived from BuiltinFunction.
import java.io.*;
import java.util.*;
import java.util.zip.*;
import java.text.*;
import java.math.*;
class Fns4
{
ClassDescription cd = new ClassDescription();
Code_attribute ca = new Code_attribute();
Method_info mi = new Method_info();
// make sure same ca and mi are not used for additional methods
Object [][] builtins =
{
{"make-java-class", new MakeJavaClassFn()},
{"method-number", new MethodNumberFn()},
{"set-access", new SetAccessFn()},
{"add-code", new AddCodeFn()},
{"add-exceptions", new AddExceptionsFn()},
{"set-this", new SetThisFn()},
{"set-super", new SetSuperFn()},
{"add-class-info", new AddClassInfoFn()},
{"add-methodref", new AddMethodrefFn()},
{"add-fieldref", new AddFieldrefFn()},
{"make-init", new MakeInitFn()},
{"make-method", new MakeMethodFn()},
{"set-stack-locals", new SetStackLocalsFn()},
{"set-label", new SetLabelFn()},
{"lookup-label", new LookupLabelFn()},
{"lookup-ref", new LookupRefFn()},
{"lookup-cinfo", new LookupCinfoFn()},
{"add-instr", new AddInstrFn()},
{"add-instr-args", new AddInstrArgsFn()},
{"finish-method", new FinishMethodFn()},
{"make-cp", new MakeCpFn()},
{"resolve-all", new ResolveAllFn()},
{"print-cp", new PrintCpFn()},
{"finish-class", new FinishClassFn()},
{"print-bytes", new PrintBytesFn()}, // not used
{"bytes-to-file", new BytesToFileFn()}, // for debugging
{"load-class", new LoadClassFn()}, // deprecated
{"instance-from-bytes", new InstanceFromBytesFn()}
};
class MakeJavaClassFn extends BuiltinFunction
{
public LispObject op0() throws Exception
{
cd = new ClassDescription();
//Jlisp.println("MakeJavaClassFn called");
return Jlisp.nil;
}
}
class MethodNumberFn extends BuiltinFunction
{
public LispObject op1(LispObject arg) throws Exception
{
int mnumber = arg.intValue();
cd.mNumber(mnumber);
//Jlisp.println("MethodNumberFn called" + mnumber);
return Jlisp.nil;
}
}
class SetAccessFn extends BuiltinFunction
{
public LispObject op0() throws Exception
{
cd.setAccess((short)(ClassDescription.ACC_PUBLIC |
ClassDescription.ACC_SUPER));
//Jlisp.println("SetAccessFn called");
return Jlisp.nil;
}
}
class AddCodeFn extends BuiltinFunction
{
public LispObject op0() throws Exception
{
cd.addCode();
//Jlisp.println("AddCodeFn called");
return Jlisp.nil;
}
}
class AddExceptionsFn extends BuiltinFunction
{
public LispObject op0() throws Exception
{
cd.addExceptions();
//Jlisp.println("AddExceptionsFn called");
return Jlisp.nil;
}
}
class SetThisFn extends BuiltinFunction
{
public LispObject op1(LispObject a) throws Exception
{
if (!(a instanceof LispString))
return error("argument 1 to set-this must be a string", a);
String name = ((LispString)a).string;
cd.setThis(name);
Jlisp.println("Setting class name: " + name);
return a;
}
}
class SetSuperFn extends BuiltinFunction
{
public LispObject op0() throws Exception
{
cd.setSuper("JavaFn");
//Jlisp.println("Setting super_class: JavaFn");
return Jlisp.nil;
}
public LispObject op1(LispObject a) throws Exception
{
if (!(a instanceof LispString))
return error("argument 1 to set-super must be a string", a);
String name = ((LispString)a).string;
cd.setSuper(name);
//Jlisp.println("Setting super_class: " + name);
return a;
}
}
class AddClassInfoFn extends BuiltinFunction
{
public LispObject op1(LispObject a) throws Exception
{
if (!(a instanceof LispString))
return error("argument 1 to add-class-info must be a string", a);
String name = ((LispString)a).string;
cd.addClassInfo(name);
//Jlisp.println("AddClassInfoFn called for class: " + name);
return Jlisp.nil;
}
}
class AddMethodrefFn extends BuiltinFunction
{
public LispObject opn(LispObject[] args) throws Exception
{
if (args.length != 3)
return error("add-methodref called with " + args.length +
" args when 3 were expected");
String classname = ((LispString)args[0]).string;
String name = ((LispString)args[1]).string;
String descriptor = ((LispString)args[2]).string;
cd.addMethodref(classname, name, descriptor);
//Jlisp.println("AddMethodrefFn called for: "
// +classname+" "+name+" "+descriptor);
return Jlisp.nil;
}
}
class AddFieldrefFn extends BuiltinFunction
{
public LispObject opn(LispObject[] args) throws Exception
{
if (args.length != 3)
return error("add-fieldref called with " + args.length +
" args when 3 were expected");
String classname = ((LispString)args[0]).string;
String name = ((LispString)args[1]).string;
String descriptor = ((LispString)args[2]).string;
cd.addFieldref(classname, name, descriptor);
//Jlisp.println("AddFieldrefFn called for: "
// +classname+" "+name+" "+descriptor);
return Jlisp.nil;
}
}
class MakeInitFn extends BuiltinFunction
{
public LispObject op0() throws Exception
{
Method_info m1 = new Method_info();
cd.addInit(m1);
//Jlisp.println("MakeInitFn called");
return Jlisp.nil;
}
}
class MakeMethodFn extends BuiltinFunction
{
public LispObject op2(LispObject a, LispObject b) throws Exception
{
if (!(a instanceof LispString))
return error("arg1 to make-method must be a string", a);
if (!(b instanceof LispString))
return error("arg2 to make-method must be a string", b);
String name = ((LispString)a).string;
String desc = ((LispString)b).string;
mi = new Method_info();
cd.addMethod(mi, name, desc, true);
mi.setAccess((short)(ClassDescription.ACC_PUBLIC));
mi.attributes_count = (short)2; //because of Exception
//must be PUBLIC for classfileloader6 to invoke it
ca = new Code_attribute();
ca.attribute_name_index = cd.code_Utf8;
//Jlisp.println("MakeMethodFn called");
return Jlisp.nil;
}
}
class SetStackLocalsFn extends BuiltinFunction
{
public LispObject op2(LispObject a, LispObject b) throws Exception
{
int stack = a.intValue();
int locals = b.intValue();
ca.setStackLocals((short)stack,(short)locals);
//Jlisp.println("SetStackLocalsFn called");
return Jlisp.nil;
}
}
class SetLabelFn extends BuiltinFunction
{
public LispObject op1(LispObject a) throws Exception
{
if (!(a instanceof Gensym))
return error("argument 1 to lookup-ref must be a gensym", a);
String label = ((Gensym)a).pname;
cd.setLabel(label, ca);
//Jlisp.println("SetLabelFn called for: " + label);
return Jlisp.nil;
}
}
class LookupLabelFn extends BuiltinFunction
{
public LispObject op1(LispObject a) throws Exception
{
if (!(a instanceof Gensym))
return error("argument 1 to lookup-ref must be a gensym", a);
String label = ((Gensym)a).pname;
cd.lookupLabel(label, ca);
//Jlisp.println("LookupLabelFn called for: " + label);
return Jlisp.nil;
}
}
class LookupRefFn extends BuiltinFunction
{
public LispObject op1(LispObject a) throws Exception
{
if (!(a instanceof LispString))
return error("argument 1 to lookup-ref must be a string", a);
String name = ((LispString)a).string;
cd.lookupRef(name, ca);
//Jlisp.println("LookupRefFn called for: " + name);
LispSmallInteger index = new LispSmallInteger(cd.refIndex);
return index;
}
}
class LookupCinfoFn extends BuiltinFunction
{
public LispObject op1(LispObject a) throws Exception
{
if (!(a instanceof LispString))
return error("argument 1 to lookup-cinfo must be a string", a);
String name = ((LispString)a).string;
cd.lookupCinfo(name, ca, true);
//'true' means 'add to ResolveList' if not found first time
//Jlisp.println("LookupCinfoFn called for: " + name);
LispSmallInteger index = new LispSmallInteger(cd.cinfoIndex);
return index;
}
}
class AddInstrFn extends BuiltinFunction
{
public LispObject op1(LispObject a) throws Exception
{
int opcode = a.intValue();
ca.addInstruction((byte)opcode);
//Jlisp.println("AddInstrFn called");
return Jlisp.nil;
}
}
class AddInstrArgsFn extends BuiltinFunction
{
public LispObject op2(LispObject a, LispObject b) throws Exception
{
int opcode = a.intValue();
int args = b.intValue();
ca.addInstruction((byte)opcode, (short)args);
//assume argument to OPCODE is SHORT value (e.g. goto, if<>)
//Jlisp.println("AddInstrArgsFn called "+opcode+", "+args);
return Jlisp.nil;
}
}
class FinishMethodFn extends BuiltinFunction
{
public LispObject op0() throws Exception
{
Jlisp.println("@@@@@@@@@@@@@@@@@@@@@@@JVM Instructions: "+ca.code_length);
ca.toInfo();
mi.attributes = new Attribute_info[mi.attributes_count];
mi.attributes[0] = ca;
mi.attributes[1] = cd.ea; //Exceptions attribute
cd.methods[cd.methods_count++] = mi;
//Jlisp.println("FinishMethodFn called");
return Jlisp.nil;
}
}
class MakeCpFn extends BuiltinFunction
{
public LispObject op0() throws Exception
{
cd.makeCP();
//Jlisp.println("MakeCpFn called");
return Jlisp.nil;
}
}
class ResolveAllFn extends BuiltinFunction
{
public LispObject op0() throws Exception
{
cd.resolveAll(); // resolve all outstanding references
//Jlisp.println("ResolveAllFn called");
return Jlisp.nil;
}
}
class PrintCpFn extends BuiltinFunction
{
public LispObject op0() throws Exception
{
cd.printCP(); //prints out contents of cp[]
//Jlisp.println("PrintCpFn called");
return Jlisp.nil;
}
}
class FinishClassFn extends BuiltinFunction
{
public LispObject op0() throws Exception
{
cd.dumpBytes(); //need do cd.dumpBytes() once
//Jlisp.println("FinishClassFn called");
return Jlisp.nil;
}
}
class PrintBytesFn extends BuiltinFunction
{
public LispObject op0() throws Exception
{
ByteArray.printBytes(cd.ClassBytes);
//Jlisp.println("PrintBytesFn called");
return Jlisp.nil;
}
}
class BytesToFileFn extends BuiltinFunction
{
public LispObject op0() throws Exception
{
cd.bytesToFile(cd.ClassBytes);
//Jlisp.println("BytesToFileFn called");
return Jlisp.nil;
}
}
class LoadClassFn extends BuiltinFunction //deprecated
{
public LispObject op0() throws Exception
{
return (LispObject)cd.loadCF();
}
}
class InstanceFromBytesFn extends BuiltinFunction
{
public LispObject op0() throws Exception
{
return (LispObject)cd.instanceFromBytes();
}
}
}
// end of Fns4.java