diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f3e7f50 --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +Copyright 2022- bensku + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c4481c4 --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +# code4jvm +code4jvm is a high-level JVM bytecode generation library for writing +compiler backends. It allows generating Java-like code without worrying +about low-level features, while still supporting JVM features that cannot +be expressed in Java. + +The core code4jvm library consists of: +* Automatic stack management and local variable slot tracking +* Stack map frame generation (with control flow tracing) +* An extensible expression system that allows generation of custom bytecode +* Simple control flow (basic blocks, jumps) +* Java-like type conversions (complex casts, boxing) +* Exception handling (including try-finally block support) + +On top of this, some higher-level features are included: +* Structured control flow (conditional blocks, loops) +* Method calls, including use of constructors +* Arithmetic and bitwise operations +* String concatenation +* Enum classes + +Under the hood, JVM bytecode is generated using the low-level +[ASM](https://asm.ow2.io/) library. + +## Usage +As of now, the only use case worth of mentioning is +[lua4jvm](lua4jvm/README.md), a work-in-progress Lua 5.4 implementation for JVM. + +## Status +This library is work-in-progress. It is being worked on in author's spare time, +and there are no guarantees about when bug fixes or new features will be +available. Additionally, code4jvm is not yet published on Maven central. +Naturally, there are also zero guarantees about API stability. + +As you might notice, the documentation is also quite sparse. There are +Javadocs, but beyond them you'd have to learn by example. + +In short: don't use this in production. If you just want to hack around, +feel free to open issues (or even pull requests!). \ No newline at end of file diff --git a/lua4jvm/README.md b/lua4jvm/README.md new file mode 100644 index 0000000..7775092 --- /dev/null +++ b/lua4jvm/README.md @@ -0,0 +1,37 @@ +# lua4jvm +lua4jvm is a work-in-progress JIT compiler for Lua 5.4 built on top +of JVM. Originally, it started as an university course project, but most of +*that* code has been rewritten at least once. + +In its current form, you shouldn't use lua4jvm. While usually reliable, it +lacks the Lua standard library implementation; instead, the development has +focused on core VM features. Rest of the work is arguably easier; the author +has just been busy for a while. + +## Architecture +The lua4jvm lacks formal documentation. However, below is a brief description +of its architecture. + +### Frontend +Lua is parsed with a custom Antlr 4 grammar. From there, it is translated to +an internal IR format that the backend consumes. There is nothing too special +about this; initially, the project included a custom parser, but quite soon I +realized that I wanted to focus on the backend. + +### Backend +Lua is a dynamically typed language with extensive runtime metaprogramming +facilities (metatables). Both of these characteristics make compiling it +into performant code rather difficult. This is especially true when the +compilation target has been primarily built for statically-typed languages; +on JVM, optimizations such as NaN tagging cannot be done. + +To tackle this issue, lua4jvm generally compiles code only immediately before +it would be executed. Function calls generate their targets on first call +based on the real types at call sites; and should the types change, the target +will just get compiled again. The same system is also used for Lua's many +operators, since they can be overridden by metatables. The generated +specializations are cached between all call sites. + +This approach also allows usage of 'static' analysis at runtime. Since the +function compiler effectively knows types of its arguments and upvalues, it +can for example use primitive types for numerical code. \ No newline at end of file diff --git a/src/main/java/fi/benjami/code4jvm/block/Block.java b/src/main/java/fi/benjami/code4jvm/block/Block.java index 2b13292..49cba60 100644 --- a/src/main/java/fi/benjami/code4jvm/block/Block.java +++ b/src/main/java/fi/benjami/code4jvm/block/Block.java @@ -31,14 +31,36 @@ import fi.benjami.code4jvm.statement.Jump; import fi.benjami.code4jvm.statement.Return; import fi.benjami.code4jvm.statement.Throw; +import fi.benjami.code4jvm.structure.IfBlock; +import fi.benjami.code4jvm.structure.LoopBlock; import fi.benjami.code4jvm.typedef.ClassDef; +/** + * A basic block of code. Blocks are lists of statements and nested blocks + * that can be compiled as {@link Method methods}. Blocks can be entered by + * falling through from blocks above them in same method or by + * {@link Jump jumping} directly to them. + * + *
For structured control flow, it is recommended to use
+ * {@link IfBlock} and {@link LoopBlock}
+ *
+ */
public class Block implements CompileHook.Carrier {
+ /**
+ * Creates a new, unnamed block.
+ * @return A new block.
+ */
public static Block create() {
return create("unnamed");
}
+ /**
+ * Creates a new block with a debug name.
+ * @param debugName Name of the block to show in code4jvm's debug
+ * printouts. This is not included in the generated bytecode!
+ * @return A new block.
+ */
public static Block create(String debugName) {
return new Block(new ArrayList<>(), new Scope(), debugName);
}
@@ -74,6 +96,10 @@ private Block(ArrayList