Skip to content

A framework for building compiled class files and bytecode.

License

Notifications You must be signed in to change notification settings

jairopaiva/Foundation

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Foundation

Opus #7

Foundation is designed to simplify the process of building classes and methods with bytecode. Tools like ASM's visitor are very effective but make simple tasks unnecessarily difficult and add cumbersome boilerplate.

This over-complication makes writing simple bytecode-generating utilities more difficult than it needs to be and makes the process unpleasant for beginners, leading people to rely on tools such as 'ASMifier' to create the bytecode-generating code.

While such tools are undoubtedly useful (and appropriate in many situations) users can develop an unnecessary dependency on them and find themselves incapable of designing the bytecode without the tool to do it for them.

Foundation is designed to set a balance between doing too much and too little, while also matching the line format and structure of Java code. Foundation uses ASM internally to create the bytecode and automatically calculate stack map frames and sizes.

Foundation 2

From Foundation 2, instructions do not directly correspond to JVM 'opcodes'. This was changed to make it easier and more intuitive to write code.

Foundation 2 aims to reflect Java code line structure, so that users do not need to worry about managing the stack.

Object var1 = "hello there"
method.line(STORE_VAR.object(1, CONSTANT.of("hello there"));
return var1
method.line(RETURN.object(LOAD_VAR.object(1))));

Maven Information

<repository>
    <id>kenzie</id>
    <url>https://repo.kenzie.mx/releases</url>
</repository>
<dependency>
    <groupId>mx.kenzie</groupId>
    <artifactId>foundation</artifactId>
    <version>2.0.0</version>
    <scope>compile</scope>
</dependency>

Supported Functionality

Foundation supports almost all basic instructions from Java, including variable and field access, method calls, branches, arithmetic and instantiation.

Foundation 2 has dropped support for individual bytecode instructions to provide more safety for beginners handling stack operations.

Examples

Generate and load a very simple class.

class MyClass {
    Class<?> test() {
        final PreClass builder = new PreClass("org.example", "Thing");
        final PreMethod method = new PreMethod(PUBLIC, STATIC, VOID, "main", String[].class);
        method.line(RETURN.none());
        builder.add(method);
        return builder.load(Loader.DEFAULT); // built-in basic class loader
    }
}

This would generate the code:

public class Thing {
    public static void main(String[] args) {
        return;
    }
}

Generate a runnable class.

class MyClass {
    Class<?> test() {
        // references to System.out and out.println(..)
        final CallMethod.Stub target = METHOD.of(PrintStream.class, "println", String.class);
        final AccessField.Stub field = FIELD.of(System.class, "out", PrintStream.class);
        
        final PreClass builder = new PreClass("org.example", "Thing");
        builder.addInterfaces(Runnable.class);
        final PreMethod method = new PreMethod(PUBLIC, VOID, "run");
        method.line(target.call(field.get(), CONSTANT.of("hello there!")));
        method.line(RETURN.none());
        builder.add(method);
        return builder.load(Loader.DEFAULT); // built-in basic class loader
    }
}

This would be the equivalent of:

class Thing implements Runnable {
    @Override // Overrides are implicit.
    public void run() {
        System.out.println("hello there!");
    }
}

About

A framework for building compiled class files and bytecode.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages

  • Java 100.0%