first commit

This commit is contained in:
Jeena Paradies 2011-04-19 11:37:05 +02:00
commit 063194f8be
349 changed files with 36508 additions and 0 deletions

View file

@ -0,0 +1,13 @@
10 October 2004, Jon Meyer
* Moved the jas src code into ../src/jas.
1 March 1997, Jon Meyer
* Modified JAS to use self-contained RuntimeConstants interface.
* Moved JAS classes into the Jasmin classes directory.
* Fixed bug in CatchEntry.

View file

@ -0,0 +1,109 @@
This is v0.3 of a simple Java bytecode assembler.
Quick Info:
-----------
If you want to just quickly check out things, do the following.
% java scm.driver examples/hworld.jas
This compiles an assembler script to bytecode.
% java out
This runs the resultant bytecode, which should print the
string "Hello World" 5 times.
Then read the online documentation at
http://www.blackdown.org/~kbs/jas.html
More Details:
-------------
* What is available:
A simple java bytecode assembler that can be used either as a
standalone scripting program or directly from java (through the jas
package)
* What is not available in this version:
- Error recovery in the scripting interface
- defining a tableswitch or lookupswitch instruction from the scripting
interface
* Documentation
You can leaf through the jas API in reference/jas You can look at
the list of available scripting functions from reference/scm. The
bulk of what documentation exists is online from
http://www.blackdown.org/~kbs/jas.html
UTSL, ofcourse ;-) And documentation is mostly demand-driven,
if there is interest I'll continue to expand it.
* Examples
The examples directory contains a few examples of using the
assembler with the script and directly from java. Look at the
README in this directory to see how to run them. Online
documentation contains more details.
simple.java
simple.jas
These are simple programs that create classes which
don't do anything but get initialized.
hworld.java
hworld.jas
These create bytecode that can be run standalone,
which print a string a few times.
exprcomp.java
This is a primitive compiler that does runtime
codegeneration and execution of arithmetic expressions.
exprcomp.jas
This is a primitive compiler written in jas to translate
jas arithmetic expressions to bytecode.
* Recompiling
You can recompile all classes if you wish. First remove the
jas/ and the scm/ directories under this directory. Then run the
script compile.sh in this directory.
You will probably want to then run the tests in the test directory
to make sure the basic api is functional. Look at the README in this
directory for details.
Running the scripting driver:
-----------------------------
If you are going to use the scripting language, the driver for it is
located in the class scm.driver. The magic incantation is
% java scm.driver [path to file]
If you don't give it a file name, it will try to read from stdin.
Using code from this distribution:
----------------------------------
There is exactly one class that I *use* from the sun/* package, which
is sun.tools.java.RuntimeConstants. I know of no other reasonable way
to keep in sync with the VM.
Outside of this class, (which is not present in this distribution) you
can freely use/modify/sell/dance on with hobnailed boots any or all of
this code. If you do end up using derived code and feel disinclined to
buy me a snowboard :) all I ask is that you add me to the list of
credits.
-KB-
kbs@sbktech.org
Version created: Tue Aug 21 09:50:23 PDT 1996

View file

@ -0,0 +1,52 @@
This contains three examples of using the assembler
from java and from the script
Look up http://www.blackdown.org/~kbs/jas.html for more
documentation. This only tells you how to run the examples. The
documentation is very Unix centric, I apologize.... I have not had
time to set this up on the PC's yet.
simple.java:
simple.jas:
Unexciting program that generates a do nothing class.
Go up a directory and compile simple.java. Run the program,
which generates the bytecode. Disassemble the bytecode
% (cd ..; javac -d . examples/simple.java; java simple; javap -p -c out)
Same thing, but using the script instead of java directly.
% (cd ..; java scm.driver examples/simple.jas; javap -p -c out)
hworld.java:
hworld.jas:
Print a string in a loop.
% (cd ..; javac -d . examples/hworld.java; java hworld; java out)
As before, but use script instead.
% (cd ..; java scm.driver examples/hworld.jas; java out)
exprcomp.java:
Primitive runtime expression compiler. It translates arithmetic
expressions into bytecode and loads it on the fly as a class, which
is run to get the answer. test.inp is an example of the sort of
arithmetic expressions it translates.
% (cd ..; javac -d . examples/exprcomp.java; java exprcomp examples/test.inp)
exprcomp.jas:
Primitive compiler for jas arithmetic expressions (in jas).
jas is fairly expressive, thats about the only point of this
exercise ;-) Unlike the java version, this gets written out
into a file which you'll have to run to get the results.
% (cd ..; java scm.driver examples/exprcomp.jas; java results)

View file

@ -0,0 +1,116 @@
;;; Simple arithmetic expression compiler for jas in jas.
;;;
;;; The compiler is defined in the function
;;; compile-expression
;;;
;;; use as (for instance)
;;; (compile-expression (quote (+ (* 2 (+ 1 3)) 1)))
;;;
;;; This will generate a standalone program called results.class
;;; Run the bytecode interpreter on it as:
;;;
;;; % java results
;;;
;;; which will print the result of the expression
(define compile-expression
(lambda (expr)
(real-compile-expression expr)
(dump-code)))
;; The fun part...
(define real-compile-expression
(lambda (expr)
(cond
((num? expr)
(compile-number expr))
(1 (progn
(real-compile-expression (get-op1 expr))
(real-compile-expression (get-op2 expr))
(compile-op (get-op expr))
(set! cur-stack-height (- cur-stack-height 1)))))))
;; Ah well. Back to boring bookkeeping.
(define compile-number
(lambda (num)
(append-insn (bipush num))
(set! cur-stack-height (+ 1 cur-stack-height))
(cond
((< max-stack-height cur-stack-height)
(set! max-stack-height cur-stack-height)))))
(define compile-op
(lambda (op)
(cond
((eq? op (quote +)) (append-insn (iadd)))
((eq? op (quote -)) (append-insn (isub)))
((eq? op (quote *)) (append-insn (imul)))
((eq? op (quote /)) (append-insn (idiv))))))
(define get-op1
(lambda (expr) (car (cdr expr))))
(define get-op2
(lambda (expr) (car (cdr (cdr expr)))))
(define get-op
(lambda (expr) (car expr)))
(define append-insn
(lambda (insn)
(jas-code-addinsn my-code insn)))
(define cur-stack-height 1)
(define max-stack-height 1)
(define my-code (make-code))
(define my-init-code (make-code))
; define the main() portion,
; and the call to print out the
; results.
(define append-sequence
(lambda (code-part insn-list)
(mapcar (lambda (insn) (jas-code-addinsn code-part insn))
insn-list)))
(append-sequence
my-init-code
(quote
((aload_0)
(invokenonvirtual (make-method-cpe "java/lang/Object" "<init>" "()V"))
(return))))
(define dump-code
(lambda ()
(define my-env (make-class-env))
(jas-class-setclass my-env (make-class-cpe "results"))
(jas-class-setsuperclass my-env (make-class-cpe "java/lang/Object"))
(jas-class-addmethod my-env acc-public "<init>" "()V" my-init-code ())
(append-sequence
my-code
(quote
((getstatic
(make-field-cpe "java/lang/System" "out" "Ljava/io/PrintStream;"))
(swap)
(invokevirtual (make-method-cpe
"java/io/PrintStream" "println" "(I)V"))
(return))))
(jas-code-stack-size my-code max-stack-height)
(jas-class-addmethod my-env
(| acc-public acc-static)
"main" "([Ljava/lang/String;)V" my-code ())
(jas-class-write my-env
(make-outputstream "results.class"))))
;;;
;;; example usage of compiler.
;;;
;;; run the compiled class with
;;; % java results
;;; to get the answer.
(compile-expression (quote (+ (* 2 (+ 1 3)) 1)))

View file

@ -0,0 +1,242 @@
// Primitive runtime code generation of expressions. This is a jas
// implementation of the example in Aho Sethi Ullman.
//
// You pass to it statements of the form
// a = 1*2 + 3*5;
// Only integer operations are allowed, and variables
// are magically created by using them in the LHS of a statement.
//
// You can print out the value of expressions with the println keyword:
// println(a + 10);
//
// It compiles this into a bytearray, and then loads it as
// a new class.
//
// Unfortunately, this trick cannot be used in an applet --- security
// restrictions prevent ClassLoaders from being placed on the
// stack. So much for writing regexp compilers that can do codegen instead of
// state tables.
//
// The grammar is simple, so code generation is part of the parsing
// step. Operator precedence is directly handled by the grammar.
//
// Grammar + production rules:
//
// start -> list EOF
// list -> id = expr ; { emit(istore, id.index); } list
// | println expr ; { emit(<println sequence>); } list
// | lambda
// expr -> term moreterms
// moreterms -> + term { emit(iadd) } moreterms
// | - term { emit(isub) } moreterms
// | lambda
// term -> factor morefactors
// morefactors -> * factor { emit(imul) } morefactors
// | / factor { emit(idiv) } morefactors
// | lambda
// factor -> ( expr )
// | number { emit(iconst, number.value) }
// | id { emit(iload, id.index); }
import java.util.*;
import java.io.*;
import jas.*;
import sun.tools.java.RuntimeConstants;
public class exprcomp implements RuntimeConstants
{
StreamTokenizer inp;
CodeAttr myCode;
short cur_stack_height;
short max_stack_height;
short max_vars;
Hashtable vars;
public exprcomp(StreamTokenizer inp)
throws jasError
{
inp.eolIsSignificant(false);
this.inp = inp;
myCode = new CodeAttr();
// Add initializations
myCode.addInsn(new Insn(opc_aload_0));
myCode.addInsn(new Insn(opc_invokenonvirtual,
new MethodCP("java/lang/Object",
"<init>", "()V")));
cur_stack_height = max_stack_height = 1;
vars = new Hashtable();
max_vars = 1;
}
public void write(DataOutputStream out)
throws IOException, jasError
{
ClassEnv clazz = new ClassEnv();
myCode.setStackSize(max_stack_height);
myCode.setVarSize(max_vars);
// add initializer to class
clazz.addMethod
((short) ACC_PUBLIC, "<init>", "()V", myCode, null);
clazz.setClassAccess((short) ACC_PUBLIC);
clazz.setClass(new ClassCP("results"));
clazz.setSuperClass(new ClassCP("java/lang/Object"));
clazz.write(out);
}
public void parse()
throws IOException, parseError, jasError
{
inp.nextToken();
while(inp.ttype != inp.TT_EOF)
{
if (inp.ttype != inp.TT_WORD)
{
throw new parseError("Expected an id at line " + inp.lineno());
}
if (inp.sval.equals("println"))
{
match(inp.TT_WORD);
expr();
match(';');
emit(new Insn(opc_getstatic,
new FieldCP("java/lang/System",
"out", "Ljava/io/PrintStream;")));
emit(new Insn(opc_swap));
emit(new Insn(opc_invokevirtual,
new MethodCP("java/io/PrintStream",
"println", "(I)V")));
}
else
{ // search, maybe add into var list
Integer idx;
if ((idx = (Integer) vars.get(inp.sval)) == null)
{
idx = new Integer(max_vars++);
vars.put(inp.sval.intern(), idx);
}
match(inp.TT_WORD); match('='); expr(); match(';');
emit(new Insn(opc_istore, idx.intValue()));
}
}
emit(new Insn(opc_return));
}
void expr()
throws IOException, parseError, jasError
{
term();
while (true)
{
switch(inp.ttype)
{
case '+':
match('+'); term(); emit(new Insn(opc_iadd)); break;
case '-':
match('-'); term(); emit(new Insn(opc_isub)); break;
default: return;
}
cur_stack_height--;
}
}
void term()
throws IOException, parseError, jasError
{
factor();
while (true)
{
switch(inp.ttype)
{
case '*': match('*'); factor(); emit(new Insn(opc_imul)); break;
case '/': match('/'); factor(); emit(new Insn(opc_idiv)); break;
default: return;
}
cur_stack_height --;
}
}
void factor()
throws IOException, parseError, jasError
{
switch(inp.ttype)
{
case '(': match('('); expr(); match(')'); break;
case inp.TT_NUMBER:
int val = (int)(inp.nval);
emit(new Insn(opc_bipush, (short)val));
match(inp.TT_NUMBER);
break;
case inp.TT_WORD:
Integer idx;
if ((idx = (Integer) vars.get(inp.sval)) == null)
{
throw new parseError
("Unknown variable " + inp.sval + " at line " + inp.lineno());
}
emit(new Insn(opc_iload, idx.intValue()));
match(inp.TT_WORD);
break;
default:
throw new parseError("Syntax error at line " + inp.lineno());
}
cur_stack_height++;
if (max_stack_height < cur_stack_height)
max_stack_height = cur_stack_height;
}
void match(int val)
throws IOException, parseError
{
if (inp.ttype != val)
{ throw new parseError
("line " + inp.lineno() + ": expected " + val + " but got " + inp); }
inp.nextToken();
}
void emit(Insn insn)
{
myCode.addInsn(insn);
}
public static void main(String argv[])
throws Exception
{
exprcomp compiler =
new exprcomp(new StreamTokenizer(new FileInputStream(argv[0])));
compiler.parse();
ByteArrayOutputStream data = new ByteArrayOutputStream();
compiler.write(new DataOutputStream(data));
dynaloader dl = new dynaloader(data.toByteArray());
dl.exec();
}
}
class dynaloader extends ClassLoader
{
Hashtable cache;
Class ex;
dynaloader(byte[] data)
throws ClassFormatError
{
cache = new Hashtable();
ex = defineClass(data, 0, data.length);
cache.put("results", ex);
resolveClass(ex);
}
void exec() throws Exception { ex.newInstance(); }
public synchronized Class loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
Class c = (Class) cache.get(name);
if (c == null)
{
c = findSystemClass(name);
cache.put(name, c);
}
if (resolve) resolveClass(c);
return c;
}
}
class parseError extends Exception
{ parseError(String s) { super(s); } }

View file

@ -0,0 +1,87 @@
;; create a container
(define my-class (make-class-env))
;; specify class hierarchy
(jas-class-setaccess my-class acc-public)
(jas-class-setclass my-class (make-class-cpe "out"))
(jas-class-setsuperclass my-class (make-class-cpe "java/lang/Object"))
;; write a convenience function to append insns as a list.
(define append-code
(lambda (code-part insn-list)
(mapcar (lambda (insn) (jas-code-addinsn code-part insn))
insn-list)))
;; Define code for initializer
;;
(define init-it (make-code))
(append-code
init-it
(quote
((aload_0)
(invokenonvirtual (make-method-cpe "java/lang/Object" "<init>" "()V"))
(return))))
;; this is the code that comprises
;; the actual task, ie the code for
;; main(String argv[]).
;; print a string 5 times
(define doit (make-code))
(append-code
doit
(quote
(
; store references in local
; variables to avoid field/cp
; lookup
(getstatic
(make-field-cpe "java/lang/System" "out" "Ljava/io/PrintStream;"))
(astore_1)
(ldc (make-string-cpe "Hello World"))
(astore_2)
(bipush 5)
(istore_3) ; store loop index in var reg 3
; loop 5 times, printing out
; the string.
(make-label "loop")
; push arguments to function
; on stack and call it
(aload_1) (aload_2)
(invokevirtual
(make-method-cpe "java/io/PrintStream" "println" "(Ljava/lang/String;)V"))
; decrement loop index
(iinc 3 -1)
(iload_3)
(ifne (make-label "loop"))
(return))))
;; set stack/var size
(jas-code-stack-size doit 3)
(jas-code-var-size doit 4)
;; fill up the class with the methods
;; first the initializer.
(jas-class-addmethod my-class acc-public "<init>" "()V" init-it ())
;; define the printing code as a static main(String argv[]) method
(jas-class-addmethod my-class
(| acc-static acc-public)
"main" "([Ljava/lang/String;)V" doit ())
;; write it out.
(jas-class-write my-class (make-outputstream "out.class"))

View file

@ -0,0 +1,78 @@
import jas.*;
import java.io.*;
import sun.tools.java.RuntimeConstants;
//
// This is program that makes calls into the jas package
// to generate a class that prints a string afew times.
//
class hworld implements RuntimeConstants
{
public static void main(String argv[])
throws jasError, IOException
{
// class hierarchy
ClassEnv nclass = new ClassEnv();
nclass.setClass(new ClassCP("out"));
nclass.setSuperClass(new ClassCP("java/lang/Object"));
nclass.setClassAccess((short)ACC_PUBLIC);
// Initialization code
CodeAttr init = new CodeAttr();
init.addInsn(new Insn(opc_aload_0));
init.addInsn(new Insn(opc_invokenonvirtual,
new MethodCP("java/lang/Object", "<init>", "()V")));
init.addInsn(new Insn(opc_return));
// Actual code to print string
CodeAttr doit = new CodeAttr();
// store refs in local variables
doit.addInsn(new Insn(opc_getstatic,
new FieldCP("java/lang/System",
"out",
"Ljava/io/PrintStream;")));
doit.addInsn(new Insn(opc_astore_1));
doit.addInsn(new Insn(opc_ldc,
new StringCP("Hello World")));
doit.addInsn(new Insn(opc_astore_2));
// Loop index in var reg 3
doit.addInsn(new Insn(opc_bipush, 5));
doit.addInsn(new Insn(opc_istore_3));
// Start the loop
Label loop = new Label("loop");
doit.addInsn(loop);
doit.addInsn(new Insn(opc_aload_1));
doit.addInsn(new Insn(opc_aload_2));
doit.addInsn(new Insn(opc_invokevirtual,
new MethodCP("java/io/PrintStream",
"println",
"(Ljava/lang/String;)V")));
doit.addInsn(new IincInsn(3, -1));
doit.addInsn(new Insn(opc_iload_3));
doit.addInsn(new Insn(opc_ifne, loop));
doit.addInsn(new Insn(opc_return));
// set the right sizes for code
doit.setStackSize((short)3); doit.setVarSize((short)4);
// Add the init code to the class.
nclass.addMethod((short)ACC_PUBLIC, "<init>", "()V", init, null);
// Add the printing code
nclass.addMethod((short)(ACC_PUBLIC|ACC_STATIC), "main",
"([Ljava/lang/String;)V", doit, null);
// write it all out
nclass.write(new DataOutputStream
(new FileOutputStream("out.class")));
}
}

View file

@ -0,0 +1,30 @@
;; script to create a class that does nothing.
; make-class-env creates
; a ClassEnv object which is
; used to store information about
; an object.
(define my-class (make-class-env))
; make-code creates a code object
; which contains the body of a
; method.
(define init-code (make-code))
(jas-code-addinsn init-code
(aload_0))
(jas-code-addinsn init-code
(invokenonvirtual
(make-method-cpe "java/lang/Object" "<init>" "()V")))
(jas-code-addinsn init-code
(return))
; fill up the class with goodies
(jas-class-setsuperclass my-class (make-class-cpe "java/lang/Object"))
(jas-class-setclass my-class (make-class-cpe "out"))
(jas-class-setaccess my-class acc-public)
(jas-class-addmethod my-class acc-public "<init>" "()V" init-code ())
; and write it all out
(jas-class-write my-class (make-outputstream "out.class"))

View file

@ -0,0 +1,45 @@
import jas.*;
import java.io.*;
import sun.tools.java.RuntimeConstants;
//
// This is program that makes calls into the jas package
// to generate a class that does nothing at all.
//
class simple implements RuntimeConstants
{
public static void main(String argv[])
throws jasError, IOException
{
// CodeAttr's contain the body of
// a method.
CodeAttr init = new CodeAttr();
init.addInsn(new Insn(opc_aload_0));
init.addInsn(new Insn(opc_invokenonvirtual,
new MethodCP("java/lang/Object", "<init>", "()V")));
init.addInsn(new Insn(opc_return));
// ClassEnv's are used as a container
// to hold all information about a class.
ClassEnv nclass = new ClassEnv();
nclass.setClass(new ClassCP("out"));
nclass.setSuperClass(new ClassCP("java/lang/Object"));
// Add the init code to the class.
nclass.addMethod((short)ACC_PUBLIC, "<init>", "()V", init, null);
// write it all out
nclass.write(new DataOutputStream
(new FileOutputStream("out.class")));
}
}

View file

@ -0,0 +1,8 @@
a = 10;
println a;
b = a + 5;
println (b);
println(a*b +2);

View file

@ -0,0 +1,16 @@
This is a start of a basic set of tests intended to exercise the API
functions available in the jas and scm packages. It is not complete by
any means.
all.java tries to touch as much of the jas API as it can, generating a
non functional class called regress.class. all.jas does
something similar, but for the scm package.
Once the jas and scm packages are compiled, do this:
% (cd ..; javac -d . tests/all.java; java all; cmp regress.class tests/regress.class)
% (cd ..; java scm.driver tests/all.jas; cmp scmregress.class tests/scmregress.class)
If both these complete silently, you are in good shape. Otherwise,
mail me a bug report and enough details for me to replicate it :)

View file

@ -0,0 +1,72 @@
(define my-env (make-class-env))
(jas-class-addcpe my-env (make-ascii-cpe "fubar"))
(jas-class-addcpe my-env (make-class-cpe "java/lang/Number"))
(jas-class-addcpe my-env (make-double-cpe 2.0))
(jas-class-addcpe my-env
(make-field-cpe "java/lang/System" "out" "Ljava/io/PrintStream;"))
(jas-class-addcpe my-env (make-float-cpe 2.0))
(jas-class-addcpe my-env (make-integer-cpe 2))
(jas-class-addcpe my-env
(make-interface-cpe "java/lang/Runnable" "run" "()V"))
(jas-class-addcpe my-env (make-long-cpe 2))
(jas-class-addcpe my-env
(make-method-cpe "java/lang/Thread" "run" "()V"))
(jas-class-addcpe my-env
(make-name-type-cpe "sdfsdf" "Ljava/lang/Object;"))
(jas-class-addcpe my-env (make-string-cpe "sdf"))
(jas-class-addfield my-env
(make-field
acc-public (make-ascii-cpe "someIntVar") (make-ascii-cpe "I") ()))
(jas-class-addfield my-env
(make-field
(| acc-public acc-static) (make-ascii-cpe "finalInt")
(make-ascii-cpe "I") (make-const (make-integer-cpe 10.2))))
(jas-class-addinterface my-env (make-class-cpe "java/lang/Runnable"))
(jas-class-setclass my-env (make-class-cpe "scmregress"))
(jas-class-setsuperclass my-env (make-class-cpe "java/lang/Object"))
(jas-class-setaccess my-env acc-public)
(define my-code (make-code))
(jas-code-addinsn my-code (return))
(jas-code-addinsn my-code (astore 5))
(jas-code-addinsn my-code (make-label "First label"))
(jas-code-addinsn my-code (jsr (make-label "First label")))
(define saved-label (make-label "second_label"))
(jas-code-addinsn my-code saved-label)
(jas-code-addinsn my-code (ldc_w (make-string-cpe "sdfsdf")))
(jas-code-addinsn my-code (iinc 2 -2))
(jas-code-addinsn my-code
(invokeinterface
(make-class-cpe "java/lang/Number") 1))
(jas-code-addinsn my-code (multianewarray (make-class-cpe "java/lang/Double")
3))
(define ctb (make-catchtable))
(jas-add-catch-entry ctb (make-catch-entry
(make-label "First label")
saved-label
saved-label
(make-class-cpe "java/lang/Exception")))
(jas-add-catch-entry ctb (make-catch-entry
(make-label "First label")
saved-label
saved-label
(make-class-cpe "java/lang/Error")))
(jas-set-catchtable my-code ctb)
(jas-code-stack-size my-code 100)
(jas-code-var-size my-code 100)
(define my-except (make-exception))
(jas-exception-add my-except (make-class-cpe "java/io/IOException"))
(jas-exception-add my-except (make-class-cpe "java/lang/Error"))
(jas-class-addmethod my-env
acc-public
"somemethod"
"(I)V"
my-code
my-except)
(jas-class-write my-env (make-outputstream "scmregress.class"))

View file

@ -0,0 +1,155 @@
// Simply try
// to access as much of
// the API as possible.
import jas.*;
import java.io.*;
import sun.tools.java.RuntimeConstants;
public class all implements RuntimeConstants
{
public static void main(String argv[])
throws Exception
{
ClassEnv c = new ClassEnv();
// Adding CP Items directly
c.addCPItem(new AsciiCP("fubar"));
c.addCPItem(new ClassCP("java/lang/Number"));
c.addCPItem(new DoubleCP(2.0));
c.addCPItem(new FieldCP("java/lang/System",
"out",
"Ljava/io/PrintStream;"));
c.addCPItem(new FloatCP((float)(2.0)));
c.addCPItem(new IntegerCP(2));
c.addCPItem(new InterfaceCP("java/lang/Runnable",
"run",
"()V"));
c.addCPItem(new LongCP(2));
c.addCPItem(new MethodCP("java/lang/Thread",
"run",
"()V"));
c.addCPItem(new NameTypeCP("sdfsdf", "Ljava/lang/Object;"));
c.addCPItem(new StringCP("sdf"));
// Add fields, creating variables
c.addField(new Var((short) ACC_PUBLIC,
new AsciiCP("someIntvar"),
new AsciiCP("I"),
null));
c.addField(new Var((short)(ACC_PUBLIC|ACC_STATIC|ACC_FINAL),
new AsciiCP("finalInt"),
new AsciiCP("I"),
new ConstAttr(new IntegerCP(10))));
// Check if I can add interfaces
c.addInterface(new ClassCP("java/lang/Runnable"));
c.setClass(new ClassCP("regress"));
c.setSuperClass(new ClassCP("java/lang/Object"));
c.setClassAccess((short) ACC_PUBLIC);
// Creating code.
CodeAttr code = new CodeAttr();
// add instructions of various
// operand types.
// No operands
code.addInsn(new Insn(opc_return));
// one arg operands
code.addInsn(new Insn(opc_astore, 5));
// one arg arguments with wide operand
code.addInsn(new Insn(opc_dstore, 256));
code.addInsn(new Insn(opc_istore, 2576));
// Add a label
code.addInsn(new Label("First label"));
// refer back to it
code.addInsn(new Insn(opc_jsr,
new Label("First label")));
// add another label
code.addInsn(new Label("second_label"));
// insn with CP argument
code.addInsn(new Insn(opc_ldc_w, new StringCP("sdfsdf")));
// the "special" instructions
code.addInsn(new IincInsn(2, -2));
// wider version check
code.addInsn(new IincInsn(1234, 2));
code.addInsn(new IincInsn(3, -200));
code.addInsn(new InvokeinterfaceInsn(new ClassCP("java/lang/Number"), 1));
code.addInsn(new MultiarrayInsn(new ClassCP("java/lang/Double"), 3));
Label woo[] = new Label[3];
woo[0] = new Label("First label");
woo[1] = new Label("second_label");
woo[2] = new Label("second_label");
code.addInsn(new TableswitchInsn(0, 2, woo[0], woo));
int m[] = new int[3];
m[0] = 11;
m[1] = 15;
m[2] = -1;
code.addInsn(new LookupswitchInsn(woo[0], m, woo));
// make a catchtable
Catchtable ctb = new Catchtable();
// add a couple of entries
ctb.addEntry(new Label("First label"),
new Label("second_label"),
new Label("second_label"),
new ClassCP("java/lang/Exception"));
ctb.addEntry(new Label("First label"),
new Label("second_label"),
new Label("second_label"),
new ClassCP("java/lang/Error"));
code.setCatchtable(ctb);
code.setStackSize((short)100);
code.setVarSize((short)500);
// Add some line table info
LineTableAttr ln = new LineTableAttr();
ln.addEntry(woo[0], 234);
ln.addEntry(woo[1], 245);
ln.addEntry(woo[2], 22);
code.setLineTable(ln);
// Add a generic attr to a method
String foo = "sldkfj sdlfkj";
byte dat[] = new byte[foo.length()];
foo.getBytes(0, dat.length, dat, 0);
code.addGenericAttr(new GenericAttr("strangeAttr", dat));
// Also adding local varinfo
LocalVarTableAttr lv = new LocalVarTableAttr();
lv.addEntry(new LocalVarEntry(woo[0], woo[2], "fakevar", "I", 22));
lv.addEntry(new LocalVarEntry(woo[1], woo[1], "morefa", "()V", 10));
code.setLocalVarTable(lv);
// check out add method, also
// adding a throws exception for
// good measure
ExceptAttr ex = new ExceptAttr();
ex.addException(new ClassCP("java/io/IOException"));
ex.addException(new ClassCP("java/lang/Error"));
c.addMethod((short) ACC_PUBLIC,
"fubarmethod",
"()V",
code,
ex);
// Add a source file attribute
c.setSource(new SourceAttr("all.java"));
// Add some more generic attribute
c.addGenericAttr(new GenericAttr("blahAttr", dat));
c.write(new DataOutputStream(new FileOutputStream("regress.class")));
}
}

Binary file not shown.

Binary file not shown.